diff --git a/Rakefile b/Rakefile index c95b814..7c599d1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,27 +1,61 @@ require 'rake/clean' require 'fileutils' -require_relative 'lib/lib_src_file.rb' +require_relative 'lib/lib_renumber.rb' require_relative 'lib/lib_src2md.rb' require_relative 'lib/lib_gen_main_tex.rb' require_relative 'lib/lib_mk_html_template.rb' -require_relative 'lib/lib_cp_images.rb' -secfiles = Sec_files.new(FileList['src/sec*.src.md'].to_a.map{|file| Sec_file.new(file)}) -secfiles.renum! +def pair array1, array2 + n = [array1.size, array2.size].max + (0...n).map{|i| [array1[i], array2[i], i]} +end +def s2md file + "#{File.basename(file,'.src.md')}.md" +end +def s2html file + "#{File.basename(file,'.src.md')}.html" +end +def s2tex file + "#{File.basename(file,'.src.md')}.tex" +end +def c_files path + dir = File.dirname(path) + File.read(path).scan(/^@@@include\n(.*?)@@@\n/m).flatten\ + .map{|s| s.each_line.to_a}.flatten\ + .map{|line| "#{dir}/#{(line.match(/^\S*/)[0])}"} +end + +# source files +secfiles = FileList['src/sec*.src.md'] +renumber(secfiles) otherfiles = ["src/turtle/turtle_doc.src.md", "src/tfetextview/tfetextview_doc.src.md", - "src/Readme_for_developers.src.md"].map {|file| Src_file.new file} + "src/Readme_for_developers.src.md"] srcfiles = secfiles + otherfiles -abstract = Src_file.new "src/abstract.src.md" +abstract = "src/abstract.src.md" +# imagesrcfiles are the image files used in the srcfiles. +# They are absolute paths. +imagesrcfiles = srcfiles.map do |file| + d = File.dirname(file) + File.read(file)\ + .gsub(/^ .*\n/,'').gsub(/^~~~.*?^~~~\n/m,'')\ + .scan(/!\[.*?\]\((.*?)\)/).flatten.uniq + .map{|img| File.absolute_path("#{d}/#{img}")} + end +imagesrcfiles = imagesrcfiles.flatten.sort.uniq # docs is a directory for html files. html_dir = 'docs' -mdfiles = srcfiles.map {|file| "gfm/" + file.to_md} -htmlfiles = srcfiles.map {|file| "#{html_dir}/" + file.to_html} -sectexfiles = secfiles.map {|file| "latex/" + file.to_tex} -othertexfiles = otherfiles.map {|file| "latex/" + file.to_tex} + +# target files +mdfiles = srcfiles.map{|file| "gfm/#{s2md(file)}"} +htmlfiles = srcfiles.map {|file| "#{html_dir}/#{s2html(file)}"} +sectexfiles = secfiles.map {|file| "latex/#{s2tex(file)}"} +othertexfiles = otherfiles.map {|file| "latex/#{s2tex(file)}"} texfiles = sectexfiles + othertexfiles -abstract_tex = "latex/"+abstract.to_tex +abstract_md = "gfm/#{s2md(abstract)}" +abstract_tex = "latex/#{s2tex(abstract)}" +htmlimagefiles = imagesrcfiles.map{|file| "#{html_dir}/image/#{File.basename(file)}"} ["gfm", html_dir, "latex"].each{|d| Dir.mkdir(d) unless Dir.exist?(d)} @@ -31,11 +65,6 @@ CLOBBER.append(FileList["docs/*.html"]) CLOBBER.append(FileList["docs/image/*"]) CLOBBER.append(FileList["latex/*.pdf"]) -def pair array1, array2 - n = [array1.size, array2.size].max - (0...n).map{|i| [array1[i], array2[i], i]} -end - # tasks task default: :md @@ -44,51 +73,49 @@ task all: [:md, :html, :pdf] task md: %w[Readme.md] + mdfiles file "Readme.md" => [abstract] + secfiles do - src2md abstract, abstract.to_md, "gfm" + src2md abstract, abstract_md, "gfm" buf = ["# Gtk4 Tutorial for beginners\n\nThe github page of this tutorial is also available. Click [here](https://toshiocp.github.io/Gtk4-tutorial/).\n\n"]\ - + File.readlines(abstract.to_md)\ + + File.readlines(abstract_md)\ + ["\n## Table of contents\n\n"] - File.delete(abstract.to_md) + File.delete(abstract_md) secfiles.each_with_index do |secfile, i| - h = File.open(secfile.path){|file| file.readline}.sub(/^#* */,"").chomp - buf << "1. [#{h}](gfm/#{secfile.to_md})\n" + h = File.open(secfile){|file| file.readline}.sub(/^#* */,"").chomp + buf << "1. [#{h}](gfm/#{s2md(secfile)})\n" end File.write("Readme.md", buf.join) end # srcfiles => mdfiles pair(srcfiles, mdfiles).each do |src, dst, i| - file dst => [src] + src.c_files do + file dst => [src] + c_files(src) do src2md src, dst, "gfm" - if src.instance_of? Sec_file + if src =~ /sec\d+\.src\.md$/ 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" + nav = "Up: [Readme.md](../Readme.md), Next: [Section 2](#{s2md(secfiles[1])})\n" elsif i == secfiles.size - 1 - nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{secfiles[i-1].to_md})\n" + nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{s2md(secfiles[i-1])})\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" + nav = "Up: [Readme.md](../Readme.md), Prev: [Section #{i}](#{s2md(secfiles[i-1])}), Next: [Section #{i+2}](#{s2md(secfiles[i+1])})\n" end File.write(dst, nav + "\n" + File.read(dst) + "\n" + nav) end end end -task html: %W[#{html_dir}/index.html] + htmlfiles do - cp_images srcfiles, "docs/image" -end +task html: %W[#{html_dir}/index.html] + htmlfiles + htmlimagefiles file "#{html_dir}/index.html" => [abstract] + secfiles do - abstract_md = "#{html_dir}/#{abstract.to_md}" - src2md abstract, abstract_md, "html" + abstract_html_md = "#{html_dir}/#{s2md(abstract)}" + src2md abstract, abstract_html_md, "html" buf = [ "# Gtk4 Tutorial for beginners\n\n" ]\ - + File.readlines(abstract_md)\ + + File.readlines(abstract_html_md)\ + ["\n## Table of contents\n\n"] - File.delete(abstract_md) + File.delete(abstract_html_md) secfiles.each_with_index do |secfile, i| - h = File.open(secfile.path){|file| file.readline}.sub(/^#* */,"").chomp - buf << "1. [#{h}](#{secfile.to_html})\n" + h = File.open(secfile){|file| file.readline}.sub(/^#* */,"").chomp + buf << "1. [#{h}](#{s2html(secfile)})\n" end buf << "\nThis website uses [Bootstrap](https://getbootstrap.jp/)." File.write("#{html_dir}/index.md", buf.join) @@ -99,10 +126,10 @@ file "#{html_dir}/index.html" => [abstract] + secfiles do end pair(srcfiles, htmlfiles).each do |src, dst, i| - file dst => [src] + src.c_files do - html_md = "#{html_dir}/#{src.to_md}" + file dst => [src] + c_files(src) do + html_md = "#{html_dir}/#{s2md(src)}" src2md src, html_md, "html" - if src.instance_of? Sec_file + if src =~ /sec\d+\.src\.md$/ if secfiles.size == 1 mk_html_template("index.html", nil, nil) elsif i == 0 @@ -121,6 +148,12 @@ pair(srcfiles, htmlfiles).each do |src, dst, i| end end +pair(imagesrcfiles, htmlimagefiles).each do |src, dst, i| + file dst => src do + cp src, dst + end +end + task pdf: %w[latex/main.tex] do sh "cd latex; lualatex main.tex" sh "cd latex; lualatex main.tex" @@ -128,19 +161,19 @@ task pdf: %w[latex/main.tex] do end file "latex/main.tex" => [abstract_tex] + texfiles do - gen_main_tex "latex", abstract.to_tex, sectexfiles, othertexfiles + gen_main_tex "latex", s2tex(abstract), sectexfiles, othertexfiles end file abstract_tex => abstract do - abstract_md = "latex/"+abstract.to_md - src2md abstract, abstract_md, "latex" - sh "pandoc --listings -o #{abstract_tex} #{abstract_md}" - File.delete(abstract_md) + abstract_tex_md = "latex/#{s2md(abstract)}" + src2md abstract, abstract_tex_md, "latex" + sh "pandoc --listings -o #{abstract_tex} #{abstract_tex_md}" + File.delete(abstract_tex_md) end pair(srcfiles, texfiles).each do |src, dst, i| - file dst => [src] + src.c_files do - tex_md = "latex/#{src.to_md}" + file dst => [src] + c_files(src) do + tex_md = "latex/#{s2md(src)}" src2md src, tex_md, "latex" if src == "src/Readme_for_developers.src.md" sh "pandoc -o #{dst} #{tex_md}" diff --git a/docs/Readme_for_developers.html b/docs/Readme_for_developers.html index 7ab6e47..0155378 100644 --- a/docs/Readme_for_developers.html +++ b/docs/Readme_for_developers.html @@ -76,7 +76,6 @@ code span.va { color: #19177c; } /* Variable */ code span.vs { color: #4070a0; } /* VerbatimString */ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ - body {width: 1080px; margin: 0 auto; font-size: large;} div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll} pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll} table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;} @@ -302,7 +301,7 @@ Refer to tfetextview API reference in appendix.
The order of the conversions are:
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 docs
directory. Then, pandoc converts them to html files. The width and height of image files are removed.
First, it generates pandoc’s markdown files under docs
directory. Then, pandoc converts them to html files. The width and height of image files are removed. Links to .src.md files will be converted like this.
[Section 5](sec5.src.md) => [Section 5](sec5.html)
+Image files are copied to docs/image
direcotiry and links to them will be converted like this:
[sample.png](../image/sample.png) => [sample.png](image/sample.png)
+Other relative links will be removed.
index.html
is the top html file. If you want to clean html files, type rake clobber
$ rake clobber
Every html file has a header (<head> -- </head>
). It is created by pandoc with ‘-s’ option. You can customize the output with your own template file for pandoc. Rake uses lib/lib_mk_html_template.rb
to create its own template. The template inserts bootstrap CSS and Javascript through jsDelivr
.
The first line is:
FC '(' NUM ',' NUM ',' NUM ')';
The parser analyzes the turtle source code and if the input matches the definition above, the parser recognizes it as a primary procedure.
-The grammar of turtle is described in the document. The following is an extract from the document.
+The grammar of turtle is described in the document. The following is an extract from the document.
program:
statement
| program statement
diff --git a/docs/sec26.html b/docs/sec26.html
index 48ca6bd..6ff59bc 100644
--- a/docs/sec26.html
+++ b/docs/sec26.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec27.html b/docs/sec27.html
index ccbc295..10a24f8 100644
--- a/docs/sec27.html
+++ b/docs/sec27.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec28.html b/docs/sec28.html
index cd056bc..1cf01bc 100644
--- a/docs/sec28.html
+++ b/docs/sec28.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec29.html b/docs/sec29.html
index b68f42a..0c670f3 100644
--- a/docs/sec29.html
+++ b/docs/sec29.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec3.html b/docs/sec3.html
index bb0f051..9413d95 100644
--- a/docs/sec3.html
+++ b/docs/sec3.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec4.html b/docs/sec4.html
index afeb657..852b6eb 100644
--- a/docs/sec4.html
+++ b/docs/sec4.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec5.html b/docs/sec5.html
index c635726..a2c9c03 100644
--- a/docs/sec5.html
+++ b/docs/sec5.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec6.html b/docs/sec6.html
index b3d7c0e..85edcc0 100644
--- a/docs/sec6.html
+++ b/docs/sec6.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec7.html b/docs/sec7.html
index 8afe53f..fe9043f 100644
--- a/docs/sec7.html
+++ b/docs/sec7.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec8.html b/docs/sec8.html
index 7b66588..eef1bd1 100644
--- a/docs/sec8.html
+++ b/docs/sec8.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/sec9.html b/docs/sec9.html
index 99c180c..a6cb1de 100644
--- a/docs/sec9.html
+++ b/docs/sec9.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/tfetextview_doc.html b/docs/tfetextview_doc.html
index 1667ef5..f09e81b 100644
--- a/docs/tfetextview_doc.html
+++ b/docs/tfetextview_doc.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/docs/turtle_doc.html b/docs/turtle_doc.html
index 6dec1d0..b7a7cce 100644
--- a/docs/turtle_doc.html
+++ b/docs/turtle_doc.html
@@ -76,7 +76,6 @@
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/gfm/Readme_for_developers.md b/gfm/Readme_for_developers.md
index 052c806..b7402cd 100644
--- a/gfm/Readme_for_developers.md
+++ b/gfm/Readme_for_developers.md
@@ -304,7 +304,7 @@ In addition, some other conversions are made by `src2md` method.
- 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.
+- Relative link is removed when the destination is html and/or latex.
The order of the conversions are:
@@ -449,6 +449,15 @@ Type `rake html` to generate html files.
First, it generates pandoc's markdown files under `docs` directory.
Then, pandoc converts them to html files.
The width and height of image files are removed.
+Links to .src.md files will be converted like this.
+
+ [Section 5](sec5.src.md) => [Section 5](sec5.html)
+
+Image files are copied to `docs/image` direcotiry and links to them will be converted like this:
+
+ [sample.png](../image/sample.png) => [sample.png](image/sample.png)
+
+Other relative links will be removed.
`index.html` is the top html file.
If you want to clean html files, type `rake clobber`
diff --git a/gfm/sec25.md b/gfm/sec25.md
index 5f85db9..ea8e288 100644
--- a/gfm/sec25.md
+++ b/gfm/sec25.md
@@ -1041,7 +1041,7 @@ The semantic value of `statement` is assigned to the one of `program` and the st
The following is the grammar rule extracted from `turtle.y`.
The rules there are based on the same idea above.
I don't want to explain the whole rules below.
-Please look into each line carefully so that you will understand all the rules and actions.
+Please look into each line carefully so that you will understand all the rules and actions.
~~~bison
program:
@@ -1203,7 +1203,7 @@ union _object_t {
node_t *node;
double value;
};
-
+
struct {
int type;
char *name;
@@ -1508,8 +1508,8 @@ struct color {
double green;
double blue;
};
-static struct color bc = {0.95, 0.95, 0.95}; /* white */
-static struct color fc = {0.0, 0.0, 0.0}; /* black */
+static struct color bc = {0.95, 0.95, 0.95}; /* white */
+static struct color fc = {0.0, 0.0, 0.0}; /* black */
/* cairo */
static cairo_t *cr;
@@ -1603,7 +1603,7 @@ double value = 0.0;
case N_NUM:
value = value(node);
break;
- default:
+ default:
runtime_error ("Illegal expression.\n");
}
return value;
@@ -1950,5 +1950,4 @@ However, the following information is very useful (but old).
Lately, lots of source codes are in the internet.
Maybe reading source codes are the most useful for programmers.
-
Up: [Readme.md](../Readme.md), Prev: [Section 24](sec24.md), Next: [Section 26](sec26.md)
diff --git a/gfm/sec26.md b/gfm/sec26.md
index c4d7f59..33a8fdf 100644
--- a/gfm/sec26.md
+++ b/gfm/sec26.md
@@ -268,7 +268,7 @@ Therefore, GtkListItem instance is used as the `this` object of the lookup tag w
`this` object will be explained in [section 28](sec28.md).
The C source code is as follows.
-Its name is `list2.c` and located under [src/misc](misc) directory.
+Its name is `list2.c` and located under [src/misc](../src/misc) directory.
~~~C
1 #include
@@ -427,7 +427,7 @@ Because it can be NULL when GListItem `item` is unbound.
If its GFileInfo, then return the filename (copy of the filename).
The whole program (`list3.c`) is as follows.
-The program is located in [src/misc](misc) directory.
+The program is located in [src/misc](../src/misc) directory.
~~~C
1 #include
diff --git a/lib/lib_cp_images.rb b/lib/lib_cp_images.rb
deleted file mode 100644
index cea8594..0000000
--- a/lib/lib_cp_images.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'fileutils'
-include FileUtils
-
-def cp_images srcmdfiles, dst_dir
- mkdir_p(dst_dir) unless Dir.exist?(dst_dir)
- images = srcmdfiles.map do |file|
- d = File.dirname(file)
- f = File.read(file)
- f = f.gsub(/^ .*\n/,'')
- f = f.gsub(/^~~~.*?^~~~\n/m,'')
- imgs = f.scan(/!\[.*?\]\((.*?)\)/).flatten.uniq
- imgs.map{|img| File.absolute_path("#{d}/#{img}")}
- end
- images = images.flatten.sort.uniq
- images.each do |src|
- dst = "#{dst_dir}/#{File.basename(src)}"
- cp(src, dst)
- end
-end
diff --git a/lib/lib_mk_html_template.rb b/lib/lib_mk_html_template.rb
index 11dd173..c9a6ab9 100644
--- a/lib/lib_mk_html_template.rb
+++ b/lib/lib_mk_html_template.rb
@@ -80,7 +80,6 @@ def mk_html_template(home, sec_prev, sec_next)
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
- body {width: 1080px; margin: 0 auto; font-size: large;}
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
diff --git a/lib/lib_renumber.rb b/lib/lib_renumber.rb
new file mode 100644
index 0000000..aac2635
--- /dev/null
+++ b/lib/lib_renumber.rb
@@ -0,0 +1,33 @@
+def renumber secfiles
+ temp_name = get_temp_name()
+ secfiles.sort!{|f,g| f.match(/\d+(\.\d+)?\.src\.md$/).to_a[0].to_f <=> g.match(/\d+(\.\d+)?\.src\.md$/).to_a[0].to_f}
+ rename_rule = []
+ secfiles.each_with_index do |file, i|
+ # rule: sec_file, filename_old, temporary_file, filename_new, number_old, number_new
+ # Be careful that the sec_file will change from filename_old to filename_new. String is mutable!
+ rename_rule << [file, file+temp_name, file.gsub(/\d+(\.\d+)?\.src\.md$/,"#{i+1}.src.md")]
+ end
+ rename_rule.each do |rule|
+ File.rename rule[0], rule[1] if rule[0] != rule[2]
+ end
+ rename_rule.each do |rule|
+ File.rename rule[1], rule[2] if rule[0] != rule[2]
+ end
+ rename_rule.each do |rule|
+ src = File.read(rule[2])
+ changed = false
+ rename_rule.each do |rule|
+ old, temp, new = rule
+ unless old == new
+ old_n = /\d+(\.\d+)?/.match(old).to_a[0]
+ new_n = /\d+(\.\d+)?/.match(new).to_a[0]
+ src = src.gsub(/(\[(S|s)ection *)#{old_n}\]\(sec#{old_n}\.src\.md\)/, "\\1#{new_n}](sec#{new_n})")
+ changed = true
+ end
+ end
+ File.write(rule[2], src) if changed
+ end
+end
+def get_temp_name
+ "temp_"+Time.now.to_f.to_s.gsub(/\./,'')
+end
diff --git a/lib/lib_src2md.rb b/lib/lib_src2md.rb
index fbbba37..a4682bd 100644
--- a/lib/lib_src2md.rb
+++ b/lib/lib_src2md.rb
@@ -298,15 +298,18 @@ def change_link src, old_dir, type, new_dir=nil
raise "Illegal type." unless type == "gfm" || type == "html" || type == "latex"
new_dir = type if new_dir == nil
p_new_dir = Pathname.new(new_dir)
- buf = src.partitions(/^ .*\n/)
- buf = buf.map{|chunk| chunk.partitions(/^~~~.*?^~~~\n/m)}
- buf = buf.inject([]){|b,e| b.append(*e)}
- buf = buf.map{|chunk| chunk.partitions(/`.*?`/)}
- buf = buf.inject([]){|b,e| b.append(*e)}
+ buf = src.partitions(/^~~~.*?^~~~\n/m)
+ buf = buf.map{|chunk| chunk =~ /\A~~~.*?^~~~\n\z/m ? chunk : chunk.partitions(/(^ .*\n)+/)}.flatten
+ # buf = buf.inject([]){|b,e| b.append(*e)}
buf = buf.map do |chunk|
- if (chunk =~ /^ .*\n/ || chunk =~ /^~~~.*?^~~~\n/m) || chunk =~ /`.*?`/
+ if (chunk =~ /\A~~~.*?^~~~\n\z/m || chunk =~ /\A(^ .*\n)+\z/)
chunk
else
+ # change inline codes (`...`) to escape char ("\e"=0x1B) in the link change procedure temporarily.
+ # This avoids the influence of the change in the inline codes.
+ # So, .src.md files must not include escape code (0x1B).
+ codes = chunk.scan(/`.*?`/)
+ chunk = chunk.gsub(/`.*?`/,"\e")
b = chunk.partitions(/!?\[.*?\]\(.*?\)(\{.*?\})?/)
b = b.map do |c|
m = c.match(/(!?\[.*?\])\((.*?)\)(\{.*?\})?/)
@@ -316,7 +319,9 @@ def change_link src, old_dir, type, new_dir=nil
name = m[1]
target = m[2]
size = m[3]
- if target =~ /\.src\.md$/
+ if target.include?("\e")
+ c
+ elsif target =~ /\.src\.md$/
case type
when "gfm"
"#{name}(#{File.basename(target).sub(/\.src\.md$/,'.md')})"
@@ -348,7 +353,10 @@ def change_link src, old_dir, type, new_dir=nil
end
end
end
- b.join
+ c = b.join
+ a = c.split("\e")
+ i = 0
+ codes.inject([a[0]]){|b, code| i+=1; b.append(code, a[i])}.join
end
end
buf.join
diff --git a/lib/lib_src_file.rb b/lib/lib_src_file.rb
deleted file mode 100644
index 0ab1a52..0000000
--- a/lib/lib_src_file.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-class Src_file other
- if other.instance_of?(Sec_file)
- self.to_f <=> other.to_f
- else
- nil
- end
- end
-# Note: is_i? indicates the number is integer mathematically. For example, 2.0 is an integer.
-# It doesn't mean the class of the number is Integer.
- def is_i?
- self.to_f == self.to_f.floor
- end
-end
-
-class Sec_files < Array
- def initialize sec_files
- raise "#{sec_files} is not an array." unless sec_files.instance_of? Array
- sec_files.each do |sec_file|
- raise "#{sec_file} is not an instance of Sec_file." unless sec_file.instance_of? Sec_file
- end
- super(sec_files)
- end
- def renum!
- temp = get_temp_name()
- self.sort!
- rename_rule = []
- self.each_with_index do |file, i|
- # rule: sec_file, filename_old, temporary_file, filename_new, number_old, number_new
- # Be careful that the sec_file will change from filename_old to filename_new. String is mutable!
- rename_rule << [file, String.new(file), file+temp, file.gsub(/\d+(\.\d+)?\.src\.md$/,"#{i+1}.src.md"),\
- file.match(/(\d+(\.\d+)?)\.src\.md$/)[1], (i+1).to_s]
- end
- rename_rule.each do |rule|
- File.rename rule[1], rule[2] if rule[1] != rule[3]
- end
- rename_rule.each do |rule|
- File.rename rule[2], rule[3] if rule[1] != rule[3]
- rule[0].replace rule[3]
- end
- self.each do |file|
- org = File.read(file)
- new = File.read(file)
- rename_rule.each do |rule|
- if rule[1] != rule[3]
- new = new.gsub(/(\[(S|s)ection *)#{rule[4]}\]\(sec#{rule[4]}\.src\.md\)/, "\\1#{rule[4]}](#{rule[2]})")
- end
- end
- rename_rule.each do |rule|
- if rule[1] != rule[3]
- new = new.gsub(/(\[(S|s)ection *)#{rule[4]}\]\(#{rule[2]}\)/, "\\1#{rule[5]}](sec#{rule[5]}.src.md)")
- end
- end
- File.write(file, new) unless new == org
- end
- end
-
-private
- def get_temp_name
- "temp_"+Time.now.to_f.to_s.gsub(/\./,'')
- end
-
-end
diff --git a/src/Readme_for_developers.src.md b/src/Readme_for_developers.src.md
index 957e424..cfdc1e0 100644
--- a/src/Readme_for_developers.src.md
+++ b/src/Readme_for_developers.src.md
@@ -304,7 +304,7 @@ In addition, some other conversions are made by `src2md` method.
- 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.
+- Relative link is removed when the destination is html and/or latex.
The order of the conversions are:
@@ -449,6 +449,15 @@ Type `rake html` to generate html files.
First, it generates pandoc's markdown files under `docs` directory.
Then, pandoc converts them to html files.
The width and height of image files are removed.
+Links to .src.md files will be converted like this.
+
+ [Section 5](sec5.src.md) => [Section 5](sec5.html)
+
+Image files are copied to `docs/image` direcotiry and links to them will be converted like this:
+
+ [sample.png](../image/sample.png) => [sample.png](image/sample.png)
+
+Other relative links will be removed.
`index.html` is the top html file.
If you want to clean html files, type `rake clobber`
diff --git a/test/test_lib_renumber.rb b/test/test_lib_renumber.rb
new file mode 100644
index 0000000..6fe254f
--- /dev/null
+++ b/test/test_lib_renumber.rb
@@ -0,0 +1,35 @@
+# test_lib_sec_file.rb
+require 'minitest/autorun'
+require 'fileutils'
+require_relative "../lib/lib_renumber.rb"
+
+
+class Test_lib_renumber < Minitest::Test
+ include FileUtils
+ def test_renumber
+ table = [
+ ["sec4.src.md", "sample5\n", "sec5.src.md"],
+ ["sec0.5.src.md", "sample2\n", "sec2.src.md"],
+ ["sec1.5.src.md", "sample4\n", "sec4.src.md"],
+ ["sec0.src.md", "sample1\n", "sec1.src.md"],
+ ["sec5.5.src.md", "sample6\n", "sec6.src.md"],
+ ["sec1.src.md", "sample3\n", "sec3.src.md"]
+ ]
+ temp_dir = get_temp_name()
+ Dir.mkdir temp_dir unless Dir.exist? temp_dir
+ table = table.map{|t| ["#{temp_dir}/#{t[0]}", t[1], "#{temp_dir}/#{t[2]}"]}
+ table.each{|t| File.write(t[0], t[1])}
+ files = table.map{|t| t[0]}
+ renumber files
+ table.each do |t|
+ t << File.read(t[2])
+ end
+ remove_entry_secure(temp_dir)
+ table.each do |t|
+ assert_equal t[1], t[3]
+ end
+ end
+ def get_temp_name
+ "temp_"+Time.now.to_f.to_s.gsub(/\./,'')
+ end
+end
diff --git a/test/test_lib_src2md.rb b/test/test_lib_src2md.rb
index a48221b..ad7ae15 100644
--- a/test/test_lib_src2md.rb
+++ b/test/test_lib_src2md.rb
@@ -847,6 +847,19 @@ class Test_lib_src_file < Minitest::Test
assert_equal "[Section 3](sec3.md)", change_link("[Section 3](sec3.src.md)", "src", "gfm")
assert_equal "[Section 3](sec3.html)", change_link("[Section 3](sec3.src.md)", "src", "html")
assert_equal "Section 3", change_link("[Section 3](sec3.src.md)", "src", "latex")
+ src_src = <<~'EOS'
+ [Section 1](`sec1.src.md`)
+ [`document`](../doc/document.src.md)
+ `![image](../image/image.png){width=9.0cm height=6.0cm}``
+ [Github`](`https://github.com/ToshioCP)
+ EOS
+ dst_src = <<~'EOS'
+ [Section 1](`sec1.src.md`)
+ [`document`](document.md)
+ `![image](../image/image.png){width=9.0cm height=6.0cm}``
+ [Github`](`https://github.com/ToshioCP)
+ EOS
+ assert_equal dst_src, change_link(src_src, "src", "gfm", "gfm")
end
def test_src2md
temp = "temp"
@@ -865,11 +878,11 @@ class Test_lib_src_file < Minitest::Test
remove_entry_secure(temp)
# If you want to see the difference
- # Diff::LCS.diff(files_src2md()[:sample_md_gfm].each_line.to_a, dst_md["gfm"].each_line.to_a).each do |array|
- # array.each do |change|
- # print "#{change.action} #{change.position.to_s.chomp}: #{change.element.to_s.chomp}\n"
- # end
- # end
+ Diff::LCS.diff(files_src2md()[:sample_md_gfm].each_line.to_a, dst_md["gfm"].each_line.to_a).each do |array|
+ array.each do |change|
+ print "#{change.action} #{change.position.to_s.chomp}: #{change.element.to_s.chomp}\n"
+ end
+ end
# Diff::LCS.diff(files()[:sample_md_latex].each_line.to_a, dst_md["latex"].each_line.to_a).each do |array|
# array.each do |change|
# print "#{change.action} #{change.position.to_s.chomp}: #{change.element.to_s.chomp}\n"
diff --git a/test/test_lib_src_file.rb b/test/test_lib_src_file.rb
deleted file mode 100644
index ab66de2..0000000
--- a/test/test_lib_src_file.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-# test_lib_sec_file.rb
-require 'minitest/autorun'
-require 'fileutils'
-require_relative "../lib/lib_src_file.rb"
-
-module Prepare_test
- def files_srcfile
- src_text = <<~'EOS'
- This is a source file.
- EOS
-
- sample_c = <<~'EOS'
- #include
-
- int
- main (int argc, char **argv) {
- printf ("Hello world.\n");
- }
- EOS
-
- sec1_text = <<~'EOS'
- This is a test file.
- The sorce of `sample.c` is:
-
- @@@include
- sample.c main
- @@@
-
- It is the simplest C program.
- EOS
-
- sec2_text = <<~'EOS'
- To compile the C source file `sample.c`, type:
-
- ~~~
- $ gcc sample.c
- ~~~
-
- Then executable file `a.out` is generated.
-
- @@@shell
- ls
- @@@
-
- To execute it, type:
-
- ~~~
- $ ./a.out
- ~~~
-
- The source code is in [Section 1](sec1.src.md)
- EOS
-
- sec05_text = <<~'EOS'
- Prerequisite
-
- - Linux OS like Ubuntu or Debian.
- - gcc
- EOS
-
- [
- ["srcfile.src.md", src_text],
- ["sample.c", sample_c],
- ["sec1.src.md", sec1_text],
- ["sec2.src.md", sec2_text],
- ["sec0.5.src.md", sec05_text]
- ]
- end
-end
-
-class Test_lib_src_file < Minitest::Test
- include FileUtils
- include Prepare_test
- def setup
- # Create sample file
- @temp = get_temp_name()
- Dir.mkdir @temp unless Dir.exist? @temp
- files_srcfile().each do |f|
- File.write "#{@temp}/#{f[0]}", f[1]
- end
- end
- def teardown
- remove_entry_secure(@temp)
- end
- def test_src_file
- 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|
- assert_equal item[1], src.public_send(item[0].to_sym)
- end
- end
- def test_sec_file
- src_sec05 = Sec_file.new "#{@temp}/sec0.5.src.md"
- src_sec1 = Sec_file.new "#{@temp}/sec1.src.md"
- src_sec2 = Sec_file.new "#{@temp}/sec2.src.md"
- test_items = [
- ["path", "#{@temp}/sec1.src.md"],
- ["basename", "sec1.src.md"],
- ["dirname", "#{@temp}"],
- ["c_files", [ "#{@temp}/sample.c" ]],
- ["to_md", "sec1.md"],
- ["to_html", "sec1.html"],
- ["to_tex", "sec1.tex"],
- ["num", "1"],
- ["to_f", 1.0],
- ["<=>", src_sec05, 1],
- ["<=>", src_sec1, 0],
- ["<=>", src_sec2, -1],
- ["is_i?", true]
- ]
- test_items.each do |item|
- if item.size == 2
- assert_equal item[1], src_sec1.public_send(item[0].to_sym)
- else
- assert_equal item[2], src_sec1.public_send(item[0].to_sym, item[1])
- end
- end
- refute src_sec05.is_i?
- end
- def test_sec_files
- temp_renum = "temp_renum"+get_temp_name()
- unless Dir.exist? temp_renum
- Dir.mkdir temp_renum
- end
- files_srcfile().each do |f|
- File.write "#{temp_renum}/#{f[0]}", f[1]
- end
- src_sec05 = Sec_file.new "#{temp_renum}/sec0.5.src.md"
- src_sec1 = Sec_file.new "#{temp_renum}/sec1.src.md"
- src_sec2 = Sec_file.new "#{temp_renum}/sec2.src.md"
- sec_files = Sec_files.new [src_sec05, src_sec1, src_sec2]
- sec_files.renum!
- line_actual = File.read(src_sec2).match(/The source code is in \[Section \d\]\(sec\d.src.md\)\n/).to_a[0]
- remove_entry_secure(temp_renum)
- assert_equal ["#{temp_renum}/sec1.src.md", "#{temp_renum}/sec2.src.md", "#{temp_renum}/sec3.src.md"], sec_files
- assert_equal "The source code is in [Section 2](sec2.src.md)\n", line_actual
- end
-private
- def get_temp_name
- "temp_"+Time.now.to_f.to_s.gsub(/\./,'')
- end
-end
diff --git a/test/test_rakefile.rb b/test/test_rakefile.rb
new file mode 100644
index 0000000..f2c77a9
--- /dev/null
+++ b/test/test_rakefile.rb
@@ -0,0 +1,57 @@
+# test_lib_sec_file.rb
+require 'minitest/autorun'
+require 'fileutils'
+# require_relative "../Rakefile"
+
+
+class Test_rakefile < Minitest::Test
+ include FileUtils
+ def test_rakefile
+ rakefile = File.read("../Rakefile")
+ c_files = rakefile.match(/^def c_files.*?^end\n/m)[0]
+ eval c_files
+ src = <<~'EOS'
+ ## meson.build
+
+ @@@include
+ tfe5/meson.build
+ @@@
+
+ ## tfe.gresource.xml
+
+ @@@include
+ tfe5/tfe.gresource.xml
+ @@@
+
+ ## tfe.ui
+
+ @@@include
+ tfe5/tfe.ui
+ @@@
+
+ ## tfe.h
+
+ @@@include
+ tfe5/tfe.h
+ @@@
+
+ ## tfeapplication.c
+
+ @@@include
+ tfe5/tfeapplication.c app_startup app_open
+ @@@
+ EOS
+ temp_dir = get_temp_name()
+ Dir.mkdir temp_dir unless Dir.exist? temp_dir
+ path = "#{temp_dir}/secXX.src.md"
+ File.write(path, src)
+ expected = ["tfe5/meson.build", "tfe5/tfe.gresource.xml", "tfe5/tfe.ui", "tfe5/tfe.h", "tfe5/tfeapplication.c"]\
+ .map{|f| "#{temp_dir}/#{f}"}
+ actual = c_files(path)
+ remove_entry_secure(temp_dir)
+ assert_equal expected.sort, actual.sort
+ end
+ def get_temp_name
+ "temp_"+Time.now.to_f.to_s.gsub(/\./,'')
+ end
+end