review-retrovert 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +9 -0
- data/.editorconfig +3 -0
- data/.github/workflows/retrovert.yml +20 -5
- data/.gitignore +1 -0
- data/.vscode/launch.json +48 -0
- data/Gemfile.lock +13 -4
- data/Makefile +24 -0
- data/docker/review.Dockerfile +10 -0
- data/lib/review/retrovert/converter.rb +374 -111
- data/lib/review/retrovert/reviewcompat.rb +57 -0
- data/lib/review/retrovert/reviewdef.rb +70 -0
- data/lib/review/retrovert/sty/{ird.sty → ird.sty.erb} +9 -1
- data/lib/review/retrovert/sty/review-retrovert-custom.sty.erb +6 -0
- data/lib/review/retrovert/utils.rb +35 -0
- data/lib/review/retrovert/version.rb +1 -1
- data/lib/review/retrovert/yamlconfig.rb +0 -1
- data/package-lock.json +6 -0
- data/package.json +1 -0
- data/review-retrovert.gemspec +5 -1
- data/testdata/mybook/.gitignore +3 -1
- data/testdata/mybook/.textlintrc +11 -0
- data/testdata/mybook/Rakefile +8 -0
- data/testdata/mybook/catalog.yml +36 -10
- data/testdata/mybook/config-starter.yml +134 -9
- data/testdata/mybook/config.yml +44 -15
- data/testdata/mybook/contents/00-preface.re +48 -2
- data/testdata/mybook/contents/01-install.re +38 -5
- data/testdata/mybook/contents/02-tutorial.re +333 -113
- data/testdata/mybook/contents/03-syntax.re +2370 -373
- data/testdata/mybook/contents/04-customize.re +424 -88
- data/testdata/mybook/contents/05-faq.re +288 -10
- data/testdata/mybook/contents/06-bestpractice.re +431 -59
- data/testdata/mybook/contents/91-compare.re +402 -2
- data/testdata/mybook/contents/92-filelist.re +14 -8
- data/testdata/mybook/contents/93-background.re +10 -10
- data/testdata/mybook/contents/99-postface.re +2 -1
- data/testdata/mybook/contents/r0-root.re +1 -1
- data/testdata/mybook/css/webstyle.css +180 -2
- data/testdata/mybook/data/terms.txt +3 -0
- data/testdata/mybook/data/words.txt +15 -0
- data/testdata/mybook/images/03-syntax/index-page.png +0 -0
- data/testdata/mybook/images/03-syntax/order-detail.png +0 -0
- data/testdata/mybook/images/04-customize/section_decoration_samples.png +0 -0
- data/testdata/mybook/images/05-faq/dummy-image.png +0 -0
- data/testdata/mybook/images/06-bestpractice/section_title_wlines.png +0 -0
- data/testdata/mybook/images/avatar-b.png +0 -0
- data/testdata/mybook/images/avatar-g.png +0 -0
- data/testdata/mybook/images/avatar-r.png +0 -0
- data/testdata/mybook/images/caution-icon.png +0 -0
- data/testdata/mybook/images/info-icon.png +0 -0
- data/testdata/mybook/images/warning-icon.png +0 -0
- data/testdata/mybook/layouts/layout.html5.erb +3 -1
- data/testdata/mybook/layouts/layout.tex.erb +265 -379
- data/testdata/mybook/layouts/layout.tex.erb.orig +386 -0
- data/testdata/mybook/lib/ruby/review-book.rb +64 -0
- data/testdata/mybook/lib/ruby/review-builder.rb +902 -63
- data/testdata/mybook/lib/ruby/review-compiler.rb +675 -22
- data/testdata/mybook/lib/ruby/review-epubbuilder.rb +33 -0
- data/testdata/mybook/lib/ruby/review-epubmaker.rb +10 -7
- data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +354 -66
- data/testdata/mybook/lib/ruby/review-latexbuilder.rb +429 -146
- data/testdata/mybook/lib/ruby/review-maker.rb +117 -6
- data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +945 -0
- data/testdata/mybook/lib/ruby/review-markdownmaker.rb +91 -0
- data/testdata/mybook/lib/ruby/review-monkeypatch.rb +2 -0
- data/testdata/mybook/lib/ruby/review-pdfmaker.rb +160 -82
- data/testdata/mybook/lib/ruby/review-webmaker.rb +20 -5
- data/testdata/mybook/lib/tasks/review.rake +14 -0
- data/testdata/mybook/lib/tasks/starter.rake +148 -4
- data/testdata/mybook/sty/indexstyle.ist +25 -0
- data/testdata/mybook/sty/mytextsize.sty +29 -0
- data/testdata/mybook/sty/mytitlepage.sty +34 -11
- data/testdata/mybook/sty/review-base.sty +276 -0
- data/testdata/mybook/sty/starter-codeblock.sty +237 -106
- data/testdata/mybook/sty/starter-color.sty +72 -17
- data/testdata/mybook/sty/starter-heading.sty +60 -13
- data/testdata/mybook/sty/starter-misc.sty +894 -0
- data/testdata/mybook/sty/starter-note.sty +67 -14
- data/testdata/mybook/sty/starter-talklist.sty +105 -0
- data/testdata/mybook/sty/starter-util.sty +35 -0
- data/testdata/mybook/sty/starter.sty +8 -526
- metadata +80 -4
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
require 'review/epubbuilder'
|
5
|
+
|
6
|
+
|
7
|
+
module ReVIEW
|
8
|
+
|
9
|
+
defined?(EPUBBuilder) or
|
10
|
+
raise "ReVIEW::EPUBBuilder class not found."
|
11
|
+
|
12
|
+
|
13
|
+
class EPUBBuilder
|
14
|
+
|
15
|
+
def target_name
|
16
|
+
"epub"
|
17
|
+
end
|
18
|
+
|
19
|
+
def inline_par(arg)
|
20
|
+
case arg
|
21
|
+
when 'i'
|
22
|
+
#"<p class=\"indent\">"
|
23
|
+
"<p class=\"indent\"></p>" # TODO: (workaround)
|
24
|
+
else
|
25
|
+
#"<p>"
|
26
|
+
"<p></p>" # TODO: (workaround)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
@@ -119,9 +119,10 @@ module ReVIEW
|
|
119
119
|
log('Call ePUB producer.')
|
120
120
|
@producer.produce(epubname, builddir, epubtmpdir)
|
121
121
|
log('Finished.')
|
122
|
-
rescue ApplicationError =>
|
122
|
+
rescue ApplicationError => ex
|
123
123
|
raise if debug?()
|
124
|
-
error(
|
124
|
+
#error(ex.message)
|
125
|
+
error(colored_errmsg(ex.message))
|
125
126
|
ensure
|
126
127
|
FileUtils.remove_entry_secure(builddir) unless debug?()
|
127
128
|
end
|
@@ -253,7 +254,7 @@ module ReVIEW
|
|
253
254
|
build_chap(chap, base_path, nil)
|
254
255
|
end
|
255
256
|
end
|
256
|
-
check_compile_status
|
257
|
+
check_compile_status()
|
257
258
|
end
|
258
259
|
|
259
260
|
def new_renderer()
|
@@ -286,10 +287,12 @@ module ReVIEW
|
|
286
287
|
@converter.convert(filename, File.join(@builddir, htmlfile))
|
287
288
|
write_info_body(htmlfile, chaptype)
|
288
289
|
remove_hidden_title(htmlfile)
|
289
|
-
|
290
|
+
## 文法エラーだけキャッチし、それ以外のエラーはキャッチしないよう変更
|
291
|
+
#rescue => ex
|
292
|
+
rescue ApplicationError => ex
|
290
293
|
@compile_errors = true
|
291
|
-
warn "compile error in #{filename} (#{
|
292
|
-
warn
|
294
|
+
warn "compile error in #{filename} (#{ex.class})"
|
295
|
+
warn colored_errmsg(ex.message)
|
293
296
|
end
|
294
297
|
end
|
295
298
|
|
@@ -327,7 +330,7 @@ module ReVIEW
|
|
327
330
|
end
|
328
331
|
|
329
332
|
def detect_properties(path)
|
330
|
-
doc = File.open(path) {|f| REXML::Document.new(f) }
|
333
|
+
doc = File.open(path, encoding: 'utf-8') {|f| REXML::Document.new(f) }
|
331
334
|
has_math = REXML::XPath.first(doc, '//m:math', 'm' => 'http://www.w3.org/1998/Math/MathML')
|
332
335
|
has_svg = REXML::XPath.first(doc, '//s:svg', 's' => 'http://www.w3.org/2000/svg')
|
333
336
|
properties = []
|
@@ -16,6 +16,10 @@ module ReVIEW
|
|
16
16
|
|
17
17
|
attr_accessor :starter_config
|
18
18
|
|
19
|
+
def target_name
|
20
|
+
"html"
|
21
|
+
end
|
22
|
+
|
19
23
|
def layoutfile
|
20
24
|
## 'rake web' のときに使うレイアウトファイルを 'layout.html5.erb' へ変更
|
21
25
|
if @book.config.maker == 'webmaker'
|
@@ -59,7 +63,7 @@ module ReVIEW
|
|
59
63
|
@toc = ReVIEW::WEBTOCPrinter.book_to_html(@book, @chapter) #+
|
60
64
|
end
|
61
65
|
|
62
|
-
ReVIEW::Template.load(layoutfile).result(binding)
|
66
|
+
ReVIEW::Template.load(layoutfile()).result(binding())
|
63
67
|
end
|
64
68
|
|
65
69
|
def headline(level, label, caption)
|
@@ -99,62 +103,109 @@ module ReVIEW
|
|
99
103
|
attrs.map {|k, arr| " #{k}=\"#{arr.join(' ')}\"" }.join()
|
100
104
|
end
|
101
105
|
|
102
|
-
|
103
|
-
|
106
|
+
## 画像
|
107
|
+
|
108
|
+
def _render_image(id, image_filepath, caption, opts)
|
109
|
+
src = image_filepath.sub(/\A\.\//, '')
|
104
110
|
alt = escape_html(compile_inline(caption))
|
105
|
-
|
106
|
-
|
111
|
+
#
|
112
|
+
classes = ["img"]
|
113
|
+
styles = []
|
114
|
+
#
|
115
|
+
if opts[:scale]
|
116
|
+
case (scale = opts[:scale])
|
117
|
+
when /\A\d+\z/, /\A\d\.\d*\z/, /\A\.\d+\z/
|
118
|
+
per = (scale.to_f * 100).round()
|
119
|
+
when /\A\d+(\.\d+)?%\z/
|
120
|
+
per = scale.sub(/%\z/, '').to_f.round()
|
121
|
+
else
|
122
|
+
error "scale=#{scale}: invalid scale value."
|
123
|
+
end
|
124
|
+
found = PERCENT_THRESHOLDS.find {|x| x == per }
|
125
|
+
if found
|
126
|
+
classes << 'width-%03dper' % per
|
127
|
+
else
|
128
|
+
styles << "max-width:#{per}%"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
#
|
132
|
+
classes << opts[:class] if opts[:class]
|
133
|
+
classes << "border" if opts[:border]
|
134
|
+
classes << "draft" if opts[:draft]
|
135
|
+
styles << opts[:style] if opts[:style]
|
136
|
+
styles << "width:#{opts[:width]}" if opts[:width]
|
137
|
+
#
|
107
138
|
puts "<div id=\"#{normalize_id(id)}\" class=\"image\">"
|
108
|
-
|
139
|
+
print "<img src=\"#{src}\" alt=\"#{alt}\""
|
140
|
+
print " class=\"#{classes.join(' ')}\"" unless classes.empty?
|
141
|
+
print " style=\"#{styles.join(' ')}\"" unless styles.empty?
|
142
|
+
puts " />"
|
109
143
|
image_header(id, caption)
|
110
144
|
puts "</div>"
|
111
145
|
end
|
112
146
|
|
113
|
-
|
147
|
+
PERCENT_THRESHOLDS = [
|
148
|
+
10, 20, 25, 30, 33, 40, 50, 60, 67, 70, 75, 80, 90, 100,
|
149
|
+
]
|
114
150
|
|
115
|
-
|
116
|
-
|
117
|
-
|
151
|
+
protected
|
152
|
+
|
153
|
+
## コードブロック(//program, //terminal, //output)
|
118
154
|
|
119
|
-
|
120
|
-
|
155
|
+
CLASSNAMES = {
|
156
|
+
"program" => "code",
|
157
|
+
"terminal" => "cmd-code",
|
158
|
+
"list" => "caption-code",
|
159
|
+
"listnum" => "code",
|
160
|
+
"emlist" => "emlist-code",
|
161
|
+
"emlistnum" => "emlistnum-code",
|
162
|
+
"source" => "source-code",
|
163
|
+
"cmd" => "cmd-code",
|
164
|
+
"output" => "output",
|
165
|
+
}
|
166
|
+
|
167
|
+
def _codeblock_eolmark()
|
168
|
+
"<small class=\"startereolmark\"></small>"
|
121
169
|
end
|
122
170
|
|
123
|
-
|
171
|
+
def _codeblock_indentmark()
|
172
|
+
'<span class="indentbar"> </span>'
|
173
|
+
end
|
124
174
|
|
125
|
-
def
|
126
|
-
|
127
|
-
## しかしCompilerクラスがそのような設計になってないので、
|
128
|
-
## 仕方ないのでBuilderクラスでパースする。
|
129
|
-
opts = _parse_codeblock_optionstr(optionstr, blockname)
|
130
|
-
CODEBLOCK_OPTIONS.each {|k, v| opts[k] = v unless opts.key?(k) }
|
175
|
+
def _render_codeblock(blockname, lines, id, caption_str, opts)
|
176
|
+
caption = caption_str
|
131
177
|
#
|
132
178
|
if opts['eolmark']
|
133
|
-
|
179
|
+
eolmark = _codeblock_eolmark() # ex: '{\startereolmark}'
|
134
180
|
else
|
135
|
-
|
181
|
+
eolmark = nil
|
136
182
|
end
|
137
183
|
#
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
}
|
184
|
+
eol = eolmark ? "#{eolmark}\n" : "\n"
|
185
|
+
lines = lines.map {|line|
|
186
|
+
line = _parse_inline(line) {|text| escape(text) }
|
187
|
+
}
|
188
|
+
#
|
189
|
+
indent_width = opts['indent']
|
190
|
+
if indent_width && indent_width > 0
|
191
|
+
lines = _add_indent_mark(lines, indent_width)
|
147
192
|
end
|
148
193
|
#
|
194
|
+
classname = CLASSNAMES[blockname] || "code"
|
195
|
+
classname += " #{opts['classname']}" if opts['classname']
|
149
196
|
puts "<div id=\"#{normalize_id(id)}\" class=\"#{classname}\">" if id.present?
|
150
197
|
puts "<div class=\"#{classname}\">" unless id.present?
|
151
198
|
#
|
199
|
+
classattr = nil
|
152
200
|
if id.present? || caption.present?
|
153
201
|
str = _build_caption_str(id, caption)
|
154
202
|
print "<span class=\"caption\">#{str}</span>\n"
|
155
203
|
classattr = "list"
|
204
|
+
end
|
205
|
+
if blockname == "output"
|
206
|
+
classattr = blockname
|
156
207
|
else
|
157
|
-
classattr
|
208
|
+
classattr ||= "emlist"
|
158
209
|
end
|
159
210
|
#
|
160
211
|
lang = opts['lang']
|
@@ -165,7 +216,7 @@ module ReVIEW
|
|
165
216
|
#
|
166
217
|
gen = opts['lineno'] ? LineNumberGenerator.new(opts['lineno']).each : nil
|
167
218
|
if gen
|
168
|
-
width = opts['linenowidth']
|
219
|
+
width = opts['linenowidth'] || -1
|
169
220
|
if width < 0
|
170
221
|
format = "%s"
|
171
222
|
elsif width == 0
|
@@ -177,10 +228,10 @@ module ReVIEW
|
|
177
228
|
end
|
178
229
|
end
|
179
230
|
buf = []
|
180
|
-
start_tag = opts['linenowidth'] >= 0 ? "<em class=\"linenowidth\">" : "<em class=\"lineno\">"
|
231
|
+
start_tag = (opts['linenowidth'] || -1) >= 0 ? "<em class=\"linenowidth\">" : "<em class=\"lineno\">"
|
181
232
|
lines.each_with_index do |line, i|
|
182
233
|
buf << start_tag << (format % gen.next) << ": </em>" if gen
|
183
|
-
buf << line
|
234
|
+
buf << line #<< "\n"
|
184
235
|
end
|
185
236
|
puts highlight(body: buf.join(), lexer: lang,
|
186
237
|
format: "html", linenum: !!gen,
|
@@ -191,27 +242,43 @@ module ReVIEW
|
|
191
242
|
print "</div>\n"
|
192
243
|
end
|
193
244
|
|
245
|
+
def _add_indent_mark(lines, indent_width)
|
246
|
+
space = " "
|
247
|
+
rexp = /\A( +)/
|
248
|
+
#
|
249
|
+
width = indent_width
|
250
|
+
mark = _codeblock_indentmark() # ex: '{\starterindentmark}'
|
251
|
+
indent = space * (width - 1) + mark
|
252
|
+
nchar = space.length
|
253
|
+
return lines.map {|line|
|
254
|
+
line.sub(rexp) {
|
255
|
+
m, n = ($1.length / nchar - 1).divmod width
|
256
|
+
"#{space}#{indent * m}#{space * n}"
|
257
|
+
}
|
258
|
+
}
|
259
|
+
end
|
260
|
+
|
194
261
|
public
|
195
262
|
|
196
263
|
## コードリスト(//list, //emlist, //listnum, //emlistnum, //cmd, //source)
|
197
264
|
def list(lines, id=nil, caption=nil, lang=nil)
|
198
|
-
_codeblock("list",
|
265
|
+
_codeblock("list", lines, id, caption, _codeblock_optstr(lang, false))
|
199
266
|
end
|
200
267
|
def listnum(lines, id=nil, caption=nil, lang=nil)
|
201
|
-
_codeblock("listnum",
|
268
|
+
_codeblock("listnum", lines, id, caption, _codeblock_optstr(lang, true))
|
202
269
|
end
|
203
270
|
def emlist(lines, caption=nil, lang=nil)
|
204
|
-
_codeblock("emlist",
|
271
|
+
_codeblock("emlist", lines, nil, caption, _codeblock_optstr(lang, false))
|
205
272
|
end
|
206
273
|
def emlistnum(lines, caption=nil, lang=nil)
|
207
|
-
_codeblock("emlistnum",
|
274
|
+
_codeblock("emlistnum", lines, nil, caption, _codeblock_optstr(lang, true))
|
208
275
|
end
|
209
276
|
def source(lines, caption=nil, lang=nil)
|
210
|
-
_codeblock("source",
|
277
|
+
_codeblock("source", lines, nil, caption, _codeblock_optstr(lang, false))
|
211
278
|
end
|
212
279
|
def cmd(lines, caption=nil, lang=nil)
|
213
280
|
lang ||= "shell-session"
|
214
|
-
_codeblock("cmd",
|
281
|
+
_codeblock("cmd", lines, nil, caption, _codeblock_optstr(lang, false))
|
215
282
|
end
|
216
283
|
def _codeblock_optstr(lang, lineno_flag)
|
217
284
|
arr = []
|
@@ -295,19 +362,16 @@ module ReVIEW
|
|
295
362
|
puts "</li>"
|
296
363
|
end
|
297
364
|
|
298
|
-
|
365
|
+
def dl_dd_begin()
|
366
|
+
puts "<dd>"
|
367
|
+
end
|
299
368
|
|
300
|
-
def
|
301
|
-
puts "
|
302
|
-
puts "<p class=\"caption\">#{compile_inline(caption)}</p>" if caption.present?
|
303
|
-
yield
|
304
|
-
puts '</div>'
|
369
|
+
def dl_dd_end()
|
370
|
+
puts "</dd>"
|
305
371
|
end
|
306
|
-
protected :on_minicolumn
|
307
372
|
|
308
|
-
|
309
|
-
|
310
|
-
filepath = find_image_filepath(imagefile)
|
373
|
+
## 画像横に文章
|
374
|
+
def _render_sideimage(filepath, imagewidth, opts, &b)
|
311
375
|
side = (opts['side'] || 'L') == 'L' ? 'left' : 'right'
|
312
376
|
imgclass = opts['border'] ? "image-bordered" : nil
|
313
377
|
normalize = proc {|s| s =~ /^\A(\d+(\.\d+))%\z/ ? "#{$1.to_f/100.0}\\textwidth" : s }
|
@@ -327,6 +391,18 @@ module ReVIEW
|
|
327
391
|
puts "</div>\n"
|
328
392
|
end
|
329
393
|
|
394
|
+
## 入れ子可能なブロック命令
|
395
|
+
|
396
|
+
def on_minicolumn(type, caption=nil, &b)
|
397
|
+
with_context(:minicolumn) do
|
398
|
+
puts "<div class=\"miniblock miniblock-#{type}\">"
|
399
|
+
puts "<p class=\"miniblock-caption\">#{compile_inline(caption)}</p>" if caption.present?
|
400
|
+
yield
|
401
|
+
puts '</div>'
|
402
|
+
end
|
403
|
+
end
|
404
|
+
protected :on_minicolumn
|
405
|
+
|
330
406
|
#### ブロック命令
|
331
407
|
|
332
408
|
def footnote(id, str)
|
@@ -385,22 +461,91 @@ module ReVIEW
|
|
385
461
|
end
|
386
462
|
|
387
463
|
## 章 (Chapter) の概要
|
388
|
-
def
|
464
|
+
def on_abstract_block()
|
389
465
|
puts '<div class="abstract">'
|
390
|
-
|
466
|
+
yield
|
391
467
|
puts '</div>'
|
392
468
|
end
|
393
469
|
|
470
|
+
## 章 (Chapter) の著者
|
471
|
+
def on_chapterauthor_block(name)
|
472
|
+
puts "<div class=\"chapterauthor\">#{escape(name)}</div>"
|
473
|
+
end
|
474
|
+
|
475
|
+
## 会話リスト
|
476
|
+
def _render_talklist(opts, &b)
|
477
|
+
c = opts[:classname]
|
478
|
+
s = c ? " #{c}" : nil
|
479
|
+
puts "<div class=\"talk-outer#{s}\">"
|
480
|
+
puts " <ul class=\"talk-list#{s}\">"
|
481
|
+
yield
|
482
|
+
puts " </ul>"
|
483
|
+
puts "</div>"
|
484
|
+
end
|
485
|
+
|
486
|
+
## 会話項目
|
487
|
+
def _render_talk(image_filepath=nil, name=nil, &b)
|
488
|
+
puts "<li class=\"talk-item\">"
|
489
|
+
print " <span class=\"talk-chara\">"
|
490
|
+
if image_filepath.present?
|
491
|
+
print "<img class=\"talk-image\" src=\"#{image_filepath}\"/>"
|
492
|
+
else
|
493
|
+
s = compile_inline(name || '')
|
494
|
+
print "<b class=\"talk-name\">#{s}</b>"
|
495
|
+
end
|
496
|
+
puts "</span>"
|
497
|
+
print " <div class=\"talk-text\">"
|
498
|
+
yield
|
499
|
+
if @output.string.end_with?("\n")
|
500
|
+
@output.seek(-1, IO::SEEK_CUR) # 改行文字を取り除く
|
501
|
+
#@output.string.chomp! # これだとヌル文字が入ってしまう
|
502
|
+
end
|
503
|
+
puts "</div>"
|
504
|
+
puts "</li>"
|
505
|
+
end
|
506
|
+
|
507
|
+
## キーと説明文のリスト
|
508
|
+
def _render_desclist(opts, &b)
|
509
|
+
bkup = @_desclist_opts
|
510
|
+
@_desclist_opts = opts
|
511
|
+
classnames = ['desc-list']
|
512
|
+
classnames << 'compact' if opts[:compact]
|
513
|
+
classnames << 'item-bold' if opts[:bold]
|
514
|
+
classnames << opts[:classname] if opts[:classname]
|
515
|
+
puts "<dl class=\"#{classnames.join(' ')}\">"
|
516
|
+
yield
|
517
|
+
puts "</dl>"
|
518
|
+
@_desclist_opts = bkup
|
519
|
+
end
|
520
|
+
|
521
|
+
## キーと説明文
|
522
|
+
def _render_desc(key, &b)
|
523
|
+
opts = @_desclist_opts
|
524
|
+
s = compile_inline(key)
|
525
|
+
s = "<b>#{s}</b>" if opts[:bold]
|
526
|
+
puts " <dt class=\"desc\">#{s}</dt>"
|
527
|
+
puts " <dd class=\"desc\">"
|
528
|
+
yield
|
529
|
+
puts " </dd>"
|
530
|
+
end
|
531
|
+
|
532
|
+
## 縦方向の空きを入れる
|
533
|
+
def _render_vspace(size)
|
534
|
+
puts "<div class=\"vspace\" style=\"height:#{size}\"></div>"
|
535
|
+
end
|
536
|
+
|
537
|
+
def _render_addvspace(size)
|
538
|
+
puts "<div class=\"addvspace\" style=\"height:#{size}\"></div>"
|
539
|
+
end
|
540
|
+
|
394
541
|
## 章タイトルを独立したページに
|
395
542
|
def makechaptitlepage(option=nil)
|
396
543
|
puts '' # HTMLでは特に何もしない
|
397
544
|
end
|
398
545
|
|
399
546
|
## 縦方向のスペースがなければ改ページ
|
400
|
-
def
|
401
|
-
|
402
|
-
puts "<div style=\"height:#{height}\"></div>"
|
403
|
-
end
|
547
|
+
def _render_needvspace(height)
|
548
|
+
puts "<div style=\"height:#{height}\"></div>"
|
404
549
|
end
|
405
550
|
|
406
551
|
## 段(Paragraph)の終わりにスペースを入れる
|
@@ -445,15 +590,17 @@ module ReVIEW
|
|
445
590
|
## ノート(//note{ ... //})
|
446
591
|
## (入れ子対応なので、中に箇条書きや別のブロックを入れられる)
|
447
592
|
def on_note_block(label=nil, caption=nil)
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
593
|
+
with_context(:minicolumn) do
|
594
|
+
caption, label = label, nil if caption.nil?
|
595
|
+
if label
|
596
|
+
puts "<div class=\"note\" id=\"#{label}\">"
|
597
|
+
else
|
598
|
+
puts "<div class=\"note\">"
|
599
|
+
end
|
600
|
+
puts "<h5>#{compile_inline(caption)}</h5>" if caption.present?
|
601
|
+
yield
|
602
|
+
puts "</div>"
|
453
603
|
end
|
454
|
-
puts "<h5>#{compile_inline(caption)}</h5>" if caption.present?
|
455
|
-
yield
|
456
|
-
puts "</div>"
|
457
604
|
end
|
458
605
|
def note(lines, label=nil, caption=nil)
|
459
606
|
on_quote_block(label, caption) do
|
@@ -472,6 +619,89 @@ module ReVIEW
|
|
472
619
|
puts "</div>"
|
473
620
|
end
|
474
621
|
|
622
|
+
## テーブル
|
623
|
+
def table(lines, id=nil, caption=nil, option=nil)
|
624
|
+
super
|
625
|
+
end
|
626
|
+
|
627
|
+
def table_header(id, caption, options)
|
628
|
+
if id.present?
|
629
|
+
begin
|
630
|
+
num = @chapter.table(id).number
|
631
|
+
rescue KeyError
|
632
|
+
error "no such table: #{id}"
|
633
|
+
end
|
634
|
+
s1 = I18n.t('table')
|
635
|
+
s2 = get_chap() \
|
636
|
+
? I18n.t('format_number_header', [get_chap(), num]) \
|
637
|
+
: I18n.t('format_number_header_without_chapter', [num])
|
638
|
+
s3 = I18n.t('caption_prefix')
|
639
|
+
puts "<p class=\"caption\">#{s1}#{s2}#{s3}#{compile_inline(caption||'')}</p>"
|
640
|
+
elsif caption.present?
|
641
|
+
puts "<p class=\"caption\">#{compile_inline(caption||'')}</p>"
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
def table_begin(_ncols, fontsize: nil)
|
646
|
+
if fontsize
|
647
|
+
puts "<table style=\"font-size:#{fontsize}\">"
|
648
|
+
else
|
649
|
+
puts "<table>"
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
protected
|
654
|
+
|
655
|
+
def _table_before(id, caption, opts)
|
656
|
+
class_ = opts[:csv] ? "table table-nohline" : "table"
|
657
|
+
if id.present?
|
658
|
+
puts "<div id=\"#{normalize_id(id)}\" class=\"#{class_}\">"
|
659
|
+
else
|
660
|
+
puts "<div class=\"#{class_}\">"
|
661
|
+
end
|
662
|
+
end
|
663
|
+
|
664
|
+
def _table_after(id, caption, opts)
|
665
|
+
puts "</div>"
|
666
|
+
end
|
667
|
+
|
668
|
+
def _table_bottom(hline: false)
|
669
|
+
end
|
670
|
+
|
671
|
+
def _table_tr(cells, hline: false)
|
672
|
+
if hline
|
673
|
+
"<tr class=\"hline\">#{cells.join}</tr>"
|
674
|
+
else
|
675
|
+
"<tr>#{cells.join}</tr>"
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
public
|
680
|
+
|
681
|
+
## //imgtable
|
682
|
+
def imgtable(lines, id, caption=nil, option=nil)
|
683
|
+
super
|
684
|
+
end
|
685
|
+
|
686
|
+
protected
|
687
|
+
|
688
|
+
def _render_imgtable(id, caption, opts)
|
689
|
+
puts "<div id=\"#{normalize_id(id)}\" class=\"imgtable image\">"
|
690
|
+
table_header(id, caption, opts)
|
691
|
+
puts " <div>"
|
692
|
+
yield
|
693
|
+
puts " </div>"
|
694
|
+
puts "</div>"
|
695
|
+
end
|
696
|
+
|
697
|
+
def _render_imgtable_caption(caption)
|
698
|
+
end
|
699
|
+
|
700
|
+
def _render_imgtable_label(id)
|
701
|
+
end
|
702
|
+
|
703
|
+
public
|
704
|
+
|
475
705
|
#### インライン命令
|
476
706
|
|
477
707
|
def inline_fn(id)
|
@@ -485,6 +715,16 @@ module ReVIEW
|
|
485
715
|
error "unknown footnote: #{id}"
|
486
716
|
end
|
487
717
|
|
718
|
+
## 改段落(箇条書き内では空行を入れられないため)
|
719
|
+
def inline_par(arg)
|
720
|
+
case arg
|
721
|
+
when 'i'
|
722
|
+
"<p class=\"indent\">"
|
723
|
+
else
|
724
|
+
"<p>"
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
488
728
|
## ファイル名
|
489
729
|
def inline_file(str)
|
490
730
|
on_inline_file { escape(str) }
|
@@ -552,7 +792,7 @@ module ReVIEW
|
|
552
792
|
|
553
793
|
def on_inline_i() ; "<i>#{yield}</i>" ; end
|
554
794
|
def on_inline_b() ; "<b>#{yield}</b>" ; end
|
555
|
-
def on_inline_code() ; "<code>#{yield}</code>" ; end
|
795
|
+
#def on_inline_code() ; "<code>#{yield}</code>" ; end
|
556
796
|
def on_inline_tt() ; "<tt>#{yield}</tt>" ; end
|
557
797
|
def on_inline_del() ; "<s>#{yield}</s>" ; end
|
558
798
|
def on_inline_sub() ; "<sub>#{yield}</sub>" ; end
|
@@ -563,6 +803,15 @@ module ReVIEW
|
|
563
803
|
def on_inline_ami() ; "<span class=\"ami\">#{yield}</span>"; end
|
564
804
|
def on_inline_balloon(); "<span class=\"balloon\">← #{yield}</span>"; end
|
565
805
|
|
806
|
+
def on_inline_code()
|
807
|
+
return "<code class=\"inline-code\">#{yield}</code>"
|
808
|
+
end
|
809
|
+
|
810
|
+
## 「“」と「”」で囲む
|
811
|
+
def on_inline_qq()
|
812
|
+
"“#{yield}”"
|
813
|
+
end
|
814
|
+
|
566
815
|
def build_inline_href(url, escaped_label) # compile_href()をベースに改造
|
567
816
|
flag_link = @book.config['externallink']
|
568
817
|
return _inline_hyperlink(url, escaped_label, flag_link)
|
@@ -571,7 +820,8 @@ module ReVIEW
|
|
571
820
|
def inline_hlink(str)
|
572
821
|
url, label = str.split(/, /, 2)
|
573
822
|
flag_link = @book.config['externallink']
|
574
|
-
|
823
|
+
label_ = label.present? ? escape(label) : nil
|
824
|
+
return _inline_hyperlink(url, label_, flag_link)
|
575
825
|
end
|
576
826
|
|
577
827
|
def _inline_hyperlink(url, escaped_label, flag_link)
|
@@ -609,11 +859,49 @@ module ReVIEW
|
|
609
859
|
"<a>#{escape(s)}</a>"
|
610
860
|
end
|
611
861
|
|
862
|
+
## 索引に載せる語句 (@<idx>{}, @<term>{})
|
863
|
+
public
|
864
|
+
def inline_idx(str)
|
865
|
+
s1, s2 = _compile_term(str)
|
866
|
+
%Q`<span class="index" title="#{s2}">#{s1}</span>`
|
867
|
+
end
|
868
|
+
def inline_hidx(str)
|
869
|
+
_, s2 = _compile_term(str)
|
870
|
+
%Q`<span class="index" title="#{s2}"></span>`
|
871
|
+
end
|
872
|
+
def inline_term(str)
|
873
|
+
s1, s2 = _compile_term(str)
|
874
|
+
%Q`<span class="index term" title="#{s2}">#{s1}</span>`
|
875
|
+
end
|
876
|
+
def on_inline_termnoidx(str)
|
877
|
+
%Q`<span class="term">#{yield}</span>`
|
878
|
+
end
|
879
|
+
|
880
|
+
def _compile_term(str)
|
881
|
+
arr = []
|
882
|
+
placeholder = "---"
|
883
|
+
display_str, see = parse_term(str, placeholder) do |term, term_e, yomi|
|
884
|
+
if yomi
|
885
|
+
arr << escape(yomi)
|
886
|
+
else
|
887
|
+
arr << term_e
|
888
|
+
end
|
889
|
+
end
|
890
|
+
title_attr = arr.join()
|
891
|
+
title_attr += " → see: #{escape(see)}" if see
|
892
|
+
return display_str, title_attr
|
893
|
+
end
|
894
|
+
private :_compile_term
|
895
|
+
|
612
896
|
end
|
613
897
|
|
614
898
|
|
615
899
|
class TEXTBuilder
|
616
900
|
|
901
|
+
def target_name
|
902
|
+
"text"
|
903
|
+
end
|
904
|
+
|
617
905
|
## nestable inline commands
|
618
906
|
|
619
907
|
def on_inline_i() ; "<i>#{yield}</i>" ; end
|