review 4.1.0 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (259) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +35 -0
  3. data/.github/workflows/ruby-win.yml +19 -9
  4. data/.github/workflows/ruby.yml +7 -3
  5. data/.rubocop.yml +138 -34
  6. data/NEWS.ja.md +285 -0
  7. data/NEWS.md +285 -1
  8. data/README.md +7 -6
  9. data/Rakefile +7 -2
  10. data/bin/review +2 -4
  11. data/bin/review-catalog-converter +4 -4
  12. data/bin/review-check +8 -12
  13. data/bin/review-checkdep +2 -5
  14. data/bin/review-compile +18 -34
  15. data/bin/review-epub2html +1 -4
  16. data/bin/review-epubmaker +3 -4
  17. data/bin/review-idgxmlmaker +1 -3
  18. data/bin/review-index +5 -86
  19. data/bin/review-init +1 -4
  20. data/bin/review-pdfmaker +1 -3
  21. data/bin/review-preproc +30 -38
  22. data/bin/review-textmaker +1 -3
  23. data/bin/review-update +1 -4
  24. data/bin/review-validate +4 -4
  25. data/bin/review-vol +5 -82
  26. data/bin/review-webmaker +1 -3
  27. data/doc/config.yml.sample +45 -11
  28. data/doc/config.yml.sample-simple +3 -3
  29. data/doc/format.ja.md +103 -13
  30. data/doc/format.md +104 -16
  31. data/doc/makeindex.ja.md +2 -2
  32. data/doc/pdfmaker.ja.md +42 -0
  33. data/doc/pdfmaker.md +41 -0
  34. data/doc/quickstart.ja.md +19 -6
  35. data/doc/quickstart.md +18 -6
  36. data/doc/writing_vertical.ja.md +6 -0
  37. data/lib/review.rb +1 -1
  38. data/lib/review/book.rb +2 -2
  39. data/lib/review/book/base.rb +67 -29
  40. data/lib/review/book/bib.rb +21 -0
  41. data/lib/review/book/book_unit.rb +158 -0
  42. data/lib/review/book/chapter.rb +33 -26
  43. data/lib/review/book/index.rb +24 -185
  44. data/lib/review/book/index/item.rb +7 -1
  45. data/lib/review/book/page_metric.rb +7 -7
  46. data/lib/review/book/part.rb +26 -11
  47. data/lib/review/book/volume.rb +5 -5
  48. data/lib/review/builder.rb +121 -52
  49. data/lib/review/call_hook.rb +20 -0
  50. data/lib/review/catalog.rb +3 -2
  51. data/lib/review/compiler.rb +230 -111
  52. data/lib/review/configure.rb +91 -7
  53. data/lib/review/converter.rb +1 -1
  54. data/lib/review/epub2html.rb +6 -1
  55. data/lib/review/epubmaker.rb +124 -152
  56. data/lib/review/epubmaker/content.rb +113 -0
  57. data/lib/review/epubmaker/epubcommon.rb +372 -0
  58. data/lib/review/epubmaker/epubv2.rb +178 -0
  59. data/lib/review/epubmaker/epubv3.rb +231 -0
  60. data/lib/review/epubmaker/producer.rb +167 -0
  61. data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
  62. data/lib/review/epubmaker/zip_exporter.rb +84 -0
  63. data/lib/review/exception.rb +13 -0
  64. data/lib/review/htmlbuilder.rb +176 -89
  65. data/lib/review/htmlutils.rb +8 -11
  66. data/lib/review/i18n.rb +2 -1
  67. data/lib/review/idgxmlbuilder.rb +165 -75
  68. data/lib/review/idgxmlmaker.rb +24 -28
  69. data/lib/review/img_math.rb +238 -0
  70. data/lib/review/index_builder.rb +645 -0
  71. data/lib/review/init.rb +9 -17
  72. data/lib/review/latexbox.rb +58 -0
  73. data/lib/review/latexbuilder.rb +193 -75
  74. data/lib/review/latexutils.rb +9 -1
  75. data/lib/review/lineinput.rb +112 -2
  76. data/lib/review/loggable.rb +27 -0
  77. data/lib/review/logger.rb +90 -3
  78. data/lib/review/makerhelper.rb +17 -188
  79. data/lib/review/markdownbuilder.rb +54 -4
  80. data/lib/review/pdfmaker.rb +76 -84
  81. data/lib/review/plaintextbuilder.rb +106 -22
  82. data/lib/review/preprocessor.rb +107 -303
  83. data/lib/review/preprocessor/directive.rb +35 -0
  84. data/lib/review/preprocessor/line.rb +34 -0
  85. data/lib/review/preprocessor/repository.rb +177 -0
  86. data/lib/review/rstbuilder.rb +27 -8
  87. data/lib/review/sec_counter.rb +14 -0
  88. data/lib/review/template.rb +11 -1
  89. data/lib/review/textmaker.rb +27 -32
  90. data/lib/review/textutils.rb +3 -12
  91. data/lib/review/tocprinter.rb +242 -97
  92. data/lib/review/topbuilder.rb +98 -31
  93. data/lib/review/update.rb +12 -13
  94. data/lib/review/version.rb +1 -1
  95. data/lib/review/volumeprinter.rb +97 -0
  96. data/lib/review/webmaker.rb +40 -47
  97. data/lib/review/webtocprinter.rb +39 -35
  98. data/lib/review/yamlloader.rb +2 -1
  99. data/review.gemspec +5 -3
  100. data/samples/sample-book/src/config-epub2.yml +1 -1
  101. data/samples/sample-book/src/config.yml +3 -3
  102. data/samples/sample-book/src/lib/tasks/review.rake +19 -1
  103. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +2 -1
  104. data/samples/syntax-book/Gemfile +1 -1
  105. data/samples/syntax-book/ch01.re +1 -1
  106. data/samples/syntax-book/ch02.re +21 -6
  107. data/samples/syntax-book/ch03.re +1 -1
  108. data/samples/syntax-book/config.yml +1 -1
  109. data/samples/syntax-book/images/img3-2.png +0 -0
  110. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +2 -1
  111. data/templates/html/_colophon.html.erb +23 -0
  112. data/templates/html/_colophon_history.html.erb +9 -0
  113. data/templates/html/_cover.html.erb +10 -0
  114. data/templates/html/_part_body.html.erb +6 -0
  115. data/templates/html/_titlepage.html.erb +20 -0
  116. data/templates/html/layout-html5.html.erb +6 -0
  117. data/templates/html/layout-xhtml1.html.erb +6 -0
  118. data/templates/latex/config.erb +35 -23
  119. data/templates/latex/review-jlreq/README.md +3 -1
  120. data/templates/latex/review-jlreq/review-base.sty +36 -23
  121. data/templates/latex/review-jlreq/review-jlreq.cls +18 -25
  122. data/templates/latex/review-jlreq/review-style.sty +6 -1
  123. data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
  124. data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
  125. data/templates/latex/review-jsbook/README.md +7 -5
  126. data/templates/latex/review-jsbook/review-base.sty +40 -24
  127. data/templates/latex/review-jsbook/review-jsbook.cls +13 -3
  128. data/templates/latex/review-jsbook/review-style.sty +6 -1
  129. data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
  130. data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
  131. data/templates/opf/epubv2.opf.erb +7 -7
  132. data/templates/opf/epubv3.opf.erb +7 -7
  133. data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
  134. data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
  135. data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
  136. data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
  137. data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
  138. data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
  139. data/templates/web/html/layout-html5.html.erb +9 -8
  140. data/templates/web/html/layout-xhtml1.html.erb +6 -0
  141. data/test/assets/header_listener.html +35 -0
  142. data/test/assets/img_math/img1.png +0 -0
  143. data/test/assets/img_math/img2.png +0 -0
  144. data/test/assets/img_math/img3.png +0 -0
  145. data/test/assets/syntax_book_index_detail.txt +58 -0
  146. data/test/assets/test_template.tex +6 -3
  147. data/test/assets/test_template_backmatter.tex +6 -3
  148. data/test/book_test_helper.rb +11 -5
  149. data/test/run_test.rb +1 -1
  150. data/test/test_book.rb +54 -63
  151. data/test/test_book_chapter.rb +95 -54
  152. data/test/test_book_part.rb +3 -3
  153. data/test/test_builder.rb +29 -20
  154. data/test/test_catalog_converter_cmd.rb +1 -1
  155. data/test/test_converter.rb +1 -0
  156. data/test/test_epub3maker.rb +170 -126
  157. data/test/test_epubmaker.rb +254 -129
  158. data/test/test_epubmaker_cmd.rb +15 -4
  159. data/test/test_helper.rb +12 -5
  160. data/test/test_htmlbuilder.rb +926 -76
  161. data/test/test_htmlutils.rb +0 -12
  162. data/test/test_i18n.rb +33 -33
  163. data/test/test_idgxmlbuilder.rb +531 -20
  164. data/test/test_idgxmlmaker_cmd.rb +7 -3
  165. data/test/test_img_math.rb +111 -0
  166. data/test/test_index.rb +62 -52
  167. data/test/test_indexbuilder.rb +52 -0
  168. data/test/test_latexbuilder.rb +891 -20
  169. data/test/test_latexbuilder_v2.rb +56 -10
  170. data/test/test_lineinput.rb +20 -93
  171. data/test/test_logger.rb +7 -7
  172. data/test/test_makerhelper.rb +0 -12
  173. data/test/test_markdownbuilder.rb +32 -0
  174. data/test/test_pdfmaker.rb +100 -11
  175. data/test/test_pdfmaker_cmd.rb +3 -3
  176. data/test/test_plaintextbuilder.rb +546 -32
  177. data/test/test_preprocessor.rb +188 -1
  178. data/test/test_review_ext.rb +2 -1
  179. data/test/test_reviewheaderlistener.rb +49 -0
  180. data/test/test_rstbuilder.rb +25 -1
  181. data/test/test_sec_counter.rb +156 -0
  182. data/test/test_template.rb +12 -2
  183. data/test/test_textmaker_cmd.rb +5 -1
  184. data/test/test_tocprinter.rb +46 -0
  185. data/test/test_topbuilder.rb +324 -20
  186. data/test/test_update.rb +44 -44
  187. data/test/test_webtocprinter.rb +75 -43
  188. data/test/test_zip_exporter.rb +5 -6
  189. data/vendor/gentombow/LICENSE +1 -1
  190. data/vendor/gentombow/Makefile +0 -1
  191. data/vendor/gentombow/bounddvi-en.pdf +0 -0
  192. data/vendor/gentombow/bounddvi-en.tex +1 -0
  193. data/vendor/gentombow/bounddvi.pdf +0 -0
  194. data/vendor/gentombow/bounddvi.sty +30 -7
  195. data/vendor/gentombow/bounddvi.tex +1 -0
  196. data/vendor/gentombow/create_archive.sh +1 -0
  197. data/vendor/gentombow/gentombow-ja.pdf +0 -0
  198. data/vendor/gentombow/gentombow-ja.tex +9 -0
  199. data/vendor/gentombow/gentombow.pdf +0 -0
  200. data/vendor/gentombow/gentombow.sty +32 -10
  201. data/vendor/gentombow/gentombow.tex +8 -0
  202. data/vendor/gentombow/tests/gentombow-01-pdfx.tex +8 -0
  203. data/vendor/gentombow/tests/gentombow-02-pdfx.tex +8 -0
  204. data/vendor/jsclasses/Makefile +3 -2
  205. data/vendor/jsclasses/create_archive.sh +5 -5
  206. data/vendor/jsclasses/jis/Makefile +3 -2
  207. data/vendor/jsclasses/jis/jsarticle.cls +22 -18
  208. data/vendor/jsclasses/jis/jsbook.cls +22 -18
  209. data/vendor/jsclasses/jis/jsclasses.dtx +94 -13
  210. data/vendor/jsclasses/jis/jsclasses.ins +15 -5
  211. data/vendor/jsclasses/jis/jslogo.ins +9 -0
  212. data/vendor/jsclasses/jis/jslogo.sty +1 -13
  213. data/vendor/jsclasses/jis/jspf.cls +22 -18
  214. data/vendor/jsclasses/jis/jsreport.cls +22 -18
  215. data/vendor/jsclasses/jis/jsverb.ins +9 -0
  216. data/vendor/jsclasses/jis/jsverb.sty +1 -13
  217. data/vendor/jsclasses/jis/kiyou.cls +22 -18
  218. data/vendor/jsclasses/jis/minijs.sty +65 -22
  219. data/vendor/jsclasses/jis/okumacro.ins +9 -0
  220. data/vendor/jsclasses/jis/okumacro.sty +1 -13
  221. data/vendor/jsclasses/jis/okuverb.ins +9 -0
  222. data/vendor/jsclasses/jis/okuverb.sty +1 -13
  223. data/vendor/jsclasses/jis/winjis.sty +23 -19
  224. data/vendor/jsclasses/jsarticle.cls +22 -18
  225. data/vendor/jsclasses/jsbook.cls +22 -18
  226. data/vendor/jsclasses/jsclasses.dtx +94 -13
  227. data/vendor/jsclasses/jsclasses.ins +15 -5
  228. data/vendor/jsclasses/jsclasses.pdf +0 -0
  229. data/vendor/jsclasses/jslogo.ins +9 -0
  230. data/vendor/jsclasses/jslogo.pdf +0 -0
  231. data/vendor/jsclasses/jslogo.sty +1 -13
  232. data/vendor/jsclasses/jspf.cls +22 -18
  233. data/vendor/jsclasses/jsreport.cls +22 -18
  234. data/vendor/jsclasses/jsverb.ins +9 -0
  235. data/vendor/jsclasses/jsverb.pdf +0 -0
  236. data/vendor/jsclasses/jsverb.sty +1 -13
  237. data/vendor/jsclasses/kiyou.cls +22 -18
  238. data/vendor/jsclasses/minijs.sty +68 -22
  239. data/vendor/jsclasses/okumacro.ins +9 -0
  240. data/vendor/jsclasses/okumacro.pdf +0 -0
  241. data/vendor/jsclasses/okumacro.sty +1 -13
  242. data/vendor/jsclasses/okuverb.ins +9 -0
  243. data/vendor/jsclasses/okuverb.pdf +0 -0
  244. data/vendor/jsclasses/okuverb.sty +1 -13
  245. data/vendor/jsclasses/tests/relfont.tex +10 -0
  246. data/vendor/jsclasses/winjis.sty +23 -19
  247. metadata +106 -22
  248. data/.rubocop_todo.yml +0 -7
  249. data/lib/epubmaker.rb +0 -23
  250. data/lib/epubmaker/content.rb +0 -110
  251. data/lib/epubmaker/epubcommon.rb +0 -441
  252. data/lib/epubmaker/epubv2.rb +0 -143
  253. data/lib/epubmaker/epubv3.rb +0 -233
  254. data/lib/epubmaker/producer.rb +0 -375
  255. data/lib/epubmaker/zip_exporter.rb +0 -81
  256. data/lib/lineinput.rb +0 -155
  257. data/lib/review/book/compilable.rb +0 -178
  258. data/lib/review/tocparser.rb +0 -275
  259. data/test/test_tocparser.rb +0 -25
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2019 Kenshi Muto
1
+ # Copyright (c) 2019-2021 Kenshi Muto
2
2
  #
3
3
  # This program is free software.
4
4
  # You can distribute or modify this program under the terms of
@@ -15,24 +15,21 @@ require 'review/book'
15
15
  require 'review/yamlloader'
16
16
  require 'review/idgxmlbuilder'
17
17
  require 'review/version'
18
+ require 'review/makerhelper'
19
+ require 'review/loggable'
18
20
 
19
21
  module ReVIEW
20
22
  class IDGXMLMaker
23
+ include MakerHelper
24
+ include Loggable
25
+
21
26
  attr_accessor :config, :basedir
22
27
 
23
28
  def initialize
24
29
  @basedir = nil
25
30
  @logger = ReVIEW.logger
26
31
  @plaintext = nil
27
- end
28
-
29
- def error(msg)
30
- @logger.error "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
31
- exit 1
32
- end
33
-
34
- def warn(msg)
35
- @logger.warn "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
32
+ @compile_errors = nil
36
33
  end
37
34
 
38
35
  def self.execute(*args)
@@ -74,25 +71,20 @@ module ReVIEW
74
71
  end
75
72
 
76
73
  def execute(*args)
77
- @config = ReVIEW::Configure.values
78
- @config.maker = 'idgxmlmaker'
79
74
  cmd_config, yamlfile = parse_opts(args)
80
- error "#{yamlfile} not found." unless File.exist?(yamlfile)
75
+ error! "#{yamlfile} not found." unless File.exist?(yamlfile)
81
76
 
82
- begin
83
- loader = ReVIEW::YAMLLoader.new
84
- @config.deep_merge!(loader.load_file(yamlfile))
85
- rescue => e
86
- error "yaml error #{e.message}"
87
- end
88
- # YAML configs will be overridden by command line options.
89
- @config.deep_merge!(cmd_config)
77
+ @config = ReVIEW::Configure.create(maker: 'idgxmlmaker',
78
+ yamlfile: yamlfile,
79
+ config: cmd_config)
90
80
  I18n.setup(@config['language'])
91
81
  begin
92
82
  generate_idgxml_files(yamlfile)
83
+ @logger.success("built #{build_path}")
93
84
  rescue ApplicationError => e
94
85
  raise if @config['debug']
95
- error(e.message)
86
+
87
+ error! e.message
96
88
  end
97
89
  end
98
90
 
@@ -102,13 +94,16 @@ module ReVIEW
102
94
  remove_old_files(@path)
103
95
  Dir.mkdir(@path)
104
96
 
105
- @book = ReVIEW::Book.load(@basedir)
106
- @book.config = @config
97
+ @book = ReVIEW::Book::Base.new(@basedir, config: @config)
107
98
  if @table
108
99
  @book.config['tableopt'] = @table
109
100
  end
110
101
 
111
102
  build_body(@path, yamlfile)
103
+
104
+ if @compile_errors
105
+ app_error 'compile error, No IDGXML file output.'
106
+ end
112
107
  end
113
108
 
114
109
  def apply_filter(xmlfile)
@@ -155,9 +150,9 @@ module ReVIEW
155
150
  end
156
151
  f.puts '<?xml version="1.0" encoding="UTF-8"?>'
157
152
  f.print '<doc xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"><title aid:pstyle="h1">'
158
- f.print CGI.escapeHTML(title)
153
+ f.print h(title)
159
154
  f.print '</title><?dtp level="1" section="'
160
- f.print CGI.escapeHTML(title)
155
+ f.print h(title)
161
156
  f.puts '"?></doc>'
162
157
  end
163
158
  apply_filter(File.join(basetmpdir, xmlfile))
@@ -183,8 +178,9 @@ module ReVIEW
183
178
  @converter.convert(filename, File.join(basetmpdir, xmlfile))
184
179
  apply_filter(File.join(basetmpdir, xmlfile))
185
180
  rescue => e
186
- warn "compile error in #{filename} (#{e.class})"
187
- warn e.message
181
+ @compile_errors = true
182
+ error "compile error in #{filename} (#{e.class})"
183
+ error e.message
188
184
  end
189
185
  end
190
186
  end
@@ -0,0 +1,238 @@
1
+ require 'fileutils'
2
+ require 'shellwords'
3
+ require 'review/loggable'
4
+
5
+ module ReVIEW
6
+ class ImgMath
7
+ include Loggable
8
+
9
+ def initialize(config, path_name: '_review_math')
10
+ @config = config
11
+ @logger = ReVIEW.logger
12
+ @math_dir = File.join(@config['imagedir'], path_name)
13
+ @math_maps = {}
14
+ end
15
+
16
+ def cleanup_mathimg
17
+ if @config['math_format'] == 'imgmath' && Dir.exist?(@math_dir)
18
+ FileUtils.rm_rf(@math_dir)
19
+ end
20
+ end
21
+
22
+ def defer_math_image(str, key)
23
+ # for Re:VIEW >3
24
+ @math_maps[key] = str
25
+ File.join(@math_dir, "_gen_#{key}.#{@config['imgmath_options']['format']}")
26
+ end
27
+
28
+ def make_math_image(str, key, fontsize = 12)
29
+ # Re:VIEW 2 compatibility
30
+
31
+ img_path = File.join(@math_dir, "_gen_#{key}.#{@config['imgmath_options']['format']}")
32
+ Dir.mkdir(@math_dir) unless Dir.exist?(@math_dir)
33
+ fontsize2 = (fontsize * 1.2).round.to_i
34
+ texsrc = <<-EOB
35
+ \\documentclass[12pt]{article}
36
+ \\usepackage[utf8]{inputenc}
37
+ \\usepackage{amsmath}
38
+ \\usepackage{amsthm}
39
+ \\usepackage{amssymb}
40
+ \\usepackage{amsfonts}
41
+ \\usepackage{anyfontsize}
42
+ \\usepackage{bm}
43
+ \\pagestyle{empty}
44
+
45
+ \\begin{document}
46
+ \\fontsize{#{fontsize}}{#{fontsize2}}\\selectfont #{str}
47
+ \\end{document}
48
+ EOB
49
+ Dir.mktmpdir do |tmpdir|
50
+ tex_path = File.join(tmpdir, 'tmpmath.tex')
51
+ dvi_path = File.join(tmpdir, 'tmpmath.dvi')
52
+ File.write(tex_path, texsrc)
53
+ cmd = "latex --interaction=nonstopmode --output-directory=#{tmpdir} #{tex_path} && dvipng -T tight -z9 -o #{img_path} #{dvi_path}"
54
+ out, status = Open3.capture2e(cmd)
55
+ unless status.success?
56
+ raise ApplicationError, "latex compile error\n\nError log:\n#{out}"
57
+ end
58
+
59
+ img_path
60
+ end
61
+ end
62
+
63
+ def make_math_images
64
+ return if @math_maps.empty?
65
+
66
+ Dir.mkdir(@math_dir) unless Dir.exist?(@math_dir)
67
+ fontsize = @config['imgmath_options']['fontsize'].to_f
68
+ lineheight = @config['imgmath_options']['lineheight'].to_f
69
+
70
+ texsrc = default_imgmath_preamble
71
+ if @config['imgmath_options']['preamble_file'] && File.readable?(@config['imgmath_options']['preamble_file'])
72
+ texsrc = File.read(@config['imgmath_options']['preamble_file'])
73
+ end
74
+
75
+ texsrc << <<-EOB
76
+ \\begin{document}
77
+ \\fontsize{#{fontsize}}{#{lineheight}}\\selectfont
78
+ \\input{__IMGMATH_BODY__}
79
+ \\end{document}
80
+ EOB
81
+
82
+ math_real_dir = File.realpath(@math_dir)
83
+ Dir.mktmpdir do |tmpdir|
84
+ File.open(File.join(tmpdir, '__IMGMATH_BODY__.tex'), 'w') do |f|
85
+ @math_maps.keys.sort.each do |key|
86
+ f.puts "% #{key}"
87
+ f.puts @math_maps[key]
88
+ f.puts '\\clearpage'
89
+ f.puts
90
+ end
91
+ end
92
+
93
+ tex_path = File.join(tmpdir, '__IMGMATH__.tex')
94
+ File.write(tex_path, texsrc)
95
+
96
+ begin
97
+ case @config['imgmath_options']['converter']
98
+ when 'pdfcrop'
99
+ make_math_images_pdfcrop(tmpdir, tex_path, math_real_dir)
100
+ when 'dvipng'
101
+ make_math_images_dvipng(tmpdir, tex_path, math_real_dir)
102
+ else
103
+ error! "unknown math converter error. imgmath_options/converter parameter should be 'pdfcrop' or 'dvipng'."
104
+ end
105
+ rescue CompileError
106
+ FileUtils.cp([tex_path,
107
+ File.join(File.dirname(tex_path), '__IMGMATH__.log')],
108
+ math_real_dir)
109
+ error! "LaTeX math compile error. See #{math_real_dir}/__IMGMATH__.log for details."
110
+ end
111
+ end
112
+ @math_maps.clear
113
+ end
114
+
115
+ private
116
+
117
+ def default_imgmath_preamble
118
+ <<-EOB
119
+ \\documentclass[uplatex,a3paper,landscape]{jsarticle}
120
+ \\usepackage[deluxe,uplatex]{otf}
121
+ \\usepackage[T1]{fontenc}
122
+ \\usepackage{textcomp}
123
+ \\usepackage{lmodern}
124
+ \\usepackage[dvipdfmx]{graphicx}
125
+ \\usepackage[dvipdfmx,table]{xcolor}
126
+ \\usepackage[utf8]{inputenc}
127
+ \\usepackage{ascmac}
128
+ \\usepackage{float}
129
+ \\usepackage{alltt}
130
+ \\usepackage{amsmath}
131
+ \\usepackage{amssymb}
132
+ \\usepackage{amsfonts}
133
+ \\usepackage{anyfontsize}
134
+ \\usepackage{bm}
135
+ \\pagestyle{empty}
136
+ % \\setpaperwidth{1000mm}
137
+ EOB
138
+ end
139
+
140
+ def make_math_images_pdfcrop(dir, tex_path, math_real_dir)
141
+ Dir.chdir(dir) do
142
+ dvi_path = '__IMGMATH__.dvi'
143
+ pdf_path = '__IMGMATH__.pdf'
144
+ out, status = Open3.capture2e(*[@config['texcommand'], @config['texoptions'].shellsplit, tex_path].flatten.compact)
145
+ if !status.success? || (!File.exist?(dvi_path) && !File.exist?(pdf_path))
146
+ raise CompileError
147
+ end
148
+
149
+ if File.exist?(dvi_path)
150
+ out, status = Open3.capture2e(*[@config['dvicommand'], @config['dvioptions'].shellsplit, dvi_path].flatten.compact)
151
+ if !status.success? || !File.exist?(pdf_path)
152
+ @logger.error "error in #{@config['dvicommand']}. Error log:\n#{out}"
153
+ raise CompileError
154
+ end
155
+ end
156
+ args = @config['imgmath_options']['pdfcrop_cmd'].shellsplit
157
+ args.map! do |m|
158
+ m.sub('%i', pdf_path).
159
+ sub('%o', '__IMGMATH__pdfcrop.pdf')
160
+ end
161
+ out, status = Open3.capture2e(*args)
162
+ unless status.success?
163
+ @logger.error "error in pdfcrop. Error log:\n#{out}"
164
+ raise CompileError
165
+ end
166
+ pdf_path = '__IMGMATH__pdfcrop.pdf'
167
+ pdf_path2 = pdf_path
168
+
169
+ @math_maps.keys.sort.each_with_index do |key, idx|
170
+ page = idx + 1
171
+ if File.exist?(File.join(math_real_dir, "_gen_#{key}.#{@config['imgmath_options']['format']}"))
172
+ # made already
173
+ next
174
+ end
175
+
176
+ if @config['imgmath_options']['extract_singlepage']
177
+ # if extract_singlepage = true, split each page
178
+ args = @config['imgmath_options']['pdfextract_cmd'].shellsplit
179
+
180
+ args.map! do |m|
181
+ m.sub('%i', pdf_path).
182
+ sub('%o', "__IMGMATH__pdfcrop_p#{page}.pdf").
183
+ sub('%O', "__IMGMATH__pdfcrop_p#{page}").
184
+ sub('%p', page.to_s)
185
+ end
186
+ out, status = Open3.capture2e(*args)
187
+ unless status.success?
188
+ @logger.error "error in pdf extracting. Error log:\n#{out}"
189
+ raise CompileError
190
+ end
191
+
192
+ pdf_path2 = "__IMGMATH__pdfcrop_p#{page}.pdf"
193
+ end
194
+
195
+ args = @config['imgmath_options']['pdfcrop_pixelize_cmd'].shellsplit
196
+ args.map! do |m|
197
+ m.sub('%i', pdf_path2).
198
+ sub('%t', @config['imgmath_options']['format']).
199
+ sub('%o', File.join(math_real_dir, "_gen_#{key}.#{@config['imgmath_options']['format']}")).
200
+ sub('%O', File.join(math_real_dir, "_gen_#{key}")).
201
+ sub('%p', page.to_s)
202
+ end
203
+ out, status = Open3.capture2e(*args)
204
+ unless status.success?
205
+ @logger.error "error in pdf pixelizing. Error log:\n#{out}"
206
+ raise CompileError
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ def make_math_images_dvipng(dir, tex_path, math_real_dir)
213
+ Dir.chdir(dir) do
214
+ dvi_path = '__IMGMATH__.dvi'
215
+ out, status = Open3.capture2e(*[@config['texcommand'], @config['texoptions'].shellsplit, tex_path].flatten.compact)
216
+ if !status.success? || !File.exist?(dvi_path)
217
+ raise CompileError
218
+ end
219
+
220
+ @math_maps.keys.sort.each_with_index do |key, idx|
221
+ page = idx + 1
222
+ args = @config['imgmath_options']['dvipng_cmd'].shellsplit
223
+ args.map! do |m|
224
+ m.sub('%i', dvi_path).
225
+ sub('%o', File.join(math_real_dir, "_gen_#{key}.#{@config['imgmath_options']['format']}")).
226
+ sub('%O', File.join(math_real_dir, "_gen_#{key}")).
227
+ sub('%p', page.to_s)
228
+ end
229
+ out, status = Open3.capture2e(*args)
230
+ unless status.success?
231
+ @logger.error "error in dvipng. Error log:\n#{out}"
232
+ raise CompileError
233
+ end
234
+ end
235
+ end
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,645 @@
1
+ # Copyright (c) 2008-2020 Minero Aoki, Kenshi Muto, Masayoshi Takahashi,
2
+ # KADO Masanori
3
+ #
4
+ # This program is free software.
5
+ # You can distribute or modify this program under the terms of
6
+ # the GNU LGPL, Lesser General Public License version 2.1.
7
+ #
8
+
9
+ require 'review/book/index'
10
+ require 'review/exception'
11
+ require 'review/builder'
12
+ require 'review/sec_counter'
13
+
14
+ module ReVIEW
15
+ class IndexBuilder < Builder
16
+ attr_reader :list_index, :table_index, :equation_index, :footnote_index,
17
+ :numberless_image_index, :image_index, :icon_index, :indepimage_index,
18
+ :headline_index, :column_index, :bibpaper_index
19
+
20
+ def initialize(strict = false, *args)
21
+ super
22
+ end
23
+
24
+ def check_id(id)
25
+ if id
26
+ if id =~ %r![#%\\{}\[\]~/$'"|*?&<>`\s]!
27
+ warn "deprecated ID: `#{$&}` in `#{id}`", location: location
28
+ elsif id.start_with?('.')
29
+ warn "deprecated ID: `#{id}` begins from `.`", location: location
30
+ end
31
+ end
32
+ end
33
+
34
+ def pre_paragraph
35
+ ''
36
+ end
37
+
38
+ def post_paragraph
39
+ ''
40
+ end
41
+
42
+ def bind(compiler, chapter, location)
43
+ @compiler = compiler
44
+ @chapter = chapter
45
+ @location = location
46
+ @output = StringIO.new
47
+ if @chapter.present?
48
+ @book = @chapter.book
49
+ end
50
+ builder_init_file
51
+ end
52
+
53
+ def builder_init_file
54
+ super
55
+ @headline_stack = []
56
+
57
+ @list_index = ReVIEW::Book::ListIndex.new
58
+ @table_index = ReVIEW::Book::TableIndex.new
59
+ @equation_index = ReVIEW::Book::EquationIndex.new
60
+ @footnote_index = ReVIEW::Book::FootnoteIndex.new
61
+ @headline_index = ReVIEW::Book::HeadlineIndex.new(@chapter)
62
+ @column_index = ReVIEW::Book::ColumnIndex.new
63
+ @chapter_index = ReVIEW::Book::ChapterIndex.new
64
+ @bibpaper_index = ReVIEW::Book::BibpaperIndex.new
65
+
66
+ if @book
67
+ @image_index = ReVIEW::Book::ImageIndex.new(@chapter)
68
+ @icon_index = ReVIEW::Book::IconIndex.new(@chapter)
69
+ @numberless_image_index = ReVIEW::Book::NumberlessImageIndex.new(@chapter)
70
+ @indepimage_index = ReVIEW::Book::IndepImageIndex.new(@chapter)
71
+ end
72
+ end
73
+ private :builder_init_file
74
+
75
+ def result
76
+ nil
77
+ end
78
+
79
+ def target_name
80
+ 'index'
81
+ end
82
+
83
+ def headline(level, label, caption)
84
+ check_id(label)
85
+ @sec_counter.inc(level)
86
+ return if level < 2
87
+
88
+ cursor = level - 2
89
+
90
+ if label
91
+ @headline_stack[cursor] = label
92
+ else
93
+ @headline_stack[cursor] = caption
94
+ end
95
+ if @headline_stack.size > cursor + 1
96
+ @headline_stack = @headline_stack.take(cursor + 1)
97
+ end
98
+
99
+ item_id = @headline_stack.join('|')
100
+
101
+ item = ReVIEW::Book::Index::Item.new(item_id, @sec_counter.number_list, caption)
102
+ @headline_index.add_item(item)
103
+ end
104
+
105
+ def nonum_begin(level, label, caption)
106
+ check_id(label)
107
+ return if level < 2
108
+
109
+ cursor = level - 2
110
+
111
+ if label
112
+ @headline_stack[cursor] = label
113
+ else
114
+ @headline_stack[cursor] = caption
115
+ end
116
+ if @headline_stack.size > cursor + 1
117
+ @headline_stack = @headline_stack.take(cursor + 1)
118
+ end
119
+
120
+ item_id = @headline_stack.join('|')
121
+
122
+ item = ReVIEW::Book::Index::Item.new(item_id, nil, caption)
123
+ @headline_index.add_item(item)
124
+ end
125
+
126
+ def nonum_end(_level)
127
+ end
128
+
129
+ def notoc_begin(level, label, caption)
130
+ check_id(label)
131
+ return if level < 2
132
+
133
+ cursor = level - 2
134
+
135
+ if label
136
+ @headline_stack[cursor] = label
137
+ else
138
+ @headline_stack[cursor] = caption
139
+ end
140
+ if @headline_stack.size > cursor + 1
141
+ @headline_stack = @headline_stack.take(cursor + 1)
142
+ end
143
+
144
+ item_id = @headline_stack.join('|')
145
+
146
+ item = ReVIEW::Book::Index::Item.new(item_id, nil, caption)
147
+ @headline_index.add_item(item)
148
+ end
149
+
150
+ def notoc_end(_level)
151
+ end
152
+
153
+ def nodisp_begin(level, label, caption)
154
+ check_id(label)
155
+ return if level < 2
156
+
157
+ cursor = level - 2
158
+
159
+ if label
160
+ @headline_stack[cursor] = label
161
+ else
162
+ @headline_stack[cursor] = caption
163
+ end
164
+ if @headline_stack.size > cursor + 1
165
+ @headline_stack = @headline_stack.take(cursor + 1)
166
+ end
167
+
168
+ item_id = @headline_stack.join('|')
169
+
170
+ item = ReVIEW::Book::Index::Item.new(item_id, nil, caption)
171
+ @headline_index.add_item(item)
172
+ end
173
+
174
+ def nodisp_end(_level)
175
+ end
176
+
177
+ def column_begin(_level, label, caption)
178
+ check_id(label)
179
+ item_id = label || caption
180
+ item = ReVIEW::Book::Index::Item.new(item_id, @column_index.size + 1, caption)
181
+ @column_index.add_item(item)
182
+ end
183
+
184
+ def column_end(_level)
185
+ end
186
+
187
+ def xcolumn_begin(_level, label, _caption)
188
+ check_id(label)
189
+ end
190
+
191
+ def xcolumn_end(_level)
192
+ end
193
+
194
+ def sup_begin(_level, label, _caption)
195
+ check_id(label)
196
+ end
197
+
198
+ def sup_end(_level)
199
+ end
200
+
201
+ def ul_begin
202
+ end
203
+
204
+ def ul_item_begin(lines)
205
+ end
206
+
207
+ def ul_item_end
208
+ end
209
+
210
+ def ul_end
211
+ end
212
+
213
+ def ol_begin
214
+ end
215
+
216
+ def ol_item(lines, _num)
217
+ end
218
+
219
+ def ol_end
220
+ end
221
+
222
+ def dl_begin
223
+ end
224
+
225
+ def dt(line)
226
+ end
227
+
228
+ def dd(lines)
229
+ end
230
+
231
+ def dl_end
232
+ end
233
+
234
+ def paragraph(lines)
235
+ end
236
+
237
+ def parasep
238
+ ''
239
+ end
240
+
241
+ def nofunc_text(_str)
242
+ ''
243
+ end
244
+
245
+ def read(_lines)
246
+ end
247
+
248
+ alias_method :lead, :read
249
+
250
+ def list(_lines, id, _caption, _lang = nil)
251
+ check_id(id)
252
+ item = ReVIEW::Book::Index::Item.new(id, @list_index.size + 1)
253
+ @list_index.add_item(item)
254
+ end
255
+
256
+ def source(_lines, _caption = nil, _lang = nil)
257
+ end
258
+
259
+ def listnum(_lines, id, _caption, _lang = nil)
260
+ check_id(id)
261
+ item = ReVIEW::Book::Index::Item.new(id, @list_index.size + 1)
262
+ @list_index.add_item(item)
263
+ end
264
+
265
+ def emlist(lines, caption = nil, lang = nil)
266
+ end
267
+
268
+ def emlistnum(lines, caption = nil, lang = nil)
269
+ end
270
+
271
+ def cmd(lines, caption = nil)
272
+ end
273
+
274
+ def quote(lines)
275
+ end
276
+
277
+ def image(_lines, id, caption, _metric = nil)
278
+ check_id(id)
279
+ item = ReVIEW::Book::Index::Item.new(id, @image_index.size + 1, caption)
280
+ @image_index.add_item(item)
281
+ end
282
+
283
+ def table(_lines, id = nil, caption = nil)
284
+ check_id(id)
285
+ if id
286
+ item = ReVIEW::Book::Index::Item.new(id, @table_index.size + 1, caption)
287
+ @table_index.add_item(item)
288
+ end
289
+ end
290
+
291
+ def emtable(_lines, _caption = nil)
292
+ # item = ReVIEW::Book::TableIndex::Item.new(id, @table_index.size + 1)
293
+ # @table_index << item
294
+ end
295
+
296
+ def comment(lines, comment = nil)
297
+ end
298
+
299
+ def imgtable(_lines, id, _caption = nil, _metric = nil)
300
+ check_id(id)
301
+ item = ReVIEW::Book::Index::Item.new(id, @table_index.size + 1)
302
+ @table_index.add_item(item)
303
+
304
+ ## to find image path
305
+ item = ReVIEW::Book::Index::Item.new(id, @indepimage_index.size + 1)
306
+ @indepimage_index.add_item(item)
307
+ end
308
+
309
+ def footnote(id, str)
310
+ check_id(id)
311
+ item = ReVIEW::Book::Index::Item.new(id, @footnote_index.size + 1, str)
312
+ @footnote_index.add_item(item)
313
+ end
314
+
315
+ def indepimage(_lines, id, _caption = '', _metric = nil)
316
+ check_id(id)
317
+ item = ReVIEW::Book::Index::Item.new(id, @indepimage_index.size + 1)
318
+ @indepimage_index.add_item(item)
319
+ end
320
+
321
+ def numberlessimage(_lines, id, _caption = '', _metric = nil)
322
+ check_id(id)
323
+ item = ReVIEW::Book::Index::Item.new(id, @indepimage_index.size + 1)
324
+ @indepimage_index.add_item(item)
325
+ end
326
+
327
+ def hr
328
+ end
329
+
330
+ def label(id)
331
+ check_id(id)
332
+ end
333
+
334
+ def blankline
335
+ end
336
+
337
+ def flushright(_lines)
338
+ end
339
+
340
+ def centering(lines)
341
+ end
342
+
343
+ def olnum(_num)
344
+ end
345
+
346
+ def pagebreak
347
+ end
348
+
349
+ def bpo(_lines)
350
+ end
351
+
352
+ def noindent
353
+ end
354
+
355
+ def compile_inline(s)
356
+ @compiler.text(s)
357
+ end
358
+
359
+ def inline_chapref(_id)
360
+ ''
361
+ end
362
+
363
+ def inline_chap(_id)
364
+ ''
365
+ end
366
+
367
+ def inline_title(_id)
368
+ ''
369
+ end
370
+
371
+ def inline_list(_id)
372
+ ''
373
+ end
374
+
375
+ def inline_img(_id)
376
+ ''
377
+ end
378
+
379
+ def inline_imgref(_id)
380
+ ''
381
+ end
382
+
383
+ def inline_table(_id)
384
+ ''
385
+ end
386
+
387
+ def inline_eq(_id)
388
+ ''
389
+ end
390
+
391
+ def inline_fn(_id)
392
+ ''
393
+ end
394
+
395
+ def inline_i(_str)
396
+ ''
397
+ end
398
+
399
+ def inline_b(_str)
400
+ ''
401
+ end
402
+
403
+ def inline_ami(_str)
404
+ ''
405
+ end
406
+
407
+ def inline_bou(str)
408
+ str
409
+ end
410
+
411
+ def inline_tti(_str)
412
+ ''
413
+ end
414
+
415
+ def inline_ttb(_str)
416
+ ''
417
+ end
418
+
419
+ def inline_dtp(_str)
420
+ ''
421
+ end
422
+
423
+ def inline_code(_str)
424
+ ''
425
+ end
426
+
427
+ def inline_idx(_str)
428
+ ''
429
+ end
430
+
431
+ def inline_hidx(_str)
432
+ ''
433
+ end
434
+
435
+ def inline_br(_str)
436
+ ''
437
+ end
438
+
439
+ def inline_m(_str)
440
+ ''
441
+ end
442
+
443
+ def firstlinenum(_num)
444
+ ''
445
+ end
446
+
447
+ def inline_ruby(_arg)
448
+ ''
449
+ end
450
+
451
+ def inline_kw(_arg)
452
+ ''
453
+ end
454
+
455
+ def inline_href(_arg)
456
+ ''
457
+ end
458
+
459
+ def inline_hr(_arg)
460
+ ''
461
+ end
462
+
463
+ def text(_str)
464
+ ''
465
+ end
466
+
467
+ def bibpaper(_lines, id, caption)
468
+ check_id(id)
469
+ item = ReVIEW::Book::Index::Item.new(id, @bibpaper_index.size + 1, caption)
470
+ @bibpaper_index.add_item(item)
471
+ end
472
+
473
+ def inline_hd(_id)
474
+ ''
475
+ end
476
+
477
+ def inline_bib(_id)
478
+ ''
479
+ end
480
+
481
+ def inline_column(_id)
482
+ ''
483
+ end
484
+
485
+ def inline_column_chap(_chapter, _id)
486
+ ''
487
+ end
488
+
489
+ def inline_pageref(_id)
490
+ ''
491
+ end
492
+
493
+ def inline_tcy(_arg)
494
+ ''
495
+ end
496
+
497
+ def inline_balloon(_arg)
498
+ ''
499
+ end
500
+
501
+ def inline_w(_s)
502
+ ''
503
+ end
504
+
505
+ def inline_wb(_s)
506
+ ''
507
+ end
508
+
509
+ def inline_abbr(_str)
510
+ ''
511
+ end
512
+
513
+ def inline_acronym(_str)
514
+ ''
515
+ end
516
+
517
+ def inline_cite(_str)
518
+ ''
519
+ end
520
+
521
+ def inline_dfn(_str)
522
+ ''
523
+ end
524
+
525
+ def inline_em(_str)
526
+ ''
527
+ end
528
+
529
+ def inline_kbd(_str)
530
+ ''
531
+ end
532
+
533
+ def inline_samp(_str)
534
+ ''
535
+ end
536
+
537
+ def inline_strong(_str)
538
+ ''
539
+ end
540
+
541
+ def inline_var(_str)
542
+ ''
543
+ end
544
+
545
+ def inline_big(_str)
546
+ ''
547
+ end
548
+
549
+ def inline_small(_str)
550
+ ''
551
+ end
552
+
553
+ def inline_sub(_str)
554
+ ''
555
+ end
556
+
557
+ def inline_sup(_str)
558
+ ''
559
+ end
560
+
561
+ def inline_tt(_str)
562
+ ''
563
+ end
564
+
565
+ def inline_del(_str)
566
+ ''
567
+ end
568
+
569
+ def inline_ins(_str)
570
+ ''
571
+ end
572
+
573
+ def inline_u(_str)
574
+ ''
575
+ end
576
+
577
+ def inline_recipe(_str)
578
+ ''
579
+ end
580
+
581
+ def inline_icon(id)
582
+ check_id(id)
583
+ item = ReVIEW::Book::Index::Item.new(id, @icon_index.size + 1)
584
+ @icon_index.add_item(item)
585
+ ''
586
+ end
587
+
588
+ def inline_uchar(_str)
589
+ ''
590
+ end
591
+
592
+ def raw(_str)
593
+ ''
594
+ end
595
+
596
+ def embed(_lines, _arg = nil)
597
+ ''
598
+ end
599
+
600
+ ## override
601
+ def error(msg = nil)
602
+ # ignore in indexing
603
+ end
604
+
605
+ def texequation(_lines, id = nil, _caption = '')
606
+ check_id(id)
607
+ if id
608
+ item = ReVIEW::Book::Index::Item.new(id, @equation_index.size + 1)
609
+ @equation_index.add_item(item)
610
+ end
611
+ end
612
+
613
+ def get_chap(_chapter = nil)
614
+ ''
615
+ end
616
+
617
+ def extract_chapter_id(_chap_ref)
618
+ ''
619
+ end
620
+
621
+ def captionblock(_type, _lines, _caption, _specialstyle = nil)
622
+ ''
623
+ end
624
+
625
+ def tsize(_str)
626
+ ''
627
+ end
628
+
629
+ def inline_raw(_args)
630
+ ''
631
+ end
632
+
633
+ def inline_embed(_args)
634
+ ''
635
+ end
636
+
637
+ def highlight?
638
+ false
639
+ end
640
+
641
+ def unknown_command(*_args)
642
+ # ignore
643
+ end
644
+ end
645
+ end # module ReVIEW