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
@@ -7,19 +7,16 @@
7
7
  # the GNU LGPL, Lesser General Public License version 2.1.
8
8
  #
9
9
 
10
- require 'cgi/util'
10
+ begin
11
+ require 'cgi/escape'
12
+ rescue
13
+ require 'cgi/util'
14
+ end
15
+
11
16
  module ReVIEW
12
17
  module HTMLUtils
13
- ESC = {
14
- '&' => '&',
15
- '<' => '&lt;',
16
- '>' => '&gt;',
17
- '"' => '&quot;'
18
- } # .freeze
19
-
20
18
  def escape(str)
21
- t = ESC
22
- str.gsub(/[&"<>]/) { |c| t[c] }
19
+ CGI.escapeHTML(str)
23
20
  end
24
21
 
25
22
  alias_method :escape_html, :escape # for backward compatibility
@@ -137,7 +134,7 @@ module ReVIEW
137
134
  elsif id =~ /\A[0-9_.-][a-z0-9_.-]*\Z/i
138
135
  "id_#{id}" # dummy prefix
139
136
  else
140
- "id_#{CGI.escape(id.gsub('_', '__')).gsub('%', '_').gsub('+', '-')}" # escape all
137
+ "id_#{CGI.escape(id.gsub('_', '__')).tr('%', '_').tr('+', '-')}" # escape all
141
138
  end
142
139
  end
143
140
  end
data/lib/review/i18n.rb CHANGED
@@ -91,6 +91,7 @@ module ReVIEW
91
91
  else
92
92
  user_i18n.each do |key, values|
93
93
  raise KeyError, "Invalid locale file: #{path}" unless values.is_a?(Hash)
94
+
94
95
  @store[key].merge!(values)
95
96
  end
96
97
  end
@@ -125,7 +126,7 @@ module ReVIEW
125
126
  frmt.gsub!('%%', '##')
126
127
 
127
128
  unless args.is_a?(Array)
128
- args = args.nil? && frmt !~ /\%/ ? [] : [args]
129
+ args = args.nil? && frmt !~ /%/ ? [] : [args]
129
130
  end
130
131
 
131
132
  percents = frmt.scan(/%[A-Za-z]{1,3}/)
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2008-2020 Minero Aoki, Kenshi Muto
2
2
  # 2002-2007 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -46,11 +46,8 @@ module ReVIEW
46
46
  '.xml'
47
47
  end
48
48
 
49
- def builder_init
50
- end
51
- private :builder_init
52
-
53
49
  def builder_init_file
50
+ super
54
51
  @warns = []
55
52
  @errors = []
56
53
  @section = 0
@@ -89,19 +86,27 @@ module ReVIEW
89
86
  s += '</sect>' if @section > 0
90
87
  s += '</chapter>' if @chapter.number > 0
91
88
  end
92
- @output.string + s + "</#{@rootelement}>\n"
89
+ solve_nest(@output.string) + s + "</#{@rootelement}>\n"
90
+ end
91
+
92
+ def solve_nest(s)
93
+ check_nest
94
+ s.gsub("</dd></dl>\x01→dl←\x01", '').
95
+ gsub("\x01→/dl←\x01", "</dd></dl>←END\x01").
96
+ gsub("</li></ul>\x01→ul←\x01", '').
97
+ gsub("\x01→/ul←\x01", "</li></ul>←END\x01").
98
+ gsub("</li></ol>\x01→ol←\x01", '').
99
+ gsub("\x01→/ol←\x01", "</li></ol>←END\x01").
100
+ gsub("</dl>←END\x01<dl>", '').
101
+ gsub("</ul>←END\x01<ul>", '').
102
+ gsub("</ol>←END\x01<ol>", '').
103
+ gsub("←END\x01", '')
93
104
  end
94
105
 
95
106
  def headline(level, label, caption)
107
+ output_close_sect_tags(level)
96
108
  case level
97
109
  when 1
98
- if @secttags
99
- print '</sect4>' if @subsubsubsection > 0
100
- print '</sect3>' if @subsubsection > 0
101
- print '</sect2>' if @subsection > 0
102
- print '</sect>' if @section > 0
103
- end
104
-
105
110
  print %Q(<chapter id="chap:#{@chapter.number}">) if @secttags
106
111
 
107
112
  @section = 0
@@ -109,12 +114,6 @@ module ReVIEW
109
114
  @subsubsection = 0
110
115
  @subsubsubsection = 0
111
116
  when 2
112
- if @secttags
113
- print '</sect4>' if @subsubsubsection > 0
114
- print '</sect3>' if @subsubsection > 0
115
- print '</sect2>' if @subsection > 0
116
- print '</sect>' if @section > 0
117
- end
118
117
  @section += 1
119
118
  print %Q(<sect id="sect:#{@chapter.number}.#{@section}">) if @secttags
120
119
 
@@ -122,30 +121,17 @@ module ReVIEW
122
121
  @subsubsection = 0
123
122
  @subsubsubsection = 0
124
123
  when 3
125
- if @secttags
126
- print '</sect4>' if @subsubsubsection > 0
127
- print '</sect3>' if @subsubsection > 0
128
- print '</sect2>' if @subsection > 0
129
- end
130
-
131
124
  @subsection += 1
132
125
  print %Q(<sect2 id="sect:#{@chapter.number}.#{@section}.#{@subsection}">) if @secttags
133
126
 
134
127
  @subsubsection = 0
135
128
  @subsubsubsection = 0
136
129
  when 4
137
- if @secttags
138
- print '</sect4>' if @subsubsubsection > 0
139
- print '</sect3>' if @subsubsection > 0
140
- end
141
-
142
130
  @subsubsection += 1
143
131
  print %Q(<sect3 id="sect:#{@chapter.number}.#{@section}.#{@subsection}.#{@subsubsection}">) if @secttags
144
132
 
145
133
  @subsubsubsection = 0
146
134
  when 5
147
- print '</sect4>' if @secttags && @subsubsubsection > 0
148
-
149
135
  @subsubsubsection += 1
150
136
  print %Q(<sect4 id="sect:#{@chapter.number}.#{@section}.#{@subsection}.#{@subsubsection}.#{@subsubsubsection}">) if @secttags
151
137
  when 6 # rubocop:disable Lint/EmptyWhen
@@ -160,6 +146,23 @@ module ReVIEW
160
146
  puts %Q(<title#{label} aid:pstyle="h#{level}">#{prefix}#{compile_inline(caption)}</title><?dtp level="#{level}" section="#{prefix}#{toccaption}"?>)
161
147
  end
162
148
 
149
+ def output_close_sect_tags(level)
150
+ if @secttags
151
+ if level <= 5 && @subsubsubsection > 0
152
+ print '</sect4>'
153
+ end
154
+ if level <= 4 && @subsubsection > 0
155
+ print '</sect3>'
156
+ end
157
+ if level <= 3 && @subsection > 0
158
+ print '</sect2>'
159
+ end
160
+ if level <= 2 && @section > 0
161
+ print '</sect>'
162
+ end
163
+ end
164
+ end
165
+
163
166
  def ul_begin
164
167
  level = block_given? ? yield : ''
165
168
  level = nil if level == 1
@@ -198,7 +201,7 @@ module ReVIEW
198
201
 
199
202
  def ol_begin
200
203
  puts '<ol>'
201
- @ol_num ||= 1
204
+ @ol_num ||= 1 # rubocop:disable Naming/MemoizedInstanceVariableName
202
205
  end
203
206
 
204
207
  def ol_item(lines, num)
@@ -263,7 +266,7 @@ module ReVIEW
263
266
  I18n.t('column', compile_inline(chapter.column(id).caption))
264
267
  end
265
268
  rescue KeyError
266
- error "unknown column: #{id}"
269
+ app_error "unknown column: #{id}"
267
270
  end
268
271
 
269
272
  def inline_list(id)
@@ -272,6 +275,7 @@ module ReVIEW
272
275
 
273
276
  def list_header(id, caption, _lang)
274
277
  return true unless caption.present?
278
+
275
279
  if get_chap.nil?
276
280
  puts %Q(<caption>#{I18n.t('list')}#{I18n.t('format_number_without_chapter', [@chapter.list(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
277
281
  else
@@ -351,7 +355,9 @@ module ReVIEW
351
355
 
352
356
  def quotedlist(lines, css_class, caption)
353
357
  print %Q(<list type='#{css_class}'>)
354
- puts "<caption aid:pstyle='#{css_class}-title'>#{compile_inline(caption)}</caption>" if caption.present?
358
+ if caption_top?('list') && caption.present?
359
+ puts "<caption aid:pstyle='#{css_class}-title'>#{compile_inline(caption)}</caption>"
360
+ end
355
361
  print '<pre>'
356
362
  no = 1
357
363
  lines.each do |line|
@@ -366,7 +372,11 @@ module ReVIEW
366
372
  print '</listinfo>' if @book.config['listinfo']
367
373
  no += 1
368
374
  end
369
- puts '</pre></list>'
375
+ puts '</pre>'
376
+ if !caption_top?('list') && caption.present?
377
+ puts "<caption aid:pstyle='#{css_class}-title'>#{compile_inline(caption)}</caption>"
378
+ end
379
+ puts '</list>'
370
380
  end
371
381
  private :quotedlist
372
382
 
@@ -410,26 +420,29 @@ module ReVIEW
410
420
  def image_image(id, caption, metric = nil)
411
421
  metrics = parse_metric('idgxml', metric)
412
422
  puts '<img>'
423
+ image_header(id, caption) if caption_top?('image')
413
424
  puts %Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A./}, '')}"#{metrics} />)
414
- image_header(id, caption)
425
+ image_header(id, caption) unless caption_top?('image')
415
426
  puts '</img>'
416
427
  end
417
428
 
418
429
  def image_dummy(id, caption, lines)
419
430
  puts '<img>'
431
+ image_header(id, caption) if caption_top?('image')
420
432
  print %Q(<pre aid:pstyle="dummyimage">)
421
433
  lines.each do |line|
422
434
  print detab(line)
423
435
  print "\n"
424
436
  end
425
437
  print '</pre>'
426
- image_header(id, caption)
438
+ image_header(id, caption) unless caption_top?('image')
427
439
  puts '</img>'
428
- warn "image not bound: #{id}"
440
+ warn "image not bound: #{id}", location: location
429
441
  end
430
442
 
431
443
  def image_header(id, caption)
432
444
  return true unless caption.present?
445
+
433
446
  if get_chap.nil?
434
447
  puts %Q(<caption>#{I18n.t('image')}#{I18n.t('format_number_without_chapter', [@chapter.image(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
435
448
  else
@@ -439,13 +452,15 @@ module ReVIEW
439
452
 
440
453
  def texequation(lines, id = nil, caption = '')
441
454
  @texblockequation += 1
455
+ caption_str = nil
442
456
  if id
443
457
  puts '<equationblock>'
444
458
  if get_chap.nil?
445
- puts %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [@chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
459
+ caption_str = %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [@chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
446
460
  else
447
- puts %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number', [get_chap, @chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
461
+ caption_str = %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number', [get_chap, @chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
448
462
  end
463
+ puts caption_str if caption_top?('equation')
449
464
  end
450
465
 
451
466
  puts %Q(<replace idref="texblock-#{@texblockequation}">)
@@ -455,6 +470,7 @@ module ReVIEW
455
470
  puts '</replace>'
456
471
 
457
472
  if id
473
+ puts caption_str unless caption_top?('equation')
458
474
  puts '</equationblock>'
459
475
  end
460
476
  end
@@ -470,19 +486,26 @@ module ReVIEW
470
486
  puts '<table>'
471
487
 
472
488
  begin
473
- table_header(id, caption) if caption.present?
474
- rescue KeyError
475
- error "no such table: #{id}"
476
- end
489
+ if caption_top?('table') && caption.present?
490
+ table_header(id, caption)
491
+ end
477
492
 
478
- if @tablewidth.nil?
479
- print '<tbody>'
480
- else
481
- print %Q(<tbody xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/" aid:table="table" aid:trows="#{rows.length}" aid:tcols="#{@col}">)
493
+ if @tablewidth.nil?
494
+ print '<tbody>'
495
+ else
496
+ print %Q(<tbody xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/" aid:table="table" aid:trows="#{rows.length}" aid:tcols="#{@col}">)
497
+ end
498
+ @table_id = id
499
+ table_rows(sepidx, rows)
500
+ puts '</tbody>'
501
+
502
+ if !caption_top?('table') && caption.present?
503
+ table_header(id, caption)
504
+ end
505
+ rescue KeyError
506
+ app_error "no such table: #{id}"
482
507
  end
483
- @table_id = id
484
- table_rows(sepidx, rows)
485
- puts '</tbody></table>'
508
+ puts '</table>'
486
509
  @tsize = nil
487
510
  end
488
511
 
@@ -490,7 +513,7 @@ module ReVIEW
490
513
  sepidx = nil
491
514
  rows = []
492
515
  lines.each_with_index do |line, idx|
493
- if /\A[\=\-]{12}/ =~ line
516
+ if /\A[=\-]{12}/ =~ line
494
517
  sepidx ||= idx
495
518
  next
496
519
  end
@@ -502,7 +525,7 @@ module ReVIEW
502
525
  col2 = rows[rows.length - 1].split(table_row_separator_regexp).length
503
526
  @col = col2 if col2 > @col
504
527
  end
505
- error 'no rows in the table' if rows.empty?
528
+ app_error 'no rows in the table' if rows.empty?
506
529
  [sepidx, rows]
507
530
  end
508
531
 
@@ -517,11 +540,11 @@ module ReVIEW
517
540
  cellwidth.size.times do |n|
518
541
  cellwidth[n] = cellwidth[n].to_f / @book.config['pt_to_mm_unit'].to_f
519
542
  totallength += cellwidth[n]
520
- warn "total length exceeds limit for table: #{@table_id}" if totallength > @tablewidth
543
+ warn "total length exceeds limit for table: #{@table_id}", location: location if totallength > @tablewidth
521
544
  end
522
545
  if cellwidth.size < @col
523
546
  cw = (@tablewidth - totallength) / (@col - cellwidth.size)
524
- warn "auto cell sizing exceeds limit for table: #{@table_id}" if cw <= 0
547
+ warn "auto cell sizing exceeds limit for table: #{@table_id}", location: location if cw <= 0
525
548
  (cellwidth.size..(@col - 1)).each { |i| cellwidth[i] = cw }
526
549
  end
527
550
  end
@@ -596,17 +619,23 @@ module ReVIEW
596
619
  if @chapter.image_bound?(id)
597
620
  metrics = parse_metric('idgxml', metric)
598
621
  puts '<table>'
599
- table_header(id, caption) if caption.present?
622
+ if caption_top?('table') && caption.present?
623
+ table_header(id, caption)
624
+ end
600
625
  puts %Q(<imgtable><Image href="file://#{@chapter.image(id).path.sub(%r{\A./}, '')}"#{metrics} /></imgtable>)
626
+ if !caption_top?('table') && caption.present?
627
+ table_header(id, caption)
628
+ end
601
629
  puts '</table>'
602
630
  else
603
- warn "image not bound: #{id}" if @strict
631
+ warn "image not bound: #{id}", location: location if @strict
604
632
  image_dummy(id, caption, lines)
605
633
  end
606
634
  end
607
635
 
608
636
  def comment(lines, comment = nil)
609
637
  return unless @book.config['draft']
638
+
610
639
  lines ||= []
611
640
  lines.unshift(escape(comment)) unless comment.blank?
612
641
  str = lines.join("\n")
@@ -628,7 +657,7 @@ module ReVIEW
628
657
  def inline_fn(id)
629
658
  %Q(<footnote>#{compile_inline(@chapter.footnote(id).content.strip)}</footnote>)
630
659
  rescue KeyError
631
- error "unknown footnote: #{id}"
660
+ app_error "unknown footnote: #{id}"
632
661
  end
633
662
 
634
663
  def compile_ruby(base, ruby)
@@ -641,7 +670,7 @@ module ReVIEW
641
670
  then escape("#{word}(#{alt.strip})")
642
671
  else escape(word)
643
672
  end +
644
- '</keyword>' +
673
+ '</keyword>' +
645
674
  %Q(<index value="#{escape(word)}" />) +
646
675
  if alt
647
676
  alt.split(/\s*,\s*/).collect! { |e| %Q(<index value="#{escape(e.strip)}" />) }.join
@@ -690,7 +719,7 @@ module ReVIEW
690
719
  sprintf('&#x%x;', 9392 + str[0] - 65)
691
720
  end
692
721
  else
693
- error "can't parse maru: #{str}"
722
+ app_error "can't parse maru: #{str}"
694
723
  end
695
724
  end
696
725
 
@@ -740,11 +769,19 @@ module ReVIEW
740
769
  %Q(<underline>#{escape(str)}</underline>)
741
770
  end
742
771
 
772
+ def inline_ins(str)
773
+ %Q(<ins>#{escape(str)}</ins>)
774
+ end
775
+
776
+ def inline_del(str)
777
+ %Q(<del>#{escape(str)}</del>)
778
+ end
779
+
743
780
  def inline_icon(id)
744
781
  begin
745
782
  %Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A\./}, '')}" type="inline" />)
746
783
  rescue
747
- warn "image not bound: #{id}"
784
+ warn "image not bound: #{id}", location: location
748
785
  ''
749
786
  end
750
787
  end
@@ -919,18 +956,22 @@ module ReVIEW
919
956
  end
920
957
 
921
958
  def note(lines, caption = nil)
959
+ check_nested_minicolumn
922
960
  captionblock('note', lines, caption)
923
961
  end
924
962
 
925
963
  def memo(lines, caption = nil)
964
+ check_nested_minicolumn
926
965
  captionblock('memo', lines, caption)
927
966
  end
928
967
 
929
968
  def tip(lines, caption = nil)
969
+ check_nested_minicolumn
930
970
  captionblock('tip', lines, caption)
931
971
  end
932
972
 
933
973
  def info(lines, caption = nil)
974
+ check_nested_minicolumn
934
975
  captionblock('info', lines, caption)
935
976
  end
936
977
 
@@ -943,6 +984,7 @@ module ReVIEW
943
984
  end
944
985
 
945
986
  def important(lines, caption = nil)
987
+ check_nested_minicolumn
946
988
  captionblock('important', lines, caption)
947
989
  end
948
990
 
@@ -951,10 +993,12 @@ module ReVIEW
951
993
  end
952
994
 
953
995
  def caution(lines, caption = nil)
996
+ check_nested_minicolumn
954
997
  captionblock('caution', lines, caption)
955
998
  end
956
999
 
957
1000
  def warning(lines, caption = nil)
1001
+ check_nested_minicolumn
958
1002
  captionblock('warning', lines, caption)
959
1003
  end
960
1004
 
@@ -967,6 +1011,7 @@ module ReVIEW
967
1011
  end
968
1012
 
969
1013
  def notice(lines, caption = nil)
1014
+ check_nested_minicolumn
970
1015
  if caption
971
1016
  captionblock('notice-t', lines, caption, 'notice-title')
972
1017
  else
@@ -1002,7 +1047,35 @@ module ReVIEW
1002
1047
  captionblock('expert', lines, nil)
1003
1048
  end
1004
1049
 
1050
+ CAPTION_TITLES.each do |name|
1051
+ class_eval %Q(
1052
+ def #{name}_begin(caption = nil)
1053
+ check_nested_minicolumn
1054
+ if '#{name}' == 'notice' && caption.present?
1055
+ @doc_status[:minicolumn] = '#{name}-t'
1056
+ print "<#{name}-t>"
1057
+ else
1058
+ @doc_status[:minicolumn] = '#{name}'
1059
+ print "<#{name}>"
1060
+ end
1061
+ if caption.present?
1062
+ puts %Q(<title aid:pstyle='#{name}-title'>\#{compile_inline(caption)}</title>)
1063
+ end
1064
+ end
1065
+
1066
+ def #{name}_end
1067
+ if '#{name}' == 'notice' && @doc_status[:minicolumn] == 'notice-t'
1068
+ print "</#{name}-t>"
1069
+ else
1070
+ print "</#{name}>"
1071
+ end
1072
+ @doc_status[:minicolumn] = nil
1073
+ end
1074
+ ), __FILE__, __LINE__ - 23
1075
+ end
1076
+
1005
1077
  def syntaxblock(type, lines, caption)
1078
+ captionstr = nil
1006
1079
  if caption.present?
1007
1080
  titleopentag = %Q(caption aid:pstyle="#{type}-title")
1008
1081
  titleclosetag = 'caption'
@@ -1010,9 +1083,13 @@ module ReVIEW
1010
1083
  titleopentag = %Q(floattitle type="insn")
1011
1084
  titleclosetag = 'floattitle'
1012
1085
  end
1013
- puts %Q(<#{type}><#{titleopentag}>#{compile_inline(caption)}</#{titleclosetag}>)
1086
+ captionstr = %Q(<#{titleopentag}>#{compile_inline(caption)}</#{titleclosetag}>)
1087
+ end
1088
+ print "<#{type}>"
1089
+ if caption_top?('list')
1090
+ puts captionstr
1014
1091
  else
1015
- puts "<#{type}>"
1092
+ puts ''
1016
1093
  end
1017
1094
 
1018
1095
  no = 1
@@ -1028,6 +1105,9 @@ module ReVIEW
1028
1105
  print '</listinfo>' if @book.config['listinfo']
1029
1106
  no += 1
1030
1107
  end
1108
+ unless caption_top?('list')
1109
+ print captionstr
1110
+ end
1031
1111
  puts "</#{type}>"
1032
1112
  end
1033
1113
 
@@ -1042,12 +1122,17 @@ module ReVIEW
1042
1122
  def indepimage(_lines, id, caption = nil, metric = nil)
1043
1123
  metrics = parse_metric('idgxml', metric)
1044
1124
  puts '<img>'
1125
+ if caption_top?('image')
1126
+ puts %Q(<caption>#{compile_inline(caption)}</caption>) if caption.present?
1127
+ end
1045
1128
  begin
1046
1129
  puts %Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A\./}, '')}"#{metrics} />)
1047
1130
  rescue
1048
- warn %Q(image not bound: #{id})
1131
+ warn %Q(image not bound: #{id}), location: location
1132
+ end
1133
+ unless caption_top?('image')
1134
+ puts %Q(<caption>#{compile_inline(caption)}</caption>) if caption.present?
1049
1135
  end
1050
- puts %Q(<caption>#{compile_inline(caption)}</caption>) if caption.present?
1051
1136
  puts '</img>'
1052
1137
  end
1053
1138
 
@@ -1101,10 +1186,10 @@ module ReVIEW
1101
1186
  chs = ['', '「', '」']
1102
1187
  if @book.config['chapref']
1103
1188
  chs2 = @book.config['chapref'].split(',')
1104
- if chs2.size != 3
1105
- error '--chapsplitter must have exactly 3 parameters with comma.'
1106
- else
1189
+ if chs2.size == 3
1107
1190
  chs = chs2
1191
+ else
1192
+ app_error '--chapsplitter must have exactly 3 parameters with comma.'
1108
1193
  end
1109
1194
  end
1110
1195
  s = "#{chs[0]}#{@book.chapter_index.number(id)}#{chs[1]}#{@book.chapter_index.title(id)}#{chs[2]}"
@@ -1122,7 +1207,7 @@ module ReVIEW
1122
1207
  end
1123
1208
  end
1124
1209
  rescue KeyError
1125
- error "unknown chapter: #{id}"
1210
+ app_error "unknown chapter: #{id}"
1126
1211
  end
1127
1212
 
1128
1213
  def inline_chap(id)
@@ -1132,7 +1217,7 @@ module ReVIEW
1132
1217
  @book.chapter_index.number(id)
1133
1218
  end
1134
1219
  rescue KeyError
1135
- error "unknown chapter: #{id}"
1220
+ app_error "unknown chapter: #{id}"
1136
1221
  end
1137
1222
 
1138
1223
  def inline_title(id)
@@ -1143,13 +1228,18 @@ module ReVIEW
1143
1228
  title
1144
1229
  end
1145
1230
  rescue KeyError
1146
- error "unknown chapter: #{id}"
1231
+ app_error "unknown chapter: #{id}"
1147
1232
  end
1148
1233
 
1149
1234
  def source(lines, caption = nil, lang = nil)
1150
1235
  puts '<source>'
1151
- source_header(caption)
1236
+ if caption_top?('list')
1237
+ source_header(caption)
1238
+ end
1152
1239
  source_body(lines, lang)
1240
+ unless caption_top?('list')
1241
+ source_header(caption)
1242
+ end
1153
1243
  puts '</source>'
1154
1244
  end
1155
1245
 
@@ -1181,7 +1271,7 @@ module ReVIEW
1181
1271
  def inline_bib(id)
1182
1272
  %Q(<span type='bibref' idref='#{id}'>[#{@chapter.bibpaper(id).number}]</span>)
1183
1273
  rescue KeyError
1184
- error "unknown bib: #{id}"
1274
+ app_error "unknown bib: #{id}"
1185
1275
  end
1186
1276
 
1187
1277
  def inline_hd_chap(chap, id)
@@ -1192,7 +1282,7 @@ module ReVIEW
1192
1282
  I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption))
1193
1283
  end
1194
1284
  rescue KeyError
1195
- error "unknown headline: #{id}"
1285
+ app_error "unknown headline: #{id}"
1196
1286
  end
1197
1287
 
1198
1288
  def inline_recipe(id)