review-retrovert 0.9.7 → 0.9.8
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.
- 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
|