review-retrovert 0.2.2 → 0.9.1
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/.github/workflows/retrovert.yml +39 -0
- data/.gitignore +2 -2
- data/.ruby-version +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +68 -2
- data/README.md +6 -3
- data/lib/review/retrovert/cli.rb +2 -0
- data/lib/review/retrovert/converter.rb +255 -16
- data/lib/review/retrovert/version.rb +1 -1
- data/review-retrovert.gemspec +1 -1
- data/testdata/mybook/.gitignore +7 -0
- data/testdata/mybook/README.md +43 -0
- data/testdata/mybook/Rakefile +16 -0
- data/testdata/mybook/catalog.yml +33 -0
- data/testdata/mybook/config-starter.yml +139 -0
- data/testdata/mybook/config.yml +375 -0
- data/testdata/mybook/contents/00-preface.re +83 -0
- data/testdata/mybook/contents/01-install.re +272 -0
- data/testdata/mybook/contents/02-tutorial.re +1008 -0
- data/testdata/mybook/contents/03-syntax.re +2613 -0
- data/testdata/mybook/contents/04-customize.re +728 -0
- data/testdata/mybook/contents/05-faq.re +328 -0
- data/testdata/mybook/contents/06-bestpractice.re +971 -0
- data/testdata/mybook/contents/91-compare.re +18 -0
- data/testdata/mybook/contents/92-filelist.re +119 -0
- data/testdata/mybook/contents/93-background.re +267 -0
- data/testdata/mybook/contents/99-postface.re +38 -0
- data/testdata/mybook/css/normalize.css +349 -0
- data/testdata/mybook/css/webstyle.css +514 -0
- data/testdata/mybook/images/03-syntax/favicon-16x16.png +0 -0
- data/testdata/mybook/images/03-syntax/figure_heretop.png +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon1.jpg +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon2.jpg +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon3.jpg +0 -0
- data/testdata/mybook/images/03-syntax/tw-icon4.jpg +0 -0
- data/testdata/mybook/images/04-customize/caption_pagebreak.png +0 -0
- data/testdata/mybook/images/04-customize/chaptitlepage_sample.png +0 -0
- data/testdata/mybook/images/05-faq/codeblock_rpadding1.png +0 -0
- data/testdata/mybook/images/05-faq/codeblock_rpadding2.png +0 -0
- data/testdata/mybook/images/06-bestpractice/figure_heretop.png +0 -0
- data/testdata/mybook/images/06-bestpractice/font_beramono.png +0 -0
- data/testdata/mybook/images/06-bestpractice/heading_design1.png +0 -0
- data/testdata/mybook/images/06-bestpractice/heading_design2.png +0 -0
- data/testdata/mybook/images/06-bestpractice/margin_book.png +0 -0
- data/testdata/mybook/images/06-bestpractice/multiline-title.png +0 -0
- data/testdata/mybook/images/06-bestpractice/preface_numbered.png +0 -0
- data/testdata/mybook/images/06-bestpractice/program_border.png +0 -0
- data/testdata/mybook/images/06-bestpractice/sechead_design_4.png +0 -0
- data/testdata/mybook/images/06-bestpractice/titlepage-samples.png +0 -0
- data/testdata/mybook/images/93-background/bug913.png +0 -0
- data/testdata/mybook/images/93-background/slide2.png +0 -0
- data/testdata/mybook/images/cover_a5.pdf +0 -0
- data/testdata/mybook/images/cover_b5.pdf +0 -0
- data/testdata/mybook/images/tw-icon.jpg +0 -0
- data/testdata/mybook/layouts/layout.epub.erb +29 -0
- data/testdata/mybook/layouts/layout.html5.erb +106 -0
- data/testdata/mybook/layouts/layout.tex.erb +546 -0
- data/testdata/mybook/lib/hooks/beforetexcompile.rb +55 -0
- data/testdata/mybook/lib/ruby/review-builder.rb +503 -0
- data/testdata/mybook/lib/ruby/review-cli.rb +58 -0
- data/testdata/mybook/lib/ruby/review-compiler.rb +523 -0
- data/testdata/mybook/lib/ruby/review-epubmaker.rb +606 -0
- data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +661 -0
- data/testdata/mybook/lib/ruby/review-latexbuilder.rb +782 -0
- data/testdata/mybook/lib/ruby/review-maker.rb +235 -0
- data/testdata/mybook/lib/ruby/review-monkeypatch.rb +91 -0
- data/testdata/mybook/lib/ruby/review-pdfmaker.rb +468 -0
- data/testdata/mybook/lib/ruby/review-textbuilder.rb +36 -0
- data/testdata/mybook/lib/ruby/review-tocparser.rb +285 -0
- data/testdata/mybook/lib/ruby/review-webmaker.rb +433 -0
- data/testdata/mybook/lib/tasks/mytasks.rake +31 -0
- data/testdata/mybook/lib/tasks/review.rake +142 -0
- data/testdata/mybook/lib/tasks/review.rake.orig +72 -0
- data/testdata/mybook/lib/tasks/starter.rake +326 -0
- data/testdata/mybook/locale.yml +6 -0
- data/testdata/mybook/review-ext.rb +206 -0
- data/testdata/mybook/sty/jumoline.sty +310 -0
- data/testdata/mybook/sty/mycolophon.sty +81 -0
- data/testdata/mybook/sty/mystyle.sty +8 -0
- data/testdata/mybook/sty/mytextsize.sty +61 -0
- data/testdata/mybook/sty/mytitlepage.sty +103 -0
- data/testdata/mybook/sty/reviewmacro.sty +60 -0
- data/testdata/mybook/sty/starter-codeblock.sty +332 -0
- data/testdata/mybook/sty/starter-color.sty +79 -0
- data/testdata/mybook/sty/starter-font.sty +112 -0
- data/testdata/mybook/sty/starter-heading.sty +514 -0
- data/testdata/mybook/sty/starter-note.sty +127 -0
- data/testdata/mybook/sty/starter-section.sty +262 -0
- data/testdata/mybook/sty/starter-toc.sty +72 -0
- data/testdata/mybook/sty/starter.sty +554 -0
- data/testdata/mybook/style.css +597 -0
- metadata +100 -3
@@ -0,0 +1,661 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
###
|
4
|
+
### ReVIEW::HTMLBuilderクラスを拡張する
|
5
|
+
###
|
6
|
+
|
7
|
+
require 'review/htmlbuilder'
|
8
|
+
|
9
|
+
|
10
|
+
module ReVIEW
|
11
|
+
|
12
|
+
defined?(HTMLBuilder) or raise "internal error: HTMLBuilder not found."
|
13
|
+
|
14
|
+
|
15
|
+
class HTMLBuilder
|
16
|
+
|
17
|
+
attr_accessor :starter_config
|
18
|
+
|
19
|
+
def layoutfile
|
20
|
+
## 'rake web' のときに使うレイアウトファイルを 'layout.html5.erb' へ変更
|
21
|
+
if @book.config.maker == 'webmaker'
|
22
|
+
htmldir = 'web/html'
|
23
|
+
#localfilename = 'layout-web.html.erb'
|
24
|
+
localfilename = 'layout.html5.erb'
|
25
|
+
else
|
26
|
+
htmldir = 'html'
|
27
|
+
localfilename = 'layout.html.erb'
|
28
|
+
end
|
29
|
+
## 以下はリファクタリングした結果
|
30
|
+
basename = @book.htmlversion == 5 ? 'layout-html5.html.erb' : 'layout-xhtml1.html.erb'
|
31
|
+
htmlfilename = File.join(htmldir, basename)
|
32
|
+
#
|
33
|
+
layout_file = File.join(@book.basedir, 'layouts', localfilename)
|
34
|
+
if ! File.exist?(layout_file)
|
35
|
+
! File.exist?(File.join(@book.basedir, 'layouts', 'layout.erb')) or
|
36
|
+
raise ReVIEW::ConfigError, 'layout.erb is obsoleted. Please use layout.html.erb.'
|
37
|
+
layout_file = nil
|
38
|
+
elsif ENV['REVIEW_SAFE_MODE'].to_i & 4 > 0
|
39
|
+
warn "user's layout is prohibited in safe mode. ignored."
|
40
|
+
layout_file = nil
|
41
|
+
end
|
42
|
+
layout_file ||= File.expand_path(htmlfilename, ReVIEW::Template::TEMPLATE_DIR)
|
43
|
+
return layout_file
|
44
|
+
end
|
45
|
+
|
46
|
+
def result
|
47
|
+
# default XHTML header/footer
|
48
|
+
@title = strip_html(compile_inline(@chapter.title))
|
49
|
+
@body = @output.string
|
50
|
+
@language = @book.config['language']
|
51
|
+
@stylesheets = @book.config['stylesheet']
|
52
|
+
@next = @chapter.next_chapter
|
53
|
+
@prev = @chapter.prev_chapter
|
54
|
+
@next_title = @next ? compile_inline(@next.title) : ''
|
55
|
+
@prev_title = @prev ? compile_inline(@prev.title) : ''
|
56
|
+
|
57
|
+
if @book.config.maker == 'webmaker'
|
58
|
+
#@toc = ReVIEW::WEBTOCPrinter.book_to_string(@book) #-
|
59
|
+
@toc = ReVIEW::WEBTOCPrinter.book_to_html(@book, @chapter) #+
|
60
|
+
end
|
61
|
+
|
62
|
+
ReVIEW::Template.load(layoutfile).result(binding)
|
63
|
+
end
|
64
|
+
|
65
|
+
def headline(level, label, caption)
|
66
|
+
prefix, anchor = headline_prefix(level)
|
67
|
+
prefix = "<span class=\"secno\">#{prefix}</span> " if prefix
|
68
|
+
puts "" if level > 1
|
69
|
+
a_id = ""
|
70
|
+
a_id = "<a id=\"h#{anchor}\"></a>" if anchor
|
71
|
+
#
|
72
|
+
if caption.empty?
|
73
|
+
puts a_id if label
|
74
|
+
else
|
75
|
+
br = ""
|
76
|
+
attr = label ? " id=\"#{normalize_id(label)}\"" : ""
|
77
|
+
conf = @starter_config
|
78
|
+
case level
|
79
|
+
when 1 ; attr << " class=\"#{conf['chapter_decoration']} #{conf['chapter_align']} #{conf['chapter_oneline'] ? 'oneline' : 'twolines'}\"" if prefix
|
80
|
+
attr << " class=\"none #{conf['chapter_align']}\"" unless prefix
|
81
|
+
br = "<br/>" unless conf['chapter_oneline']
|
82
|
+
when 2 ; attr << " class=\"#{conf['section_decoration']}\""
|
83
|
+
when 3 ; attr << " class=\"#{conf['subsection_decoration']}\""
|
84
|
+
end
|
85
|
+
puts "<h#{level}#{attr}>#{a_id}#{prefix}#{br}#{compile_inline(caption)}</h#{level}>"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def result_metric(array)
|
90
|
+
attrs = {}
|
91
|
+
array.each do |item|
|
92
|
+
k = item.keys[0]
|
93
|
+
v = item[k]
|
94
|
+
if k == 'border' && v == 'on'
|
95
|
+
k = 'class'; v = 'border-on'
|
96
|
+
end
|
97
|
+
(attrs[k] ||= []) << v
|
98
|
+
end
|
99
|
+
attrs.map {|k, arr| " #{k}=\"#{arr.join(' ')}\"" }.join()
|
100
|
+
end
|
101
|
+
|
102
|
+
def image_image(id, caption, metric)
|
103
|
+
src = @chapter.image(id).path.sub(%r{\A\./}, '')
|
104
|
+
alt = escape_html(compile_inline(caption))
|
105
|
+
metrics = parse_metric('html', metric)
|
106
|
+
metrics = " class=\"img\"" unless metrics.present?
|
107
|
+
puts "<div id=\"#{normalize_id(id)}\" class=\"image\">"
|
108
|
+
puts "<img src=\"#{src}\" alt=\"#{alt}\"#{metrics} />"
|
109
|
+
image_header(id, caption)
|
110
|
+
puts "</div>"
|
111
|
+
end
|
112
|
+
|
113
|
+
## コードブロック(//program, //terminal)
|
114
|
+
|
115
|
+
def program(lines, id=nil, caption=nil, optionstr=nil)
|
116
|
+
_codeblock('program', 'code', lines, id, caption, optionstr)
|
117
|
+
end
|
118
|
+
|
119
|
+
def terminal(lines, id=nil, caption=nil, optionstr=nil)
|
120
|
+
_codeblock('terminal', 'cmd-code', lines, id, caption, optionstr)
|
121
|
+
end
|
122
|
+
|
123
|
+
protected
|
124
|
+
|
125
|
+
def _codeblock(blockname, classname, lines, id, caption, optionstr)
|
126
|
+
## ブロックコマンドのオプション引数はCompilerクラスでパースすべき。
|
127
|
+
## しかしCompilerクラスがそのような設計になってないので、
|
128
|
+
## 仕方ないのでBuilderクラスでパースする。
|
129
|
+
opts = _parse_codeblock_optionstr(optionstr, blockname)
|
130
|
+
CODEBLOCK_OPTIONS.each {|k, v| opts[k] = v unless opts.key?(k) }
|
131
|
+
#
|
132
|
+
if opts['eolmark']
|
133
|
+
lines = lines.map {|line| "#{detab(line)}<small class=\"startereolmark\"></small>" }
|
134
|
+
else
|
135
|
+
lines = lines.map {|line| detab(line) }
|
136
|
+
end
|
137
|
+
#
|
138
|
+
indent_w = opts['indentwidth']
|
139
|
+
if indent_w && indent_w > 0
|
140
|
+
indent_str = " " * (indent_w - 1) + '<span class="indentbar"> </span>'
|
141
|
+
lines = lines.map {|line|
|
142
|
+
line.sub(/\A( +)/) {
|
143
|
+
m, n = ($1.length - 1).divmod indent_w
|
144
|
+
" " << indent_str * m << " " * n
|
145
|
+
}
|
146
|
+
}
|
147
|
+
end
|
148
|
+
#
|
149
|
+
puts "<div id=\"#{normalize_id(id)}\" class=\"#{classname}\">" if id.present?
|
150
|
+
puts "<div class=\"#{classname}\">" unless id.present?
|
151
|
+
#
|
152
|
+
if id.present? || caption.present?
|
153
|
+
str = _build_caption_str(id, caption)
|
154
|
+
print "<span class=\"caption\">#{str}</span>\n"
|
155
|
+
classattr = "list"
|
156
|
+
else
|
157
|
+
classattr = "emlist"
|
158
|
+
end
|
159
|
+
#
|
160
|
+
lang = opts['lang']
|
161
|
+
lang = File.extname(id || "").gsub(".", "") if lang.blank?
|
162
|
+
classattr << " language-#{lang}" unless lang.blank?
|
163
|
+
classattr << " highlight" if highlight?
|
164
|
+
print "<pre class=\"#{classattr}\">"
|
165
|
+
#
|
166
|
+
gen = opts['lineno'] ? LineNumberGenerator.new(opts['lineno']).each : nil
|
167
|
+
if gen
|
168
|
+
width = opts['linenowidth']
|
169
|
+
if width < 0
|
170
|
+
format = "%s"
|
171
|
+
elsif width == 0
|
172
|
+
last_lineno = gen.each.take(lines.length).compact.last
|
173
|
+
width = last_lineno.to_s.length
|
174
|
+
format = "%#{width}s"
|
175
|
+
else
|
176
|
+
format = "%#{width}s"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
buf = []
|
180
|
+
start_tag = opts['linenowidth'] >= 0 ? "<em class=\"linenowidth\">" : "<em class=\"lineno\">"
|
181
|
+
lines.each_with_index do |line, i|
|
182
|
+
buf << start_tag << (format % gen.next) << ": </em>" if gen
|
183
|
+
buf << line << "\n"
|
184
|
+
end
|
185
|
+
puts highlight(body: buf.join(), lexer: lang,
|
186
|
+
format: "html", linenum: !!gen,
|
187
|
+
#options: {linenostart: start}
|
188
|
+
)
|
189
|
+
#
|
190
|
+
print "</pre>\n"
|
191
|
+
print "</div>\n"
|
192
|
+
end
|
193
|
+
|
194
|
+
public
|
195
|
+
|
196
|
+
## コードリスト(//list, //emlist, //listnum, //emlistnum, //cmd, //source)
|
197
|
+
def list(lines, id=nil, caption=nil, lang=nil)
|
198
|
+
_codeblock("list", "caption-code", lines, id, caption, _codeblock_optstr(lang, false))
|
199
|
+
end
|
200
|
+
def listnum(lines, id=nil, caption=nil, lang=nil)
|
201
|
+
_codeblock("listnum", "code", lines, id, caption, _codeblock_optstr(lang, true))
|
202
|
+
end
|
203
|
+
def emlist(lines, caption=nil, lang=nil)
|
204
|
+
_codeblock("emlist", "emlist-code", lines, nil, caption, _codeblock_optstr(lang, false))
|
205
|
+
end
|
206
|
+
def emlistnum(lines, caption=nil, lang=nil)
|
207
|
+
_codeblock("emlistnum", "emlistnum-code", lines, nil, caption, _codeblock_optstr(lang, true))
|
208
|
+
end
|
209
|
+
def source(lines, caption=nil, lang=nil)
|
210
|
+
_codeblock("source", "source-code", lines, nil, caption, _codeblock_optstr(lang, false))
|
211
|
+
end
|
212
|
+
def cmd(lines, caption=nil, lang=nil)
|
213
|
+
lang ||= "shell-session"
|
214
|
+
_codeblock("cmd", "cmd-code", lines, nil, caption, _codeblock_optstr(lang, false))
|
215
|
+
end
|
216
|
+
def _codeblock_optstr(lang, lineno_flag)
|
217
|
+
arr = []
|
218
|
+
arr << lang if lang
|
219
|
+
if lineno_flag
|
220
|
+
first_line_num = line_num()
|
221
|
+
arr << "lineno=#{first_line_num}"
|
222
|
+
arr << "linenowidth=0"
|
223
|
+
end
|
224
|
+
return arr.join(",")
|
225
|
+
end
|
226
|
+
private :_codeblock_optstr
|
227
|
+
|
228
|
+
protected
|
229
|
+
|
230
|
+
## @<secref>{}
|
231
|
+
|
232
|
+
def _build_secref(chap, num, title, parent_title)
|
233
|
+
s = ""
|
234
|
+
## 親セクションのタイトルがあれば使う
|
235
|
+
if parent_title
|
236
|
+
s << "「%s」内の" % parent_title # TODO: I18n化
|
237
|
+
end
|
238
|
+
## 対象セクションへのリンクを作成する
|
239
|
+
if @book.config['chapterlink']
|
240
|
+
filename = "#{chap.id}#{extname()}"
|
241
|
+
dom_id = 'h' + num.gsub('.', '-')
|
242
|
+
s << "「<a href=\"#{filename}##{dom_id}\">#{title}</a>」"
|
243
|
+
else
|
244
|
+
s << "「#{title}」"
|
245
|
+
end
|
246
|
+
return s
|
247
|
+
end
|
248
|
+
|
249
|
+
public
|
250
|
+
|
251
|
+
## 順序つきリスト
|
252
|
+
|
253
|
+
def ol_begin(start_num=nil)
|
254
|
+
@_ol_types ||= [] # stack
|
255
|
+
case start_num
|
256
|
+
when nil
|
257
|
+
type = "1"; start = 1
|
258
|
+
when /\A(\d+)\.\z/
|
259
|
+
type = "1"; start = $1.to_i
|
260
|
+
when /\A([A-Z])\.\z/
|
261
|
+
type = "A"; start = $1.ord - 'A'.ord + 1
|
262
|
+
when /\A([a-z])\.\z/
|
263
|
+
type = "a"; start = $1.ord - 'a'.ord + 1
|
264
|
+
else
|
265
|
+
type = nil; start = nil
|
266
|
+
end
|
267
|
+
if type
|
268
|
+
puts "<ol start=\"#{start}\" type=\"#{type}\">"
|
269
|
+
else
|
270
|
+
puts "<ol class=\"ol-none\">"
|
271
|
+
end
|
272
|
+
@_ol_types.push(type)
|
273
|
+
end
|
274
|
+
|
275
|
+
def ol_end()
|
276
|
+
ol = !! @_ol_types.pop()
|
277
|
+
if ol
|
278
|
+
puts "</ol>"
|
279
|
+
else
|
280
|
+
puts "</ol>"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def ol_item_begin(lines, num)
|
285
|
+
ol = !! @_ol_types[-1]
|
286
|
+
if ol
|
287
|
+
print "<li>#{lines.join}"
|
288
|
+
else
|
289
|
+
n = escape_html(num)
|
290
|
+
print "<li data-mark=\"#{n}\"><span class=\"li-mark\">#{n} </span>#{lines.join}"
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def ol_item_end()
|
295
|
+
puts "</li>"
|
296
|
+
end
|
297
|
+
|
298
|
+
## 入れ子可能なブロック命令
|
299
|
+
|
300
|
+
def on_minicolumn(type, caption, &b)
|
301
|
+
puts "<div class=\"#{type}\">"
|
302
|
+
puts "<p class=\"caption\">#{compile_inline(caption)}</p>" if caption.present?
|
303
|
+
yield
|
304
|
+
puts '</div>'
|
305
|
+
end
|
306
|
+
protected :on_minicolumn
|
307
|
+
|
308
|
+
def on_sideimage_block(imagefile, imagewidth, option_str=nil, &b)
|
309
|
+
imagefile, imagewidth, opts = validate_sideimage_args(imagefile, imagewidth, option_str)
|
310
|
+
filepath = find_image_filepath(imagefile)
|
311
|
+
side = (opts['side'] || 'L') == 'L' ? 'left' : 'right'
|
312
|
+
imgclass = opts['border'] ? "image-bordered" : nil
|
313
|
+
normalize = proc {|s| s =~ /^\A(\d+(\.\d+))%\z/ ? "#{$1.to_f/100.0}\\textwidth" : s }
|
314
|
+
imgwidth = normalize.call(imagewidth)
|
315
|
+
boxwidth = normalize.call(opts['boxwidth']) || imgwidth
|
316
|
+
sepwidth = normalize.call(opts['sep'] || "0pt")
|
317
|
+
#
|
318
|
+
puts "<div class=\"sideimage\">\n"
|
319
|
+
puts " <div class=\"sideimage-image\" style=\"float:#{side};text-align:center;width:#{boxwidth}\">\n"
|
320
|
+
puts " <img src=\"#{filepath}\" class=\"#{imgclass}\" style=\"width:#{imgwidth}\"/>\n"
|
321
|
+
puts " </div>\n"
|
322
|
+
puts " <div class=\"sideimage-text\" style=\"margin-#{side}:#{boxwidth}\">\n"
|
323
|
+
puts " <div style=\"padding-#{side}:#{sepwidth}\">\n"
|
324
|
+
yield
|
325
|
+
puts " </div>\n"
|
326
|
+
puts " </div>\n"
|
327
|
+
puts "</div>\n"
|
328
|
+
end
|
329
|
+
|
330
|
+
#### ブロック命令
|
331
|
+
|
332
|
+
def footnote(id, str)
|
333
|
+
id_val = "fn-#{normalize_id(id)}"
|
334
|
+
href = "#fnb-#{normalize_id(id)}"
|
335
|
+
text = compile_inline(str)
|
336
|
+
chap_num = @chapter.footnote(id).number
|
337
|
+
if @book.config['epubversion'].to_i == 3
|
338
|
+
attr = " epub:type=\"footnote\""
|
339
|
+
mark = "[*#{chap_num}]"
|
340
|
+
else
|
341
|
+
attr = ""
|
342
|
+
mark = "[<a href=\"#{href}\">*#{chap_num}</a>]"
|
343
|
+
end
|
344
|
+
#
|
345
|
+
if truncate_if_endwith?("</div><!--/.footnote-list-->\n")
|
346
|
+
else
|
347
|
+
puts "<div class=\"footnote-list\">"
|
348
|
+
end
|
349
|
+
print "<div class=\"footnote\" id=\"#{id_val}\"#{attr}>"
|
350
|
+
print "<p class=\"footnote\">"
|
351
|
+
print "<span class=\"footnote-mark\">#{mark} </span>"
|
352
|
+
print text
|
353
|
+
print "</p>"
|
354
|
+
puts "</div>"
|
355
|
+
puts "</div><!--/.footnote-list-->\n"
|
356
|
+
end
|
357
|
+
|
358
|
+
alias __original_texequation texequation
|
359
|
+
def texequation(lines, label=nil, caption=nil)
|
360
|
+
if label.present?
|
361
|
+
chap = get_chap()
|
362
|
+
if chap.nil?
|
363
|
+
key = "format_number_header_without_chapter"
|
364
|
+
args = [@chapter.equation(label).number]
|
365
|
+
else
|
366
|
+
key = "format_number_header"
|
367
|
+
args = [chap, @chapter.equation(label).number]
|
368
|
+
end
|
369
|
+
s1 = I18n.t("equation")
|
370
|
+
s2 = I18n.t(key, args)
|
371
|
+
s3 = I18n.t("caption_prefix")
|
372
|
+
s4 = compile_inline(caption)
|
373
|
+
puts "<span class=\"caption\">#{s1}#{s2}#{s3}#{s4}</span>"
|
374
|
+
has_caption_line = true
|
375
|
+
elsif caption.present?
|
376
|
+
s3 = I18n.t("caption_prefix")
|
377
|
+
s4 = compile_inline(caption)
|
378
|
+
puts "<span class=\"caption\">#{s3}#{s4}</span>"
|
379
|
+
has_caption_line = true
|
380
|
+
else
|
381
|
+
has_caption_line = false
|
382
|
+
end
|
383
|
+
#
|
384
|
+
__original_texequation(lines)
|
385
|
+
end
|
386
|
+
|
387
|
+
## 章 (Chapter) の概要
|
388
|
+
def abstract(lines)
|
389
|
+
puts '<div class="abstract">'
|
390
|
+
puts lines
|
391
|
+
puts '</div>'
|
392
|
+
end
|
393
|
+
|
394
|
+
## 章タイトルを独立したページに
|
395
|
+
def makechaptitlepage(option=nil)
|
396
|
+
puts '' # HTMLでは特に何もしない
|
397
|
+
end
|
398
|
+
|
399
|
+
## 縦方向のスペースがなければ改ページ
|
400
|
+
def needvspace(builder_name, height)
|
401
|
+
if builder_name == 'html' || builder_name == 'epub'
|
402
|
+
puts "<div style=\"height:#{height}\"></div>"
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
## 段(Paragraph)の終わりにスペースを入れる
|
407
|
+
def paragraphend()
|
408
|
+
puts '' # HTMLでは特に何もしない
|
409
|
+
end
|
410
|
+
|
411
|
+
## 小段(Subparagraph)の終わりにスペースを入れる(あれば)
|
412
|
+
def subparagraphend()
|
413
|
+
puts '' # HTMLでは特に何もしない
|
414
|
+
end
|
415
|
+
|
416
|
+
## 引用(複数段落に対応)
|
417
|
+
def blockquote(lines)
|
418
|
+
puts '<blockquote class="blockquote">'
|
419
|
+
puts lines
|
420
|
+
puts '</blockquote>'
|
421
|
+
end
|
422
|
+
|
423
|
+
## 引用(//quote{ ... //})
|
424
|
+
## (入れ子対応なので、中に箇条書きや別のブロックを入れられる)
|
425
|
+
def on_quote_block()
|
426
|
+
puts '<blockquote class="blockquote">'
|
427
|
+
yield
|
428
|
+
puts '</blockquote>'
|
429
|
+
end
|
430
|
+
def quote(lines)
|
431
|
+
on_quote_block() do
|
432
|
+
puts lines
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
## 引用 (====[quote] ... ====[/quote])
|
437
|
+
## (ブロック構文ではないので、中に別のブロックや箇条書きを入れられる)
|
438
|
+
def quote_begin(level, label, caption)
|
439
|
+
puts '<blockquote class="blockquote">'
|
440
|
+
end
|
441
|
+
def quote_end(level)
|
442
|
+
puts '</blockquote>'
|
443
|
+
end
|
444
|
+
|
445
|
+
## ノート(//note{ ... //})
|
446
|
+
## (入れ子対応なので、中に箇条書きや別のブロックを入れられる)
|
447
|
+
def on_note_block(label=nil, caption=nil)
|
448
|
+
caption, label = label, nil if caption.nil?
|
449
|
+
if label
|
450
|
+
puts "<div class=\"note\" id=\"#{label}\">"
|
451
|
+
else
|
452
|
+
puts "<div class=\"note\">"
|
453
|
+
end
|
454
|
+
puts "<h5>#{compile_inline(caption)}</h5>" if caption.present?
|
455
|
+
yield
|
456
|
+
puts "</div>"
|
457
|
+
end
|
458
|
+
def note(lines, label=nil, caption=nil)
|
459
|
+
on_quote_block(label, caption) do
|
460
|
+
puts lines
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
## ノート (====[note] ... ====[/note])
|
465
|
+
## (ブロック構文ではないので、中に別のブロックや箇条書きを入れられる)
|
466
|
+
def note_begin(level, label, caption)
|
467
|
+
s = compile_inline(caption || "")
|
468
|
+
puts "<div class=\"note\">"
|
469
|
+
puts "<h5>#{s}</h5>" if s.present?
|
470
|
+
end
|
471
|
+
def note_end(level)
|
472
|
+
puts "</div>"
|
473
|
+
end
|
474
|
+
|
475
|
+
#### インライン命令
|
476
|
+
|
477
|
+
def inline_fn(id)
|
478
|
+
if @book.config['epubversion'].to_i == 3
|
479
|
+
type = " epub:type=\"noteref\""
|
480
|
+
else
|
481
|
+
type = ""
|
482
|
+
end
|
483
|
+
return "<sup><a id=\"fnb-#{normalize_id(id)}\" href=\"#fn-#{normalize_id(id)}\" class=\"noteref\"#{type}>*#{@chapter.footnote(id).number}</a></sup>"
|
484
|
+
rescue KeyError
|
485
|
+
error "unknown footnote: #{id}"
|
486
|
+
end
|
487
|
+
|
488
|
+
## ファイル名
|
489
|
+
def inline_file(str)
|
490
|
+
on_inline_file { escape(str) }
|
491
|
+
end
|
492
|
+
def on_inline_file
|
493
|
+
"<span class=\"file\">#{yield}</span>"
|
494
|
+
end
|
495
|
+
|
496
|
+
## ユーザ入力
|
497
|
+
def inline_userinput(str)
|
498
|
+
on_inline_input { escape(str) }
|
499
|
+
end
|
500
|
+
def on_inline_userinput
|
501
|
+
"<span class=\"userinput\">#{yield}</span>"
|
502
|
+
end
|
503
|
+
|
504
|
+
## 引数をそのまま表示 (No Operation)
|
505
|
+
def inline_nop(str)
|
506
|
+
escape_html(str || "")
|
507
|
+
end
|
508
|
+
alias inline_letitgo inline_nop
|
509
|
+
|
510
|
+
## 目立たせない(@<strong>{} の反対)
|
511
|
+
def inline_weak(str)
|
512
|
+
on_inline_weak { escape(str) }
|
513
|
+
end
|
514
|
+
def on_inline_weak
|
515
|
+
"<span class=\"weak\">#{yield}</span>"
|
516
|
+
end
|
517
|
+
|
518
|
+
## 文字を小さくする
|
519
|
+
def inline_small(str) ; on_inline_small { escape(str) } ; end
|
520
|
+
def inline_xsmall(str) ; on_inline_xsmall { escape(str) } ; end
|
521
|
+
def inline_xxsmall(str) ; on_inline_xxsmall { escape(str) } ; end
|
522
|
+
|
523
|
+
def on_inline_small ; "<small style=\"font-size:small\">#{yield}</small>" ; end
|
524
|
+
def on_inline_xsmall ; "<small style=\"font-size:x-small\">#{yield}</small>" ; end
|
525
|
+
def on_inline_xxsmall ; "<small style=\"font-size:xx-small\">#{yield}</small>"; end
|
526
|
+
|
527
|
+
## 文字を大きくする
|
528
|
+
def inline_large(str) ; on_inline_large { escape(str) } ; end
|
529
|
+
def inline_xlarge(str) ; on_inline_xlarge { escape(str) } ; end
|
530
|
+
def inline_xxlarge(str) ; on_inline_xxlarge { escape(str) } ; end
|
531
|
+
def on_inline_large ; "<span style=\"font-size:large\">#{yield}</span>" ; end
|
532
|
+
def on_inline_xlarge ; "<span style=\"font-size:x-large\">#{yield}</span>" ; end
|
533
|
+
def on_inline_xxlarge ; "<span style=\"font-size:xx-large\">#{yield}</span>"; end
|
534
|
+
|
535
|
+
## 文字を大きくした@<strong>{}
|
536
|
+
def inline_xstrong(str) ; on_inline_xstrong { escape(str) }; end
|
537
|
+
def inline_xxstrong(str); on_inline_xxstrong { escape(str) }; end
|
538
|
+
def on_inline_xstrong ; "<span style=\"font-size:x-large\">#{yield}</span>"; end
|
539
|
+
def on_inline_xxstrong; "<span style=\"font-size:xx-large\">#{yield}</span>"; end
|
540
|
+
|
541
|
+
## コードブロック中で折り返し箇所を手動で指定する
|
542
|
+
def inline_foldhere(arg)
|
543
|
+
'<br>'
|
544
|
+
end
|
545
|
+
|
546
|
+
## ターミナルでのカーソル(背景が白、文字が黒)
|
547
|
+
def inline_cursor(str)
|
548
|
+
"<span class=\"cursor\">#{escape_html(str)}</span>"
|
549
|
+
end
|
550
|
+
|
551
|
+
## nestable inline commands
|
552
|
+
|
553
|
+
def on_inline_i() ; "<i>#{yield}</i>" ; end
|
554
|
+
def on_inline_b() ; "<b>#{yield}</b>" ; end
|
555
|
+
def on_inline_code() ; "<code>#{yield}</code>" ; end
|
556
|
+
def on_inline_tt() ; "<tt>#{yield}</tt>" ; end
|
557
|
+
def on_inline_del() ; "<s>#{yield}</s>" ; end
|
558
|
+
def on_inline_sub() ; "<sub>#{yield}</sub>" ; end
|
559
|
+
def on_inline_sup() ; "<sup>#{yield}</sup>" ; end
|
560
|
+
def on_inline_em() ; "<em>#{yield}</em>" ; end
|
561
|
+
def on_inline_strong(); "<strong>#{yield}</strong>" ; end
|
562
|
+
def on_inline_u() ; "<u>#{yield}</u>" ; end
|
563
|
+
def on_inline_ami() ; "<span class=\"ami\">#{yield}</span>"; end
|
564
|
+
def on_inline_balloon(); "<span class=\"balloon\">← #{yield}</span>"; end
|
565
|
+
|
566
|
+
def build_inline_href(url, escaped_label) # compile_href()をベースに改造
|
567
|
+
flag_link = @book.config['externallink']
|
568
|
+
return _inline_hyperlink(url, escaped_label, flag_link)
|
569
|
+
end
|
570
|
+
|
571
|
+
def inline_hlink(str)
|
572
|
+
url, label = str.split(/, /, 2)
|
573
|
+
flag_link = @book.config['externallink']
|
574
|
+
return _inline_hyperlink(url, escape(label), flag_link)
|
575
|
+
end
|
576
|
+
|
577
|
+
def _inline_hyperlink(url, escaped_label, flag_link)
|
578
|
+
if flag_link
|
579
|
+
label = escaped_label || escape_html(url)
|
580
|
+
"<a href=\"#{escape_html(url)}\" class=\"link\">#{label}</a>"
|
581
|
+
elsif escaped_label
|
582
|
+
I18n.t('external_link', [escaped_label, escape_html(url)])
|
583
|
+
else
|
584
|
+
escape_html(url)
|
585
|
+
end
|
586
|
+
end
|
587
|
+
private :_inline_hyperlink
|
588
|
+
|
589
|
+
def build_inline_ruby(escaped_word, escaped_yomi) # compile_ruby()をベースに改造
|
590
|
+
pre = I18n.t('ruby_prefix'); post = I18n.t('ruby_postfix')
|
591
|
+
if @book.htmlversion == 5
|
592
|
+
"<ruby>#{escaped_word}<rp>#{pre}</rp><rt>#{escaped_yomi}</rt><rp>#{post}</rp></ruby>"
|
593
|
+
else
|
594
|
+
"<ruby><rb>#{escaped_word}</rb><rp>#{pre}</rp><rt>#{escaped_yomi}</rt><rp>#{post}</rp></ruby>"
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
598
|
+
protected
|
599
|
+
|
600
|
+
## ノートを参照する
|
601
|
+
def build_noteref(chapter, label, caption)
|
602
|
+
href = chapter ? "#{chapter.id}#{extname()}##{label}" : "##{label}"
|
603
|
+
%Q`ノート「<a href="#{href}">#{escape(caption)}</a>」`
|
604
|
+
end
|
605
|
+
|
606
|
+
## 数式を参照する
|
607
|
+
def build_eq(chapter, label, number)
|
608
|
+
s = "#{I18n.t('equation')}#{chapter.number}.#{number}"
|
609
|
+
"<a>#{escape(s)}</a>"
|
610
|
+
end
|
611
|
+
|
612
|
+
end
|
613
|
+
|
614
|
+
|
615
|
+
class TEXTBuilder
|
616
|
+
|
617
|
+
## nestable inline commands
|
618
|
+
|
619
|
+
def on_inline_i() ; "<i>#{yield}</i>" ; end
|
620
|
+
def on_inline_b() ; "<b>#{yield}</b>" ; end
|
621
|
+
def on_inline_code() ; "<code>#{yield}</code>" ; end
|
622
|
+
def on_inline_tt() ; "<tt>#{yield}</tt>" ; end
|
623
|
+
def on_inline_del() ; "<s>#{yield}</s>" ; end
|
624
|
+
def on_inline_sub() ; "<sub>#{yield}</sub>" ; end
|
625
|
+
def on_inline_sup() ; "<sup>#{yield}</sup>" ; end
|
626
|
+
def on_inline_em() ; "<em>#{yield}</em>" ; end
|
627
|
+
def on_inline_strong(); "<strong>#{yield}</strong>" ; end
|
628
|
+
def on_inline_u() ; "<u>#{yield}</u>" ; end
|
629
|
+
def on_inline_ami() ; "<span class=\"ami\">#{yield}</span>"; end
|
630
|
+
|
631
|
+
def build_inline_href(url, escaped_label) # compile_href()をベースに改造
|
632
|
+
if @book.config['externallink']
|
633
|
+
label = escaped_label || escape_html(url)
|
634
|
+
"<a href=\"#{escape_html(url)}\" class=\"link\">#{label}</a>"
|
635
|
+
elsif escaped_label
|
636
|
+
I18n.t('external_link', [escaped_label, escape_html(url)])
|
637
|
+
else
|
638
|
+
escape_html(url)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
def build_inline_ruby(escaped_word, escaped_yomi) # compile_ruby()をベースに改造
|
643
|
+
pre = I18n.t('ruby_prefix'); post = I18n.t('ruby_postfix')
|
644
|
+
if @book.htmlversion == 5
|
645
|
+
"<ruby>#{escaped_word}<rp>#{pre}</rp><rt>#{escaped_yomi}</rt><rp>#{post}</rp></ruby>"
|
646
|
+
else
|
647
|
+
"<ruby><rb>#{escaped_word}</rb><rp>#{pre}</rp><rt>#{escaped_yomi}</rt><rp>#{post}</rp></ruby>"
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
## その他
|
652
|
+
|
653
|
+
def inline_nop(str)
|
654
|
+
str || ''
|
655
|
+
end
|
656
|
+
alias inline_letitgo inline_nop
|
657
|
+
|
658
|
+
end
|
659
|
+
|
660
|
+
|
661
|
+
end
|