review-peg 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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