review 4.2.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-win.yml +11 -5
  3. data/.rubocop.yml +113 -24
  4. data/NEWS.ja.md +94 -0
  5. data/NEWS.md +94 -0
  6. data/bin/review-catalog-converter +1 -1
  7. data/bin/review-check +2 -4
  8. data/bin/review-checkdep +1 -1
  9. data/bin/review-compile +8 -14
  10. data/bin/review-validate +1 -1
  11. data/doc/config.yml.sample +4 -1
  12. data/doc/config.yml.sample-simple +1 -1
  13. data/doc/format.ja.md +83 -4
  14. data/doc/format.md +84 -7
  15. data/doc/makeindex.ja.md +2 -2
  16. data/doc/quickstart.ja.md +3 -3
  17. data/doc/quickstart.md +2 -2
  18. data/lib/epubmaker/content.rb +3 -2
  19. data/lib/epubmaker/epubcommon.rb +33 -25
  20. data/lib/epubmaker/epubv2.rb +5 -6
  21. data/lib/epubmaker/epubv3.rb +20 -18
  22. data/lib/review/book.rb +2 -2
  23. data/lib/review/book/base.rb +61 -25
  24. data/lib/review/book/bib.rb +21 -0
  25. data/lib/review/book/book_unit.rb +155 -0
  26. data/lib/review/book/chapter.rb +30 -26
  27. data/lib/review/book/index.rb +23 -185
  28. data/lib/review/book/index/item.rb +7 -1
  29. data/lib/review/book/part.rb +21 -9
  30. data/lib/review/book/volume.rb +1 -1
  31. data/lib/review/builder.rb +68 -13
  32. data/lib/review/catalog.rb +2 -2
  33. data/lib/review/compiler.rb +159 -73
  34. data/lib/review/configure.rb +22 -1
  35. data/lib/review/converter.rb +1 -1
  36. data/lib/review/epub2html.rb +6 -1
  37. data/lib/review/epubmaker.rb +12 -23
  38. data/lib/review/htmlbuilder.rb +36 -7
  39. data/lib/review/htmlutils.rb +7 -10
  40. data/lib/review/i18n.rb +1 -1
  41. data/lib/review/idgxmlbuilder.rb +51 -6
  42. data/lib/review/idgxmlmaker.rb +9 -14
  43. data/lib/review/index_builder.rb +653 -0
  44. data/lib/review/init.rb +5 -13
  45. data/lib/review/latexbuilder.rb +65 -4
  46. data/lib/review/logger.rb +2 -2
  47. data/lib/review/makerhelper.rb +11 -0
  48. data/lib/review/markdownbuilder.rb +19 -1
  49. data/lib/review/pdfmaker.rb +17 -36
  50. data/lib/review/plaintextbuilder.rb +48 -2
  51. data/lib/review/preprocessor.rb +5 -5
  52. data/lib/review/rstbuilder.rb +25 -6
  53. data/lib/review/sec_counter.rb +13 -0
  54. data/lib/review/textmaker.rb +4 -12
  55. data/lib/review/tocprinter.rb +2 -3
  56. data/lib/review/topbuilder.rb +26 -0
  57. data/lib/review/update.rb +7 -7
  58. data/lib/review/version.rb +1 -1
  59. data/lib/review/volumeprinter.rb +2 -3
  60. data/lib/review/webmaker.rb +9 -20
  61. data/review.gemspec +2 -2
  62. data/samples/sample-book/src/config.yml +1 -1
  63. data/samples/syntax-book/Gemfile +1 -1
  64. data/samples/syntax-book/config.yml +1 -1
  65. data/templates/latex/config.erb +27 -23
  66. data/templates/latex/review-jlreq/README.md +3 -1
  67. data/templates/latex/review-jlreq/review-base.sty +31 -15
  68. data/templates/latex/review-jlreq/review-jlreq.cls +8 -24
  69. data/templates/latex/review-jsbook/README.md +7 -5
  70. data/templates/latex/review-jsbook/review-base.sty +34 -16
  71. data/templates/latex/review-jsbook/review-jsbook.cls +4 -2
  72. data/templates/web/html/layout-html5.html.erb +1 -1
  73. data/test/assets/test_template.tex +3 -3
  74. data/test/assets/test_template_backmatter.tex +3 -3
  75. data/test/book_test_helper.rb +11 -5
  76. data/test/test_book.rb +54 -63
  77. data/test/test_book_chapter.rb +93 -52
  78. data/test/test_builder.rb +24 -15
  79. data/test/test_converter.rb +1 -0
  80. data/test/test_epub3maker.rb +2 -2
  81. data/test/test_epubmaker.rb +8 -0
  82. data/test/test_helper.rb +4 -1
  83. data/test/test_htmlbuilder.rb +627 -56
  84. data/test/test_htmlutils.rb +0 -12
  85. data/test/test_i18n.rb +33 -33
  86. data/test/test_idgxmlbuilder.rb +358 -11
  87. data/test/test_idgxmlmaker_cmd.rb +1 -1
  88. data/test/test_index.rb +62 -52
  89. data/test/test_indexbuilder.rb +52 -0
  90. data/test/test_latexbuilder.rb +547 -10
  91. data/test/test_latexbuilder_v2.rb +43 -5
  92. data/test/test_logger.rb +7 -7
  93. data/test/test_makerhelper.rb +0 -12
  94. data/test/test_markdownbuilder.rb +3 -0
  95. data/test/test_pdfmaker.rb +13 -12
  96. data/test/test_pdfmaker_cmd.rb +1 -1
  97. data/test/test_plaintextbuilder.rb +422 -7
  98. data/test/test_review_ext.rb +2 -1
  99. data/test/test_rstbuilder.rb +25 -1
  100. data/test/test_sec_counter.rb +156 -0
  101. data/test/test_textmaker_cmd.rb +1 -1
  102. data/test/test_topbuilder.rb +187 -10
  103. data/test/test_update.rb +10 -10
  104. data/test/test_webtocprinter.rb +12 -12
  105. data/vendor/gentombow/LICENSE +1 -1
  106. data/vendor/gentombow/Makefile +0 -1
  107. data/vendor/gentombow/bounddvi-en.pdf +0 -0
  108. data/vendor/gentombow/bounddvi-en.tex +1 -0
  109. data/vendor/gentombow/bounddvi.pdf +0 -0
  110. data/vendor/gentombow/bounddvi.sty +30 -7
  111. data/vendor/gentombow/bounddvi.tex +1 -0
  112. data/vendor/gentombow/create_archive.sh +1 -0
  113. data/vendor/gentombow/gentombow-ja.pdf +0 -0
  114. data/vendor/gentombow/gentombow-ja.tex +9 -0
  115. data/vendor/gentombow/gentombow.pdf +0 -0
  116. data/vendor/gentombow/gentombow.sty +32 -10
  117. data/vendor/gentombow/gentombow.tex +8 -0
  118. data/vendor/gentombow/tests/gentombow-01-pdfx.tex +8 -0
  119. data/vendor/gentombow/tests/gentombow-02-pdfx.tex +8 -0
  120. data/vendor/jsclasses/Makefile +3 -2
  121. data/vendor/jsclasses/create_archive.sh +5 -5
  122. data/vendor/jsclasses/jis/Makefile +3 -2
  123. data/vendor/jsclasses/jis/jsarticle.cls +22 -18
  124. data/vendor/jsclasses/jis/jsbook.cls +22 -18
  125. data/vendor/jsclasses/jis/jsclasses.dtx +94 -13
  126. data/vendor/jsclasses/jis/jsclasses.ins +15 -5
  127. data/vendor/jsclasses/jis/jslogo.ins +9 -0
  128. data/vendor/jsclasses/jis/jslogo.sty +1 -13
  129. data/vendor/jsclasses/jis/jspf.cls +22 -18
  130. data/vendor/jsclasses/jis/jsreport.cls +22 -18
  131. data/vendor/jsclasses/jis/jsverb.ins +9 -0
  132. data/vendor/jsclasses/jis/jsverb.sty +1 -13
  133. data/vendor/jsclasses/jis/kiyou.cls +22 -18
  134. data/vendor/jsclasses/jis/minijs.sty +65 -22
  135. data/vendor/jsclasses/jis/okumacro.ins +9 -0
  136. data/vendor/jsclasses/jis/okumacro.sty +1 -13
  137. data/vendor/jsclasses/jis/okuverb.ins +9 -0
  138. data/vendor/jsclasses/jis/okuverb.sty +1 -13
  139. data/vendor/jsclasses/jis/winjis.sty +23 -19
  140. data/vendor/jsclasses/jsarticle.cls +22 -18
  141. data/vendor/jsclasses/jsbook.cls +22 -18
  142. data/vendor/jsclasses/jsclasses.dtx +94 -13
  143. data/vendor/jsclasses/jsclasses.ins +15 -5
  144. data/vendor/jsclasses/jsclasses.pdf +0 -0
  145. data/vendor/jsclasses/jslogo.ins +9 -0
  146. data/vendor/jsclasses/jslogo.pdf +0 -0
  147. data/vendor/jsclasses/jslogo.sty +1 -13
  148. data/vendor/jsclasses/jspf.cls +22 -18
  149. data/vendor/jsclasses/jsreport.cls +22 -18
  150. data/vendor/jsclasses/jsverb.ins +9 -0
  151. data/vendor/jsclasses/jsverb.pdf +0 -0
  152. data/vendor/jsclasses/jsverb.sty +1 -13
  153. data/vendor/jsclasses/kiyou.cls +22 -18
  154. data/vendor/jsclasses/minijs.sty +68 -22
  155. data/vendor/jsclasses/okumacro.ins +9 -0
  156. data/vendor/jsclasses/okumacro.pdf +0 -0
  157. data/vendor/jsclasses/okumacro.sty +1 -13
  158. data/vendor/jsclasses/okuverb.ins +9 -0
  159. data/vendor/jsclasses/okuverb.pdf +0 -0
  160. data/vendor/jsclasses/okuverb.sty +1 -13
  161. data/vendor/jsclasses/tests/relfont.tex +10 -0
  162. data/vendor/jsclasses/winjis.sty +23 -19
  163. metadata +14 -6
  164. data/.rubocop_todo.yml +0 -7
  165. data/lib/review/book/compilable.rb +0 -174
@@ -10,7 +10,11 @@
10
10
 
11
11
  require 'review/i18n'
12
12
  require 'review/template'
13
- require 'cgi'
13
+ begin
14
+ require 'cgi/escape'
15
+ rescue LoadError
16
+ require 'cgi/util'
17
+ end
14
18
 
15
19
  module EPUBMaker
16
20
  # EPUBCommon is the common class for EPUB producer.
@@ -22,6 +26,10 @@ module EPUBMaker
22
26
  @body_ext = nil
23
27
  end
24
28
 
29
+ def h(str)
30
+ CGI.escapeHTML(str)
31
+ end
32
+
25
33
  # Return mimetype content.
26
34
  def mimetype
27
35
  'application/epub+zip'
@@ -59,10 +67,10 @@ module EPUBMaker
59
67
  def ncx_doctitle
60
68
  <<EOT
61
69
  <docTitle>
62
- <text>#{CGI.escapeHTML(@producer.config['title'])}</text>
70
+ <text>#{h(@producer.config['title'])}</text>
63
71
  </docTitle>
64
72
  <docAuthor>
65
- <text>#{@producer.config['aut'].nil? ? '' : CGI.escapeHTML(join_with_separator(@producer.config['aut'], ReVIEW::I18n.t('names_splitter')))}</text>
73
+ <text>#{@producer.config['aut'].nil? ? '' : h(join_with_separator(@producer.config['aut'], ReVIEW::I18n.t('names_splitter')))}</text>
66
74
  </docAuthor>
67
75
  EOT
68
76
  end
@@ -72,7 +80,7 @@ EOT
72
80
  <navMap>
73
81
  <navPoint id="top" playOrder="1">
74
82
  <navLabel>
75
- <text>#{CGI.escapeHTML(@producer.config['title'])}</text>
83
+ <text>#{h(@producer.config['title'])}</text>
76
84
  </navLabel>
77
85
  <content src="#{@producer.config['cover']}"/>
78
86
  </navPoint>
@@ -84,7 +92,7 @@ EOT
84
92
  s << <<EOT
85
93
  <navPoint id="toc" playOrder="#{nav_count}">
86
94
  <navLabel>
87
- <text>#{CGI.escapeHTML(@producer.res.v('toctitle'))}</text>
95
+ <text>#{h(@producer.res.v('toctitle'))}</text>
88
96
  </navLabel>
89
97
  <content src="#{@producer.config['bookname']}-toc.#{@producer.config['htmlext']}"/>
90
98
  </navPoint>
@@ -100,7 +108,7 @@ EOT
100
108
  s << <<EOT
101
109
  <navPoint id="nav-#{nav_count}" playOrder="#{nav_count}">
102
110
  <navLabel>
103
- <text>#{indent[level]}#{CGI.escapeHTML(item.title)}</text>
111
+ <text>#{indent[level]}#{h(item.title)}</text>
104
112
  </navLabel>
105
113
  <content src="#{item.file}"/>
106
114
  </navPoint>
@@ -131,21 +139,21 @@ EOT
131
139
  raise "coverimage #{@producer.config['coverimage']} not found. Abort." unless file
132
140
  @body = <<-EOT
133
141
  <div id="cover-image" class="cover-image">
134
- <img src="#{file}" alt="#{CGI.escapeHTML(@producer.config.name_of('title'))}" class="max"/>
142
+ <img src="#{file}" alt="#{h(@producer.config.name_of('title'))}" class="max"/>
135
143
  </div>
136
144
  EOT
137
145
  else
138
146
  @body = <<-EOT
139
- <h1 class="cover-title">#{CGI.escapeHTML(@producer.config.name_of('title'))}</h1>
147
+ <h1 class="cover-title">#{h(@producer.config.name_of('title'))}</h1>
140
148
  EOT
141
149
  if @producer.config['subtitle']
142
150
  @body << <<-EOT
143
- <h2 class="cover-subtitle">#{CGI.escapeHTML(@producer.config.name_of('subtitle'))}</h2>
151
+ <h2 class="cover-subtitle">#{h(@producer.config.name_of('subtitle'))}</h2>
144
152
  EOT
145
153
  end
146
154
  end
147
155
 
148
- @title = CGI.escapeHTML(@producer.config.name_of('title'))
156
+ @title = h(@producer.config.name_of('title'))
149
157
  @language = @producer.config['language']
150
158
  @stylesheets = @producer.config['stylesheet']
151
159
  tmplfile = if @producer.config['htmlversion'].to_i == 5
@@ -161,7 +169,7 @@ EOT
161
169
  # NOTE: this method is not used yet.
162
170
  # see lib/review/epubmaker.rb#build_titlepage
163
171
  def titlepage
164
- @title = CGI.escapeHTML(@producer.config.name_of('title'))
172
+ @title = h(@producer.config.name_of('title'))
165
173
 
166
174
  @body = <<EOT
167
175
  <h1 class="tp-title">#{@title}</h1>
@@ -169,7 +177,7 @@ EOT
169
177
 
170
178
  if @producer.config['subtitle']
171
179
  @body << <<EOT
172
- <h2 class="tp-subtitle">#{CGI.escapeHTML(@producer.config.name_of('subtitle'))}</h2>
180
+ <h2 class="tp-subtitle">#{h(@producer.config.name_of('subtitle'))}</h2>
173
181
  EOT
174
182
  end
175
183
 
@@ -179,7 +187,7 @@ EOT
179
187
  <br />
180
188
  <br />
181
189
  </p>
182
- <h2 class="tp-author">#{CGI.escapeHTML(join_with_separator(@producer.config.names_of('aut'), ReVIEW::I18n.t('names_splitter')))}</h2>
190
+ <h2 class="tp-author">#{h(join_with_separator(@producer.config.names_of('aut'), ReVIEW::I18n.t('names_splitter')))}</h2>
183
191
  EOT
184
192
  end
185
193
 
@@ -192,7 +200,7 @@ EOT
192
200
  <br />
193
201
  <br />
194
202
  </p>
195
- <h3 class="tp-publisher">#{CGI.escapeHTML(join_with_separator(publisher, ReVIEW::I18n.t('names_splitter')))}</h3>
203
+ <h3 class="tp-publisher">#{h(join_with_separator(publisher, ReVIEW::I18n.t('names_splitter')))}</h3>
196
204
  EOT
197
205
  end
198
206
 
@@ -209,18 +217,18 @@ EOT
209
217
 
210
218
  # Return colophon content.
211
219
  def colophon
212
- @title = CGI.escapeHTML(@producer.res.v('colophontitle'))
220
+ @title = h(@producer.res.v('colophontitle'))
213
221
  @body = <<EOT
214
222
  <div class="colophon">
215
223
  EOT
216
224
 
217
225
  if @producer.config['subtitle'].nil?
218
226
  @body << <<EOT
219
- <p class="title">#{CGI.escapeHTML(@producer.config.name_of('title'))}</p>
227
+ <p class="title">#{h(@producer.config.name_of('title'))}</p>
220
228
  EOT
221
229
  else
222
230
  @body << <<EOT
223
- <p class="title">#{CGI.escapeHTML(@producer.config.name_of('title'))}<br /><span class="subtitle">#{CGI.escapeHTML(@producer.config.name_of('subtitle'))}</span></p>
231
+ <p class="title">#{h(@producer.config.name_of('title'))}<br /><span class="subtitle">#{h(@producer.config.name_of('subtitle'))}</span></p>
224
232
  EOT
225
233
  end
226
234
 
@@ -229,7 +237,7 @@ EOT
229
237
  @body << %Q( <table class="colophon">\n)
230
238
  @body << @producer.config['colophon_order'].map do |role|
231
239
  if @producer.config[role]
232
- %Q( <tr><th>#{CGI.escapeHTML(@producer.res.v(role))}</th><td>#{CGI.escapeHTML(join_with_separator(@producer.config.names_of(role), ReVIEW::I18n.t('names_splitter')))}</td></tr>\n)
240
+ %Q( <tr><th>#{h(@producer.res.v(role))}</th><td>#{h(join_with_separator(@producer.config.names_of(role), ReVIEW::I18n.t('names_splitter')))}</td></tr>\n)
233
241
  else
234
242
  ''
235
243
  end
@@ -238,7 +246,7 @@ EOT
238
246
  @body << %Q( <tr><th>ISBN</th><td>#{@producer.isbn_hyphen}</td></tr>\n) if @producer.isbn_hyphen
239
247
  @body << %Q( </table>\n)
240
248
  if @producer.config['rights'] && !@producer.config['rights'].empty?
241
- @body << %Q( <p class="copyright">#{join_with_separator(@producer.config.names_of('rights').map { |m| CGI.escapeHTML(m) }, '<br />')}</p>\n)
249
+ @body << %Q( <p class="copyright">#{join_with_separator(@producer.config.names_of('rights').map { |m| h(m) }, '<br />')}</p>\n)
242
250
  end
243
251
  @body << %Q( </div>\n)
244
252
 
@@ -261,11 +269,11 @@ EOT
261
269
  items.each_with_index do |item, rev|
262
270
  editstr = edit == 0 ? ReVIEW::I18n.t('first_edition') : ReVIEW::I18n.t('nth_edition', (edit + 1).to_s)
263
271
  revstr = ReVIEW::I18n.t('nth_impression', (rev + 1).to_s)
264
- if item =~ /\A\d+\-\d+\-\d+\Z/
272
+ if item =~ /\A\d+-\d+-\d+\Z/
265
273
  buf << %Q( <p>#{ReVIEW::I18n.t('published_by1', [date_to_s(item), editstr + revstr])}</p>\n)
266
- elsif item =~ /\A(\d+\-\d+\-\d+)[\s ](.+)/
274
+ elsif item =~ /\A(\d+-\d+-\d+)[\s ](.+)/
267
275
  # custom date with string
268
- item.match(/\A(\d+\-\d+\-\d+)[\s ](.+)/) do |m|
276
+ item.match(/\A(\d+-\d+-\d+)[\s ](.+)/) do |m|
269
277
  buf << %Q( <p>#{ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]])}</p>\n)
270
278
  end
271
279
  else
@@ -289,9 +297,9 @@ EOT
289
297
 
290
298
  # Return own toc content.
291
299
  def mytoc
292
- @title = CGI.escapeHTML(@producer.res.v('toctitle'))
300
+ @title = h(@producer.res.v('toctitle'))
293
301
 
294
- @body = %Q( <h1 class="toc-title">#{CGI.escapeHTML(@producer.res.v('toctitle'))}</h1>\n)
302
+ @body = %Q( <h1 class="toc-title">#{h(@producer.res.v('toctitle'))}</h1>\n)
295
303
  if @producer.config['epubmaker']['flattoc'].nil?
296
304
  @body << hierarchy_ncx('ul')
297
305
  else
@@ -385,7 +393,7 @@ EOT
385
393
  @producer.contents.each do |item|
386
394
  next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > @producer.config['toclevel'].to_i
387
395
  is = indent == true ? ' ' * item.level : ''
388
- s << %Q(<li><a href="#{item.file}">#{is}#{CGI.escapeHTML(item.title)}</a></li>\n)
396
+ s << %Q(<li><a href="#{item.file}">#{is}#{h(item.title)}</a></li>\n)
389
397
  end
390
398
  s << %Q(</#{type}>\n)
391
399
 
@@ -9,14 +9,13 @@
9
9
  #
10
10
 
11
11
  require 'epubmaker/epubcommon'
12
- require 'cgi'
13
12
  require 'epubmaker/zip_exporter'
14
13
 
15
14
  module EPUBMaker
16
15
  # EPUBv2 is EPUB version 2 producer.
17
16
  class EPUBv2 < EPUBCommon
18
17
  # Construct object with parameter hash +config+ and message resource hash +res+.
19
- def initialize(producer)
18
+ def initialize(producer) # rubocop:disable Lint/UselessMethodDefinition
20
19
  super
21
20
  end
22
21
 
@@ -37,9 +36,9 @@ module EPUBMaker
37
36
  %w[title language date type format source description relation coverage subject rights].each do |item|
38
37
  next unless @producer.config[item]
39
38
  if @producer.config[item].is_a?(Array)
40
- s << @producer.config.names_of(item).map { |i| %Q( <dc:#{item}>#{CGI.escapeHTML(i)}</dc:#{item}>\n) }.join
39
+ s << @producer.config.names_of(item).map { |i| %Q( <dc:#{item}>#{h(i)}</dc:#{item}>\n) }.join
41
40
  else
42
- s << %Q( <dc:#{item}>#{CGI.escapeHTML(@producer.config.name_of(item).to_s)}</dc:#{item}>\n)
41
+ s << %Q( <dc:#{item}>#{h(@producer.config.name_of(item).to_s)}</dc:#{item}>\n)
43
42
  end
44
43
  end
45
44
 
@@ -54,7 +53,7 @@ module EPUBMaker
54
53
  %w[aut a-adp a-ann a-arr a-art a-asn a-aqt a-aft a-aui a-ant a-bkp a-clb a-cmm a-dsr a-edt a-ill a-lyr a-mdc a-mus a-nrt a-oth a-pht a-prt a-red a-rev a-spn a-ths a-trc a-trl].each do |role|
55
54
  next unless @producer.config[role]
56
55
  @producer.config.names_of(role).each do |v|
57
- s << %Q( <dc:creator opf:role="#{role.sub('a-', '')}">#{CGI.escapeHTML(v)}</dc:creator>\n)
56
+ s << %Q( <dc:creator opf:role="#{role.sub('a-', '')}">#{h(v)}</dc:creator>\n)
58
57
  end
59
58
  end
60
59
 
@@ -62,7 +61,7 @@ module EPUBMaker
62
61
  %w[adp ann arr art asn aqt aft aui ant bkp clb cmm dsr edt ill lyr mdc mus nrt oth pht prt red rev spn ths trc trl].each do |role|
63
62
  next unless @producer.config[role]
64
63
  @producer.config.names_of(role).each do |v|
65
- s << %Q( <dc:contributor opf:role="#{role}">#{CGI.escapeHTML(v)}</dc:contributor>\n)
64
+ s << %Q( <dc:contributor opf:role="#{role}">#{h(v)}</dc:contributor>\n)
66
65
  if role == 'prt'
67
66
  s << %Q( <dc:publisher>#{v}</dc:publisher>\n)
68
67
  end
@@ -40,6 +40,7 @@ module EPUBMaker
40
40
  ReVIEW::Template.load(tmplfile).result(binding)
41
41
  end
42
42
 
43
+ # rubocop:disable Metrics/PerceivedComplexity
43
44
  def opf_metainfo
44
45
  s = ''
45
46
  %w[title language date type format source description relation coverage subject rights].each do |item|
@@ -47,23 +48,23 @@ module EPUBMaker
47
48
  if @producer.config[item].is_a?(Array)
48
49
  @producer.config[item].each_with_index do |v, i|
49
50
  if v.is_a?(Hash)
50
- s << %Q( <dc:#{item} id="#{item}-#{i}">#{CGI.escapeHTML(v['name'])}</dc:#{item}>\n)
51
+ s << %Q( <dc:#{item} id="#{item}-#{i}">#{h(v['name'])}</dc:#{item}>\n)
51
52
  v.each_pair do |name, val|
52
53
  next if name == 'name'
53
- s << %Q( <meta refines="##{item}-#{i}" property="#{name}">#{CGI.escapeHTML(val)}</meta>\n)
54
+ s << %Q( <meta refines="##{item}-#{i}" property="#{name}">#{h(val)}</meta>\n)
54
55
  end
55
56
  else
56
- s << %Q( <dc:#{item} id="#{item}-#{i}">#{CGI.escapeHTML(v.to_s)}</dc:#{item}>\n)
57
+ s << %Q( <dc:#{item} id="#{item}-#{i}">#{h(v.to_s)}</dc:#{item}>\n)
57
58
  end
58
59
  end
59
60
  elsif @producer.config[item].is_a?(Hash)
60
- s << %Q( <dc:#{item} id="#{item}">#{CGI.escapeHTML(@producer.config[item]['name'])}</dc:#{item}>\n)
61
+ s << %Q( <dc:#{item} id="#{item}">#{h(@producer.config[item]['name'])}</dc:#{item}>\n)
61
62
  @producer.config[item].each_pair do |name, val|
62
63
  next if name == 'name'
63
- s << %Q( <meta refines="##{item}" property="#{name}">#{CGI.escapeHTML(val)}</meta>\n)
64
+ s << %Q( <meta refines="##{item}" property="#{name}">#{h(val)}</meta>\n)
64
65
  end
65
66
  else
66
- s << %Q( <dc:#{item} id="#{item}">#{CGI.escapeHTML(@producer.config[item].to_s)}</dc:#{item}>\n)
67
+ s << %Q( <dc:#{item} id="#{item}">#{h(@producer.config[item].to_s)}</dc:#{item}>\n)
67
68
  end
68
69
  end
69
70
 
@@ -81,14 +82,14 @@ module EPUBMaker
81
82
  next unless @producer.config[role]
82
83
  @producer.config[role].each_with_index do |v, i|
83
84
  if v.is_a?(Hash)
84
- s << %Q( <dc:creator id="#{role}-#{i}">#{CGI.escapeHTML(v['name'])}</dc:creator>\n)
85
+ s << %Q( <dc:creator id="#{role}-#{i}">#{h(v['name'])}</dc:creator>\n)
85
86
  s << %Q( <meta refines="##{role}-#{i}" property="role" scheme="marc:relators">#{role.sub('a-', '')}</meta>\n)
86
87
  v.each_pair do |name, val|
87
88
  next if name == 'name'
88
- s << %Q( <meta refines="##{role.sub('a-', '')}-#{i}" property="#{name}">#{CGI.escapeHTML(val)}</meta>\n)
89
+ s << %Q( <meta refines="##{role.sub('a-', '')}-#{i}" property="#{name}">#{h(val)}</meta>\n)
89
90
  end
90
91
  else
91
- s << %Q( <dc:creator id="#{role}-#{i}">#{CGI.escapeHTML(v)}</dc:creator>\n)
92
+ s << %Q( <dc:creator id="#{role}-#{i}">#{h(v)}</dc:creator>\n)
92
93
  s << %Q( <meta refines="##{role}-#{i}" property="role" scheme="marc:relators">#{role.sub('a-', '')}</meta>\n)
93
94
  end
94
95
  end
@@ -99,27 +100,27 @@ module EPUBMaker
99
100
  next unless @producer.config[role]
100
101
  @producer.config[role].each_with_index do |v, i|
101
102
  if v.is_a?(Hash)
102
- s << %Q( <dc:contributor id="#{role}-#{i}">#{CGI.escapeHTML(v['name'])}</dc:contributor>\n)
103
+ s << %Q( <dc:contributor id="#{role}-#{i}">#{h(v['name'])}</dc:contributor>\n)
103
104
  s << %Q( <meta refines="##{role}-#{i}" property="role" scheme="marc:relators">#{role}</meta>\n)
104
105
  v.each_pair do |name, val|
105
106
  next if name == 'name'
106
- s << %Q( <meta refines="##{role}-#{i}" property="#{name}">#{CGI.escapeHTML(val)}</meta>\n)
107
+ s << %Q( <meta refines="##{role}-#{i}" property="#{name}">#{h(val)}</meta>\n)
107
108
  end
108
109
  else
109
- s << %Q( <dc:contributor id="#{role}-#{i}">#{CGI.escapeHTML(v)}</dc:contributor>\n)
110
+ s << %Q( <dc:contributor id="#{role}-#{i}">#{h(v)}</dc:contributor>\n)
110
111
  s << %Q( <meta refines="##{role}-#{i}" property="role" scheme="marc:relators">#{role}</meta>\n)
111
112
  end
112
113
 
113
114
  if %w[prt pbl].include?(role)
114
115
  if v.is_a?(Hash)
115
- s << %Q( <dc:publisher id="pub-#{role}-#{i}">#{CGI.escapeHTML(v['name'])}</dc:publisher>\n)
116
+ s << %Q( <dc:publisher id="pub-#{role}-#{i}">#{h(v['name'])}</dc:publisher>\n)
116
117
  s << %Q( <meta refines="#pub-#{role}-#{i}" property="role" scheme="marc:relators">#{role}</meta>\n)
117
118
  v.each_pair do |name, val|
118
119
  next if name == 'name'
119
- s << %Q( <meta refines="#pub-#{role}-#{i}" property="#{name}">#{CGI.escapeHTML(val)}</meta>\n)
120
+ s << %Q( <meta refines="#pub-#{role}-#{i}" property="#{name}">#{h(val)}</meta>\n)
120
121
  end
121
122
  else
122
- s << %Q( <dc:publisher id="pub-#{role}-#{i}">#{CGI.escapeHTML(v)}</dc:publisher>\n)
123
+ s << %Q( <dc:publisher id="pub-#{role}-#{i}">#{h(v)}</dc:publisher>\n)
123
124
  s << %Q( <meta refines="#pub-#{role}-#{i}" property="role" scheme="marc:relators">prt</meta>\n)
124
125
  end
125
126
  end
@@ -129,12 +130,13 @@ module EPUBMaker
129
130
  ## add custom <meta> element
130
131
  if @producer.config['opf_meta'].present?
131
132
  @producer.config['opf_meta'].each do |k, v|
132
- s << %Q( <meta property="#{k}">#{CGI.escapeHTML(v)}</meta>\n)
133
+ s << %Q( <meta property="#{k}">#{h(v)}</meta>\n)
133
134
  end
134
135
  end
135
136
 
136
137
  s
137
138
  end
139
+ # rubocop:enable Metrics/PerceivedComplexity
138
140
 
139
141
  def opf_manifest
140
142
  s = ''
@@ -206,11 +208,11 @@ EOT
206
208
 
207
209
  @body = <<EOT
208
210
  <nav xmlns:epub="http://www.idpf.org/2007/ops" epub:type="toc" id="toc">
209
- <h1 class="toc-title">#{CGI.escapeHTML(@producer.res.v('toctitle'))}</h1>
211
+ <h1 class="toc-title">#{h(@producer.res.v('toctitle'))}</h1>
210
212
  #{ncx_main} </nav>
211
213
  EOT
212
214
 
213
- @title = CGI.escapeHTML(@producer.res.v('toctitle'))
215
+ @title = h(@producer.res.v('toctitle'))
214
216
  @language = @producer.config['language']
215
217
  @stylesheets = @producer.config['stylesheet']
216
218
  tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
@@ -18,8 +18,8 @@ require 'review/book/index'
18
18
 
19
19
  module ReVIEW
20
20
  module Book
21
- def self.load(dir)
22
- Base.load(dir)
21
+ def self.load(_dir)
22
+ raise NotImplementedError, 'ReVIEW::Book.load is obsoleted. Please use ReVIEW::Book::Base.new.'
23
23
  end
24
24
  end
25
25
  end
@@ -9,26 +9,34 @@
9
9
  #
10
10
  require 'review/configure'
11
11
  require 'review/catalog'
12
+ require 'review/book/bib'
12
13
 
13
14
  module ReVIEW
14
15
  module Book
15
16
  class Base
16
17
  attr_accessor :config
17
18
  attr_writer :parts
18
- attr_writer :catalog
19
+ attr_accessor :catalog
19
20
  attr_reader :basedir
21
+ attr_accessor :bibpaper_index
20
22
 
21
- def self.load(dir = '.')
22
- new(dir)
23
+ def self.load(basedir = '.', config: nil)
24
+ new(basedir, config: config)
23
25
  end
24
26
 
25
- def initialize(basedir = '.')
27
+ def initialize(basedir = '.', config: nil)
26
28
  @basedir = basedir
27
29
  @logger = ReVIEW.logger
28
30
  @parts = nil
29
31
  @chapter_index = nil
30
- @config = ReVIEW::Configure.values
32
+ @config = config || ReVIEW::Configure.values
31
33
  @catalog = nil
34
+ @bibpaper_index = nil
35
+ catalog_path = filename_join(@basedir, @config['catalogfile'])
36
+ if catalog_path && File.file?(catalog_path)
37
+ parse_catalog_file(catalog_path)
38
+ end
39
+
32
40
  @warn_old_files = {} # XXX for checking CHAPS, PREDEF, POSTDEF
33
41
  @basedir_seen = {}
34
42
  update_rubyenv
@@ -44,6 +52,14 @@ module ReVIEW
44
52
  end
45
53
  end
46
54
 
55
+ def execute_indexer
56
+ return unless @catalog
57
+
58
+ parts.each do |part|
59
+ part.chapters.each(&:execute_indexer)
60
+ end
61
+ end
62
+
47
63
  def bib_file
48
64
  config['bib_file']
49
65
  end
@@ -94,6 +110,30 @@ module ReVIEW
94
110
  end
95
111
  end
96
112
 
113
+ def create_chapter_index
114
+ chapter_index = ChapterIndex.new
115
+ each_chapter do |chap|
116
+ chapter_index.add_item(Index::Item.new(chap.id, chap.number, chap))
117
+ end
118
+ parts.each do |prt|
119
+ if prt.id.present?
120
+ chapter_index.add_item(Index::Item.new(prt.id, prt.number, prt))
121
+ end
122
+ end
123
+ chapter_index
124
+ end
125
+
126
+ def generate_indexes
127
+ if bib_exist?
128
+ bib = ReVIEW::Book::Bib.new(file_content: bib_content, book: self)
129
+ bib.generate_indexes(use_bib: true)
130
+ @bibpaper_index = bib.bibpaper_index
131
+ end
132
+ self.each_chapter(&:generate_indexes)
133
+ self.parts.map(&:generate_indexes)
134
+ @chapter_index = create_chapter_index
135
+ end
136
+
97
137
  def parts
98
138
  @parts ||= read_parts
99
139
  end
@@ -101,7 +141,7 @@ module ReVIEW
101
141
  def parts_in_file
102
142
  # TODO: should be `parts.find_all{|part| part.present? and part.file?}` ?
103
143
  parts.find_all do |part|
104
- part if part.present? and part.file?
144
+ part if part.present? && part.file?
105
145
  end
106
146
  end
107
147
 
@@ -136,15 +176,7 @@ module ReVIEW
136
176
 
137
177
  def chapter_index
138
178
  return @chapter_index if @chapter_index
139
- @chapter_index = ChapterIndex.new
140
- each_chapter do |chap|
141
- @chapter_index.add_item(Index::Item.new(chap.id, chap.number, chap))
142
- end
143
- parts.each do |prt|
144
- if prt.id.present?
145
- @chapter_index.add_item(Index::Item.new(prt.id, prt.number, prt))
146
- end
147
- end
179
+ @chapter_index = create_chapter_index
148
180
  @chapter_index
149
181
  end
150
182
 
@@ -183,17 +215,15 @@ module ReVIEW
183
215
  @config.merge!(new_conf)
184
216
  end
185
217
 
186
- def catalog
187
- return @catalog if @catalog.present?
188
-
189
- catalogfile_path = filename_join(@basedir, config['catalogfile'])
190
- if File.file?(catalogfile_path)
191
- @catalog = File.open(catalogfile_path, 'rt:BOM|utf-8') { |f| Catalog.new(f) }
218
+ def parse_catalog_file(path)
219
+ unless File.file?(path)
220
+ raise FileNotFound, "catalog.yml is not found #{path}"
192
221
  end
193
- if @catalog
222
+
223
+ File.open(path, 'rt:BOM|utf-8') do |f|
224
+ @catalog = Catalog.new(f)
194
225
  @catalog.validate!(@config, basedir)
195
226
  end
196
- @catalog
197
227
  end
198
228
 
199
229
  def read_chaps
@@ -252,6 +282,10 @@ module ReVIEW
252
282
  File.exist?(File.join(contentdir, bib_file))
253
283
  end
254
284
 
285
+ def bib_content
286
+ File.read(File.join(contentdir, bib_file))
287
+ end
288
+
255
289
  def prefaces
256
290
  if catalog
257
291
  return Part.mkpart_from_namelist(self, catalog.predef)
@@ -333,8 +367,8 @@ module ReVIEW
333
367
  end
334
368
  end
335
369
 
336
- chap = read_chaps.map(&:strip).join("\n").split(/\n{2,}/).
337
- map do |part_chunk|
370
+ # rubocop:disable Style/RedundantAssignment
371
+ chap = read_chaps.map(&:strip).join("\n").split(/\n{2,}/).map do |part_chunk|
338
372
  chaps = part_chunk.split.map { |chapid| Chapter.new(self, num += 1, chapid, File.join(contentdir, chapid)) }
339
373
  if part_exist? && read_part.size > part
340
374
  Part.new(self, part += 1, chaps, read_part[part - 1])
@@ -342,6 +376,8 @@ module ReVIEW
342
376
  Part.new(self, nil, chaps)
343
377
  end
344
378
  end
379
+ # rubocop:enable Style/RedundantAssignment
380
+
345
381
  chap
346
382
  end
347
383