diff --git a/Rakefile b/Rakefile index 7ed056b..4483c20 100644 --- a/Rakefile +++ b/Rakefile @@ -1,21 +1,58 @@ require 'rake/clean' -require_relative 'lib/lib_sec_file.rb' +require_relative 'lib/lib_src_file.rb' require_relative 'lib/lib_src2md.rb' require_relative 'lib/lib_gen_main_tex.rb' require_relative 'lib/lib_add_head_tail_html.rb' -srcfiles = [] +secfiles = [] FileList['src/sec*.src.md'].each do |file| - srcfiles << Sec_file.new(file) + secfiles << Sec_file.new(file) end -srcfiles = Sec_files.new srcfiles -srcfiles.renum! +secfiles = Sec_files.new secfiles +secfiles.renum! + +def basename srcfile + File.basename(srcfile, ".src.md") +end + +abstract = Src_file.new "src/abstract.src.md" + +otherfiles = ["src/turtle/turtle_doc.src.md", + "src/tfetextview/tfetextview_doc.src.md", + "src/Readme_for_developers.src.md"] +otherfiles = otherfiles.map {|file| Src_file.new file} +srcfiles = secfiles + otherfiles + +file_table = srcfiles.map do |srcfile| + [ + srcfile, + "gfm/" + srcfile.to_md, + "html/" + srcfile.to_html, + "latex/" + srcfile.to_tex + ] +end + +# Paths are relative from the directory "src". +file_table_src = srcfiles.map do |srcfile| + [ + srcfile.sub(/^src\//, ""), + "../gfm/" + srcfile.to_md, + "../html/" + srcfile.to_html, + "../latex/" + srcfile.to_tex + ] +end + +othermdfiles = otherfiles.map {|file| "gfm/" + file.to_md} +otherhtmlfiles = otherfiles.map {|file| "html/" + file.to_html} +othertexfiles = otherfiles.map {|file| "latex/" + file.to_tex} + +mdfiles = srcfiles.map {|file| "gfm/" + file.to_md} +htmlfiles = srcfiles.map {|file| "html/" + file.to_html} +sectexfiles = secfiles.map {|file| "latex/" + file.to_tex} +othertexfiles = otherfiles.map {|file| "latex/" + file.to_tex} +texfiles = srcfiles.map {|file| "latex/" + file.to_tex} -mdpathnames = srcfiles.map {|srcfile| "gfm/#{srcfile.to_md}"} -htmlpathnames = srcfiles.map {|srcfile| "html/#{srcfile.to_html}"} -texpathnames = srcfiles.map {|srcfile| "latex/#{srcfile.to_tex}"} -texfilenames = srcfiles.map {|srcfile| srcfile.to_tex} ["gfm", "html", "latex"].each do |d| if ! Dir.exist?(d) @@ -23,7 +60,7 @@ texfilenames = srcfiles.map {|srcfile| srcfile.to_tex} end end -CLEAN.append(*mdpathnames) +CLEAN.append(*mdfiles) CLEAN << "Readme.md" # tasks @@ -31,61 +68,57 @@ CLEAN << "Readme.md" task default: :md task all: [:md, :html, :pdf] -task md: ["Readme.md", "src/turtle/turtle_doc.md"] +task md: %w[Readme.md] + mdfiles -file "Readme.md" => mdpathnames+["src/abstract.src.md"] do +file "Readme.md" => [abstract] + secfiles do buf = [ "# Gtk4 Tutorial for beginners\n", "\n" ] - src2md "src/abstract.src.md", "abstract.md" - buf += File.readlines("abstract.md") - File.delete("abstract.md") + src2md abstract, abstract.to_md, file_table_src, "gfm" + buf += File.readlines(abstract.to_md) + File.delete(abstract.to_md) buf.append("\n", "## Table of contents\n", "\n") - 0.upto(srcfiles.size-1) do |i| - h = File.open(srcfiles[i].path) { |file| file.readline } + 0.upto(secfiles.size-1) do |i| + h = File.open(secfiles[i].path) { |file| file.readline } h = h.gsub(/^#* */,"").chomp - buf << "1. [#{h}](gfm/#{srcfiles[i].to_md})\n" + buf << "1. [#{h}](gfm/#{secfiles[i].to_md})\n" end File.write("Readme.md", buf.join) end -0.upto(srcfiles.size - 1) do |i| - file "gfm/#{srcfiles[i].to_md}" => (srcfiles[i].c_files << srcfiles[i].path) do - src2md srcfiles[i].path, "gfm/#{srcfiles[i].to_md}" - if srcfiles.size == 1 - nav = "Up: [Readme.md](../Readme.md)\n" - elsif i == 0 - nav = "Up: [Readme.md](../Readme.md), Next: [Section 2](#{srcfiles[1].to_md})\n" - elsif i == srcfiles.size - 1 - nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{srcfiles[i-1].to_md})\n" - else - nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{srcfiles[i-1].to_md}), Next: [Section #{i+2}](#{srcfiles[i+1].to_md})\n" +file_table.each do |tbl| + file tbl[1] => tbl[0] do + src2md tbl[0], tbl[1], file_table_src, "gfm" + if tbl[0].instance_of? Sec_file + i = tbl[0].num.to_i - 1 + if secfiles.size == 1 + nav = "Up: [Readme.md](../Readme.md)\n" + elsif i == 0 + nav = "Up: [Readme.md](../Readme.md), Next: [Section 2](#{secfiles[1].to_md})\n" + elsif i == secfiles.size - 1 + nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{secfiles[i-1].to_md})\n" + else + nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{secfiles[i-1].to_md}), Next: [Section #{i+2}](#{secfiles[i+1].to_md})\n" + end + buf = [nav, "\n"] + buf += File.readlines tbl[1] + buf.append("\n", nav) + File.write tbl[1], buf.join end - buf = File.readlines "gfm/#{srcfiles[i].to_md}" - buf.insert(0, nav, "\n") - buf.append("\n", nav) - File.write "gfm/#{srcfiles[i].to_md}", buf.join end end -file "src/turtle/turtle_doc.md" => "src/turtle/turtle_doc.src.md" do - src2md "src/turtle/turtle_doc.src.md", "src/turtle/turtle_doc.md" -end +task html: ["html/index.html"] + htmlfiles -task html: ["html/index.html", "html/tfetextview_doc.html", "html/turtle_doc.html", "html/Readme_for_developers.html"] - -file "html/index.html" => htmlpathnames+["src/abstract.src.md"] do +file "html/index.html" => [abstract] + secfiles do buf = [ "# Gtk4 Tutorial for beginners\n", "\n" ] - src2md "src/abstract.src.md", "html/abstract.md" - buf += File.readlines("html/abstract.md") - File.delete("html/abstract.md") + abstract_md = "html/#{abstract.to_md}" + src2md abstract, abstract_md, file_table_src, "html" + buf += File.readlines(abstract_md) + File.delete(abstract_md) buf.append("\n", "## Table of contents\n", "\n") - 0.upto(srcfiles.size-1) do |i| - h = File.open(srcfiles[i].path) { |file| file.readline } + 0.upto(secfiles.size-1) do |i| + h = File.open(secfiles[i].path) { |file| file.readline } h = h.gsub(/^#* */,"").chomp - buf << "1. [#{h}](#{srcfiles[i].to_html})\n" - end - buf.each do |line| - line.gsub!(/doc\/Readme_for_developers.md/,"html/Readme_for_developers.html") - line.gsub!(/(\[[^\]]*\])\((.+)\.md\)/,"\\1(\\2.html)") + buf << "1. [#{h}](#{secfiles[i].to_html})\n" end File.write("html/index.md", buf.join) sh "pandoc -o html/index.html html/index.md" @@ -93,47 +126,29 @@ file "html/index.html" => htmlpathnames+["src/abstract.src.md"] do add_head_tail_html "html/index.html" end -file "html/tfetextview_doc.html" => "src/tfetextview/tfetextview_doc.md" do - sh "pandoc -o html/tfetextview_doc.html src/tfetextview/tfetextview_doc.md" - add_head_tail_html "html/tfetextview_doc.html" -end - -file "html/turtle_doc.html" => "src/turtle/turtle_doc.src.md" do - src2md "src/turtle/turtle_doc.src.md", "html/turtle_doc.md" - sh "pandoc -o html/turtle_doc.html html/turtle_doc.md" - File.delete "html/turtle_doc.md" - add_head_tail_html "html/turtle_doc.html" -end - -file "html/Readme_for_developers.html" => "doc/Readme_for_developers.md" do - sh "pandoc -o html/Readme_for_developers.html doc/Readme_for_developers.md" - add_head_tail_html "html/Readme_for_developers.html" -end - -0.upto(srcfiles.size - 1) do |i| - html_md = "html/#{srcfiles[i].to_md}" - html_html = "html/#{srcfiles[i].to_html}" - file html_html => (srcfiles[i].c_files << srcfiles[i].path) do - src2md srcfiles[i].path, html_md - if srcfiles.size == 1 - nav = "Up: [index.html](index.html)\n" - elsif i == 0 - nav = "Up: [index.html](index.html), Next: [Section 2](#{srcfiles[1].to_html})\n" - elsif i == srcfiles.size - 1 - nav = "Up: [index.html](index.html), Prev: [Section #{i}](#{srcfiles[i-1].to_html})\n" - else - nav = "Up: [index.html](index.html), Prev: [Section #{i}](#{srcfiles[i-1].to_html}), Next: [Section #{i+2}](#{srcfiles[i+1].to_html})\n" +file_table.each do |tbl| + file tbl[2] => tbl[0] do + html_md = "html/" + tbl[0].to_md + src2md tbl[0], html_md, file_table_src, "html" + if tbl[0].instance_of? Sec_file + i = tbl[0].num.to_i - 1 # 0 based index + if secfiles.size == 1 + nav = "Up: [index.html](index.html)\n" + elsif i == 0 + nav = "Up: [index.html](index.html), Next: [Section 2](#{secfiles[1].to_html})\n" + elsif i == secfiles.size - 1 + nav = "Up: [index.html](index.html), Prev: [Section #{i}](#{secfiles[i-1].to_html})\n" + else + nav = "Up: [index.html](index.html), Prev: [Section #{i}](#{secfiles[i-1].to_html}), Next: [Section #{i+2}](#{secfiles[i+1].to_html})\n" + end + buf = [nav, "\n"] + buf += File.readlines html_md + buf.append("\n", nav) + File.write html_md, buf.join end - buf = File.readlines html_md - buf.insert(0, nav, "\n") - buf.append("\n", nav) - buf.each do |line| - line.gsub!(/(\[[^\]]*\])\((.+)\.md\)/,"\\1(\\2.html)") - end - File.write html_md, buf.join - sh "pandoc -o #{html_html} #{html_md}" + sh "pandoc -o #{tbl[2]} #{html_md}" File.delete(html_md) - add_head_tail_html html_html + add_head_tail_html tbl[2] end end @@ -145,33 +160,24 @@ end task latex: ["latex/main.tex"] -file "latex/main.tex" => ["latex/abstract.tex", "latex/tfetextview_doc.tex", "latex/turtle_doc.tex"] + texpathnames do - gen_main_tex "latex", texfilenames, ["tfetextview_doc.tex", "turtle_doc.tex"] +file "latex/main.tex" => ["latex/abstract.tex"]+texfiles do + gen_main_tex "latex", sectexfiles, othertexfiles end -file "latex/abstract.tex" => "src/abstract.src.md" do - src2md "src/abstract.src.md", "latex/abstract.md" - sh "pandoc --listings -o latex/abstract.tex latex/abstract.md" - File.delete("latex/abstract.md") +abstract_tex = "latex/"+abstract.to_tex +file abstract_tex => abstract do + abstract_md = "latex/"+abstract.to_md + src2md abstract, abstract_md, file_table_src, "latex" + sh "pandoc --listings -o #{abstract_tex} #{abstract_md}" + File.delete(abstract_md) end -file "latex/tfetextview_doc.tex" => "src/tfetextview/tfetextview_doc.md" do - sh "pandoc --listings -o latex/tfetextview_doc.tex src/tfetextview/tfetextview_doc.md" -end - -file "latex/turtle_doc.tex" => "src/turtle/turtle_doc.src.md" do - src2md "src/turtle/turtle_doc.src.md", "latex/turtle_doc.md" - sh "pandoc --listings -o latex/turtle_doc.tex latex/turtle_doc.md" - File.delete("latex/turtle_doc.md") -end - -0.upto(srcfiles.size - 1) do |i| - latex_md = "latex/#{srcfiles[i].to_md}" - latex_tex = "latex/#{srcfiles[i].to_tex}" - file latex_tex => (srcfiles[i].c_files << srcfiles[i].path) do - src2md srcfiles[i].path, latex_md - sh "pandoc --listings -o #{latex_tex} #{latex_md}" - File.delete(latex_md) +file_table.each do |tbl| + file tbl[3] => tbl[0] do + tex_md = "latex/" + tbl[0].to_md + src2md tbl[0], tex_md, file_table_src, "latex" + sh "pandoc --listings -o #{tbl[3]} #{tex_md}" + File.delete(tex_md) end end diff --git a/Readme.md b/Readme.md index 4e77c88..6ace705 100644 --- a/Readme.md +++ b/Readme.md @@ -20,7 +20,7 @@ The latest version of the tutorial is located at [Gtk4-tutorial github repositor You can read it without download. If you want to get a html or pdf version, you can make them with `rake`, which is a ruby version of make. -There is a documentation \("[How to build Gtk4 Tutorial](doc/Readme_for_developers.md)"\) that describes how to make them. +There is a documentation \("[How to build Gtk4 Tutorial](gfm/Readme_for_developers.md)"\) that describes how to make them. If you have a question, feel free to post it to the issue. Any question is helpful to make this tutorial get better. diff --git a/doc/Readme_for_developers.md b/gfm/Readme_for_developers.md similarity index 94% rename from doc/Readme_for_developers.md rename to gfm/Readme_for_developers.md index 5f1884e..7c32ad6 100644 --- a/doc/Readme_for_developers.md +++ b/gfm/Readme_for_developers.md @@ -49,11 +49,9 @@ It is @@@ command. The command starts with a line that begins with "@@@" and it ends with a line "@@@". For example, -~~~ -@@@include -tfeapplication.c -@@@ -~~~ + @@@include + tfeapplication.c + @@@ There are four types of @@@ command. @@ -61,29 +59,23 @@ There are four types of @@@ command. This type of @@@ command starts with a line "@@@include". -~~~ -@@@include -tfeapplication.c -@@@ -~~~ + @@@include + tfeapplication.c + @@@ This command replaces itself with the text read from the C source files surrounded by `@@@include` and `@@@`. If a function list follows the filename, only the functions are read. If no function list is given, the command can read any text file other than C source file. -~~~ -@@@include -tfeapplication.c main startup -@@@ -~~~ + @@@include + tfeapplication.c main startup + @@@ The command above is replaced by the contents of `main` and `startup` functions in `tfeapplication.c`. -~~~ -@@@include -lib_src2md.rb -@@@ -~~~ + @@@include + lib_src2md.rb + @@@ This command is replaced by the contents of `lib_src2md.rb` which is a ruby script (not C file). @@ -192,7 +184,7 @@ The markdwon above is converted to the following latex source file. Listing package can color or emphasize keywords, strings, comments and directives. But it doesn't analyze the syntax or token of the language, so the kind of emphasis target is limited. -@@@include command have two advantages. + @@@include command have two advantages. 1. Less typing. 2. You don't need to modify your src.md file, even if the C source file is modified. @@ -201,12 +193,10 @@ But it doesn't analyze the syntax or token of the language, so the kind of empha This type of @@@ command starts with a line begins with "@@@shell". -~~~ -@@@shell -shell command - ... ... -@@@ -~~~ + @@@shell + shell command + ... ... + @@@ This command replaces itself with: @@ -215,11 +205,9 @@ This command replaces itself with: For example, -~~~ -@@@shell -wc Rakefile -@@@ -~~~ + @@@shell + wc Rakefile + @@@ This is converted to: @@ -234,15 +222,13 @@ This type of @@@ command starts with a line begins with "@@@if", "@@@elif", "@@@ This command is similar to "#if", "#elif", #else" and "#end" directives in C preprocessor. For example, -~~~ -@@@if gfm -Refer to [tfetextview API reference](tfetextview/tfetextview_doc.md) -@@@elif html -Refer to [tfetextview API reference](tfetextview_doc.html) -@@@elif latex -Refer to tfetextview API reference in appendix. -@@@end -~~~ + @@@if gfm + Refer to [tfetextview API reference](tfetextview/tfetextview_doc.src.md) + @@@elif html + Refer to [tfetextview API reference](tfetextview/tfetextview_doc.src.html) + @@@elif latex + Refer to tfetextview API reference in appendix. + @@@end `@@@if` and `@@@elif` have conditions. They are `gfm`, `html` or `latex` so far. @@ -400,17 +386,17 @@ Navigation lines are added at the top and bottom of each markdown section file. You can describe width and height of images in src.md files. For example, - ![sample image](../image/sample_image.png){width=10cm height=6cm} + ![sample image](../image/sample_image.png) The size between left brace and right brace is used in latex file and it is not fit to GFM syntax. So the size is removed in the conversion. If a src.md file has relative URL link, it will be changed by conversion. Because src.md files are located under `src` directory and GFM files are located under `gfm` directory, base URL of GFM files is different from base URL of src.md files. -For example, `[src/sample.c](sample.c)` is translated to `[src/sample.c](../src/sample.c)`. +For example, `[src/sample.c](../src/sample.c)` is translated to `[src/sample.c](../src/sample.c)`. If a link points another src.md file, then the target filename will be changed to .md file. -For example, `[Section 5](sec5.src.md)` is translated to `[Section 5](sec5.md)`. +For example, `[Section 5](sec5.md)` is translated to `[Section 5](../src/sec5.md)`. If you want to clean the directory, that means remove all the generated markdown files, type `rake clean`. @@ -462,7 +448,7 @@ Links to files or directories are removed because latex doesn't support them. However, links to full URL are kept. Image size is set with the size between the left brace and right brace. - ![sample image](../image/sample_image.png){width=10cm height=6cm} + ![sample image](../image/sample_image.png) You need to specify appropriate width and height. It is almost `0.015 x pixels` cm. diff --git a/gfm/sec12.md b/gfm/sec12.md index 21c8d20..bca7222 100644 --- a/gfm/sec12.md +++ b/gfm/sec12.md @@ -415,11 +415,11 @@ Otherwise, if the caller frees the GFile object, `tv->file` is no more guarantee ## API document and source file of tfetextview.c -Refer [API document of TfeTextView](../src/tfetextview/tfetextview_doc.md). +Refer [API document of TfeTextView](tfetextview/tfetextview_doc.src.md). It is under the directory `src/tfetextview`. All the source files are listed in [Section 15](sec15.md). -You can find them under [src/tfe5](../src/tfe5) and [src/tfetextview](../tfetextview) directories. +You can find them under [src/tfe5](../src/tfe5) and [src/tfetextview](../src/tfetextview) directories. Up: [Readme.md](../Readme.md), Prev: [Section 11](sec11.md), Next: [Section 13](sec13.md) diff --git a/gfm/sec15.md b/gfm/sec15.md index f31c3e8..05e3b50 100644 --- a/gfm/sec15.md +++ b/gfm/sec15.md @@ -5,7 +5,7 @@ Up: [Readme.md](../Readme.md), Prev: [Section 14](sec14.md), Next: [Section 16] ## How to compile and execute tfe text editor. First, source files are shown in the later subsections. -How to download them is written at the end of the [previous section](../src/sec14.src.md). +How to download them is written at the end of the [previous section](sec14.md). The following is the instruction of compilation and execution. diff --git a/gfm/sec23.md b/gfm/sec23.md index 5bab48f..b186be6 100644 --- a/gfm/sec23.md +++ b/gfm/sec23.md @@ -18,7 +18,7 @@ So, readers can skip that part of this sections. ## How to use turtle -The documentation of turtle is [here](../src/turtle/turtle_doc.md). +The documentation of turtle is [here](turtle_doc.md). I'll show you a simple example. ~~~ @@ -529,7 +529,7 @@ FC '(' NUM ',' NUM ',' NUM ')'; You can find this is a primary_procedure easily. The parser of the turtle language analyzes the turtle source code in the same way. -The grammar of turtle is described in the [document](../src/turtle/turtle_doc.md). +The grammar of turtle is described in the [document](turtle_doc.md). The following is an extract from the document. ~~~ diff --git a/gfm/tfetextview_doc.md b/gfm/tfetextview_doc.md new file mode 100644 index 0000000..066c6bf --- /dev/null +++ b/gfm/tfetextview_doc.md @@ -0,0 +1,203 @@ +# TfeTextView API reference + +TfeTextView -- Child widget of GtkTextView. It holds GFile the contents of GtkTextBuffer correponds to. + +## Functions +- GFile *[tfe_text_view_get_file ()](../src/tfetextview/#tfe_text_view_get_file) +- void [tfe_text_view_open ()](../src/tfetextview/#tfe_text_view_open) +- void [tfe_text_view_save ()](../src/tfetextview/#tfe_text_view_save) +- void [tfe_text_view_saveas ()](../src/tfetextview/#tfe_text_view_saveas) +- GtkWidget *[tfe_text_view_new_with_file ()](../src/tfetextview/#tfe_text_view_new_with_file) +- GtkWidget *[tfe_text_view_new ()](../src/tfetextview/#tfe_text_view_new) + +## Signals + +- void [change-file](../src/tfetextview/#change-file) +- void [open-response](../src/tfetextview/#open-response) + +## Types and Values + +- [TfeTextView](../src/tfetextview/#tfetextview-1) +- [TfeTextViewClass](../src/tfetextview/#tfetextviewclass) +- [TfeTextViewOpenResponseType](../src/tfetextview/#enum-tfetextviewopenresponsetype) + +## Object Hierarchy + +~~~ +GObject ++--GInitiallyUnowned + +--GtkWidget + +--GtkTextView + +--TfeTextView +~~~ + +## Includes + +~~~ +#include +~~~ + +## Description + +TfeTextView holds GFile the contents of GtkTextBuffer corresponds to. +File manipulation functions have been added to this object. + +## Functions + +### tfe_text_view_get_file() + +~~~ +GFile * +tfe_text_view_get_file (TfeTextView *tv); +~~~ + +Returns the copy of the GFile in the TfeTextView. + +Parameters + +- tv: a TfeTextView + +### tfe_text_view_open() + +~~~ +void +tfe_text_view_open (TfeTextView *tv, GtkWidget *win); +~~~ + +Just shows a GtkFileChooserDialog so that a user can choose a file to read. +This function doesn't do any I/O operations. +They are done by the signal handler connected to the `response` signal emitted by GtkFileChooserDialog. +Therefore the caller can't know the I/O status directly from the function. +Instead, the status is informed by `open-response` signal. +The caller needs to set a handler to this signal in advance. + +parameters + +- tv: a TfeTextView +- win: the top level window + +### tfe_text_view_save() + +~~~ +void +tfe_text_view_save (TfeTextView *tv); +~~~ + +Saves the content of a TfeTextView to a file. +If `tv` holds a GFile, it is used. +Otherwise, this function calls GtkFileChosserDialog so that a user can choose a file to save. + +Parameters + +- tv: a TfeTextView + +### tfe_text_view_saveas() + +~~~ +void +tfe_text_view_saveas (TfeTextView *tv); +~~~ + +Saves the content of a TfeTextView to a file. +This function calls GtkFileChosserDialog so that a user can choose a file to save. + +Parameters + +- tv: a TfeTextView + +### tfe_text_view_new_with_file() + +~~~ +GtkWidget * +tfe_text_view_new_with_file (GFile *file); +~~~ + +Creates a new TfeTextView and read the contents of the `file` and set it to the GtkTextBuffer corresponds to the newly created TfeTextView. +Then returns the TfeTextView as GtkWidget. +If I/O error happens, it returns `NULL`. + +Parameters + +- file: a GFile + +Returns + +- a new TfeTextView. + +### tfe_text_view_new() + +~~~ +GtkWidget * +tfe_text_view_new (void); +~~~ + +Creates a new TfeTextView and returns the TfeTextView as GtkWidget. + +Returns + +- a new TfeTextView. + +## Types and Values + +### TfeTextView + +~~~ +typedef struct _TfeTextView TfeTextView +struct _TfeTextView +{ + GtkTextView parent; + GFile *file; +}; +~~~ + +The members of this structure are not allowed to be accessed by any outer objects. +If you want to obtain GFile, use `tfe_text_view_get_file`. + +### TfeTextViewClass + +~~~ +typedef struct { + GtkTextViewClass parent_class; +} TfeTextViewClass; +~~~ + +No member is added because TfeTextView is a final type object. + +### enum TfeTextViewOpenResponseType + +Predefined values for the response id given by `open-response` signal. + +Members: + +- TFE_OPEN_RESPONSE_SUCCESS: The file is successfully opened. +- TFE_OPEN_RESPONSE_CANCEL: Reading file is canceled by the user. +- TFE_OPEN_RESPONSE_ERROR: An error happened during the opening or reading process. + +## Signals + +### change-file + +~~~ +void +user_function (TfeTextView *tv, + gpointer user_data) +~~~ + +Emitted when the GFile in the TfeTextView object is changed. +The signal is emitted when: + +- a new file is opened and read +- a user choose a file with GtkFileChooserDialog and save the contents. +- an error occured during I/O operation, and GFile removed as a result. + +### open-response + +~~~ +void +user_function (TfeTextView *tv, + TfeTextViewOpenResponseType response-id, + gpointer user_data) +~~~ + +Emitted after the user called `tfe_text_view_open`. +This signal informs the status of file opening and reading. diff --git a/gfm/turtle_doc.md b/gfm/turtle_doc.md new file mode 100644 index 0000000..e88f1d4 --- /dev/null +++ b/gfm/turtle_doc.md @@ -0,0 +1,445 @@ +# Turtle's manual + +Turtle is a simple interpreter for turtle graphics. + +## Prerequisite and compiling + +Turtle is written in C language. +You need: + +- Linux. Turtle is tested on ubuntu 20.10 +- gcc, meson and ninja +- gtk4 + +It is easy to compile the source file of turtle. +If you have installed gtk4 with an option `--prefix=$HOME/local`, put the same option to meson so that you can install `turtle` under the directory `$HOME/local/bin`. +The instruction is: + +~~~ +$ meson --prefix=$HOME/local _build +$ ninja -C _build +$ ninja -C _build install +~~~ + +Type the following command then turtle shows the following window. + +~~~ +$ turtle +~~~ + +![Screenshot just after it's executed](../src/turtle/image/turtle1.png) + +The left half is a text editor and the right half is a surface. +Surface is like a canvas to draw shapes. + +Write turtle language in the text editor and click on `run` button, then the program will be executed and it draws shapes on the surface. + +![Tree](../src/turtle/image/turtle_tree.png) + +If you add the following line in `turtle.h`, then codes to inform the status will also be compiled. +However, the speed will be quite slow because of the output messages. + +~~~ +# define debug 1 +~~~ + +## Example + +Imagine a turtle. +The turtle has a pen and initially he is at the center of the screen, facing to the north (to the north means up on the screen). +You can let the turtle down the pen or up the pen. +You can order the turtle to move forward. + +~~~ +pd +fd 100 +~~~ + +- pd: Pen Down. The turtle put the pen down so that the turtle will draw a line if he/she moves. +- fd 100: move ForwarD 100. The turtle goes forward 100 pixels. + +If you click on `run` button, then a line segment appears on the screen. +One of the endpoints of the line segment is at the center of the surface and the other is at 100 pixels up from the center. +The point at the center is the start point of the turtle and the other endpoint is the end point of the movement. + +If the turtle picks the pen up, then no line segment appears. + +~~~ +pu +fd 100 +~~~ + +The command `pu` means "Pen Up". + +The turtle can change the direction. + +~~~ +pd +fd 100 +tr 90 +fd 100 +~~~ + +The command `tr` is "Turn Right". +The argument is angle with degrees. +Therefore, `tr 90` means "Turn right by 90 degrees". +If you click on `run`button, then two line segment appears. +One is vertical and the other is horizontal. + +![Two line segments on the surface](../src/turtle/image/turtle2.png) + +## Background and foreground color + +Colors are specified by RGB. +A vector (r, g, b) denotes RGB color. +Each of the elements is a real number between 0 and 1. + +- Red is (1.0, 0.0, 0.0). +You can write (1, 0, 0) instead. +- Green is (0.0, 1.0, 0.0) +- Blue is (0.0, 0.0, 1.0) +- Black is (0.0, 0.0, 0.0) +- White is (1.0, 1.0, 1.0) + +You can express a variety of colors by changing each element. + +There are two commands to change colors. + +- bc: Background Color. `bc (1,0,0)` changes the background color to red. +This command clear the surface and change the background color. +So, the shapes on the surface disappears. +- fc: Foreground Color. `fc (0,1,0)` changes the foreground color to green. +This command changes the pen color. +The prior shapes on the surface aren't affected. +After this command, the turtle draws lines with the new color. + +![Change the foreground color](../src/turtle/image/turtle3.png) + +## Other simple commands + +- pw: Pen Width. This is the same as pen size or line width. +For example, `pw 5` makes lines thick and `pw 1` makes it thin. +- rs: ReSet. The turtle moves back to the initial position and direction. +In addition, The command initialize the pen, line width (pen size), and foreground color. +The pen is down, the line width is 2 and the foreground color is black. + +An order such as `fd 100`, `pd` and so on is a statement. +Statements are executed in the order from the top to the end + +## Comment and spaces + +Characters between `#` (hash mark) and `\n` (new line) inclusive are comment. +Characters between `#` and `EOF` (end of file) are also comment. +Comments are ignored. + +~~~ +# draw a triangle +fd 100 # forward 100 pixels +tr 120 # turn right by 90 degrees +fd 100 +tr 120 +fd 100 # Now a triangle appears. +~~~ + +\ and \ are newline code and end of file respectively. +The comments in the line 1, 2, 3 and 6 are correct syntactically. + +Spaces (white space, tab and new line) are ignored. +They are used only as delimiters. +Tabs are recognized as eight spaces to calculate the column number. + +## Variables and expressions + +Variable begins alphabet followed by alphabet or digit except key words like `fd`, `tr` and so on. +`Distance` and `angle5` can be variables, but `1step` isn't a variable because the first character isn't alphabet. +Variable names are case sensitive. +Variables keep real numbers. +Their type is the same as `double` in C language. +Integers are casted to real numbers automatically. +So 1 and 1.0 are the same value. +Numbers begins digits, not signs (`+` or `-`). + +- 100, 20.34 and 0.01 are numbers +- +100 isn't a number. It causes syntax error. Use 100 instead. +- -100 isn't a number. But turtle recognizes it unary minus and a number 100. +So turtle calculate it and the result is -100. +- 100 + -20: This is recognized 100 + (- 20). +However, using bracket, 100 + (-20), is better for easy reading. + +~~~ +distance = 100 +fd distance +~~~ + +A value 100 is assigned to the variable `distance` in the first line. +Assignment is a statement. +Most of statements begin with commands like `fd`. +Assignment is the only exception. + +This program draws a line segment of 100 pixels long. + +You can use variables in any places in expressions. +There are 8 kinds of calculations available. + +- addition: x + y +- subtraction: x - y +- multiplication: x * y +- division: x / y +- unary minus: - x +- logical equal: x = y. This symbol `=` works as `==` in C language. +- greater than: x > y +- less than: x < y + +The last three symbols are mainly used in the condition of if statement. + +Variables are registered to a symbol table when it is assigned a value for the first time. +Evaluating a variable before the registration isn't allowed and occurs an error. + +## If statement + +Turtle language has very simple if statement. + +~~~ +if (x > 50) { + fd x +} +~~~ + +There is no else part. + +## Procedures + +Procedures are similar to functions in C language. +The difference is that procedures don't have return values. + +~~~ +dp triangle (side) { + fd side + tr 120 + fd side + tr 120 + fd side +} + +triangle (100) +~~~ + +`dp` (Define Procedure) is a key word followed by procedure name, parameters, and body. +Procedure names start alphabet followed by alphabet or digit. +Parameters are a list of variables. +For example + +~~~ +dp abc (a) { ... ... } +dp abc (a, b) { ... ... } +dp abc (a, b, c) { ... ... } +~~~ + +Body is a sequence of statements. +The statements aren't executed when the procedure is defined. +They will be executed when the procedure is called later. + +Procedures are called by the name followed by arguments. + +~~~ +dp proc (a, b, c) { ... ... } + +proc (100, 0, -20*3) +~~~ + +The number of parameters and arguments must be the same. +Arguments can be any expressions. +When you call a procedure, brackets following the procedure name must exist even if the procedure has no argument. + +Procedure names and variable names don't conflict. + +~~~ +dp a () {fd a} +a=100 +a () +~~~ + +This is a correct program. + +- 1: Defines a procedure `a`. +A variable `a` is in its body. +- 2: Assigns 100 to a variable `a`. +- 3: Procedure `a` is called. + +However, using the same name to a procedure and variable makes confusing. +You should avoid that. + +## Recursive call + +Procedures can be called recursively. + +~~~ +dp repeat (n) { + n = n - 1 + if (n < 0) { + rt + } + fd 100 + tr 90 + repeat (n) +} + +repeat (4) +~~~ + +Repeat is called in the body of repeat. +The call to itself is a recursive call. +Parameters are generated each time the procedure is called. +So, parameter `n` is 4 at the first call but it is 3 at the second call. +Each time the procedure is called, the parameter `n` decreases by one. +Finally, it becomes less than zero, then the procedures return. + +The program above draws a square. + +Turtle doesn't have any primary loop statements. +It should probably be added to the future version. +However, the program above shows that we can program loop with a recursive call. + +## Fractal curves + +Recursive call can be applied to draw fractal curves. +Fractal curves appear when a procedure is applied to it repeatedly. +The procedure replaces a part of the curve with the contracted curve. + +![Tree](../src/turtle/image/turtle_tree.png) + +This shape is called tree. +The basic pattern of this shape is a line segment. +It is the first stage. +The second stage adds two shorter line segments at the endpoint of the original segment. +The new segment has 70 percent length to the original segment and the orientation is +30 or -30 degrees different. +The third stage adds two shorter line segments to the second stage line segments. +And repeats this several times. + +This repeating is programmed by recursive call. +Two more examples are shown here. +They are Koch curve and Square Koch curve. + +![Koch curve](../src/turtle/image/turtle_koch.png) + +![Square Koch curve](../src/turtle/image/turtle_square_koch.png) + +## Tokens and punctuations + +The following is the list of tokens. + +Keywords: + +- pu: pen up +- pd: pen down +- pw: pen width = line width +- fd: forward +- tr: turn right +- bc: background color +- fc: foreground color +- if: if statement +- rt: return +- rs: reset +- dp: define procedure + +identifiers and numbers: + +- identifier: This is used for the name of variables, parameters and procedures. +It is expressed ` [a-zA-Z][a-zA-Z0-9]*` by regular expression. +- number: This is expressed `(0|[1-9][0-9]*)(\.[0-9]+)?` by regular expression. +It doesn't have `+` or `-` sign because they bring some syntactic confusion. +However negative number such as `-10` can be recognized as unary minus and a number. + +Symbols for expression + +- `=` +- `>` +- `<` +- `+` +- `-` +- `*` +- `/` +- `(` +- `)` + +Delimiters + +- `(` +- `)` +- `{` +- `}` +- `,` + +Comments and spaces: + +- comment: This is characters between `#` and new line inclusive. +- white space: +- horizontal tab: tab is recognized as eight spaces. +- new line: This is the end of a line and denoted by '\\n'. + +These characters are used to separate tokens explicitly. +They doesn't have any syntactic meaning and are ignored by the parser. + +## Grammar + +~~~ +program: + statement +| program statement +; + +statement: + primary_procedure +| procedure_definition +; + +primary_procedure: + PU +| PD +| PW expression +| FD expression +| TR expression +| BC '(' expression ',' expression ',' expression ')' +| FC '(' expression ',' expression ',' expression ')' +| ID '=' expression +| IF '(' expression ')' '{' primary_procedure_list '}' +| RT +| RS +| ID '(' ')' +| ID '(' argument_list ')' +; + +procedure_definition: + DP ID '(' ')' '{' primary_procedure_list '}' +| DP ID '(' parameter_list ')' '{' primary_procedure_list '}' +; + +parameter_list: + ID +| parameter_list ',' ID +; + +argument_list: + expression +| argument_list ',' expression +; + +primary_procedure_list: + primary_procedure +| primary_procedure_list primary_procedure +; + +expression: + expression '=' expression +| expression '>' expression +| expression '<' expression +| expression '+' expression +| expression '-' expression +| expression '*' expression +| expression '/' expression +| '-' expression %prec UMINUS +| '(' expression ')' +| ID +| NUM +; +~~~ diff --git a/image/state_diagram.png b/image/state_diagram.png index 9909b52..51edbe7 100644 Binary files a/image/state_diagram.png and b/image/state_diagram.png differ diff --git a/lib/lib_src2md.rb b/lib/lib_src2md.rb index 504356b..7c6539e 100644 --- a/lib/lib_src2md.rb +++ b/lib/lib_src2md.rb @@ -2,7 +2,7 @@ require 'pathname' # The method 'src2md' converts .src.md file into .md file. -# The outputed .md file is fit for the final format, which is one of markdown, html and latex. +# The .md file is the final format for GFM, or intermediate markdown file for html and/or latex. # - Links to relative URL are removed for latex. Otherwise, it remains. # See "Hyperref and relative link" below for further explanation. # - Width and height for images are removed for markdown and html. it remains for latex. @@ -19,7 +19,7 @@ require 'pathname' # (sec13.tex) # \hypertarget{tfeapplication.c}{% # \section{tfeapplication.c}\label{tfeapplication.c}} -# If you click the text 'Section 13' in sec11.tex, then you can move to '13 tfeapplication.c' ("13 " is automatically added by latex), which is section 13 in sec13.tex. +# If you click on the text 'Section 13' in sec11.tex, then you will move to 'tfeapplication.c' in sec13.tex. # The following lines are the original one in sec11.md and the result in sec11.tex, which is generated by pandoc. # (sec11.md) @@ -38,7 +38,7 @@ require 'pathname' # The pdf file generated by lualatex recognizes that the link 'href{../src/tfe}' points a pdf file '../src/tfe.pdf'. # To avoid generating such incorrect links, it is good to remove the links from the original markdown file. -# If the target is full URL, which means absolute URL begins with "http", no problem happens. +# If the target is full URL, which means absolute URL begins with "http(s)", no problem happens. # This script just remove the links if its target is relative URL if the target is latex. # If you want to revive the link with relative URL, refer the description above. @@ -71,7 +71,13 @@ require 'pathname' # Listings package supports only C, ruby, xml and make. # Bison, lex, markdown and meson aren't supported. -def src2md srcmd, md, type="gfm" +# file_table contains paths of source, GFM, html and latex. +# It is possible to get the relationship between source file and created GFM/html/latex file. + +# type is "gfm", "html" or "latex". +# Caller can specify the target type. + +def src2md srcmd, md, file_table=nil, type="gfm" # parameters: # srcmd: .src.md file's path. source # md: .md file's path. destination @@ -237,7 +243,7 @@ def src2md srcmd, md, type="gfm" md_buf << "~~~\n" shell_flag = true else - line = change_rel_link(line, src_dir, md_dir) + line = change_rel_link(line, src_dir, md_dir, file_table, type) if type == "latex" # remove relative link if ! (line =~ /\[[^\]]*\]\(http[^)]*\)/) line.gsub!(/^([^!]*)\[([^\]]*)\]\([^\)]*\)/,"\\1\\2") @@ -252,7 +258,9 @@ def src2md srcmd, md, type="gfm" end # Change the base of relative links from org_dir to new_dir -def change_rel_link line, org_dir, new_dir +def change_rel_link line, org_dir, new_dir, file_table=nil, type="gfm" + i = [nil, "gfm", "html", "latex"].find_index(type) + raise "Illegal type (#{type}).\n" unless i == 1 || i == 2 || i == 3 p_new_dir = Pathname.new new_dir left = "" right = line @@ -261,9 +269,15 @@ def change_rel_link line, org_dir, new_dir right = $' name = $1 link = $2 - if name =~ /\[(S|s)ection (\d+)\]/ - link = "sec#{$2}.md" - elsif ! (link =~ /^(http|\/)/) + if file_table + file_table.each do |tbl| + if tbl[0] == link + link = tbl[i] + break + end + end + end + if ! (link =~ /^(http|\/)/) p_link = Pathname.new "#{org_dir}/#{link}" link = p_link.relative_path_from(p_new_dir).to_s end diff --git a/lib/lib_sec_file.rb b/lib/lib_src_file.rb similarity index 84% rename from lib/lib_sec_file.rb rename to lib/lib_src_file.rb index 14bd764..5bb02cb 100644 --- a/lib/lib_sec_file.rb +++ b/lib/lib_src_file.rb @@ -1,15 +1,15 @@ -class Sec_file < String +class Src_file C +- `.rb` => ruby +- `.xml` => xml + +The supported language is written in line 274 and 275 in `lib/lib_src2md.rb`. + +A line number is inserted at the top of each line in the code block. +If you don't want to insert it, give "-N" option to @@@include command. + +Options: + +- `-n`: Inserts a line number at the top of each line (default). +- `-N`: No line number is inserted. + +The following shows that line numbers are inserted at the beginning of lines. + + $cat src/sample.src.md + ... ... + @@@include + sample.c + @@@ + ... ... + $ ruby src2md.rb src/sample.src.md gfm/sample.md + $ cat gfm/sample.md + ... ... + ~~~C + 1 int + 2 main (int argc, char **argv) { + ... ... + 14 } + ~~~ + ... ... + +If the target markdown is an intermediate file to html, then another type of info string follows the beginning fence. +If @@@include command doesn't have -N option, then the generated markdown is: + + ~~~{.C .numberLines} + int + main (int argc, char **argv) { + ... ... + } + ~~~ + +The info string `.C` specifies C language. +The info string `.numberLines` is a class of the pandoc markdown. +If the class is given, pandoc generates CSS to insert line numbers to the source code in the html file. +That's why the fence code block in the markdown doesn't have line numbers, which is different from gfm markdown. +If `-N` option is given, then the info string is `{.C}` only. + +If the target markdown is an intermediate file to latex, then the same info string follows the beginning fence. + + ~~~{.C .numberLines} + int + main (int argc, char **argv) { + ... ... + } + ~~~ + +Rake uses pandoc with --listings option when it converts markdown to latex. +The generated latex file uses listings package to list source files instead of verbatim environment. +The markdwon above is converted to the following latex source file. + + \begin{lstlisting}[language=C, numbers=left] + int + main (int argc, char **argv) { + ... ... + } + \end{lstlisting} + +Listing package can color or emphasize keywords, strings, comments and directives. +But it doesn't analyze the syntax or token of the language, so the kind of emphasis target is limited. + + @@@include command have two advantages. + +1. Less typing. +2. You don't need to modify your src.md file, even if the C source file is modified. + +### @@@shell + +This type of @@@ command starts with a line begins with "@@@shell". + + @@@shell + shell command + ... ... + @@@ + +This command replaces itself with: + +- the shell command +- the standard output from the shell command + +For example, + + @@@shell + wc Rakefile + @@@ + +This is converted to: + + ~~~ + $ wc Rakefile + 164 475 4971 Rakefile + ~~~ + +### @@@if series + +This type of @@@ command starts with a line begins with "@@@if", "@@@elif", "@@@else" or "@@@end". +This command is similar to "#if", "#elif", #else" and "#end" directives in C preprocessor. +For example, + + @@@if gfm + Refer to [tfetextview API reference](tfetextview/tfetextview_doc.md) + @@@elif html + Refer to [tfetextview API reference](tfetextview_doc.html) + @@@elif latex + Refer to tfetextview API reference in appendix. + @@@end + +`@@@if` and `@@@elif` have conditions. +They are `gfm`, `html` or `latex` so far. + +- gfm: builds a GFM file +- html: builds a html file +- latex: builds a latex file or pdf file. + +Other type of conditions may be available in the future version. + +## Conversion + +The @@@ commands above (@@@include, @@@shell and @@@if series) are carried out by `src2md.rb`. +In addition, some other conversions are made by `src2md.rb`. + +- Relative links are changed according to the change of the base directory. +- Size option in image link is removed when the destination is GFM or html. +- Relative link is removed when the destination is latex. +- Lines in fence code block are folded when the destination is latex. + +There's a method `src2md` in the `lib/lib_src2md.rb`. +This method converts src.md file into md file. +The script `src2md.rb` just invokes this method. +In the same way, the method is called in the action in `Rakefile`. + +The code analyzing @@@if series command is rather complicated. +It is based on the state diagram below. + +![state diagram](../image/state_diagram.png) + +## mktbl.rb script + +The fourth @@@ command begins with "@@@table". +The contents of this command is a table of GFM or pandoc's markdown. +The script `mktbl.rb` in `src` directory makes a table easy to read. +For example, a text file `sample.md` has a table like this: + + Price list + + @@@table + |item|price| + |:---:|:---:| + |mouse|$10| + |PC|$500| + @@@ + +Run the script. + +~~~ +$ cd src +$ ruby mktbl.rb sample.md +~~~ + +Then, the file is changed to: + +~~~ +Price list + +|item |price| +|:---:|:---:| +|mouse| $10 | +| PC |$500 | +~~~ + +The script makes a backup file `sample.md.bak`. + +The task of the script seems easy, but the program is not so simple. +The script `mktbl.rb` uses a library `lib/lib_mktbl.rb` +This script is independent from `src2md.rb`. + +## Directory structure + +There are seven directories under `gtk4_tutorial` directory. +They are `gfm`, `src`, `image`, `html`, `latex`, `doc` and `lib`. +Three directories `gfm`, `html` and `latex` are the destination directories for GFM, html and latex files respectively. +It is possible that these three directories don't exist before the conversion. + +- src: This directory contains src.md files and C-related source files. +- image: This directory contains image files like png or jpg. +- gfm: `rake` converts src.md files to GFM files and store them in this directory. +- html: This directory is empty at first. `rake html` will convert src.md files to html files and store them in this directory. +- latex: This directory is empty at first. `rake latex` will convert src.md files to latex files and store them in this directory. +`rake pdf` creates pdf file in `latex` directory. +- doc: This directory contains `Readme_for_developers.md` (this file). +- lib: This directory includes ruby library files. + +## Src directory and the top directory + +Src directory contains src.md files and C-related source files. +The top directory, which is gtk\_tutorial directory, contains `Rakefile`, `src2md.rb` and some other files. +When `Readme.md` is generated, it will be located at the top directory. +`Readme.md` has title, abstract, table of contents and links to GFM files under `gfm` directory. + +Rakefile describes how to convert src.md files into GFM files. +Rake carries out the conversion according to the `Rakefile`. + +## The name of files in src directory + +Each file in `src` directory is an abstract or section of the whole document. +A `abstract.src.md` contains the abstract of this tutorial. +Each section filename is "sec", number of the section and ".src.md" suffix. +For example, "sec1.src.md", "sec5.src.md" or "sec12.src.md". +They are the files correspond to section 1, section 5 and section 12 respectively. + +## C source file directory + +Most of Src.md files have `@@@include` commands and they include C source files. +Such C source files are located in the subdirectories of `src` directory. + +Those C files have been compiled and tested. +When you compile source files, some auxiliary files and a target file like `a.out` are created. +Or `_build` directory is made when `meson` and `ninja` is used when compiling. +Those files are not tracked by `git` because they are specified in `.gitignore`. + +The name of the subdirectories should be independent of section names. +It is because of renumbering, which will be explained in the next subsection. + +## Renumbering + +Sometimes you might want to insert a section. +For example, you want to insert it between section 4 and section 5. +You can make a temporary section 4.5, that is a rational number between 4 and 5. +However, section numbers are usually integer so section 4.5 must be changed to section 5. +And the numbers of the following sections must be increased by one. + +This renumbering is done by a method `renum` of the class `Sec_files`. +The method and class is written in `lib/lib_sec_file.rb`. + +- It changes file names. +- If there are references to sections in src.md files, the section numbers will be automatically renumbered. + +## Rakefile + +Rakefile is a similar file to Makefile but controlled by rake, which is a make-like program written in ruby. +Rakefile in this tutorial has the following tasks. + +- md: generate GFM markdown files. This is the default. +- html: generate html files. +- pdf: generate latex files and a pdf file, which is compiled by lualatex. +- latex: generate latex files. +- all: generate md, html, latex and pdf files. + +Rake does renumbering before the tasks above. + +## Generate GFM markdown files + +Markdown files (GFM) are generated by rake. + + $ rake + +This command generates `Readme.md` with `src/abstract.src.md` and titles of src.md files. +At the same time, it converts each src.md file into GFM file under `gfm` directory. +Navigation lines are added at the top and bottom of each markdown section file. + +You can describe width and height of images in src.md files. +For example, + + ![sample image](../image/sample_image.png){width=10cm height=6cm} + +The size between left brace and right brace is used in latex file and it is not fit to GFM syntax. +So the size is removed in the conversion. + +If a src.md file has relative URL link, it will be changed by conversion. +Because src.md files are located under `src` directory and GFM files are located under `gfm` directory, base URL of GFM files is different from base URL of src.md files. +For example, `[src/sample.c](sample.c)` is translated to `[src/sample.c](../src/sample.c)`. + +If a link points another src.md file, then the target filename will be changed to .md file. +For example, `[Section 5](sec5.src.md)` is translated to `[Section 5](sec5.md)`. + +If you want to clean the directory, that means remove all the generated markdown files, type `rake clean`. + + $ rake clean + +If you see the github repository (ToshioCP/Gtk4-tutorial), `Readme.md` is shown below the code. +And `Readme.md` includes links to each markdown files. +The repository not only stores source files but also shows the whole tutorial. + +## Generate html files + +Src.md files can be translated to html files. +You need pandoc to do this. +Most linux distribution has pandoc package. +Refer to your distribution document to install it. + +Type `rake html` to generate html files. + + $ rake html + +First, it generates pandoc's markdown files under `html` directory. +Then, pandoc converts them to html files. +The width and height of image files are removed. + +`index.html` is the top html file. +If you want to clean `html` directory, type `rake cleanhtml` + + $ rake cleanhtml + +Every html file has stylesheet in its header. +This is created by `lib/lib_add_head_tail_html.rb`. +This script has a sample markdown code and convert it with pandoc and `-s` option. +Pandoc generates a html file with header. +The script extracts the header and use it for html files. +You can customize the style by modifying `lib/lib_add_head_tail_html.rb`. + +## Generate latex files and a pdf file + +Src.md files can be translated to latex files. +You need pandoc to do this. + +Type `rake latex` to generate latex files. + + $ rake latex + +First, it generates pandoc's markdown files under `latex` directory. +Then, pandoc converts them to latex files. +Links to files or directories are removed because latex doesn't support them. +However, links to full URL are kept. +Image size is set with the size between the left brace and right brace. + + ![sample image](../image/sample_image.png){width=10cm height=6cm} + +You need to specify appropriate width and height. +It is almost `0.015 x pixels` cm. +For example, if the width of an image is 400 pixels, the width in a latex file will be almost 6cm. + + +`main.tex` is the top latex file. +If you want to clean `latex` directory, type `rake cleanlatex` + + $ rake cleanlatex + +`main.tex` is a root file and it includes each section file between `\begin{document}` and `\end{document}`. +`main.tex` also includes `helper.tex` in its preamble. +`main.tex` and `helper.tex` is created by `lib/lib_gen_main_tex.rb`. +It has a sample markdown code and convert it witn pandoc and `-s` option. +Pandoc generates preamble. +`lib/lib_gen_main_tx.rb` extracts the preamble and put a part of it into `helper.tex`. +You can customize `helper.tex` by modifying `lib/lib_gen_main_tex.rb`. + +You can generate pdf file by typing `rake pdf`. + + $ rake pdf + +This does `rake latex` first. +After that the latex files are compiled by lualatex. diff --git a/src/abstract.src.md b/src/abstract.src.md index 71f673f..6c6c778 100644 --- a/src/abstract.src.md +++ b/src/abstract.src.md @@ -18,7 +18,13 @@ The latest version of the tutorial is located at [Gtk4-tutorial github repositor You can read it without download. If you want to get a html or pdf version, you can make them with `rake`, which is a ruby version of make. -There is a documentation \("[How to build Gtk4 Tutorial](../doc/Readme_for_developers.md)"\) that describes how to make them. +@@@if gfm +There is a documentation \("[How to build Gtk4 Tutorial](Readme_for_developers.src.md)"\) that describes how to make them. +@@@elif html +There is a documentation \("[How to build Gtk4 Tutorial](Readme_for_developers.src.md)"\) that describes how to make them. +@@@elif latex +An appendix "How to build Gtk4 Tutorial" describes how to make them. +@@@end If you have a question, feel free to post it to the issue. Any question is helpful to make this tutorial get better. diff --git a/src/sec12.src.md b/src/sec12.src.md index 7aa4ddb..b116c76 100644 --- a/src/sec12.src.md +++ b/src/sec12.src.md @@ -232,5 +232,5 @@ Its original markdown file is under the directory `src/tfetextview`. @@@end All the source files are listed in [Section 15](sec15.src.md). -You can find them under [src/tfe5](tfe5) and [src/tfetextview](../tfetextview) directories. +You can find them under [src/tfe5](tfe5) and [src/tfetextview](tfetextview) directories. diff --git a/src/sec23.src.md b/src/sec23.src.md index 1e1d988..1285502 100644 --- a/src/sec23.src.md +++ b/src/sec23.src.md @@ -17,7 +17,7 @@ So, readers can skip that part of this sections. ## How to use turtle @@@if gfm -The documentation of turtle is [here](turtle/turtle_doc.md). +The documentation of turtle is [here](turtle/turtle_doc.src.md). @@@elif html The documentation of turtle is [here](../html/turtle_doc.html). @@@if latex @@ -407,7 +407,7 @@ FC '(' NUM ',' NUM ',' NUM ')'; You can find this is a primary_procedure easily. The parser of the turtle language analyzes the turtle source code in the same way. -The grammar of turtle is described in the [document](turtle/turtle_doc.md). +The grammar of turtle is described in the [document](turtle/turtle_doc.src.md). The following is an extract from the document. ~~~ diff --git a/src/tfetextview/tfetextview_doc.md b/src/tfetextview/tfetextview_doc.src.md similarity index 100% rename from src/tfetextview/tfetextview_doc.md rename to src/tfetextview/tfetextview_doc.src.md diff --git a/test/test_lib_src2md.rb b/test/test_lib_src2md.rb index 7273a16..b648457 100644 --- a/test/test_lib_src2md.rb +++ b/test/test_lib_src2md.rb @@ -467,12 +467,13 @@ files.each do |f| end # --- test change_rel_link +file_table = [["sec3.src.md", "../gfm/sec3.md", "../html/sec3.html", "../latex/sec3.html"]] # general relative link s = "[sample.c](temp/sample.c)" t = change_rel_link s, "test", "gfm" if t != "[sample.c](../test/temp/sample.c)" print "Relative link change according to base directory change didn't work.\n" - print " Base directory test => gtm\n" + print " Base directory test => gfm\n" print " Original link => #{s}\n" print " Relative link temp/sample.c => #{t}\n" print " ** Correct new link must be [sample.c](../test/temp/sample.c) **\n" @@ -481,13 +482,13 @@ end # srcdir/secXX.src.md is converted to dstdir/secXX.md. # Therefore, secXX.src.md must be changed tp secXX.md. s = "[Section 3](sec3.src.md)" -t = change_rel_link s, "test", "gfm" +t = change_rel_link s, "src", "gfm", file_table, "gfm" if t != "[Section 3](sec3.md)" print "Relative link change according to base directory change didn't work.\n" - print " Base directory test => gtm\n" + print " Base directory test => gfm\n" print " Original link => #{s}\n" print " Relative link temp/sample.c => #{t}\n" - print " ** Correct new link must be [Section 2](sec3) **\n" + print " ** Correct new link must be [Section 3](sec3) **\n" end # --- test src2md diff --git a/test/test_lib_sec_file.rb b/test/test_lib_src_file.rb similarity index 83% rename from test/test_lib_sec_file.rb rename to test/test_lib_src_file.rb index 0a15275..5a8827d 100644 --- a/test/test_lib_sec_file.rb +++ b/test/test_lib_src_file.rb @@ -1,7 +1,11 @@ # test_lib_sec_file.rb -require_relative "../lib/lib_sec_file.rb" +require_relative "../lib/lib_src_file.rb" # Sample files for the test +src_text = <<'EOS' +This is a source file. +EOS + sample_c = <<'EOS' #include @@ -52,6 +56,7 @@ Prerequisite EOS files = [ + ["temp/srcfile.src.md", src_text], ["temp/sample.c", sample_c], ["temp/sec1.src.md", sec1_text], ["temp/sec2.src.md", sec2_text], @@ -66,6 +71,24 @@ files.each do |f| File.write f[0], f[1] end +# Test Src_file +print "****** Src_file class test ******\n" +src = Src_file.new "temp/srcfile.src.md" +test_items = [ + ["path", "\"temp/srcfile.src.md\""], + ["basename", "\"srcfile.src.md\""], + ["dirname", "\"temp\""], + ["to_md", "\"srcfile.md\""], + ["to_html", "\"srcfile.html\""], + ["to_tex", "\"srcfile.tex\""], +] +test_items.each do |item| + if eval("src.#{item[0]} != #{item[1]}") + print "src.#{item[0]} != #{item[1]}\n" + print " .... src.#{item[0]} is #{eval("src_sec1.#{item[0]}")}\n" + end +end + # Test Sec_file print "****** Sec_file class test ******\n" src_sec05 = Sec_file.new "temp/sec0.5.src.md"