review-peg 0.1.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 (174) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rubocop.yml +47 -0
  4. data/.rubocop_todo.yml +605 -0
  5. data/.travis.yml +18 -0
  6. data/COPYING +515 -0
  7. data/ChangeLog +2449 -0
  8. data/Dockerfile +22 -0
  9. data/Gemfile +6 -0
  10. data/README.rdoc +81 -0
  11. data/Rakefile +51 -0
  12. data/bin/review-catalog-converter-peg +129 -0
  13. data/bin/review-check-peg +169 -0
  14. data/bin/review-checkdep-peg +63 -0
  15. data/bin/review-compile-peg +202 -0
  16. data/bin/review-epubmaker-legacy-peg +1024 -0
  17. data/bin/review-epubmaker-peg +44 -0
  18. data/bin/review-index-peg +110 -0
  19. data/bin/review-init-peg +151 -0
  20. data/bin/review-pdfmaker-peg +18 -0
  21. data/bin/review-preproc-peg +131 -0
  22. data/bin/review-validate-peg +51 -0
  23. data/bin/review-vol-peg +100 -0
  24. data/debian/README.Debian +12 -0
  25. data/debian/README.source +5 -0
  26. data/debian/changelog +5 -0
  27. data/debian/compat +1 -0
  28. data/debian/control +22 -0
  29. data/debian/copyright +62 -0
  30. data/debian/docs +6 -0
  31. data/debian/manpage.1.ex +59 -0
  32. data/debian/patches/path.diff +91 -0
  33. data/debian/patches/series +1 -0
  34. data/debian/review.install +13 -0
  35. data/debian/review.links +4 -0
  36. data/debian/rules +13 -0
  37. data/debian/source/format +1 -0
  38. data/doc/NEWS.ja.md +350 -0
  39. data/doc/NEWS.md +354 -0
  40. data/doc/catalog.ja.md +53 -0
  41. data/doc/catalog.md +52 -0
  42. data/doc/format.ja.md +734 -0
  43. data/doc/format.md +746 -0
  44. data/doc/format_idg.ja.md +203 -0
  45. data/doc/quickstart.ja.md +222 -0
  46. data/doc/quickstart.md +252 -0
  47. data/doc/ruby-uuid/README +11 -0
  48. data/doc/ruby-uuid/README.ja +34 -0
  49. data/doc/sample.css +108 -0
  50. data/doc/sample.yml +238 -0
  51. data/lib/epubmaker.rb +24 -0
  52. data/lib/epubmaker/content.rb +93 -0
  53. data/lib/epubmaker/epubcommon.rb +424 -0
  54. data/lib/epubmaker/epubv2.rb +139 -0
  55. data/lib/epubmaker/epubv3.rb +222 -0
  56. data/lib/epubmaker/producer.rb +330 -0
  57. data/lib/lineinput.rb +107 -0
  58. data/lib/review.rb +3 -0
  59. data/lib/review/book.rb +43 -0
  60. data/lib/review/book/base.rb +401 -0
  61. data/lib/review/book/chapter.rb +100 -0
  62. data/lib/review/book/compilable.rb +184 -0
  63. data/lib/review/book/image_finder.rb +71 -0
  64. data/lib/review/book/index.rb +413 -0
  65. data/lib/review/book/page_metric.rb +47 -0
  66. data/lib/review/book/part.rb +54 -0
  67. data/lib/review/book/volume.rb +67 -0
  68. data/lib/review/builder.rb +452 -0
  69. data/lib/review/catalog.rb +52 -0
  70. data/lib/review/compiler.rb +5183 -0
  71. data/lib/review/compiler/literals_1_9.kpeg +22 -0
  72. data/lib/review/compiler/literals_1_9.rb +435 -0
  73. data/lib/review/configure.rb +64 -0
  74. data/lib/review/epubbuilder.rb +18 -0
  75. data/lib/review/epubmaker.rb +480 -0
  76. data/lib/review/ewbbuilder.rb +381 -0
  77. data/lib/review/exception.rb +21 -0
  78. data/lib/review/extentions.rb +4 -0
  79. data/lib/review/extentions/array.rb +25 -0
  80. data/lib/review/extentions/object.rb +9 -0
  81. data/lib/review/extentions/string.rb +33 -0
  82. data/lib/review/htmlbuilder.rb +1166 -0
  83. data/lib/review/htmllayout.rb +41 -0
  84. data/lib/review/htmltoc.rb +45 -0
  85. data/lib/review/htmlutils.rb +90 -0
  86. data/lib/review/i18n.rb +96 -0
  87. data/lib/review/i18n.yml +169 -0
  88. data/lib/review/idgxmlbuilder.rb +1233 -0
  89. data/lib/review/inaobuilder.rb +357 -0
  90. data/lib/review/latexbuilder.rb +941 -0
  91. data/lib/review/latexindex.rb +35 -0
  92. data/lib/review/latexutils.rb +95 -0
  93. data/lib/review/layout.tex.erb +340 -0
  94. data/lib/review/lineinput.rb +17 -0
  95. data/lib/review/location.rb +24 -0
  96. data/lib/review/makerhelper.rb +67 -0
  97. data/lib/review/markdownbuilder.rb +339 -0
  98. data/lib/review/node.rb +288 -0
  99. data/lib/review/pdfmaker.rb +332 -0
  100. data/lib/review/preprocessor.rb +530 -0
  101. data/lib/review/review.kpeg +745 -0
  102. data/lib/review/sec_counter.rb +69 -0
  103. data/lib/review/template.rb +21 -0
  104. data/lib/review/textbuilder.rb +17 -0
  105. data/lib/review/textutils.rb +16 -0
  106. data/lib/review/tocparser.rb +348 -0
  107. data/lib/review/tocprinter.rb +205 -0
  108. data/lib/review/topbuilder.rb +796 -0
  109. data/lib/review/unfold.rb +138 -0
  110. data/lib/review/version.rb +3 -0
  111. data/lib/uuid.rb +312 -0
  112. data/review.gemspec +32 -0
  113. data/templates/html/layout-html5.html.erb +17 -0
  114. data/templates/html/layout-xhtml1.html.erb +20 -0
  115. data/templates/ncx/epubv2.ncx.erb +11 -0
  116. data/templates/opf/epubv2.opf.erb +21 -0
  117. data/templates/opf/epubv3.opf.erb +18 -0
  118. data/templates/xml/container.xml.erb +6 -0
  119. data/test/CHAPS +2 -0
  120. data/test/assets/test.xml.erb +3 -0
  121. data/test/assets/test_template.tex +255 -0
  122. data/test/assets/test_template_backmatter.tex +32 -0
  123. data/test/bib.re +13 -0
  124. data/test/book_test_helper.rb +35 -0
  125. data/test/sample-book/README.md +7 -0
  126. data/test/sample-book/src/Rakefile +58 -0
  127. data/test/sample-book/src/_cover.html +3 -0
  128. data/test/sample-book/src/catalog.yml +10 -0
  129. data/test/sample-book/src/ch01.re +71 -0
  130. data/test/sample-book/src/ch02.re +3 -0
  131. data/test/sample-book/src/config.yml +186 -0
  132. data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
  133. data/test/sample-book/src/images/cover.jpg +0 -0
  134. data/test/sample-book/src/preface.re +15 -0
  135. data/test/sample-book/src/sty/jumoline.sty +310 -0
  136. data/test/sample-book/src/sty/reviewmacro.sty +39 -0
  137. data/test/sample-book/src/style.css +251 -0
  138. data/test/sample-book/src/vendor/jumoline/README +29 -0
  139. data/test/sample-book/src/vendor/jumoline/jumoline.dtx +2988 -0
  140. data/test/sample-book/src/vendor/jumoline/jumoline.ins +6 -0
  141. data/test/test.re +43 -0
  142. data/test/test_book.rb +556 -0
  143. data/test/test_book_chapter.rb +280 -0
  144. data/test/test_book_part.rb +54 -0
  145. data/test/test_builder.rb +80 -0
  146. data/test/test_catalog.rb +119 -0
  147. data/test/test_catalog_converter_cmd.rb +73 -0
  148. data/test/test_compiler.rb +92 -0
  149. data/test/test_configure.rb +50 -0
  150. data/test/test_epub3maker.rb +529 -0
  151. data/test/test_epubmaker.rb +569 -0
  152. data/test/test_epubmaker_cmd.rb +40 -0
  153. data/test/test_helper.rb +92 -0
  154. data/test/test_htmlbuilder.rb +1114 -0
  155. data/test/test_htmltoc.rb +32 -0
  156. data/test/test_htmlutils.rb +50 -0
  157. data/test/test_i18n.rb +180 -0
  158. data/test/test_idgxmlbuilder.rb +608 -0
  159. data/test/test_image_finder.rb +82 -0
  160. data/test/test_inaobuilder.rb +245 -0
  161. data/test/test_index.rb +174 -0
  162. data/test/test_latexbuilder.rb +732 -0
  163. data/test/test_lineinput.rb +182 -0
  164. data/test/test_makerhelper.rb +66 -0
  165. data/test/test_markdownbuilder.rb +125 -0
  166. data/test/test_pdfmaker.rb +171 -0
  167. data/test/test_pdfmaker_cmd.rb +40 -0
  168. data/test/test_preprocessor.rb +23 -0
  169. data/test/test_review_ext.rb +31 -0
  170. data/test/test_template.rb +26 -0
  171. data/test/test_textutils.rb +32 -0
  172. data/test/test_topbuilder.rb +291 -0
  173. data/test/test_uuid.rb +157 -0
  174. metadata +357 -0
@@ -0,0 +1,1166 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (c) 2002-2007 Minero Aoki
4
+ # 2008-2014 Minero Aoki, Kenshi Muto, Masayoshi Takahashi,
5
+ # KADO Masanori
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ #
11
+
12
+ require 'review/builder'
13
+ require 'review/htmlutils'
14
+ require 'review/htmllayout'
15
+ require 'review/textutils'
16
+
17
+ module ReVIEW
18
+
19
+ class HTMLBuilder < Builder
20
+
21
+ include TextUtils
22
+ include HTMLUtils
23
+
24
+ [:ref].each {|e| Compiler.definline(e) }
25
+ Compiler.defblock(:memo, 0..1)
26
+ Compiler.defblock(:tip, 0..1)
27
+ Compiler.defblock(:info, 0..1)
28
+ Compiler.defblock(:planning, 0..1)
29
+ Compiler.defblock(:best, 0..1)
30
+ Compiler.defblock(:important, 0..1)
31
+ Compiler.defblock(:security, 0..1)
32
+ Compiler.defblock(:caution, 0..1)
33
+ Compiler.defblock(:notice, 0..1)
34
+ Compiler.defblock(:point, 0..1)
35
+ Compiler.defblock(:shoot, 0..1)
36
+
37
+ def extname
38
+ ".#{@book.config["htmlext"]}"
39
+ end
40
+
41
+ def builder_init(no_error = false)
42
+ @no_error = no_error
43
+ @noindent = nil
44
+ @ol_num = nil
45
+ end
46
+ private :builder_init
47
+
48
+ def builder_init_file
49
+ @warns = []
50
+ @errors = []
51
+ @chapter.book.image_types = %w( .png .jpg .jpeg .gif .svg )
52
+ @column = 0
53
+ @sec_counter = SecCounter.new(5, @chapter)
54
+ end
55
+ private :builder_init_file
56
+
57
+ def result
58
+ layout_file = File.join(@book.basedir, "layouts", "layout.html.erb")
59
+ unless File.exist?(layout_file) # backward compatibility
60
+ layout_file = File.join(@book.basedir, "layouts", "layout.erb")
61
+ end
62
+ if File.exist?(layout_file)
63
+ if ENV["REVIEW_SAFE_MODE"].to_i & 4 > 0
64
+ warn "user's layout is prohibited in safe mode. ignored."
65
+ else
66
+ title = strip_html(@chapter.title)
67
+
68
+ toc = ""
69
+ toc_level = 0
70
+ @chapter.headline_index.items.each do |i|
71
+ caption = "<li>#{strip_html(i.caption)}</li>\n"
72
+ if toc_level == i.number.size
73
+ # do nothing
74
+ elsif toc_level < i.number.size
75
+ toc += "<ul>\n" * (i.number.size - toc_level)
76
+ toc_level = i.number.size
77
+ elsif toc_level > i.number.size
78
+ toc += "</ul>\n" * (toc_level - i.number.size)
79
+ toc_level = i.number.size
80
+ toc += "<ul>\n" * (toc_level - 1)
81
+ end
82
+ toc += caption
83
+ end
84
+ toc += "</ul>" * toc_level
85
+
86
+ return messages() +
87
+ HTMLLayout.new(
88
+ {'body' => @output.string, 'title' => title, 'toc' => toc,
89
+ 'builder' => self,
90
+ 'next' => @chapter.next_chapter,
91
+ 'prev' => @chapter.prev_chapter},
92
+ layout_file).result
93
+ end
94
+ end
95
+
96
+ # default XHTML header/footer
97
+ @error_messages = error_messages
98
+ @warning_messages = warning_messages
99
+ @title = strip_html(@chapter.title)
100
+ @body = @output.string
101
+ @language = @book.config['language']
102
+ @stylesheets = @book.config["stylesheet"]
103
+
104
+ if @book.htmlversion == 5
105
+ htmlfilename = "layout-html5.html.erb"
106
+ else
107
+ htmlfilename = "layout-xhtml1.html.erb"
108
+ end
109
+ tmplfile = File.expand_path('./html/'+htmlfilename, ReVIEW::Template::TEMPLATE_DIR)
110
+ tmpl = ReVIEW::Template.load(tmplfile)
111
+ tmpl.result(binding)
112
+ end
113
+
114
+ def xmlns_ops_prefix
115
+ if @book.config["epubversion"].to_i == 3
116
+ "epub"
117
+ else
118
+ "ops"
119
+ end
120
+ end
121
+
122
+ def warn(msg)
123
+ if @no_error
124
+ @warns.push [@location.filename, @location.lineno, msg]
125
+ puts "----WARNING: #{escape_html(msg)}----"
126
+ else
127
+ $stderr.puts "#{@location}: warning: #{msg}"
128
+ end
129
+ end
130
+
131
+ def error(msg)
132
+ if @no_error
133
+ @errors.push [@location.filename, @location.lineno, msg]
134
+ puts "----ERROR: #{escape_html(msg)}----"
135
+ else
136
+ $stderr.puts "#{@location}: error: #{msg}"
137
+ end
138
+ end
139
+
140
+ def messages
141
+ error_messages() + warning_messages()
142
+ end
143
+
144
+ def error_messages
145
+ return '' if @errors.empty?
146
+ "<h2>Syntax Errors</h2>\n" +
147
+ "<ul>\n" +
148
+ @errors.map {|file, line, msg|
149
+ "<li>#{escape_html(file)}:#{line}: #{escape_html(msg.to_s)}</li>\n"
150
+ }.join('') +
151
+ "</ul>\n"
152
+ end
153
+
154
+ def warning_messages
155
+ return '' if @warns.empty?
156
+ "<h2>Warnings</h2>\n" +
157
+ "<ul>\n" +
158
+ @warns.map {|file, line, msg|
159
+ "<li>#{escape_html(file)}:#{line}: #{escape_html(msg)}</li>\n"
160
+ }.join('') +
161
+ "</ul>\n"
162
+ end
163
+
164
+ def headline(level, label, caption)
165
+ buf = ""
166
+ prefix, anchor = headline_prefix(level)
167
+ unless prefix.nil?
168
+ prefix = %Q[<span class="secno">#{prefix}</span>]
169
+ end
170
+ a_id = ""
171
+ unless anchor.nil?
172
+ a_id = %Q[<a id="h#{anchor}"></a>]
173
+ end
174
+ if caption.empty?
175
+ buf << a_id+"\n" unless label.nil?
176
+ else
177
+ if label.nil?
178
+ buf << %Q[<h#{level}>#{a_id}#{prefix}#{caption}</h#{level}>\n]
179
+ else
180
+ buf << %Q[<h#{level} id="#{normalize_id(label)}">#{a_id}#{prefix}#{caption}</h#{level}>\n]
181
+ end
182
+ end
183
+ buf
184
+ end
185
+
186
+ def nonum_begin(level, label, caption)
187
+ buf = ""
188
+ buf << "\n" if level > 1
189
+ unless caption.empty?
190
+ if label.nil?
191
+ buf << %Q[<h#{level}>#{caption}</h#{level}>\n]
192
+ else
193
+ buf << %Q[<h#{level} id="#{normalize_id(label)}">#{caption}</h#{level}>\n]
194
+ end
195
+ end
196
+ buf
197
+ end
198
+
199
+ def nonum_end(level)
200
+ end
201
+
202
+ def column_begin(level, label, caption)
203
+ buf = %Q[<div class="column">\n]
204
+
205
+ @column += 1
206
+ buf << "\n" if level > 1
207
+ a_id = %Q[<a id="column-#{@column}"></a>]
208
+
209
+ if caption.empty?
210
+ buf << a_id + "\n" unless label.nil?
211
+ else
212
+ if label.nil?
213
+ buf << %Q[<h#{level}>#{a_id}#{caption}</h#{level}>\n]
214
+ else
215
+ buf << %Q[<h#{level} id="#{normalize_id(label)}">#{a_id}#{caption}</h#{level}>\n]
216
+ end
217
+ end
218
+ buf
219
+ end
220
+
221
+ def column_end(level)
222
+ "</div>\n"
223
+ end
224
+
225
+ def xcolumn_begin(level, label, caption)
226
+ buf << %Q[<div class="xcolumn">\n]
227
+ buf << headline(level, label, caption)
228
+ buf
229
+ end
230
+
231
+ def xcolumn_end(level)
232
+ "</div>\n"
233
+ end
234
+
235
+ def ref_begin(level, label, caption)
236
+ buf << %Q[<div class="reference">\n]
237
+ buf << headline(level, label, caption)
238
+ buf
239
+ end
240
+
241
+ def ref_end(level)
242
+ "</div>\n"
243
+ end
244
+
245
+ def sup_begin(level, label, caption)
246
+ buf << %Q[<div class="supplement">\n]
247
+ buf << headline(level, label, caption)
248
+ buf
249
+ end
250
+
251
+ def sup_end(level)
252
+ "</div>\n"
253
+ end
254
+
255
+ def tsize(str)
256
+ # null
257
+ end
258
+
259
+ def captionblock(type, lines, caption)
260
+ buf = %Q[<div class="#{type}">\n]
261
+ unless caption.nil?
262
+ buf << %Q[<p class="caption">#{caption}</p>\n]
263
+ end
264
+ if @book.config["deprecated-blocklines"].nil?
265
+ buf << lines.join("")
266
+ else
267
+ error "deprecated-blocklines is obsoleted."
268
+ end
269
+ buf << "</div>\n"
270
+ buf
271
+ end
272
+
273
+ def memo(lines, caption = nil)
274
+ captionblock("memo", lines, caption)
275
+ end
276
+
277
+ def tip(lines, caption = nil)
278
+ captionblock("tip", lines, caption)
279
+ end
280
+
281
+ def info(lines, caption = nil)
282
+ captionblock("info", lines, caption)
283
+ end
284
+
285
+ def planning(lines, caption = nil)
286
+ captionblock("planning", lines, caption)
287
+ end
288
+
289
+ def best(lines, caption = nil)
290
+ captionblock("best", lines, caption)
291
+ end
292
+
293
+ def important(lines, caption = nil)
294
+ captionblock("important", lines, caption)
295
+ end
296
+
297
+ def security(lines, caption = nil)
298
+ captionblock("security", lines, caption)
299
+ end
300
+
301
+ def caution(lines, caption = nil)
302
+ captionblock("caution", lines, caption)
303
+ end
304
+
305
+ def notice(lines, caption = nil)
306
+ captionblock("notice", lines, caption)
307
+ end
308
+
309
+ def point(lines, caption = nil)
310
+ captionblock("point", lines, caption)
311
+ end
312
+
313
+ def shoot(lines, caption = nil)
314
+ captionblock("shoot", lines, caption)
315
+ end
316
+
317
+ def box(lines, caption = nil)
318
+ buf = ""
319
+ buf << %Q[<div class="syntax">\n]
320
+ buf << %Q[<p class="caption">#{caption}</p>\n] unless caption.nil?
321
+ buf << %Q[<pre class="syntax">]
322
+ lines.each {|line| buf << detab(line) << "\n" }
323
+ buf << "</pre>\n"
324
+ buf << "</div>\n"
325
+ buf
326
+ end
327
+
328
+ def note(lines, caption = nil)
329
+ captionblock("note", lines, caption)
330
+ end
331
+
332
+ def ul_begin
333
+ "<ul>\n"
334
+ end
335
+
336
+ def ul_item(lines)
337
+ "<li>#{lines.map(&:to_s).join}</li>\n"
338
+ end
339
+
340
+ def ul_item_begin(lines)
341
+ "<li>#{lines.map(&:to_s).join}"
342
+ end
343
+
344
+ def ul_item_end
345
+ "</li>\n"
346
+ end
347
+
348
+ def ul_end
349
+ "</ul>\n"
350
+ end
351
+
352
+ def ol_begin
353
+ if @ol_num
354
+ num = @ol_num
355
+ @ol_num = nil
356
+ "<ol start=\"#{num}\">\n" ## it's OK in HTML5, but not OK in XHTML1.1
357
+ else
358
+ "<ol>\n"
359
+ end
360
+ end
361
+
362
+ def ol_item(lines, num)
363
+ "<li>#{lines.map(&:to_s).join}</li>\n"
364
+ end
365
+
366
+ def ol_end
367
+ "</ol>\n"
368
+ end
369
+
370
+ def dl_begin
371
+ "<dl>\n"
372
+ end
373
+
374
+ def dt(line)
375
+ "<dt>#{line}</dt>\n"
376
+ end
377
+
378
+ def dd(lines)
379
+ "<dd>#{lines.join}</dd>\n"
380
+ end
381
+
382
+ def dl_end
383
+ "</dl>\n"
384
+ end
385
+
386
+ def paragraph(lines)
387
+ if @noindent.nil?
388
+ "<p>#{lines.join}</p>\n"
389
+ else
390
+ @noindent = nil
391
+ %Q[<p class="noindent">#{lines.join}</p>\n]
392
+ end
393
+ end
394
+
395
+ def parasep
396
+ "<br />\n"
397
+ end
398
+
399
+ def read(lines)
400
+ if @book.config["deprecated-blocklines"].nil?
401
+ %Q[<div class="lead">\n#{lines.join("")}\n</div>\n]
402
+ else
403
+ error "deprecated-blocklines is obsoleted."
404
+ end
405
+ end
406
+
407
+ alias_method :lead, :read
408
+
409
+ def list(lines, id, caption, lang = nil)
410
+ buf = %Q[<div class="caption-code">\n]
411
+ begin
412
+ buf << list_header(id, caption, lang)
413
+ rescue KeyError
414
+ error "no such list: #{id}"
415
+ end
416
+ buf << list_body(id, lines, lang)
417
+ buf << "</div>\n"
418
+ buf
419
+ end
420
+
421
+ def list_header(id, caption, lang)
422
+ if get_chap.nil?
423
+ %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
424
+ else
425
+ %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
426
+ end
427
+ end
428
+
429
+ def list_body(id, lines, lang)
430
+ id ||= ''
431
+ buf = %Q[<pre class="list">]
432
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
433
+ lexer = lang || File.extname(id).gsub(/\./, '')
434
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
435
+ buf << "</pre>\n"
436
+ buf
437
+ end
438
+
439
+ def source(lines, caption = nil, lang = nil)
440
+ buf = %Q[<div class="source-code">\n]
441
+ buf << source_header(caption)
442
+ buf << source_body(caption, lines, lang)
443
+ buf << "</div>\n"
444
+ buf
445
+ end
446
+
447
+ def source_header(caption)
448
+ if caption.present?
449
+ %Q[<p class="caption">#{caption}</p>\n]
450
+ end
451
+ end
452
+
453
+ def source_body(id, lines, lang)
454
+ id ||= ''
455
+ buf = %Q[<pre class="source">]
456
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
457
+ lexer = lang || File.extname(id).gsub(/\./, '')
458
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
459
+ buf << "</pre>\n"
460
+ buf
461
+ end
462
+
463
+ def listnum(lines, id, caption, lang = nil)
464
+ buf = %Q[<div class="code">\n]
465
+ begin
466
+ buf << list_header(id, caption, lang)
467
+ rescue KeyError
468
+ error "no such list: #{id}"
469
+ end
470
+ buf << listnum_body(lines, lang)
471
+ buf << "</div>"
472
+ buf
473
+ end
474
+
475
+ def listnum_body(lines, lang)
476
+ buf = ""
477
+ if highlight?
478
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
479
+ lexer = lang
480
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html',
481
+ :options => {:linenos => 'inline', :nowrap => false})
482
+ else
483
+ buf << '<pre class="list">'
484
+ lines.each_with_index do |line, i|
485
+ buf << detab((i+1).to_s.rjust(2) + ": " + line) << "\n"
486
+ end
487
+ buf << '</pre>' << "\n"
488
+ end
489
+ buf
490
+ end
491
+
492
+ def emlist(lines, caption = nil, lang = nil)
493
+ buf = %Q[<div class="emlist-code">\n]
494
+ if caption.present?
495
+ buf << %Q(<p class="caption">#{caption}</p>\n)
496
+ end
497
+ buf << %Q[<pre class="emlist">]
498
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
499
+ lexer = lang
500
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
501
+ buf << "</pre>\n"
502
+ buf << "</div>\n"
503
+ buf
504
+ end
505
+
506
+ def emlistnum(lines, caption = nil, lang = nil)
507
+ buf = %Q[<div class="emlistnum-code">\n]
508
+ if caption.present?
509
+ buf << %Q(<p class="caption">#{caption}</p>\n)
510
+ end
511
+ if highlight?
512
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
513
+ lexer = lang
514
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html',
515
+ :options => {:linenos => 'inline', :nowrap => false})
516
+ else
517
+ buf << '<pre class="emlist">'
518
+ lines.each_with_index do |line, i|
519
+ buf << detab((i+1).to_s.rjust(2) + ": " + line) << "\n"
520
+ end
521
+ buf << '</pre>' << "\n"
522
+ end
523
+
524
+ buf << '</div>' << "\n"
525
+ buf
526
+ end
527
+
528
+ def cmd(lines, caption = nil)
529
+ buf = %Q[<div class="cmd-code">\n]
530
+ if caption.present?
531
+ buf << %Q(<p class="caption">#{caption}</p>\n)
532
+ end
533
+ buf << %Q[<pre class="cmd">]
534
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
535
+ lexer = 'shell-session'
536
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
537
+ buf << "</pre>\n"
538
+ buf << "</div>\n"
539
+ buf
540
+ end
541
+
542
+ def quotedlist(lines, css_class)
543
+ buf = %Q[<blockquote><pre class="#{css_class}">\n]
544
+ lines.each do |line|
545
+ buf << detab(line) << "\n"
546
+ end
547
+ buf << "</pre></blockquote>\n"
548
+ end
549
+ private :quotedlist
550
+
551
+ def quote(lines)
552
+ if @book.config["deprecated-blocklines"].nil?
553
+ "<blockquote>#{lines.join("")}</blockquote>\n"
554
+ else
555
+ error "deprecated-blocklines is obsoleted."
556
+ end
557
+ end
558
+
559
+ def doorquote(lines, ref)
560
+ buf = ""
561
+ if @book.config["deprecated-blocklines"].nil?
562
+ buf << %Q[<blockquote style="text-align:right;">\n]
563
+ buf << "#{lines.join("")}\n"
564
+ buf << %Q[<p>#{ref}より</p>\n]
565
+ buf << %Q[</blockquote>\n]
566
+ else
567
+ error "deprecated-blocklines is obsoleted."
568
+ end
569
+ buf
570
+ end
571
+
572
+ def talk(lines)
573
+ buf = ""
574
+ buf << %Q[<div class="talk">\n]
575
+ if @book.config["deprecated-blocklines"].nil?
576
+ buf << "#{lines.join("\n")}\n"
577
+ else
578
+ error "deprecated-blocklines is obsoleted."
579
+ end
580
+ buf << "</div>\n"
581
+ buf
582
+ end
583
+
584
+ def texequation(lines)
585
+ buf << %Q[<div class="equation">\n]
586
+ if @book.config["mathml"]
587
+ require 'math_ml'
588
+ require 'math_ml/symbol/character_reference'
589
+ p = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::CharacterReference)
590
+ buf << p.parse(unescape_html(lines.join("\n")), true) << "\n"
591
+ else
592
+ buf << '<pre>'
593
+ buf << lines.join("\n") << "\n"
594
+ buf << "</pre>\n"
595
+ end
596
+ buf << "</div>\n"
597
+ buf
598
+ end
599
+
600
+ def handle_metric(str)
601
+ if str =~ /\Ascale=([\d.]+)\Z/
602
+ return "width=\"#{($1.to_f * 100).round}%\""
603
+ else
604
+ k, v = str.split('=', 2)
605
+ return %Q|#{k}=\"#{v.sub(/\A&quot;/, '').sub(/\A["']/, '').sub(/&quot;\Z/, '').sub(/["']\Z/, '')}\"|
606
+ end
607
+ end
608
+
609
+ def result_metric(array)
610
+ " #{array.join(' ')}"
611
+ end
612
+
613
+ def image_image(id, caption, metric)
614
+ metrics = parse_metric("html", metric)
615
+ buf = %Q[<div id="#{normalize_id(id)}" class="image">\n]
616
+ buf << %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="#{escape_html(caption)}"#{metrics} />\n]
617
+ buf << image_header(id, caption)
618
+ buf << %Q[</div>\n]
619
+ buf
620
+ end
621
+
622
+ def image_dummy(id, caption, lines)
623
+ buf = %Q[<div class="image">\n]
624
+ buf << %Q[<pre class="dummyimage">\n]
625
+ lines.each do |line|
626
+ buf << detab(line) << "\n"
627
+ end
628
+ buf << %Q[</pre>\n]
629
+ buf << image_header(id, caption)
630
+ buf << %Q[</div>\n]
631
+ warn "no such image: #{id}"
632
+ buf
633
+ end
634
+
635
+ def image_header(id, caption)
636
+ buf = %Q[<p class="caption">\n]
637
+ if get_chap.nil?
638
+ buf << %Q[#{I18n.t("image")}#{I18n.t("format_number_header_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix")}#{caption}\n]
639
+ else
640
+ buf << %Q[#{I18n.t("image")}#{I18n.t("format_number_header", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix")}#{caption}\n]
641
+ end
642
+ buf << %Q[</p>\n]
643
+ buf
644
+ end
645
+
646
+ def table(lines, id = nil, caption = nil)
647
+ rows = []
648
+ sepidx = nil
649
+ lines.each_with_index do |line, idx|
650
+ if /\A[\=\-]{12}/ =~ line
651
+ # just ignore
652
+ #error "too many table separator" if sepidx
653
+ sepidx ||= idx
654
+ next
655
+ end
656
+ rows.push line.strip.split(/\t+/).map {|s| s.sub(/\A\./, '') }
657
+ end
658
+ rows = adjust_n_cols(rows)
659
+
660
+ if id
661
+ buf = %Q[<div id="#{normalize_id(id)}" class="table">\n]
662
+ else
663
+ buf = %Q[<div class="table">\n]
664
+ end
665
+ begin
666
+ buf << table_header(id, caption) unless caption.nil?
667
+ rescue KeyError
668
+ error "no such table: #{id}"
669
+ end
670
+ buf << table_begin(rows.first.size)
671
+ return if rows.empty?
672
+ if sepidx
673
+ sepidx.times do
674
+ buf << tr(rows.shift.map {|s| th(s) })
675
+ end
676
+ rows.each do |cols|
677
+ buf << tr(cols.map {|s| td(s) })
678
+ end
679
+ else
680
+ rows.each do |cols|
681
+ h, *cs = *cols
682
+ buf << tr([th(h)] + cs.map {|s| td(s) })
683
+ end
684
+ end
685
+ buf << table_end
686
+ buf << %Q[</div>\n]
687
+ buf
688
+ end
689
+
690
+ def table_header(id, caption)
691
+ if get_chap.nil?
692
+ %Q[<p class="caption">#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
693
+ else
694
+ %Q[<p class="caption">#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
695
+ end
696
+ end
697
+
698
+ def table_begin(ncols)
699
+ "<table>\n"
700
+ end
701
+
702
+ def tr(rows)
703
+ "<tr>#{rows.join}</tr>\n"
704
+ end
705
+
706
+ def th(str)
707
+ "<th>#{str}</th>"
708
+ end
709
+
710
+ def td(str)
711
+ "<td>#{str}</td>"
712
+ end
713
+
714
+ def table_end
715
+ "</table>\n"
716
+ end
717
+
718
+ def comment(lines, comment = nil)
719
+ lines ||= []
720
+ lines.unshift comment unless comment.blank?
721
+ if @book.config["draft"]
722
+ str = lines.map{|line| escape_html(line) }.join("<br />")
723
+ return %Q(<div class="draft-comment">#{str}</div>\n)
724
+ else
725
+ str = lines.join("\n")
726
+ return %Q(<!-- #{escape_comment(str)} -->\n)
727
+ end
728
+ end
729
+
730
+ def footnote(id, str)
731
+ if @book.config["epubversion"].to_i == 3
732
+ %Q(<div class="footnote" epub:type="footnote" id="fn-#{normalize_id(id)}"><p class="footnote">[*#{@chapter.footnote(id).number}] #{str}</p></div>\n)
733
+ else
734
+ %Q(<div class="footnote" id="fn-#{normalize_id(id)}"><p class="footnote">[<a href="#fnb-#{normalize_id(id)}">*#{@chapter.footnote(id).number}</a>] #{str}</p></div>\n)
735
+ end
736
+ end
737
+
738
+ def indepimage(id, caption="", metric=nil)
739
+ metrics = parse_metric("html", metric)
740
+ caption = "" if caption.nil?
741
+ buf = %Q[<div class="image">\n]
742
+ begin
743
+ buf << %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="#{escape_html(caption)}"#{metrics} />\n]
744
+ rescue
745
+ buf << %Q[<pre>missing image: #{id}</pre>\n]
746
+ end
747
+
748
+ unless caption.empty?
749
+ buf << %Q[<p class="caption">\n]
750
+ buf << %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{caption}\n]
751
+ buf << %Q[</p>\n]
752
+ end
753
+ buf << %Q[</div>\n]
754
+ buf
755
+ end
756
+
757
+ alias_method :numberlessimage, :indepimage
758
+
759
+ def hr
760
+ "<hr />\n"
761
+ end
762
+
763
+ def label(id)
764
+ %Q(<a id="#{normalize_id(id)}"></a>\n)
765
+ end
766
+
767
+ def linebreak
768
+ "<br />\n"
769
+ end
770
+
771
+ def pagebreak
772
+ %Q(<br class="pagebreak" />\n)
773
+ end
774
+
775
+ def bpo(lines)
776
+ buf = "<bpo>\n"
777
+ lines.each do |line|
778
+ buf << detab(line) + "\n"
779
+ end
780
+ buf << "</bpo>\n"
781
+ buf
782
+ end
783
+
784
+ def noindent
785
+ @noindent = true
786
+ end
787
+
788
+ def inline_labelref(idref)
789
+ %Q[<a target='#{(idref)}'>「#{I18n.t("label_marker")}#{(idref)}」</a>]
790
+ end
791
+
792
+ alias_method :inline_ref, :inline_labelref
793
+
794
+ def inline_chapref(id)
795
+ title = super
796
+ if @book.config["chapterlink"]
797
+ %Q(<a href="./#{id}#{extname}">#{title}</a>)
798
+ else
799
+ title
800
+ end
801
+ rescue KeyError
802
+ error "unknown chapter: #{id}"
803
+ nofunc_text("[UnknownChapter:#{id}]")
804
+ end
805
+
806
+ def inline_chap(id)
807
+ if @book.config["chapterlink"]
808
+ %Q(<a href="./#{id}#{extname}">#{@book.chapter_index.number(id)}</a>)
809
+ else
810
+ @book.chapter_index.number(id)
811
+ end
812
+ rescue KeyError
813
+ error "unknown chapter: #{id}"
814
+ nofunc_text("[UnknownChapter:#{id}]")
815
+ end
816
+
817
+ def inline_title(id)
818
+ title = super
819
+ if @book.config["chapterlink"]
820
+ %Q(<a href="./#{id}#{extname}">#{title}</a>)
821
+ else
822
+ title
823
+ end
824
+ rescue KeyError
825
+ error "unknown chapter: #{id}"
826
+ nofunc_text("[UnknownChapter:#{id}]")
827
+ end
828
+
829
+ def inline_fn(id)
830
+ if @book.config["epubversion"].to_i == 3
831
+ %Q(<a id="fnb-#{normalize_id(id)}" href="#fn-#{normalize_id(id)}" class="noteref" epub:type="noteref">*#{@chapter.footnote(id).number}</a>)
832
+ else
833
+ %Q(<a id="fnb-#{normalize_id(id)}" href="#fn-#{normalize_id(id)}" class="noteref">*#{@chapter.footnote(id).number}</a>)
834
+ end
835
+ end
836
+
837
+ def compile_ruby(base, ruby)
838
+ if @book.htmlversion == 5
839
+ %Q[<ruby>#{base}<rp>#{I18n.t("ruby_prefix")}</rp><rt>#{ruby}</rt><rp>#{I18n.t("ruby_postfix")}</rp></ruby>]
840
+ else
841
+ %Q[<ruby><rb>#{(base)}</rb><rp>#{I18n.t("ruby_prefix")}</rp><rt>#{ruby}</rt><rp>#{I18n.t("ruby_postfix")}</rp></ruby>]
842
+ end
843
+ end
844
+
845
+ def compile_kw(word, alt)
846
+ %Q[<b class="kw">] +
847
+ if alt
848
+ then escape_html(word + " (#{alt.strip})")
849
+ else escape_html(word)
850
+ end +
851
+ "</b><!-- IDX:#{escape_comment(escape_html(word))} -->"
852
+ end
853
+
854
+ def inline_i(str)
855
+ %Q(<i>#{str}</i>)
856
+ end
857
+
858
+ def inline_b(str)
859
+ %Q(<b>#{str}</b>)
860
+ end
861
+
862
+ def inline_ami(str)
863
+ %Q(<span class="ami">#{(str)}</span>)
864
+ end
865
+
866
+ def inline_bou(str)
867
+ %Q(<span class="bou">#{(str)}</span>)
868
+ end
869
+
870
+ def inline_tti(str)
871
+ if @book.htmlversion == 5
872
+ %Q(<code class="tt"><i>#{(str)}</i></code>)
873
+ else
874
+ %Q(<tt><i>#{(str)}</i></tt>)
875
+ end
876
+ end
877
+
878
+ def inline_ttb(str)
879
+ if @book.htmlversion == 5
880
+ %Q(<code class="tt"><b>#{(str)}</b></code>)
881
+ else
882
+ %Q(<tt><b>#{(str)}</b></tt>)
883
+ end
884
+ end
885
+
886
+ def inline_dtp(str)
887
+ "<?dtp #{str} ?>"
888
+ end
889
+
890
+ def inline_code(str)
891
+ if @book.htmlversion == 5
892
+ %Q(<code class="inline-code tt">#{(str)}</code>)
893
+ else
894
+ %Q(<tt class="inline-code">#{(str)}</tt>)
895
+ end
896
+ end
897
+
898
+ def inline_idx(str)
899
+ %Q(#{(str)}<!-- IDX:#{escape_comment(escape_html(str))} -->)
900
+ end
901
+
902
+ def inline_hidx(str)
903
+ %Q(<!-- IDX:#{escape_comment(escape_html(str))} -->)
904
+ end
905
+
906
+ def inline_br(str)
907
+ %Q(<br />)
908
+ end
909
+
910
+ def inline_m(str)
911
+ if @book.config["mathml"]
912
+ require 'math_ml'
913
+ require 'math_ml/symbol/character_reference'
914
+ parser = MathML::LaTeX::Parser.new(
915
+ :symbol => MathML::Symbol::CharacterReference)
916
+ %Q[<span class="equation">#{parser.parse(str, nil)}</span>]
917
+ else
918
+ %Q[<span class="equation">#{(str)}</span>]
919
+ end
920
+ end
921
+
922
+ def text(str)
923
+ str
924
+ end
925
+
926
+ def bibpaper(lines, id, caption)
927
+ buf = %Q[<div class="bibpaper">\n]
928
+ buf << bibpaper_header(id, caption)
929
+ unless lines.empty?
930
+ buf << bibpaper_bibpaper(id, caption, lines)
931
+ end
932
+ buf << "</div>" << "\n"
933
+ buf
934
+ end
935
+
936
+ def bibpaper_header(id, caption)
937
+ buf = %Q(<a id="bib-#{normalize_id(id)}">)
938
+ buf << "[#{@chapter.bibpaper(id).number}]"
939
+ buf << %Q(</a>)
940
+ buf << " #{(caption)}" << "\n"
941
+ end
942
+
943
+ def bibpaper_bibpaper(id, caption, lines)
944
+ lines.join("")
945
+ end
946
+
947
+ def inline_bib(id)
948
+ %Q(<a href="#{@book.bib_file.gsub(/\.re\Z/, ".#{@book.config['htmlext']}")}#bib-#{normalize_id(id)}">[#{@chapter.bibpaper(id).number}]</a>)
949
+ end
950
+
951
+ def inline_hd_chap(chap, id)
952
+ n = chap.headline_index.number(id)
953
+ if chap.number and @book.config["secnolevel"] >= n.split('.').size
954
+ str = I18n.t("chapter_quote", "#{n} #{chap.headline(id).caption}")
955
+ else
956
+ str = I18n.t("chapter_quote", chap.headline(id).caption)
957
+ end
958
+ if @book.config["chapterlink"]
959
+ anchor = "h"+n.gsub(/\./, "-")
960
+ %Q(<a href="#{chap.id}#{extname}##{anchor}">#{str}</a>)
961
+ else
962
+ str
963
+ end
964
+ end
965
+
966
+ def column_label(id)
967
+ num = @chapter.column(id).number
968
+ "column-#{num}"
969
+ end
970
+ private :column_label
971
+
972
+ def inline_column(id)
973
+ if @book.config["chapterlink"]
974
+ %Q(<a href="\##{column_label(id)}" class="columnref">#{I18n.t("column", (@chapter.column(id).caption))}</a>)
975
+ else
976
+ I18n.t("column", (@chapter.column(id).caption))
977
+ end
978
+ rescue KeyError
979
+ error "unknown column: #{id}"
980
+ nofunc_text("[UnknownColumn:#{id}]")
981
+ end
982
+
983
+ def inline_list(id)
984
+ chapter, id = extract_chapter_id(id)
985
+ if get_chap(chapter).nil?
986
+ "#{I18n.t("list")}#{I18n.t("format_number_without_header", [chapter.list(id).number])}"
987
+ else
988
+ "#{I18n.t("list")}#{I18n.t("format_number", [get_chap(chapter), chapter.list(id).number])}"
989
+ end
990
+ rescue KeyError
991
+ error "unknown list: #{id}"
992
+ nofunc_text("[UnknownList:#{id}]")
993
+ end
994
+
995
+ def inline_table(id)
996
+ chapter, id = extract_chapter_id(id)
997
+ str = nil
998
+ if get_chap(chapter).nil?
999
+ str = "#{I18n.t("table")}#{I18n.t("format_number_without_chapter", [chapter.table(id).number])}"
1000
+ else
1001
+ str = "#{I18n.t("table")}#{I18n.t("format_number", [get_chap(chapter), chapter.table(id).number])}"
1002
+ end
1003
+ if @book.config["chapterlink"]
1004
+ %Q(<a href="./#{chapter.id}#{extname}##{id}">#{str}</a>)
1005
+ else
1006
+ str
1007
+ end
1008
+ rescue KeyError
1009
+ error "unknown table: #{id}"
1010
+ nofunc_text("[UnknownTable:#{id}]")
1011
+ end
1012
+
1013
+ def inline_img(id)
1014
+ chapter, id = extract_chapter_id(id)
1015
+ str = nil
1016
+ if get_chap(chapter).nil?
1017
+ str = "#{I18n.t("image")}#{I18n.t("format_number_without_chapter", [chapter.image(id).number])}"
1018
+ else
1019
+ str = "#{I18n.t("image")}#{I18n.t("format_number", [get_chap(chapter), chapter.image(id).number])}"
1020
+ end
1021
+ if @book.config["chapterlink"]
1022
+ %Q(<a href="./#{chapter.id}#{extname}##{normalize_id(id)}">#{str}</a>)
1023
+ else
1024
+ str
1025
+ end
1026
+ rescue KeyError
1027
+ error "unknown image: #{id}"
1028
+ nofunc_text("[UnknownImage:#{id}]")
1029
+ end
1030
+
1031
+ def inline_asis(str, tag)
1032
+ %Q(<#{tag}>#{(str)}</#{tag}>)
1033
+ end
1034
+
1035
+ def inline_abbr(str)
1036
+ inline_asis(str, "abbr")
1037
+ end
1038
+
1039
+ def inline_acronym(str)
1040
+ inline_asis(str, "acronym")
1041
+ end
1042
+
1043
+ def inline_cite(str)
1044
+ inline_asis(str, "cite")
1045
+ end
1046
+
1047
+ def inline_dfn(str)
1048
+ inline_asis(str, "dfn")
1049
+ end
1050
+
1051
+ def inline_em(str)
1052
+ inline_asis(str, "em")
1053
+ end
1054
+
1055
+ def inline_kbd(str)
1056
+ inline_asis(str, "kbd")
1057
+ end
1058
+
1059
+ def inline_samp(str)
1060
+ inline_asis(str, "samp")
1061
+ end
1062
+
1063
+ def inline_strong(str)
1064
+ inline_asis(str, "strong")
1065
+ end
1066
+
1067
+ def inline_var(str)
1068
+ inline_asis(str, "var")
1069
+ end
1070
+
1071
+ def inline_big(str)
1072
+ inline_asis(str, "big")
1073
+ end
1074
+
1075
+ def inline_small(str)
1076
+ inline_asis(str, "small")
1077
+ end
1078
+
1079
+ def inline_sub(str)
1080
+ inline_asis(str, "sub")
1081
+ end
1082
+
1083
+ def inline_sup(str)
1084
+ inline_asis(str, "sup")
1085
+ end
1086
+
1087
+ def inline_tt(str)
1088
+ if @book.htmlversion == 5
1089
+ %Q(<code class="tt">#{(str)}</code>)
1090
+ else
1091
+ %Q(<tt>#{(str)}</tt>)
1092
+ end
1093
+ end
1094
+
1095
+ def inline_del(str)
1096
+ inline_asis(str, "del")
1097
+ end
1098
+
1099
+ def inline_ins(str)
1100
+ inline_asis(str, "ins")
1101
+ end
1102
+
1103
+ def inline_u(str)
1104
+ %Q(<u>#{(str)}</u>)
1105
+ end
1106
+
1107
+ def inline_recipe(str)
1108
+ %Q(<span class="recipe">「#{(str)}」</span>)
1109
+ end
1110
+
1111
+ def inline_icon(id)
1112
+ begin
1113
+ %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="[#{id}]" />]
1114
+ rescue
1115
+ %Q[<pre>missing image: #{id}</pre>]
1116
+ end
1117
+ end
1118
+
1119
+ def inline_uchar(str)
1120
+ %Q(&#x#{str};)
1121
+ end
1122
+
1123
+ def inline_comment(str)
1124
+ if @book.config["draft"]
1125
+ %Q(<span class="draft-comment">#{(str)}</span>)
1126
+ else
1127
+ %Q(<!-- #{escape_comment(escape_html(str))} -->)
1128
+ end
1129
+ end
1130
+
1131
+ def inline_raw(str)
1132
+ super(str)
1133
+ end
1134
+
1135
+ def nofunc_text(str)
1136
+ escape_html(str)
1137
+ end
1138
+
1139
+ def compile_href(url, label)
1140
+ %Q(<a href="#{escape_html(url)}" class="link">#{label.nil? ? (url) : (label)}</a>)
1141
+ end
1142
+
1143
+ def flushright(lines)
1144
+ result = ""
1145
+ if @book.config["deprecated-blocklines"].nil?
1146
+ result << lines.join("").gsub("<p>", "<p class=\"flushright\">")
1147
+ else
1148
+ error "deprecated-blocklines is obsoleted."
1149
+ end
1150
+ result
1151
+ end
1152
+
1153
+ def centering(lines)
1154
+ lines.join("").gsub("<p>", "<p class=\"center\">")
1155
+ end
1156
+
1157
+ def image_ext
1158
+ "png"
1159
+ end
1160
+
1161
+ def olnum(num)
1162
+ @ol_num = num.to_i
1163
+ end
1164
+ end
1165
+
1166
+ end # module ReVIEW