review 3.2.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (282) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +31 -0
  3. data/.github/workflows/ruby-win.yml +45 -0
  4. data/.github/workflows/ruby.yml +27 -0
  5. data/.rubocop.yml +167 -42
  6. data/.travis.yml +1 -1
  7. data/Dockerfile +21 -5
  8. data/NEWS.ja.md +428 -1
  9. data/NEWS.md +429 -2
  10. data/README.md +11 -7
  11. data/Rakefile +7 -2
  12. data/appveyor.yml +0 -20
  13. data/bin/review +2 -4
  14. data/bin/review-catalog-converter +5 -5
  15. data/bin/review-check +13 -17
  16. data/bin/review-checkdep +3 -6
  17. data/bin/review-compile +13 -22
  18. data/bin/review-epub2html +1 -4
  19. data/bin/review-epubmaker +3 -4
  20. data/bin/review-idgxmlmaker +14 -0
  21. data/bin/review-index +5 -86
  22. data/bin/review-init +1 -4
  23. data/bin/review-pdfmaker +1 -3
  24. data/bin/review-preproc +11 -13
  25. data/bin/review-textmaker +1 -3
  26. data/bin/review-update +1 -4
  27. data/bin/review-validate +7 -7
  28. data/bin/review-vol +5 -82
  29. data/bin/review-webmaker +1 -3
  30. data/doc/config.yml.sample +67 -16
  31. data/doc/config.yml.sample-simple +4 -3
  32. data/doc/format.ja.md +133 -21
  33. data/doc/format.md +135 -34
  34. data/doc/makeindex.ja.md +2 -2
  35. data/doc/pdfmaker.ja.md +43 -1
  36. data/doc/pdfmaker.md +42 -1
  37. data/doc/quickstart.ja.md +55 -25
  38. data/doc/quickstart.md +47 -17
  39. data/lib/review.rb +1 -1
  40. data/lib/review/book.rb +2 -2
  41. data/lib/review/book/base.rb +89 -90
  42. data/lib/review/book/bib.rb +21 -0
  43. data/lib/review/book/book_unit.rb +158 -0
  44. data/lib/review/book/chapter.rb +51 -29
  45. data/lib/review/book/index.rb +42 -248
  46. data/lib/review/book/index/item.rb +46 -0
  47. data/lib/review/book/page_metric.rb +7 -7
  48. data/lib/review/book/part.rb +45 -10
  49. data/lib/review/book/volume.rb +5 -5
  50. data/lib/review/builder.rb +171 -54
  51. data/lib/review/call_hook.rb +20 -0
  52. data/lib/review/catalog.rb +15 -17
  53. data/lib/review/compiler.rb +240 -102
  54. data/lib/review/configure.rb +101 -12
  55. data/lib/review/converter.rb +1 -1
  56. data/lib/review/epub2html.rb +6 -1
  57. data/lib/review/epubmaker.rb +120 -118
  58. data/lib/review/epubmaker/content.rb +113 -0
  59. data/lib/review/epubmaker/epubcommon.rb +372 -0
  60. data/lib/review/epubmaker/epubv2.rb +178 -0
  61. data/lib/review/epubmaker/epubv3.rb +231 -0
  62. data/lib/review/epubmaker/producer.rb +168 -0
  63. data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
  64. data/lib/review/epubmaker/zip_exporter.rb +84 -0
  65. data/lib/review/exception.rb +6 -0
  66. data/lib/review/extentions/string.rb +0 -4
  67. data/lib/review/htmlbuilder.rb +147 -149
  68. data/lib/review/htmlutils.rb +10 -14
  69. data/lib/review/i18n.rb +4 -3
  70. data/lib/review/idgxmlbuilder.rb +229 -103
  71. data/lib/review/idgxmlmaker.rb +188 -0
  72. data/lib/review/img_math.rb +245 -0
  73. data/lib/review/index_builder.rb +654 -0
  74. data/lib/review/init-web/finish.html +10 -0
  75. data/lib/review/init-web/index.html +190 -0
  76. data/lib/review/init-web/review-layout-design.js +691 -0
  77. data/lib/review/init.rb +124 -41
  78. data/lib/review/latexbox.rb +58 -0
  79. data/lib/review/latexbuilder.rb +249 -97
  80. data/lib/review/latexutils.rb +9 -1
  81. data/lib/review/lineinput.rb +113 -3
  82. data/lib/review/logger.rb +43 -8
  83. data/lib/review/makerhelper.rb +13 -186
  84. data/lib/review/markdownbuilder.rb +75 -39
  85. data/lib/review/md2inaobuilder.rb +3 -5
  86. data/lib/review/pdfmaker.rb +88 -83
  87. data/lib/review/plaintextbuilder.rb +158 -83
  88. data/lib/review/preprocessor.rb +30 -24
  89. data/lib/review/rstbuilder.rb +58 -39
  90. data/lib/review/sec_counter.rb +14 -0
  91. data/lib/review/template.rb +6 -0
  92. data/lib/review/textmaker.rb +29 -17
  93. data/lib/review/textutils.rb +68 -2
  94. data/lib/review/tocprinter.rb +242 -97
  95. data/lib/review/topbuilder.rb +147 -61
  96. data/lib/review/update.rb +27 -28
  97. data/lib/review/version.rb +1 -1
  98. data/lib/review/volumeprinter.rb +97 -0
  99. data/lib/review/webmaker.rb +36 -35
  100. data/lib/review/webtocprinter.rb +39 -35
  101. data/lib/review/yamlloader.rb +4 -0
  102. data/review.gemspec +8 -5
  103. data/samples/sample-book/README.md +7 -2
  104. data/samples/sample-book/src/.gitignore +154 -0
  105. data/samples/sample-book/src/config-ebook.yml +4 -0
  106. data/samples/sample-book/src/config-epub2.yml +1 -1
  107. data/samples/sample-book/src/config-jlreq-ebook.yml +4 -0
  108. data/samples/sample-book/src/config-jlreq.yml +6 -0
  109. data/samples/sample-book/src/config.yml +3 -3
  110. data/samples/sample-book/src/lib/tasks/review.rake +45 -14
  111. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +14 -8
  112. data/samples/syntax-book/Gemfile +1 -1
  113. data/samples/syntax-book/ch01.re +3 -1
  114. data/samples/syntax-book/ch02.re +28 -21
  115. data/samples/syntax-book/ch03.re +4 -7
  116. data/samples/syntax-book/config-jlreq-lualatex.yml +4 -0
  117. data/samples/syntax-book/config-jlreq.yml +5 -0
  118. data/samples/syntax-book/config-print.yml +3 -0
  119. data/samples/syntax-book/config.yml +1 -1
  120. data/samples/syntax-book/images/img3-2.png +0 -0
  121. data/samples/syntax-book/lib/tasks/review.rake +30 -15
  122. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +14 -8
  123. data/templates/html/_colophon.html.erb +23 -0
  124. data/templates/html/_colophon_history.html.erb +9 -0
  125. data/templates/html/_cover.html.erb +10 -0
  126. data/templates/html/_part_body.html.erb +6 -0
  127. data/templates/html/_titlepage.html.erb +20 -0
  128. data/templates/html/layout-html5.html.erb +6 -0
  129. data/templates/html/layout-xhtml1.html.erb +6 -0
  130. data/templates/latex/config.erb +45 -27
  131. data/templates/latex/layout.tex.erb +1 -0
  132. data/templates/latex/review-jlreq/README.md +3 -1
  133. data/templates/latex/review-jlreq/review-base.sty +124 -37
  134. data/templates/latex/review-jlreq/review-jlreq.cls +29 -22
  135. data/templates/latex/review-jlreq/review-style.sty +9 -1
  136. data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
  137. data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
  138. data/templates/latex/review-jsbook/README.md +46 -5
  139. data/templates/latex/review-jsbook/review-base.sty +111 -30
  140. data/templates/latex/review-jsbook/review-jsbook.cls +16 -2
  141. data/templates/latex/review-jsbook/review-style.sty +10 -2
  142. data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
  143. data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
  144. data/templates/opf/epubv2.opf.erb +7 -7
  145. data/templates/opf/epubv3.opf.erb +7 -7
  146. data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
  147. data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
  148. data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
  149. data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
  150. data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
  151. data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
  152. data/templates/web/html/layout-html5.html.erb +9 -8
  153. data/templates/web/html/layout-xhtml1.html.erb +6 -0
  154. data/test/assets/header_listener.html +35 -0
  155. data/test/assets/img_math/img1.png +0 -0
  156. data/test/assets/img_math/img2.png +0 -0
  157. data/test/assets/img_math/img3.png +0 -0
  158. data/test/assets/syntax_book_index_detail.txt +58 -0
  159. data/test/assets/test_template.tex +20 -9
  160. data/test/assets/test_template_backmatter.tex +20 -9
  161. data/test/book_test_helper.rb +11 -5
  162. data/test/run_test.rb +1 -1
  163. data/test/test_book.rb +123 -78
  164. data/test/test_book_chapter.rb +99 -56
  165. data/test/test_book_part.rb +3 -3
  166. data/test/test_builder.rb +24 -15
  167. data/test/test_catalog.rb +19 -42
  168. data/test/test_catalog_converter_cmd.rb +1 -1
  169. data/test/test_converter.rb +1 -0
  170. data/test/test_epub3maker.rb +170 -126
  171. data/test/test_epubmaker.rb +249 -129
  172. data/test/test_epubmaker_cmd.rb +16 -9
  173. data/test/test_helper.rb +23 -11
  174. data/test/test_htmlbuilder.rb +1083 -114
  175. data/test/test_htmlutils.rb +0 -12
  176. data/test/test_i18n.rb +37 -37
  177. data/test/test_idgxmlbuilder.rb +627 -27
  178. data/test/test_idgxmlmaker_cmd.rb +50 -0
  179. data/test/test_image_finder.rb +52 -70
  180. data/test/test_img_math.rb +111 -0
  181. data/test/test_index.rb +62 -52
  182. data/test/test_indexbuilder.rb +52 -0
  183. data/test/test_latexbuilder.rb +1189 -59
  184. data/test/test_latexbuilder_v2.rb +74 -34
  185. data/test/test_lineinput.rb +20 -93
  186. data/test/test_logger.rb +17 -4
  187. data/test/test_makerhelper.rb +2 -14
  188. data/test/test_markdownbuilder.rb +77 -4
  189. data/test/test_md2inaobuilder.rb +12 -2
  190. data/test/test_pdfmaker.rb +101 -12
  191. data/test/test_pdfmaker_cmd.rb +102 -8
  192. data/test/test_plaintextbuilder.rb +562 -31
  193. data/test/test_review_ext.rb +2 -1
  194. data/test/test_reviewheaderlistener.rb +49 -0
  195. data/test/test_rstbuilder.rb +58 -5
  196. data/test/test_sec_counter.rb +156 -0
  197. data/test/test_template.rb +12 -2
  198. data/test/test_textmaker_cmd.rb +58 -0
  199. data/test/test_textutils.rb +109 -2
  200. data/test/test_tocprinter.rb +46 -0
  201. data/test/test_topbuilder.rb +400 -17
  202. data/test/test_update.rb +53 -44
  203. data/test/test_webtocprinter.rb +75 -43
  204. data/test/test_yamlloader.rb +13 -0
  205. data/test/test_zip_exporter.rb +5 -6
  206. data/vendor/gentombow/LICENSE +1 -1
  207. data/vendor/gentombow/Makefile +0 -1
  208. data/vendor/gentombow/bounddvi-en.pdf +0 -0
  209. data/vendor/gentombow/bounddvi-en.tex +1 -0
  210. data/vendor/gentombow/bounddvi.pdf +0 -0
  211. data/vendor/gentombow/bounddvi.sty +30 -7
  212. data/vendor/gentombow/bounddvi.tex +1 -0
  213. data/vendor/gentombow/create_archive.sh +1 -0
  214. data/vendor/gentombow/gentombow-ja.pdf +0 -0
  215. data/vendor/gentombow/gentombow-ja.tex +9 -0
  216. data/vendor/gentombow/gentombow.pdf +0 -0
  217. data/vendor/gentombow/gentombow.sty +32 -10
  218. data/vendor/gentombow/gentombow.tex +8 -0
  219. data/vendor/gentombow/tests/gentombow-01-pdfx.tex +8 -0
  220. data/vendor/gentombow/tests/gentombow-02-pdfx.tex +8 -0
  221. data/vendor/jsclasses/LICENSE +1 -1
  222. data/vendor/jsclasses/Makefile +3 -2
  223. data/vendor/jsclasses/create_archive.sh +5 -5
  224. data/vendor/jsclasses/jis/Makefile +3 -2
  225. data/vendor/jsclasses/jis/jsarticle.cls +74 -31
  226. data/vendor/jsclasses/jis/jsbook.cls +74 -31
  227. data/vendor/jsclasses/jis/jsclasses.dtx +176 -36
  228. data/vendor/jsclasses/jis/jsclasses.ins +15 -5
  229. data/vendor/jsclasses/jis/jslogo.dtx +4 -4
  230. data/vendor/jsclasses/jis/jslogo.ins +9 -0
  231. data/vendor/jsclasses/jis/jslogo.sty +4 -16
  232. data/vendor/jsclasses/jis/jspf.cls +73 -30
  233. data/vendor/jsclasses/jis/jsreport.cls +74 -31
  234. data/vendor/jsclasses/jis/jsverb.ins +9 -0
  235. data/vendor/jsclasses/jis/jsverb.sty +1 -13
  236. data/vendor/jsclasses/jis/kiyou.cls +74 -31
  237. data/vendor/jsclasses/jis/minijs.sty +65 -22
  238. data/vendor/jsclasses/jis/okumacro.dtx +4 -5
  239. data/vendor/jsclasses/jis/okumacro.ins +9 -0
  240. data/vendor/jsclasses/jis/okumacro.sty +4 -17
  241. data/vendor/jsclasses/jis/okuverb.ins +9 -0
  242. data/vendor/jsclasses/jis/okuverb.sty +1 -13
  243. data/vendor/jsclasses/jis/winjis.sty +23 -19
  244. data/vendor/jsclasses/jsarticle.cls +74 -31
  245. data/vendor/jsclasses/jsbook.cls +74 -31
  246. data/vendor/jsclasses/jsclasses.dtx +176 -36
  247. data/vendor/jsclasses/jsclasses.ins +15 -5
  248. data/vendor/jsclasses/jsclasses.pdf +0 -0
  249. data/vendor/jsclasses/jslogo.dtx +4 -4
  250. data/vendor/jsclasses/jslogo.ins +9 -0
  251. data/vendor/jsclasses/jslogo.pdf +0 -0
  252. data/vendor/jsclasses/jslogo.sty +4 -16
  253. data/vendor/jsclasses/jspf.cls +73 -30
  254. data/vendor/jsclasses/jsreport.cls +74 -31
  255. data/vendor/jsclasses/jsverb.ins +9 -0
  256. data/vendor/jsclasses/jsverb.pdf +0 -0
  257. data/vendor/jsclasses/jsverb.sty +1 -13
  258. data/vendor/jsclasses/kiyou.cls +74 -31
  259. data/vendor/jsclasses/minijs.sty +68 -22
  260. data/vendor/jsclasses/okumacro.dtx +4 -5
  261. data/vendor/jsclasses/okumacro.ins +9 -0
  262. data/vendor/jsclasses/okumacro.pdf +0 -0
  263. data/vendor/jsclasses/okumacro.sty +4 -17
  264. data/vendor/jsclasses/okuverb.ins +9 -0
  265. data/vendor/jsclasses/okuverb.pdf +0 -0
  266. data/vendor/jsclasses/okuverb.sty +1 -13
  267. data/vendor/jsclasses/tests/relfont.tex +10 -0
  268. data/vendor/jsclasses/winjis.sty +23 -19
  269. metadata +136 -23
  270. data/.rubocop_todo.yml +0 -7
  271. data/lib/epubmaker.rb +0 -23
  272. data/lib/epubmaker/content.rb +0 -110
  273. data/lib/epubmaker/epubcommon.rb +0 -441
  274. data/lib/epubmaker/epubv2.rb +0 -143
  275. data/lib/epubmaker/epubv3.rb +0 -233
  276. data/lib/epubmaker/producer.rb +0 -375
  277. data/lib/epubmaker/zip_exporter.rb +0 -81
  278. data/lib/lineinput.rb +0 -155
  279. data/lib/review/book/compilable.rb +0 -173
  280. data/lib/review/tocparser.rb +0 -271
  281. data/samples/syntax-book/review-ext.rb +0 -14
  282. data/test/test_tocparser.rb +0 -25
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto
2
+ #
3
+ # This program is free software.
4
+ # You can distribute or modify this program under the terms of
5
+ # the GNU LGPL, Lesser General Public License version 2.1.
6
+ # For details of LGPL, see the file "COPYING".
7
+ #
8
+
9
+ require 'review/extentions'
10
+ require 'review/exception'
11
+ require 'review/book/image_finder'
12
+ require 'review/i18n'
13
+ require 'review/logger'
14
+
15
+ module ReVIEW
16
+ module Book
17
+ class Index
18
+ class Item
19
+ def initialize(id, number, caption = nil)
20
+ @id = id
21
+ @number = number
22
+ @caption = caption
23
+ @path = nil
24
+ @index = nil
25
+ end
26
+
27
+ attr_reader :id
28
+ attr_reader :number
29
+ attr_reader :caption
30
+ attr_accessor :index # internal use only
31
+
32
+ alias_method :content, :caption
33
+
34
+ def path
35
+ if @path
36
+ return @path
37
+ end
38
+
39
+ @path = @index.find_path(@id)
40
+
41
+ @path
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2009-2020 Minero Aoki, Kenshi Muto
2
2
  # 2002-2008 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -11,21 +11,21 @@ module ReVIEW
11
11
  class PageMetric
12
12
  MetricData = Struct.new(:n_lines, :n_columns)
13
13
 
14
- def initialize(list_lines, list_columns, text_lines, text_columns, page_per_kbyte)
14
+ def initialize(list_lines, list_columns, text_lines, text_columns, _page_per_kbyte = 1)
15
+ # page_per_kbyte is obsolete. Just for backward compatibility
15
16
  @list = MetricData.new(list_lines, list_columns)
16
17
  @text = MetricData.new(text_lines, text_columns)
17
- @page_per_kbyte = page_per_kbyte
18
18
  end
19
19
 
20
- A5 = PageMetric.new(46, 80, 30, 74, 1)
21
- B5 = PageMetric.new(46, 80, 30, 74, 2)
20
+ # based on review-jsbook's default
21
+ A5 = PageMetric.new(40, 34, 29, 34)
22
+ B5 = PageMetric.new(50, 40, 36, 40)
22
23
 
23
24
  attr_reader :list
24
25
  attr_reader :text
25
- attr_reader :page_per_kbyte
26
26
 
27
27
  def ==(other)
28
- self.list == other.list && self.text == other.text && self.page_per_kbyte == other.page_per_kbyte
28
+ self.list == other.list && self.text == other.text
29
29
  end
30
30
  end
31
31
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2018 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2009-2020 Minero Aoki, Kenshi Muto, Masayoshi Takahashi
2
2
  # 2002-2008 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -6,27 +6,46 @@
6
6
  # the GNU LGPL, Lesser General Public License version 2.1.
7
7
  # For details of the GNU LGPL, see the file "COPYING".
8
8
  #
9
- require 'review/book/compilable'
9
+ require 'review/book/book_unit'
10
10
 
11
11
  module ReVIEW
12
12
  module Book
13
- class Part
14
- include Compilable
13
+ class Part < BookUnit
14
+ def self.mkpart_from_namelistfile(book, path)
15
+ chaps = []
16
+ File.read(path, mode: 'rt:BOM|utf-8').split.each_with_index do |name, number|
17
+ if path =~ /PREDEF/
18
+ chaps << Chapter.mkchap(book, name)
19
+ else
20
+ chaps << Chapter.mkchap(book, name, number + 1)
21
+ end
22
+ end
23
+ Part.mkpart(chaps)
24
+ end
25
+
26
+ def self.mkpart_from_namelist(book, names)
27
+ Part.mkpart(names.map { |name| Chapter.mkchap_ifexist(book, name) }.compact)
28
+ end
29
+
30
+ def self.mkpart(chaps)
31
+ chaps.empty? ? nil : Part.new(chaps[0].book, nil, chaps)
32
+ end
15
33
 
16
34
  # if Part is dummy, `number` is nil.
17
35
  #
18
36
  def initialize(book, number, chapters, name = '', io = nil)
19
37
  @book = book
20
38
  @number = number
21
- @chapters = chapters
22
39
  @name = name
40
+ @chapters = chapters
23
41
  @path = name
24
- @content = nil
25
42
  if io
26
43
  @content = io.read
27
44
  elsif @path.present? && File.exist?(File.join(@book.config['contentdir'], @path))
28
- @content = File.read(File.join(@book.config['contentdir'], @path), mode: 'r:BOM|utf-8')
29
- @name = File.basename(@name, '.re')
45
+ @content = File.read(File.join(@book.config['contentdir'], @path), mode: 'rt:BOM|utf-8')
46
+ @name = File.basename(name, '.re')
47
+ else
48
+ @content = ''
30
49
  end
31
50
  if file?
32
51
  @title = nil
@@ -34,6 +53,19 @@ module ReVIEW
34
53
  @title = name
35
54
  end
36
55
  @volume = nil
56
+
57
+ super()
58
+ end
59
+
60
+ def generate_indexes
61
+ super
62
+
63
+ return unless content
64
+
65
+ @numberless_image_index = @indexes.numberless_image_index
66
+ @image_index = @indexes.image_index
67
+ @icon_index = @indexes.icon_index
68
+ @indepimage_index = @indexes.indepimage_index
37
69
  end
38
70
 
39
71
  attr_reader :number
@@ -45,8 +77,11 @@ module ReVIEW
45
77
  end
46
78
 
47
79
  def volume
48
- vol = Volume.sum(@chapters.map(&:volume))
49
- vol.page_per_kbyte = @book.page_metric.page_per_kbyte
80
+ if @number && file?
81
+ vol = Volume.count_file(File.join(@book.config['contentdir'], @path))
82
+ else
83
+ vol = Volume.new(0, 0, 0)
84
+ end
50
85
  vol
51
86
  end
52
87
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2017 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2007-2020 Minero Aoki, Kenshi Muto
2
2
  # 2002-2007 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -13,6 +13,7 @@ module ReVIEW
13
13
  b = c = l = 0
14
14
  File.foreach(path) do |line|
15
15
  next if /\A\#@/ =~ line
16
+
16
17
  text = line.gsub(/\s+/, '')
17
18
  b += text.bytesize
18
19
  c += text.size
@@ -22,7 +23,7 @@ module ReVIEW
22
23
  end
23
24
 
24
25
  def self.sum(vols)
25
- vols.inject(new) { |sum, i| sum + i }
26
+ vols.inject(new) { |sum, i| sum + i } # rubocop:disable Performance/Sum
26
27
  end
27
28
 
28
29
  def self.dummy
@@ -33,20 +34,19 @@ module ReVIEW
33
34
  @bytes = bytes
34
35
  @chars = chars
35
36
  @lines = lines
36
- @page_per_kbyte = nil
37
37
  end
38
38
 
39
39
  attr_reader :bytes
40
40
  attr_reader :chars
41
41
  attr_accessor :lines
42
- attr_accessor :page_per_kbyte
43
42
 
44
43
  def kbytes
45
44
  (@bytes.to_f / 1024).ceil
46
45
  end
47
46
 
48
47
  def page
49
- (kbytes.to_f / @page_per_kbyte).ceil
48
+ # XXX:unrelibable
49
+ kbytes.to_f.ceil
50
50
  end
51
51
 
52
52
  def to_s
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2002-2018 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2002-2020 Minero Aoki, Kenshi Muto
2
2
  #
3
3
  # This program is free software.
4
4
  # You can distribute or modify this program under the terms of
@@ -10,8 +10,8 @@ require 'review/exception'
10
10
  require 'review/textutils'
11
11
  require 'review/compiler'
12
12
  require 'review/sec_counter'
13
+ require 'review/img_math'
13
14
  require 'stringio'
14
- require 'cgi'
15
15
  require 'fileutils'
16
16
  require 'tempfile'
17
17
  require 'csv'
@@ -20,7 +20,7 @@ module ReVIEW
20
20
  class Builder
21
21
  include TextUtils
22
22
 
23
- CAPTION_TITLES = %w[note memo tip info warning important caution notice].freeze
23
+ CAPTION_TITLES = Compiler.minicolumn_names
24
24
 
25
25
  def pre_paragraph
26
26
  nil
@@ -30,21 +30,18 @@ module ReVIEW
30
30
  nil
31
31
  end
32
32
 
33
- attr_accessor :doc_status
33
+ attr_accessor :doc_status, :previous_list_type
34
34
 
35
- def initialize(strict = false, *args)
35
+ def initialize(strict = false, *_args, img_math: nil)
36
36
  @strict = strict
37
37
  @output = nil
38
38
  @logger = ReVIEW.logger
39
39
  @doc_status = {}
40
40
  @dictionary = {}
41
- builder_init(*args)
41
+ @previous_list_type = nil
42
+ @img_math = img_math
42
43
  end
43
44
 
44
- def builder_init(*args)
45
- end
46
- private :builder_init
47
-
48
45
  def bind(compiler, chapter, location)
49
46
  @compiler = compiler
50
47
  @chapter = chapter
@@ -53,26 +50,63 @@ module ReVIEW
53
50
  if @chapter.present?
54
51
  @book = @chapter.book
55
52
  end
53
+ @chapter.generate_indexes
54
+ if @book
55
+ @book.generate_indexes
56
+ end
56
57
  @tabwidth = nil
57
58
  @tsize = nil
58
59
  if @book && @book.config
59
- if @book.config['words_file']
60
- load_words(@book.config['words_file'])
60
+ @img_math ||= ReVIEW::ImgMath.new(@book.config)
61
+ if words_file_path = @book.config['words_file']
62
+ if words_file_path.is_a?(String)
63
+ words_files = [words_file_path]
64
+ else
65
+ words_files = words_file_path
66
+ end
67
+ words_files.each do |f|
68
+ load_words(f)
69
+ end
61
70
  end
62
71
  if @book.config['tabwidth']
63
72
  @tabwidth = @book.config['tabwidth']
64
73
  end
74
+
75
+ if @book.config['join_lines_by_lang']
76
+ begin
77
+ require 'unicode/eaw'
78
+ rescue LoadError
79
+ warn 'not found unicode/eaw. disabled join_lines_by_lang feature.'
80
+ @book.config['join_lines_by_lang'] = nil
81
+ end
82
+ end
65
83
  end
66
84
  builder_init_file
67
85
  end
68
86
 
69
87
  def builder_init_file
70
88
  @sec_counter = SecCounter.new(5, @chapter)
89
+ @doc_status = {}
71
90
  end
72
91
  private :builder_init_file
73
92
 
93
+ def highlight?
94
+ false
95
+ end
96
+
97
+ def solve_nest(s)
98
+ check_nest
99
+ s.gsub(/\x01→.+?←\x01/, '')
100
+ end
101
+
102
+ def check_nest
103
+ if @children && !@children.empty?
104
+ error "//beginchild of #{@children.reverse.join(',')} misses //endchild"
105
+ end
106
+ end
107
+
74
108
  def result
75
- @output.string
109
+ solve_nest(@output.string)
76
110
  end
77
111
 
78
112
  alias_method :raw_result, :result
@@ -114,6 +148,7 @@ module ReVIEW
114
148
 
115
149
  def line_num
116
150
  return 1 unless @first_line_num
151
+
117
152
  line_n = @first_line_num
118
153
  @first_line_num = nil
119
154
 
@@ -122,59 +157,87 @@ module ReVIEW
122
157
 
123
158
  def list(lines, id, caption, lang = nil)
124
159
  begin
125
- list_header id, caption, lang
160
+ list_header(id, caption, lang) if caption_top?('list')
161
+ list_body(id, lines, lang)
162
+ list_header(id, caption, lang) unless caption_top?('list')
126
163
  rescue KeyError
127
164
  error "no such list: #{id}"
128
165
  end
129
- list_body id, lines, lang
130
166
  end
131
167
 
132
168
  def listnum(lines, id, caption, lang = nil)
133
169
  begin
134
- list_header id, caption, lang
170
+ list_header(id, caption, lang) if caption_top?('list')
171
+ listnum_body(lines, lang)
172
+ list_header(id, caption, lang) unless caption_top?('list')
135
173
  rescue KeyError
136
174
  error "no such list: #{id}"
137
175
  end
138
- listnum_body lines, lang
139
176
  end
140
177
 
141
- def source(lines, caption, lang = nil)
142
- source_header caption
143
- source_body lines, lang
178
+ def source(lines, caption = nil, lang = nil)
179
+ source_header(caption) if caption_top?('list')
180
+ source_body(lines, lang)
181
+ source_header(caption) unless caption_top?('list')
144
182
  end
145
183
 
146
184
  def image(lines, id, caption, metric = nil)
147
- if @chapter.image(id).bound?
148
- image_image id, caption, metric
185
+ if @chapter.image_bound?(id)
186
+ image_image(id, caption, metric)
149
187
  else
150
188
  warn "image not bound: #{id}" if @strict
151
- image_dummy id, caption, lines
189
+ image_dummy(id, caption, lines)
152
190
  end
153
191
  end
154
192
 
155
193
  def table(lines, id = nil, caption = nil)
156
- rows = []
194
+ sepidx, rows = parse_table_rows(lines)
195
+ begin
196
+ if caption_top?('table') && caption.present?
197
+ table_header(id, caption)
198
+ end
199
+ table_begin(rows.first.size)
200
+ table_rows(sepidx, rows)
201
+ table_end
202
+ if !caption_top?('table') && caption.present?
203
+ table_header(id, caption)
204
+ end
205
+ rescue KeyError
206
+ error "no such table: #{id}"
207
+ end
208
+ end
209
+
210
+ def table_row_separator_regexp
211
+ case @book.config['table_row_separator']
212
+ when 'tabs'
213
+ Regexp.new('\t+')
214
+ when 'singletab'
215
+ Regexp.new('\t')
216
+ when 'spaces'
217
+ Regexp.new('\s+')
218
+ when 'verticalbar'
219
+ Regexp.new('\s*\\' + escape('|') + '\s*')
220
+ else
221
+ error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar"
222
+ end
223
+ end
224
+
225
+ def parse_table_rows(lines)
157
226
  sepidx = nil
227
+ rows = []
158
228
  lines.each_with_index do |line, idx|
159
- if /\A[\=\-]{12}/ =~ line
160
- # just ignore
161
- # error "too many table separator" if sepidx
229
+ if /\A[=\-]{12}/ =~ line || /\A[={\-}]{12}/ =~ line
162
230
  sepidx ||= idx
163
231
  next
164
232
  end
165
- rows.push(line.strip.split(/\t+/).map { |s| s.sub(/\A\./, '') })
233
+ rows.push(line.strip.split(table_row_separator_regexp).map { |s| s.sub(/\A\./, '') })
166
234
  end
167
235
  rows = adjust_n_cols(rows)
168
236
  error 'no rows in the table' if rows.empty?
237
+ [sepidx, rows]
238
+ end
169
239
 
170
- begin
171
- if caption.present?
172
- table_header id, caption
173
- end
174
- rescue KeyError
175
- error "no such table: #{id}"
176
- end
177
- table_begin rows.first.size
240
+ def table_rows(sepidx, rows)
178
241
  if sepidx
179
242
  sepidx.times do
180
243
  tr(rows.shift.map { |s| th(s) })
@@ -188,18 +251,17 @@ module ReVIEW
188
251
  tr([th(h)] + cs.map { |s| td(s) })
189
252
  end
190
253
  end
191
- table_end
192
254
  end
193
255
 
194
256
  def adjust_n_cols(rows)
195
257
  rows.each do |cols|
196
- while cols.last and cols.last.strip.empty?
258
+ while cols.last && cols.last.strip.empty?
197
259
  cols.pop
198
260
  end
199
261
  end
200
262
  n_maxcols = rows.map(&:size).max
201
263
  rows.each do |cols|
202
- cols.concat [''] * (n_maxcols - cols.size)
264
+ cols.concat([''] * (n_maxcols - cols.size))
203
265
  end
204
266
  rows
205
267
  end
@@ -230,7 +292,7 @@ module ReVIEW
230
292
  end
231
293
 
232
294
  def inline_chapref(id)
233
- compile_inline @book.chapter_index.display_string(id)
295
+ compile_inline(@book.chapter_index.display_string(id))
234
296
  rescue KeyError
235
297
  error "unknown chapter: #{id}"
236
298
  end
@@ -242,7 +304,7 @@ module ReVIEW
242
304
  end
243
305
 
244
306
  def inline_title(id)
245
- compile_inline @book.chapter_index.title(id)
307
+ compile_inline(@book.chapter_index.title(id))
246
308
  rescue KeyError
247
309
  error "unknown chapter: #{id}"
248
310
  end
@@ -341,10 +403,10 @@ module ReVIEW
341
403
  end
342
404
 
343
405
  def bibpaper(lines, id, caption)
344
- bibpaper_header id, caption
406
+ bibpaper_header(id, caption)
345
407
  unless lines.empty?
346
408
  puts
347
- bibpaper_bibpaper id, caption, lines
409
+ bibpaper_bibpaper(id, caption, lines)
348
410
  end
349
411
  puts
350
412
  end
@@ -404,7 +466,12 @@ module ReVIEW
404
466
  end
405
467
 
406
468
  def inline_wb(s)
407
- inline_b(unescape(inline_w(s)))
469
+ translated = @dictionary[s]
470
+ if translated
471
+ inline_b(translated)
472
+ else
473
+ inline_b("[missing word: #{s}]")
474
+ end
408
475
  end
409
476
 
410
477
  def raw(str)
@@ -423,9 +490,9 @@ module ReVIEW
423
490
  if arg
424
491
  builders = arg.gsub(/^\s*\|/, '').gsub(/\|\s*$/, '').gsub(/\s/, '').split(',')
425
492
  c = target_name
426
- print lines.join if builders.include?(c)
493
+ print lines.join("\n") + "\n" if builders.include?(c)
427
494
  else
428
- print lines.join
495
+ print lines.join("\n") + "\n"
429
496
  end
430
497
  end
431
498
 
@@ -451,11 +518,13 @@ module ReVIEW
451
518
 
452
519
  def parse_metric(type, metric)
453
520
  return '' if metric.blank?
521
+
454
522
  params = metric.split(/,\s*/)
455
523
  results = []
456
524
  params.each do |param|
457
525
  if param =~ /\A.+?::/
458
526
  next unless param =~ /\A#{type}::/
527
+
459
528
  param.sub!(/\A#{type}::/, '')
460
529
  end
461
530
  param2 = handle_metric(param)
@@ -480,6 +549,7 @@ module ReVIEW
480
549
  if m
481
550
  ch = @book.contents.detect { |chap| chap.id == m[1] }
482
551
  raise KeyError unless ch
552
+
483
553
  return [ch, m[2]]
484
554
  end
485
555
  [@chapter, chap_ref]
@@ -492,9 +562,36 @@ module ReVIEW
492
562
  CAPTION_TITLES.each do |name|
493
563
  class_eval %Q(
494
564
  def #{name}(lines, caption = nil)
565
+ check_nested_minicolumn
495
566
  captionblock("#{name}", lines, caption)
496
567
  end
497
- )
568
+
569
+ def #{name}_begin(caption = nil)
570
+ check_nested_minicolumn
571
+ @doc_status[:minicolumn] = '#{name}'
572
+ if caption
573
+ puts compile_inline(caption)
574
+ end
575
+ end
576
+
577
+ def #{name}_end
578
+ @doc_status[:minicolumn] = nil
579
+ end
580
+ ), __FILE__, __LINE__ - 17
581
+ end
582
+
583
+ def check_nested_minicolumn
584
+ if @doc_status[:minicolumn]
585
+ error "#{@location}: nested mini-column is not allowed"
586
+ end
587
+ end
588
+
589
+ def in_minicolumn?
590
+ @doc_status[:minicolumn]
591
+ end
592
+
593
+ def minicolumn_block_name?(name)
594
+ CAPTION_TITLES.include?(name)
498
595
  end
499
596
 
500
597
  def graph(lines, id, command, caption = '')
@@ -504,13 +601,13 @@ module ReVIEW
504
601
  file = "#{id}.#{image_ext}"
505
602
  file_path = File.join(dir, file)
506
603
 
507
- line = self.unescape(lines.join("\n"))
604
+ content = lines.join("\n") + "\n"
508
605
 
509
606
  tf = Tempfile.new('review_graph')
510
- tf.puts line
607
+ tf.puts content
511
608
  tf.close
512
609
  begin
513
- file_path = send("graph_#{command}".to_sym, id, file_path, line, tf.path)
610
+ file_path = send("graph_#{command}".to_sym, id, file_path, content, tf.path)
514
611
  ensure
515
612
  tf.unlink
516
613
  end
@@ -558,7 +655,7 @@ EOTGNUPLOT
558
655
  file_path.sub!(/\.pdf\Z/, '.eps')
559
656
  end
560
657
  system_graph(id, 'java', '-jar', 'plantuml.jar', "-t#{ext}", '-charset', 'UTF-8', tf_path)
561
- FileUtils.mv "#{tf_path}.#{ext}", file_path
658
+ FileUtils.mv("#{tf_path}.#{ext}", file_path)
562
659
  file_path
563
660
  end
564
661
 
@@ -567,7 +664,7 @@ EOTGNUPLOT
567
664
  end
568
665
 
569
666
  def inline_include(file_name)
570
- compile_inline File.read(file_name, mode: 'rt:BOM|utf-8').chomp
667
+ compile_inline(File.read(file_name, mode: 'rt:BOM|utf-8').chomp)
571
668
  end
572
669
 
573
670
  def ul_item_begin(lines)
@@ -635,8 +732,28 @@ EOTGNUPLOT
635
732
  str
636
733
  end
637
734
 
638
- def unescape(str)
639
- str
735
+ def beginchild
736
+ @children ||= []
737
+ unless @previous_list_type
738
+ error "//beginchild is shown, but previous element isn't ul, ol, or dl"
739
+ end
740
+ puts "\x01→#{@previous_list_type}←\x01"
741
+ @children.push(@previous_list_type)
742
+ end
743
+
744
+ def endchild
745
+ if @children.nil? || @children.empty?
746
+ error "//endchild is shown, but any opened //beginchild doesn't exist"
747
+ else
748
+ puts "\x01→/#{@children.pop}←\x01"
749
+ end
750
+ end
751
+
752
+ def caption_top?(type)
753
+ unless %w[top bottom].include?(@book.config['caption_position'][type])
754
+ warn("invalid caption_position/#{type} parameter. 'top' is assumed")
755
+ end
756
+ @book.config['caption_position'][type] != 'bottom'
640
757
  end
641
758
  end
642
759
  end # module ReVIEW