review-retrovert 0.9.11 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.editorconfig +1 -1
- data/.pinact.yaml +12 -0
- data/.ruby-version +1 -1
- data/Dockerfile +2 -1
- data/Dockerfile.local +13 -0
- data/Gemfile.lock +62 -35
- data/Rakefile +9 -0
- data/aqua.yaml +20 -0
- data/hooks/post_push +14 -1
- data/lib/review/retrovert/cli.rb +6 -0
- data/lib/review/retrovert/converter.rb +38 -0
- data/lib/review/retrovert/version.rb +1 -1
- data/lib/review/retrovert/yamlconfig.rb +38 -1
- data/review-retrovert.gemspec +18 -4
- data/zizmor.yml +5 -0
- metadata +53 -127
- data/.github/FUNDING.yml +0 -4
- data/.github/workflows/docker-build.yml +0 -26
- data/.github/workflows/release.yml +0 -26
- data/.github/workflows/retrovert.yml +0 -91
- data/testdata/mybook/.gitignore +0 -13
- data/testdata/mybook/.textlintrc +0 -11
- data/testdata/mybook/README.md +0 -43
- data/testdata/mybook/Rakefile +0 -24
- data/testdata/mybook/catalog.yml +0 -60
- data/testdata/mybook/config-noretrovert.yml +0 -404
- data/testdata/mybook/config-retrovert.yml +0 -16
- data/testdata/mybook/config-starter.yml +0 -264
- data/testdata/mybook/config.yml +0 -404
- data/testdata/mybook/contents/00-preface.re +0 -129
- data/testdata/mybook/contents/01-install.re +0 -305
- data/testdata/mybook/contents/02-tutorial.re +0 -1228
- data/testdata/mybook/contents/03-syntax.re +0 -4610
- data/testdata/mybook/contents/04-customize.re +0 -1064
- data/testdata/mybook/contents/05-faq.re +0 -606
- data/testdata/mybook/contents/06-bestpractice.re +0 -1343
- data/testdata/mybook/contents/91-compare.re +0 -418
- data/testdata/mybook/contents/92-filelist.re +0 -125
- data/testdata/mybook/contents/93-background.re +0 -267
- data/testdata/mybook/contents/99-postface.re +0 -39
- data/testdata/mybook/contents/r0-inner.re +0 -2
- data/testdata/mybook/contents/r0-root.re +0 -49
- data/testdata/mybook/contents/table.csv +0 -4
- data/testdata/mybook/contents/test.txt +0 -1
- data/testdata/mybook/contents/ut.re +0 -5
- data/testdata/mybook/css/normalize.css +0 -349
- data/testdata/mybook/css/webstyle.css +0 -692
- data/testdata/mybook/data/terms.txt +0 -3
- data/testdata/mybook/data/words.txt +0 -15
- 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/index-page.png +0 -0
- data/testdata/mybook/images/03-syntax/order-detail.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/04-customize/section_decoration_samples.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/05-faq/dummy-image.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/section_title_wlines.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/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/cover_a5.pdf +0 -0
- data/testdata/mybook/images/cover_b5.pdf +0 -0
- data/testdata/mybook/images/info-icon.png +0 -0
- data/testdata/mybook/images/tw-icon.jpg +0 -0
- data/testdata/mybook/images/warning-icon.png +0 -0
- data/testdata/mybook/layouts/layout.epub.erb +0 -29
- data/testdata/mybook/layouts/layout.html5.erb +0 -108
- data/testdata/mybook/layouts/layout.tex.erb +0 -432
- data/testdata/mybook/layouts/layout.tex.erb.orig +0 -386
- data/testdata/mybook/lib/hooks/beforetexcompile.rb +0 -55
- data/testdata/mybook/lib/ruby/review-book.rb +0 -64
- data/testdata/mybook/lib/ruby/review-builder.rb +0 -1342
- data/testdata/mybook/lib/ruby/review-cli.rb +0 -58
- data/testdata/mybook/lib/ruby/review-compiler.rb +0 -1176
- data/testdata/mybook/lib/ruby/review-epubbuilder.rb +0 -33
- data/testdata/mybook/lib/ruby/review-epubmaker.rb +0 -609
- data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +0 -949
- data/testdata/mybook/lib/ruby/review-latexbuilder.rb +0 -1065
- data/testdata/mybook/lib/ruby/review-maker.rb +0 -346
- data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +0 -945
- data/testdata/mybook/lib/ruby/review-markdownmaker.rb +0 -91
- data/testdata/mybook/lib/ruby/review-monkeypatch.rb +0 -93
- data/testdata/mybook/lib/ruby/review-pdfmaker.rb +0 -546
- data/testdata/mybook/lib/ruby/review-textbuilder.rb +0 -36
- data/testdata/mybook/lib/ruby/review-tocparser.rb +0 -285
- data/testdata/mybook/lib/ruby/review-webmaker.rb +0 -448
- data/testdata/mybook/lib/tasks/mytasks.rake +0 -31
- data/testdata/mybook/lib/tasks/review.rake +0 -156
- data/testdata/mybook/lib/tasks/review.rake.orig +0 -72
- data/testdata/mybook/lib/tasks/starter.rake +0 -470
- data/testdata/mybook/locale.yml +0 -6
- data/testdata/mybook/review-ext.rb +0 -206
- data/testdata/mybook/sty/indexstyle.ist +0 -25
- data/testdata/mybook/sty/jumoline.sty +0 -310
- data/testdata/mybook/sty/mycolophon.sty +0 -81
- data/testdata/mybook/sty/mystyle.sty +0 -8
- data/testdata/mybook/sty/mytextsize.sty +0 -94
- data/testdata/mybook/sty/mytitlepage.sty +0 -126
- data/testdata/mybook/sty/review-base.sty +0 -276
- data/testdata/mybook/sty/reviewmacro.sty +0 -60
- data/testdata/mybook/sty/starter-codeblock.sty +0 -463
- data/testdata/mybook/sty/starter-color.sty +0 -134
- data/testdata/mybook/sty/starter-font.sty +0 -112
- data/testdata/mybook/sty/starter-heading.sty +0 -561
- data/testdata/mybook/sty/starter-misc.sty +0 -894
- data/testdata/mybook/sty/starter-note.sty +0 -180
- data/testdata/mybook/sty/starter-section.sty +0 -262
- data/testdata/mybook/sty/starter-talklist.sty +0 -105
- data/testdata/mybook/sty/starter-toc.sty +0 -72
- data/testdata/mybook/sty/starter-util.sty +0 -39
- data/testdata/mybook/sty/starter.sty +0 -36
- data/testdata/mybook/sty/ut.sty +0 -26
- data/testdata/mybook/style.css +0 -597
- data/testdata/mybook/ut-catalog.yml +0 -61
- data/testdata/mybook/ut-config-starter.yml +0 -3
- data/testdata/mybook/ut-config.yml +0 -404
|
@@ -1,1065 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
## ReVIEW::LATEXBuilderクラスを拡張する
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
require 'review/latexbuilder'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
module ReVIEW
|
|
11
|
-
|
|
12
|
-
defined?(LATEXBuilder) or raise "internal error: LATEXBuilder not found."
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class LATEXBuilder
|
|
16
|
-
|
|
17
|
-
public :print, :puts
|
|
18
|
-
|
|
19
|
-
def target_name
|
|
20
|
-
"latex"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
## 章や節や項や目のタイトル
|
|
24
|
-
def headline(level, label, caption)
|
|
25
|
-
with_context(:headline) do
|
|
26
|
-
_, anchor = headline_prefix(level)
|
|
27
|
-
headname = _headline_name(level) # 'chapter', 'section', 'subsection', ...
|
|
28
|
-
headstar = _headline_star(level) # '*' or nil
|
|
29
|
-
blank() unless @output.pos == 0
|
|
30
|
-
with_context(:caption) do
|
|
31
|
-
print macro("#{headname}#{headstar}", compile_inline(caption))
|
|
32
|
-
print "\n" unless level >= 5 # \paragraphと\subpararaphでは改行しない
|
|
33
|
-
end
|
|
34
|
-
if headstar && _headline_toc?(level) # 番号はつかないけど目次には出す場合
|
|
35
|
-
## starter-heading.sty を使っているときは \addcontentsline が必要ない
|
|
36
|
-
#puts "\\@ifundefined{Chapter}{\\addcontentsline{toc}{#{headname}}{#{compile_inline(caption)}}}{}"
|
|
37
|
-
puts "\\ifx\\Chapter\\undefined{\\addcontentsline{toc}{#{headname}}{#{compile_inline(caption)}}}\\fi"
|
|
38
|
-
end
|
|
39
|
-
if _headline_chapter?(level)
|
|
40
|
-
## \Chapter直後の\addvspaceが効くように、
|
|
41
|
-
## \lastskipをいったん保存し、\labelのあとで復元する。
|
|
42
|
-
puts "\\keeplastskip{"
|
|
43
|
-
puts " \\label{#{chapter_label()}}"
|
|
44
|
-
puts " \\par\\nobreak"
|
|
45
|
-
puts "}"
|
|
46
|
-
elsif level >= 5 # 段(Paragraph)と小段(Subparagraph)では
|
|
47
|
-
nil # 何もしない、\labelもつけない
|
|
48
|
-
else
|
|
49
|
-
## \Section最後と\Subsection最初の\addvspaceが効くように、
|
|
50
|
-
## \lastskipをいったん保存し、\labelのあとで復元する。
|
|
51
|
-
puts "\\keeplastskip{"
|
|
52
|
-
puts " \\label{#{sec_label(anchor)}}"
|
|
53
|
-
puts " \\label{#{label}}" if label
|
|
54
|
-
puts " \\par\\nobreak"
|
|
55
|
-
puts "}"
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
rescue
|
|
59
|
-
error "unknown level: #{level}"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
def _headline_name(level)
|
|
65
|
-
return 'part' if @chapter.is_a?(ReVIEW::Book::Part)
|
|
66
|
-
return HEADLINE[level] # 1: 'chapter', 2: 'section', ...
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def _headline_star(level)
|
|
70
|
-
return '*' if level > @book.config['secnolevel']
|
|
71
|
-
return '*' if @chapter.number.to_s.empty? && level > 1
|
|
72
|
-
return nil
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def _headline_toc?(level)
|
|
76
|
-
return level <= @book.config['toclevel'].to_i
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def _headline_chapter?(level)
|
|
80
|
-
return level == 1
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
public
|
|
84
|
-
|
|
85
|
-
def nonum_begin(level, _label, caption)
|
|
86
|
-
blank() unless @output.pos == 0
|
|
87
|
-
with_context(:headline) do
|
|
88
|
-
with_context(:caption) do
|
|
89
|
-
puts macro(HEADLINE[level] + '*', compile_inline(caption))
|
|
90
|
-
puts "\\ifx\\Chapter\\undefined"
|
|
91
|
-
puts macro('addcontentsline', 'toc', HEADLINE[level], compile_inline(caption))
|
|
92
|
-
puts "\\fi"
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def notoc_begin(level, _label, caption)
|
|
98
|
-
blank() unless @output.pos == 0
|
|
99
|
-
with_context(:headline) do
|
|
100
|
-
with_context(:caption) do
|
|
101
|
-
puts "\\ifx\\Chapter\\undefined"
|
|
102
|
-
puts macro(HEADLINE[level] + '*', compile_inline(caption))
|
|
103
|
-
puts "\\else"
|
|
104
|
-
puts macro(HEADLINE[level] + '[]', compile_inline(caption))
|
|
105
|
-
puts "\\fi"
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
## テーブル
|
|
111
|
-
def table(lines, id=nil, caption=nil, option=nil)
|
|
112
|
-
super
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def table_header(id, caption, options)
|
|
116
|
-
if id.present? || caption.present?
|
|
117
|
-
@table_caption = true
|
|
118
|
-
pos = options[:pos] || 'h'
|
|
119
|
-
star = id.present? ? '' : '*'
|
|
120
|
-
s = with_context(:caption) { compile_inline(caption || '') }
|
|
121
|
-
puts "\\begin{table}[#{pos}]%%#{id}"
|
|
122
|
-
puts "\\centering%"
|
|
123
|
-
puts macro("reviewtablecaption#{star}", s)
|
|
124
|
-
end
|
|
125
|
-
begin
|
|
126
|
-
puts macro('label', table_label(id)) if id.present?
|
|
127
|
-
rescue KeyError
|
|
128
|
-
error "no such table: #{id}"
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
alias __original_table_begin table_begin
|
|
133
|
-
|
|
134
|
-
def table_begin(ncols, fontsize: nil)
|
|
135
|
-
if fontsize
|
|
136
|
-
font = FONTSIZES[fontsize]
|
|
137
|
-
puts "\\def\\startertablefont{\\#{font}}" if font
|
|
138
|
-
end
|
|
139
|
-
__original_table_begin(ncols)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
## CSVテーブル
|
|
143
|
-
def _table_hline()
|
|
144
|
-
"\\hline"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def _table_bottom(hline: false)
|
|
148
|
-
puts "\\hline" if hline
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def _table_tr(cells, hline: false)
|
|
152
|
-
s = "#{cells.join(' & ')} \\\\"
|
|
153
|
-
s << " \\hline" if hline
|
|
154
|
-
return s
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
## 改行命令「\\」のあとに改行文字「\n」を置かない。
|
|
158
|
-
##
|
|
159
|
-
## 「\n」が置かれると、たとえば
|
|
160
|
-
##
|
|
161
|
-
## foo@<br>{}
|
|
162
|
-
## bar
|
|
163
|
-
##
|
|
164
|
-
## が
|
|
165
|
-
##
|
|
166
|
-
## foo\\
|
|
167
|
-
##
|
|
168
|
-
## bar
|
|
169
|
-
##
|
|
170
|
-
## に展開されてしまう。
|
|
171
|
-
## つまり改行のつもりが改段落になってしまう。
|
|
172
|
-
def inline_br(_str)
|
|
173
|
-
#"\\\\\n" # original
|
|
174
|
-
#"\\\\{}" # これだと後続行の先頭に1/4空白が入ってしまう
|
|
175
|
-
"\\\\[0pt]" # これなら後続行の先頭に1/4空白が入らない
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
protected
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
## コードブロック(//program, //terminal, //output)
|
|
182
|
-
|
|
183
|
-
FONTSIZES = {
|
|
184
|
-
"small" => "small",
|
|
185
|
-
"x-small" => "footnotesize",
|
|
186
|
-
"xx-small" => "scriptsize",
|
|
187
|
-
"large" => "large",
|
|
188
|
-
"x-large" => "Large",
|
|
189
|
-
"xx-large" => "LARGE",
|
|
190
|
-
"medium" => "normalsize",
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
def _codeblock_eolmark()
|
|
194
|
-
"{\\startereolmark}"
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def _codeblock_indentmark()
|
|
198
|
-
"{\\starterindentchar}"
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
LATEX_ESCAPE_TABLE = {
|
|
202
|
-
'{' => '\{',
|
|
203
|
-
'}' => '\}',
|
|
204
|
-
'%' => '\%',
|
|
205
|
-
'$' => '\$',
|
|
206
|
-
'#' => '\#',
|
|
207
|
-
'&' => '\&',
|
|
208
|
-
'_' => '\_',
|
|
209
|
-
'\\' => '{\textbackslash}',
|
|
210
|
-
'^' => '{\textasciicircum}',
|
|
211
|
-
'~' => '{\textasciitilde}',
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
def _render_codeblock(blockname, lines, id, caption_str, opts)
|
|
215
|
-
if opts['eolmark']
|
|
216
|
-
eolmark = _codeblock_eolmark() # ex: '{\startereolmark}'
|
|
217
|
-
else
|
|
218
|
-
eolmark = nil
|
|
219
|
-
end
|
|
220
|
-
#
|
|
221
|
-
eol = eolmark ? "#{eolmark}\\par\n" : "\\par\n"
|
|
222
|
-
lines = lines.map {|line|
|
|
223
|
-
line = _parse_inline(line) {|text|
|
|
224
|
-
_convert_and_escape_str(text)
|
|
225
|
-
}
|
|
226
|
-
if line =~ /\A\n/
|
|
227
|
-
"\\mbox{}#{eol}\n"
|
|
228
|
-
else
|
|
229
|
-
line.gsub(/(?:\\-)?\n/, eol)
|
|
230
|
-
end
|
|
231
|
-
}
|
|
232
|
-
#
|
|
233
|
-
indent_width = opts['indent']
|
|
234
|
-
if indent_width && indent_width > 0
|
|
235
|
-
lines = _add_indent_mark(lines, indent_width)
|
|
236
|
-
end
|
|
237
|
-
#
|
|
238
|
-
default_opts = _codeblock_default_options(blockname)
|
|
239
|
-
opts2 = {}
|
|
240
|
-
opts.each do |k, v|
|
|
241
|
-
opts2[k] = v unless v == default_opts[k]
|
|
242
|
-
end
|
|
243
|
-
fontsize = FONTSIZES[opts['fontsize']]
|
|
244
|
-
#
|
|
245
|
-
environ = "starter#{blockname}"
|
|
246
|
-
puts "\\begingroup"
|
|
247
|
-
puts " \\makeatletter" if fontsize
|
|
248
|
-
puts " \\def\\starter@#{blockname}@fontsize{#{fontsize}}" if fontsize
|
|
249
|
-
puts " \\makeatother" if fontsize
|
|
250
|
-
puts " \\makeatletter" unless opts2.empty?
|
|
251
|
-
opts2.each do |k, v|
|
|
252
|
-
x = k.gsub(/[^a-zA-Z]/, '_')
|
|
253
|
-
v = v == true ? 'Y' : v == false ? '' : v #escape(v.to_s)
|
|
254
|
-
puts " \\edef\\starter@#{blockname}@#{x}{#{v}}"
|
|
255
|
-
#puts " \\edef\\starter@codeblock@#{x}{#{v}}"
|
|
256
|
-
end
|
|
257
|
-
puts " \\makeatother" unless opts2.empty?
|
|
258
|
-
print "\\begin{#{environ}}[#{id}]{#{caption_str}}"
|
|
259
|
-
print "\\startersetfoldmark{}" unless opts['foldmark']
|
|
260
|
-
if opts['lineno']
|
|
261
|
-
gen = LineNumberGenerator.new(opts['lineno'])
|
|
262
|
-
width = opts['linenowidth'] || -1
|
|
263
|
-
if width && width >= 0
|
|
264
|
-
if width == 0
|
|
265
|
-
last_lineno = gen.each.take(lines.length).compact.last
|
|
266
|
-
width = last_lineno.to_s.length
|
|
267
|
-
end
|
|
268
|
-
print "\\startersetfoldindentwidth{#{'9'*(width+2)}}"
|
|
269
|
-
format = "\\starterinnerlineno{%#{width}s:} "
|
|
270
|
-
else
|
|
271
|
-
format = "\\starterouterlineno{%s}"
|
|
272
|
-
end
|
|
273
|
-
buf = []
|
|
274
|
-
lines.zip(gen).each do |x, n|
|
|
275
|
-
buf << "#{(format % n.to_s).gsub(' ', '~')}#{x}"
|
|
276
|
-
end
|
|
277
|
-
print buf.join()
|
|
278
|
-
else
|
|
279
|
-
print lines.join()
|
|
280
|
-
end
|
|
281
|
-
puts "\\end{#{environ}}"
|
|
282
|
-
puts "\\endgroup"
|
|
283
|
-
nil
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
def _convert_and_escape_str(str)
|
|
287
|
-
#str.gsub(/[\{\}\\\%\^\_\$\&\~]/, LATEX_ESCAPE_TABLE)
|
|
288
|
-
rexp = /[\{\}\\\#\%\^\_\$\&\~]/
|
|
289
|
-
cs = []
|
|
290
|
-
zenkaku_rexp = ZENKAKU_CHAR_REXP
|
|
291
|
-
str.each_char do |c|
|
|
292
|
-
cs << (
|
|
293
|
-
case c
|
|
294
|
-
when / / ; '~'
|
|
295
|
-
when /\n/ ; "\n"
|
|
296
|
-
when rexp ; LATEX_ESCAPE_TABLE[c]
|
|
297
|
-
when zenkaku_rexp ; "\\ZC{#{c}}" # 全角文字
|
|
298
|
-
else ; c # 半角文字
|
|
299
|
-
end
|
|
300
|
-
)
|
|
301
|
-
end
|
|
302
|
-
cs << "" unless cs[-1] == "\n"
|
|
303
|
-
return cs.join('\\-')
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
ZENKAKU_CHAR_REXP = /\A[^\000-\177]\z/
|
|
307
|
-
|
|
308
|
-
def _add_indent_mark(lines, indent_width)
|
|
309
|
-
space = "~\\-"
|
|
310
|
-
rexp = /\A((?:~\\-)+)/
|
|
311
|
-
#
|
|
312
|
-
width = indent_width
|
|
313
|
-
mark = _codeblock_indentmark() # ex: '{\starterindentmark}'
|
|
314
|
-
indent = space * (width - 1) + mark
|
|
315
|
-
nchar = space.length
|
|
316
|
-
return lines.map {|line|
|
|
317
|
-
line.sub(rexp) {
|
|
318
|
-
m, n = ($1.length / nchar - 1).divmod width
|
|
319
|
-
"#{space}#{indent * m}#{space * n}"
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
public
|
|
325
|
-
|
|
326
|
-
## ・\caption{} のかわりに \reviewimagecaption{} を使うよう修正
|
|
327
|
-
## ・「scale=X」に加えて「pos=X」も受け付けるように拡張
|
|
328
|
-
def _render_image(id, image_filepath, caption, opts)
|
|
329
|
-
width = "\\maxwidth"
|
|
330
|
-
if opts[:scale]
|
|
331
|
-
case (scale = opts[:scale])
|
|
332
|
-
when /\A\d+\z/, /\A\d\.\d*\z/, /\A\.\d+\z/
|
|
333
|
-
when /\A\d+(\.\d+)?%\z/
|
|
334
|
-
scale = scale.sub(/%\z/, '').to_f / 100.0
|
|
335
|
-
else
|
|
336
|
-
error "scale=#{scale}: invalid scale value."
|
|
337
|
-
end
|
|
338
|
-
width = "#{scale}\\maxwidth" # not '\textwidth'
|
|
339
|
-
end
|
|
340
|
-
#
|
|
341
|
-
if opts[:width]
|
|
342
|
-
case opts[:width]
|
|
343
|
-
when /\A\d+\z/, /\A\d\.\d*\z/, /\A\.\d+\z/
|
|
344
|
-
width = "#{opts[:width]}\\textwidth" # not '\maxwidth'
|
|
345
|
-
when /\A(\d+(\.\d+)?)%\z/
|
|
346
|
-
width = "#{$1.to_f/100.0}\\textwidth" # not '\maxwidth'
|
|
347
|
-
when /\A(\d+(?:\.\d*)?)(mm|cm)\z/
|
|
348
|
-
width = "#{$1}true#{$2}" # 'mm'->'truemm', 'cm'->'truecm'
|
|
349
|
-
else
|
|
350
|
-
width = opts[:width]
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
#
|
|
354
|
-
metrics = ["width=#{width}"]
|
|
355
|
-
metrics << "draft=#{opts[:draft]}" if opts[:draft] != nil
|
|
356
|
-
#
|
|
357
|
-
pos = opts[:pos] || config_starter()['image_position']
|
|
358
|
-
puts "\\begin{reviewimage}[#{pos}]%%#{id}"
|
|
359
|
-
puts "\\starterimageframe{%" if opts[:border]
|
|
360
|
-
puts "\\includegraphics[#{metrics.join(',')}]{#{image_filepath}}%"
|
|
361
|
-
puts "}%" if opts[:border]
|
|
362
|
-
with_context(:caption) do
|
|
363
|
-
#puts macro('caption', compile_inline(caption)) if caption.present? # original
|
|
364
|
-
puts "\\reviewimagecaption{#{compile_inline(caption)}}" if caption.present?
|
|
365
|
-
end
|
|
366
|
-
puts "\\label{#{image_label(id)}}"
|
|
367
|
-
puts "\\end{reviewimage}"
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
## //imgtable
|
|
371
|
-
def imgtable(lines, id, caption=nil, option=nil)
|
|
372
|
-
super
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
def _render_imgtable(id, caption, opts)
|
|
376
|
-
pos = opts['pos'] || 'h'
|
|
377
|
-
puts "\\begin{table}[#{pos}]%%#{id}"
|
|
378
|
-
puts "\\centering"
|
|
379
|
-
yield
|
|
380
|
-
puts "\\end{table}"
|
|
381
|
-
blank()
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
def _render_imgtable_caption(caption)
|
|
385
|
-
puts macro('reviewimgtablecaption', compile_inline(caption))
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
def _render_imgtable_label(id)
|
|
389
|
-
puts macro('label', table_label(id))
|
|
390
|
-
rescue ReVIEW::KeyError
|
|
391
|
-
error "no such table: #{id}"
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
def imgtable_image(id, _caption, metric)
|
|
395
|
-
metrics = parse_metric('latex', metric)
|
|
396
|
-
# image is always bound here
|
|
397
|
-
#puts "\\begin{reviewimage}%%#{id}" #-
|
|
398
|
-
metrics = "width=\\maxwidth" unless metrics.present?
|
|
399
|
-
imagefile = @chapter.image(id).path
|
|
400
|
-
puts "\\includegraphics[#{metrics}]{#{imagefile}}"
|
|
401
|
-
#puts '\end{reviewimage}' #-
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
##
|
|
405
|
-
|
|
406
|
-
def _build_secref(chap, num, title, parent_title)
|
|
407
|
-
s = ""
|
|
408
|
-
## 親セクションのタイトルがあれば使う
|
|
409
|
-
if parent_title && self.config_starter['secref_parenttitle']
|
|
410
|
-
s << "「%s」内の" % parent_title # TODO: I18n化
|
|
411
|
-
end
|
|
412
|
-
## 対象セクションへのリンクを作成する
|
|
413
|
-
if @book.config['chapterlink']
|
|
414
|
-
label = "sec:" + num.gsub('.', '-')
|
|
415
|
-
level = num.split('.').length
|
|
416
|
-
case level
|
|
417
|
-
when 2 ; s << "\\startersecref{#{title}}{#{label}}"
|
|
418
|
-
when 3 ; s << "\\startersubsecref{#{title}}{#{label}}"
|
|
419
|
-
when 4 ; s << "\\startersubsubsecref{#{title}}{#{label}}"
|
|
420
|
-
else
|
|
421
|
-
raise "#{num}: unexpected section level (expected: 2~4)."
|
|
422
|
-
end
|
|
423
|
-
else
|
|
424
|
-
s << title
|
|
425
|
-
end
|
|
426
|
-
return s
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
###
|
|
430
|
-
|
|
431
|
-
public
|
|
432
|
-
|
|
433
|
-
def ul_begin
|
|
434
|
-
blank()
|
|
435
|
-
puts '\begin{starteritemize}' # instead of 'itemize'
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
def ul_end
|
|
439
|
-
puts '\end{starteritemize}' # instead of 'itemize'
|
|
440
|
-
blank()
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
def ol_begin(start_num=nil)
|
|
444
|
-
blank()
|
|
445
|
-
puts '\begin{starterenumerate}' # instead of 'enumerate'
|
|
446
|
-
if start_num.nil?
|
|
447
|
-
return true unless @ol_num
|
|
448
|
-
puts "\\setcounter{enumi}{#{@ol_num - 1}}"
|
|
449
|
-
@ol_num = nil
|
|
450
|
-
end
|
|
451
|
-
end
|
|
452
|
-
|
|
453
|
-
def ol_end
|
|
454
|
-
puts '\end{starterenumerate}' # instead of 'enumerate'
|
|
455
|
-
blank()
|
|
456
|
-
end
|
|
457
|
-
|
|
458
|
-
def ol_item_begin(lines, num)
|
|
459
|
-
str = lines.join
|
|
460
|
-
num = escape(num).sub(']', '\rbrack{}')
|
|
461
|
-
puts "\\item[#{num}] #{str}"
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
def ol_item_end()
|
|
465
|
-
end
|
|
466
|
-
|
|
467
|
-
def dt(str)
|
|
468
|
-
puts "\\starterdt{#{str}}%"
|
|
469
|
-
end
|
|
470
|
-
|
|
471
|
-
def dl_dd_begin()
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
def dl_dd_end()
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
## コラム
|
|
478
|
-
|
|
479
|
-
def column_begin(level, label, caption)
|
|
480
|
-
blank()
|
|
481
|
-
@doc_status[:column] = true
|
|
482
|
-
puts "\\begin{reviewcolumn}\n"
|
|
483
|
-
puts "\\phantomsection % for hyperref" #+
|
|
484
|
-
if label
|
|
485
|
-
puts "\\hypertarget{#{column_label(label)}}{}"
|
|
486
|
-
else
|
|
487
|
-
puts "\\hypertarget{#{column_label(caption)}}{}"
|
|
488
|
-
end
|
|
489
|
-
@doc_status[:caption] = true
|
|
490
|
-
puts macro('reviewcolumnhead', nil, compile_inline(caption))
|
|
491
|
-
@doc_status[:caption] = nil
|
|
492
|
-
if level <= @book.config['toclevel'].to_i
|
|
493
|
-
#puts "\\addcontentsline{toc}{#{HEADLINE[level]}}{#{compile_inline(caption)}}" #-
|
|
494
|
-
puts "\\addcontentsline{toc}{#{HEADLINE[level]}}{\\numberline{#{toc_column()}}#{compile_inline(caption)}}" #+
|
|
495
|
-
end
|
|
496
|
-
end
|
|
497
|
-
|
|
498
|
-
def toc_column
|
|
499
|
-
#escape('コラム:')
|
|
500
|
-
escape('[コラム]')
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
#### ブロック命令
|
|
504
|
-
|
|
505
|
-
## 導入文(//lead{ ... //})のデザインをLaTeXのスタイルファイルで
|
|
506
|
-
## 変更できるよう、マクロを使う。
|
|
507
|
-
def lead(lines)
|
|
508
|
-
puts '\begin{starterlead}' # オリジナルは \begin{quotation}
|
|
509
|
-
puts lines
|
|
510
|
-
puts '\end{starterlead}'
|
|
511
|
-
end
|
|
512
|
-
|
|
513
|
-
## 章 (Chapter) の概要
|
|
514
|
-
## (導入文 //lead{ ... //} と似ているが、導入文では詩や物語を
|
|
515
|
-
## 引用するのが普通らしく、概要 (abstract) とは違うみたいなので、
|
|
516
|
-
## 概要を表すブロックを用意した。)
|
|
517
|
-
def on_abstract_block()
|
|
518
|
-
puts '\begin{starterabstract}'
|
|
519
|
-
yield
|
|
520
|
-
puts '\end{starterabstract}'
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
## 章 (Chapter) の著者
|
|
524
|
-
def on_chapterauthor_block(name)
|
|
525
|
-
puts "\\starterchapterauthor{#{escape(name)}}"
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
## 会話リスト
|
|
529
|
-
def _render_talklist(opts, &b)
|
|
530
|
-
puts '\begingroup'
|
|
531
|
-
puts ' \makeatletter' unless opts.empty?
|
|
532
|
-
opts.each do |k, v|
|
|
533
|
-
puts " \\def\\starter@talklist@#{k}{#{v}}"
|
|
534
|
-
end
|
|
535
|
-
puts ' \makeatother' unless opts.empty?
|
|
536
|
-
puts '\begin{startertalklist}'
|
|
537
|
-
yield
|
|
538
|
-
puts '\end{startertalklist}'
|
|
539
|
-
puts '\endgroup'
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
## 会話項目
|
|
543
|
-
def _render_talk(image_filepath=nil, name=nil, &b)
|
|
544
|
-
s = name ? compile_inline(name) : nil
|
|
545
|
-
print "\\startertalk{#{image_filepath}}{#{s}}{%"
|
|
546
|
-
yield
|
|
547
|
-
@blank_needed = false
|
|
548
|
-
puts "}"
|
|
549
|
-
end
|
|
550
|
-
|
|
551
|
-
## キーと説明文のリスト
|
|
552
|
-
def _render_desclist(opts, &b)
|
|
553
|
-
bkup = @_desclist_opts
|
|
554
|
-
@_desclist_opts = opts
|
|
555
|
-
star = opts[:compact] ? '*' : ''
|
|
556
|
-
puts "\\begingroup"
|
|
557
|
-
puts " \\makeatletter" unless opts.empty?
|
|
558
|
-
opts.each do |k, v|
|
|
559
|
-
k_ = k.to_s.gsub('_', '@')
|
|
560
|
-
v_ = v == true ? 'Y' : v == false ? '' : escape(v.to_s)
|
|
561
|
-
puts " \\def\\starter@desclist@#{k_}{#{v_}}"
|
|
562
|
-
end
|
|
563
|
-
puts " \\makeatother" unless opts.empty?
|
|
564
|
-
puts "\\begin{starterdesclist}"
|
|
565
|
-
yield
|
|
566
|
-
puts "\\end{starterdesclist}"
|
|
567
|
-
puts "\\endgroup"
|
|
568
|
-
@_desclist_opts = bkup
|
|
569
|
-
end
|
|
570
|
-
|
|
571
|
-
## キーと説明文
|
|
572
|
-
def on_desc_block(key, text=nil, &b)
|
|
573
|
-
text = "\n" + text if text
|
|
574
|
-
super(key, text, &b)
|
|
575
|
-
end
|
|
576
|
-
def _render_desc(key, &b)
|
|
577
|
-
opts = @_desclist_opts
|
|
578
|
-
s = compile_inline(key)
|
|
579
|
-
#print "\\begin{starterdesc}{#{s}}"
|
|
580
|
-
#print "\\begin{starterdesc}{#{s}}%"
|
|
581
|
-
print "\\begin{starterdesc}{#{s}}\\ignorespaces "
|
|
582
|
-
yield
|
|
583
|
-
@blank_needed = false
|
|
584
|
-
puts "\\end{starterdesc}"
|
|
585
|
-
end
|
|
586
|
-
|
|
587
|
-
## 縦方向の空きを入れる
|
|
588
|
-
def _render_vspace(size)
|
|
589
|
-
puts "\\vspace{#{size}}"
|
|
590
|
-
end
|
|
591
|
-
|
|
592
|
-
def _render_addvspace(size)
|
|
593
|
-
puts "\\addvspace{#{size}}"
|
|
594
|
-
end
|
|
595
|
-
|
|
596
|
-
## 章タイトルを独立したページに
|
|
597
|
-
def makechaptitlepage(option=nil)
|
|
598
|
-
case option
|
|
599
|
-
when nil, "" ;
|
|
600
|
-
when 'toc=section', 'toc=subsection' ;
|
|
601
|
-
when 'toc', 'toc=on'
|
|
602
|
-
option = "toc=on"
|
|
603
|
-
else
|
|
604
|
-
raise ArgumentError.new("//makechaptitlepage[#{option}]: unknown option (expected 'toc=section' or 'toc=subsection').")
|
|
605
|
-
end
|
|
606
|
-
puts "\\makechaptitlepage{#{option}}"
|
|
607
|
-
end
|
|
608
|
-
|
|
609
|
-
## 縦方向のスペースがなければ改ページ
|
|
610
|
-
def _render_needvspace(height)
|
|
611
|
-
puts "\\needvspace{#{height}}"
|
|
612
|
-
end
|
|
613
|
-
|
|
614
|
-
## 段(Paragraph)の終わりにスペースを入れる
|
|
615
|
-
def paragraphend()
|
|
616
|
-
puts "\\ParagraphEnd"
|
|
617
|
-
end
|
|
618
|
-
|
|
619
|
-
## 小段(Subparagraph)の終わりにスペースを入れる(あれば)
|
|
620
|
-
def subparagraphend()
|
|
621
|
-
puts "\\SubparagraphEnd"
|
|
622
|
-
end
|
|
623
|
-
|
|
624
|
-
## 引用(複数段落に対応)
|
|
625
|
-
## (入れ子対応なので、中に箇条書きや別のブロックを入れられる)
|
|
626
|
-
def on_quote_block()
|
|
627
|
-
puts '\begin{starterquote}'
|
|
628
|
-
yield
|
|
629
|
-
puts '\end{starterquote}'
|
|
630
|
-
end
|
|
631
|
-
def quote(lines)
|
|
632
|
-
on_quote_block() do
|
|
633
|
-
puts lines
|
|
634
|
-
end
|
|
635
|
-
end
|
|
636
|
-
|
|
637
|
-
## 引用 (====[quote] ... ====[/quote])
|
|
638
|
-
## (ブロック構文ではないので、中に箇条書きや別のブロックを入れられる)
|
|
639
|
-
def quote_begin(level, label, caption)
|
|
640
|
-
puts '\begin{starterquote}'
|
|
641
|
-
end
|
|
642
|
-
def quote_end(level)
|
|
643
|
-
puts '\end{starterquote}'
|
|
644
|
-
end
|
|
645
|
-
|
|
646
|
-
## ノート(//note[caption]{ ... //})
|
|
647
|
-
## (入れ子対応なので、中に箇条書きや別のブロックを入れられる)
|
|
648
|
-
def on_note_block(label=nil, caption=nil)
|
|
649
|
-
with_context(:minicolumn) do
|
|
650
|
-
caption, label = label, nil if caption.nil?
|
|
651
|
-
s = compile_inline(caption || "")
|
|
652
|
-
puts "\\begin{starternote}[#{label}]{#{s}}"
|
|
653
|
-
yield
|
|
654
|
-
puts "\\end{starternote}"
|
|
655
|
-
end
|
|
656
|
-
end
|
|
657
|
-
def note(lines, label=nil, caption=nil)
|
|
658
|
-
on_note_block(label, caption) do
|
|
659
|
-
puts lines
|
|
660
|
-
end
|
|
661
|
-
end
|
|
662
|
-
|
|
663
|
-
## ノート (====[note] ... ====[/note])
|
|
664
|
-
## (ブロック構文ではないので、中に箇条書きや別のブロックを入れられる)
|
|
665
|
-
def note_begin(level, label, caption)
|
|
666
|
-
enter_context(:note)
|
|
667
|
-
s = compile_inline(caption || "")
|
|
668
|
-
puts "\\begin{starternote}[#{label}]{#{s}}"
|
|
669
|
-
end
|
|
670
|
-
def note_end(level)
|
|
671
|
-
puts "\\end{starternote}"
|
|
672
|
-
exit_context(:note)
|
|
673
|
-
end
|
|
674
|
-
|
|
675
|
-
## コードリスト(//list, //emlist, //listnum, //emlistnum, //cmd, //source)
|
|
676
|
-
## TODO: code highlight support
|
|
677
|
-
def list(lines, id=nil, caption=nil, lang=nil)
|
|
678
|
-
program(lines, id, caption, _codeblock_optstr(lang, false))
|
|
679
|
-
end
|
|
680
|
-
def listnum(lines, id=nil, caption=nil, lang=nil)
|
|
681
|
-
program(lines, id, caption, _codeblock_optstr(lang, true))
|
|
682
|
-
end
|
|
683
|
-
def emlist(lines, caption=nil, lang=nil)
|
|
684
|
-
program(lines, nil, caption, _codeblock_optstr(lang, false))
|
|
685
|
-
end
|
|
686
|
-
def emlistnum(lines, caption=nil, lang=nil)
|
|
687
|
-
program(lines, nil, caption, _codeblock_optstr(lang, true))
|
|
688
|
-
end
|
|
689
|
-
def source(lines, caption=nil, lang=nil)
|
|
690
|
-
program(lines, nil, caption, _codeblock_optstr(lang, false))
|
|
691
|
-
end
|
|
692
|
-
def cmd(lines, caption=nil, lang=nil)
|
|
693
|
-
terminal(lines, nil, caption, _codeblock_optstr(lang, false))
|
|
694
|
-
end
|
|
695
|
-
def _codeblock_optstr(lang, lineno_flag)
|
|
696
|
-
arr = []
|
|
697
|
-
arr << lang if lang
|
|
698
|
-
if lineno_flag
|
|
699
|
-
first_line_num = line_num()
|
|
700
|
-
arr << "lineno=#{first_line_num}"
|
|
701
|
-
arr << "linenowidth=0"
|
|
702
|
-
end
|
|
703
|
-
return arr.join(",")
|
|
704
|
-
end
|
|
705
|
-
private :_codeblock_optstr
|
|
706
|
-
|
|
707
|
-
## 画像横に文章
|
|
708
|
-
def _render_sideimage(filepath, imagewidth, opts, &b)
|
|
709
|
-
side = opts['side'] || 'L'
|
|
710
|
-
normalize = proc {|s|
|
|
711
|
-
rexp = /\A(\d+(?:\.\d+)?)(%|mm|cm)\z/
|
|
712
|
-
if s !~ rexp ; s
|
|
713
|
-
elsif $2 == '%' ; "#{$1.to_f/100.0}\\textwidth"
|
|
714
|
-
else ; "#{$1}true#{$2}"
|
|
715
|
-
end
|
|
716
|
-
}
|
|
717
|
-
imgwidth = normalize.call(imagewidth)
|
|
718
|
-
boxwidth = normalize.call(opts['boxwidth']) || imgwidth
|
|
719
|
-
sepwidth = normalize.call(opts['sep'] || "0pt")
|
|
720
|
-
puts "{\n"
|
|
721
|
-
puts " \\def\\starterminiimageframe{Y}\n" if opts['border']
|
|
722
|
-
puts " \\begin{startersideimage}{#{side}}{#{filepath}}{#{imgwidth}}{#{boxwidth}}{#{sepwidth}}{}\n"
|
|
723
|
-
yield
|
|
724
|
-
puts " \\end{startersideimage}\n"
|
|
725
|
-
puts "}\n"
|
|
726
|
-
end
|
|
727
|
-
|
|
728
|
-
## 入れ子可能なブロック命令
|
|
729
|
-
|
|
730
|
-
def on_minicolumn(type, caption=nil, &b)
|
|
731
|
-
with_context(:minicolumn) do
|
|
732
|
-
s = caption ? with_context(:caption) { compile_inline(caption) } : nil
|
|
733
|
-
puts "\\begin{starter#{type}}{#{s}}"
|
|
734
|
-
yield
|
|
735
|
-
puts "\\end{starter#{type}}\n"
|
|
736
|
-
end
|
|
737
|
-
end
|
|
738
|
-
protected :on_minicolumn
|
|
739
|
-
|
|
740
|
-
## 数式
|
|
741
|
-
|
|
742
|
-
def texequation(lines, label=nil, caption=nil)
|
|
743
|
-
blank()
|
|
744
|
-
#
|
|
745
|
-
if label.present?
|
|
746
|
-
puts macro("begin", "reviewequationblock")
|
|
747
|
-
chap = get_chap()
|
|
748
|
-
if chap.nil?
|
|
749
|
-
key = "format_number_header_without_chapter"
|
|
750
|
-
args = [@chapter.equation(label).number]
|
|
751
|
-
else
|
|
752
|
-
key = "format_number_header"
|
|
753
|
-
args = [chap, @chapter.equation(label).number]
|
|
754
|
-
end
|
|
755
|
-
s1 = I18n.t("equation")
|
|
756
|
-
s2 = I18n.t(key, args)
|
|
757
|
-
s3 = I18n.t("caption_prefix")
|
|
758
|
-
s4 = compile_inline(caption)
|
|
759
|
-
puts macro("reviewequationcaption", "#{s1}#{s2}#{s3}#{s4}")
|
|
760
|
-
has_caption_line = true
|
|
761
|
-
elsif caption.present?
|
|
762
|
-
puts macro("begin", "reviewequationblock")
|
|
763
|
-
s3 = I18n.t("caption_prefix")
|
|
764
|
-
s4 = compile_inline(caption)
|
|
765
|
-
puts macro("reviewequationcaption", "#{s3}#{s4}")
|
|
766
|
-
has_caption_line = true
|
|
767
|
-
else
|
|
768
|
-
has_caption_line = false
|
|
769
|
-
end
|
|
770
|
-
#
|
|
771
|
-
puts macro("begin", "equation*")
|
|
772
|
-
lines.each do |line|
|
|
773
|
-
puts unescape_latex(line)
|
|
774
|
-
end
|
|
775
|
-
puts macro("end", "equation*")
|
|
776
|
-
#
|
|
777
|
-
if has_caption_line
|
|
778
|
-
puts macro("end", "reviewequationblock")
|
|
779
|
-
end
|
|
780
|
-
#
|
|
781
|
-
blank()
|
|
782
|
-
end
|
|
783
|
-
|
|
784
|
-
#### インライン命令
|
|
785
|
-
|
|
786
|
-
## 改段落(箇条書き内では空行を入れられないため)
|
|
787
|
-
def inline_par(arg)
|
|
788
|
-
"\\starterpar{#{arg}}"
|
|
789
|
-
end
|
|
790
|
-
|
|
791
|
-
## ファイル名
|
|
792
|
-
def inline_file(str)
|
|
793
|
-
on_inline_file { escape(str) }
|
|
794
|
-
end
|
|
795
|
-
def on_inline_file
|
|
796
|
-
"\\starterfile{#{yield}}"
|
|
797
|
-
end
|
|
798
|
-
|
|
799
|
-
## ユーザ入力
|
|
800
|
-
def inline_userinput(str)
|
|
801
|
-
on_inline_userinput { escape(str) }
|
|
802
|
-
end
|
|
803
|
-
def on_inline_userinput
|
|
804
|
-
#if within_codeblock?()
|
|
805
|
-
# "{\\starteruserinput{\\seqsplit{#{yield}}}}"
|
|
806
|
-
#else
|
|
807
|
-
"\\starteruserinput{#{yield}}"
|
|
808
|
-
#end
|
|
809
|
-
end
|
|
810
|
-
|
|
811
|
-
## 引数をそのまま表示
|
|
812
|
-
## 例:
|
|
813
|
-
## //emlist{
|
|
814
|
-
## @<b>{ABC} ← 太字の「ABC」が表示される
|
|
815
|
-
## @<nop>$@<b>{ABC}$ ← 「@<b>{ABC}」がそのまま表示される
|
|
816
|
-
## //}
|
|
817
|
-
def inline_nop(str)
|
|
818
|
-
escape(str || "")
|
|
819
|
-
end
|
|
820
|
-
alias inline_letitgo inline_nop
|
|
821
|
-
|
|
822
|
-
## 目立たせない(@<strong>{} の反対)
|
|
823
|
-
def inline_weak(str)
|
|
824
|
-
on_inline_weak { escape(str) }
|
|
825
|
-
end
|
|
826
|
-
def on_inline_weak
|
|
827
|
-
#if within_codeblock?()
|
|
828
|
-
# "{\\starterweak{\\seqsplit{#{yield}}}}"
|
|
829
|
-
#else
|
|
830
|
-
"\\starterweak{#{yield}}"
|
|
831
|
-
#end
|
|
832
|
-
end
|
|
833
|
-
|
|
834
|
-
## 文字を小さくする
|
|
835
|
-
def inline_small(str) ; on_inline_small { escape(str) } ; end
|
|
836
|
-
def inline_xsmall(str) ; on_inline_xsmall { escape(str) } ; end
|
|
837
|
-
def inline_xxsmall(str) ; on_inline_xxsmall { escape(str) }; end
|
|
838
|
-
def on_inline_small() ; "{\\small{}#{yield}}" ; end
|
|
839
|
-
def on_inline_xsmall() ; "{\\footnotesize{}#{yield}}"; end
|
|
840
|
-
def on_inline_xxsmall() ; "{\\scriptsize{}#{yield}}" ; end
|
|
841
|
-
|
|
842
|
-
## 文字を大きくする
|
|
843
|
-
def inline_large(str) ; on_inline_large { escape(str) } ; end
|
|
844
|
-
def inline_xlarge(str) ; on_inline_xlarge { escape(str) } ; end
|
|
845
|
-
def inline_xxlarge(str) ; on_inline_xxlarge { escape(str) }; end
|
|
846
|
-
def on_inline_large() ; "{\\large{}#{yield}}" ; end
|
|
847
|
-
def on_inline_xlarge() ; "{\\Large{}#{yield}}" ; end
|
|
848
|
-
def on_inline_xxlarge() ; "{\\LARGE{}#{yield}}" ; end
|
|
849
|
-
|
|
850
|
-
## 文字を大きくした@<strong>{}
|
|
851
|
-
def inline_xstrong(str) ; on_inline_xstring { escape(str) } ; end
|
|
852
|
-
def inline_xxstrong(str); on_inline_xxstring { escape(str) }; end
|
|
853
|
-
def on_inline_xstrong(&b) ; "{\\Large{}#{on_inline_strong(&b)}}" ; end
|
|
854
|
-
def on_inline_xxstrong(&b); "{\\LARGE{}#{on_inline_strong(&b)}}" ; end
|
|
855
|
-
|
|
856
|
-
## コードブロック中で折り返し箇所を手動で指定する
|
|
857
|
-
## (\seqsplit による自動折り返し機能が日本語には効かないので、
|
|
858
|
-
## 長い行を日本語の箇所で折り返したいときは @<foldhere>{} を使う)
|
|
859
|
-
def inline_foldhere(arg)
|
|
860
|
-
return '\starterfoldhere{}'
|
|
861
|
-
end
|
|
862
|
-
|
|
863
|
-
## ターミナルでのカーソル(背景が白、文字が黒)
|
|
864
|
-
def inline_cursor(str)
|
|
865
|
-
"{\\startercursor{#{escape(str)}}}"
|
|
866
|
-
end
|
|
867
|
-
|
|
868
|
-
## 脚注(「//footnote」の脚注テキストを「@<fn>{}」でパースすることに注意)
|
|
869
|
-
def inline_fn(id)
|
|
870
|
-
if @book.config['footnotetext']
|
|
871
|
-
macro("footnotemark[#{@chapter.footnote(id).number}]", '')
|
|
872
|
-
elsif @doc_status[:caption] || @doc_status[:table] || @doc_status[:column]
|
|
873
|
-
@foottext[id] = @chapter.footnote(id).number
|
|
874
|
-
macro('protect\\footnotemark', '')
|
|
875
|
-
else
|
|
876
|
-
with_context(:footnote) { #+
|
|
877
|
-
macro('footnote', compile_inline(@chapter.footnote(id).content.strip))
|
|
878
|
-
} #+
|
|
879
|
-
end
|
|
880
|
-
rescue KeyError
|
|
881
|
-
error "unknown footnote: #{id}"
|
|
882
|
-
end
|
|
883
|
-
|
|
884
|
-
## nestable inline commands
|
|
885
|
-
|
|
886
|
-
def on_inline_i() ; "{\\reviewit{#{yield}}}" ; end
|
|
887
|
-
#def on_inline_b() ; "{\\reviewbold{#{yield}}}" ; end
|
|
888
|
-
#def on_inline_tt() ; "{\\reviewtt{#{yield}}}" ; end
|
|
889
|
-
def on_inline_tti() ; "{\\reviewtti{#{yield}}}" ; end
|
|
890
|
-
def on_inline_ttb() ; "{\\reviewttb{#{yield}}}" ; end
|
|
891
|
-
#def on_inline_code() ; "{\\reviewcode{#{yield}}}" ; end
|
|
892
|
-
#def on_inline_del() ; "{\\reviewstrike{#{yield}}}" ; end
|
|
893
|
-
def on_inline_sub() ; "{\\textsubscript{#{yield}}}" ; end
|
|
894
|
-
def on_inline_sup() ; "{\\textsuperscript{#{yield}}}"; end
|
|
895
|
-
def on_inline_em() ; "{\\reviewem{#{yield}}}" ; end
|
|
896
|
-
def on_inline_strong(); "{\\reviewstrong{#{yield}}}" ; end
|
|
897
|
-
def on_inline_u() ; "{\\reviewunderline{#{yield}}}"; end
|
|
898
|
-
def on_inline_ami() ; "{\\reviewami{#{yield}}}" ; end
|
|
899
|
-
def on_inline_balloon(); "{\\reviewballoon{#{yield}}}" ; end
|
|
900
|
-
|
|
901
|
-
def on_inline_tt()
|
|
902
|
-
return "{\\reviewtt{#{yield}}}"
|
|
903
|
-
end
|
|
904
|
-
|
|
905
|
-
def on_inline_code()
|
|
906
|
-
with_context(:inline_code) {
|
|
907
|
-
## 連続した空白が1つの空白として扱われるのを防ぐ
|
|
908
|
-
s = yield
|
|
909
|
-
s = s.gsub(/ /, '{\\starterspacechar}')
|
|
910
|
-
## 連続した「`」や「'」はエスケープする必要がある
|
|
911
|
-
s = s.gsub(/\'\'/, "{'}{'}")
|
|
912
|
-
s = s.gsub(/\`\`/, '{`}{`}')
|
|
913
|
-
## コンテキストによって、背景色をつけないことがある
|
|
914
|
-
if false
|
|
915
|
-
elsif within_context?(:headline) # 章タイトルや節タイトルでは
|
|
916
|
-
"{\\reviewcode[headline]{#{s}}}" # 背景色をつけない(かも)
|
|
917
|
-
elsif within_context?(:caption) # リストや画像のキャプションでも
|
|
918
|
-
"{\\reviewcode[caption]{#{s}}}" # 背景色をつけない(かも)
|
|
919
|
-
else # それ以外では
|
|
920
|
-
"{\\reviewcode{#{s}}}" # 背景色をつける(かも)
|
|
921
|
-
end
|
|
922
|
-
}
|
|
923
|
-
end
|
|
924
|
-
|
|
925
|
-
## @<b>{} が //terminal{ ... //} で効くように上書き
|
|
926
|
-
def inline_b(str)
|
|
927
|
-
on_inline_b { escape(str) }
|
|
928
|
-
end
|
|
929
|
-
def on_inline_b() # nestable
|
|
930
|
-
if within_codeblock?()
|
|
931
|
-
#"{\\bfseries #{yield}}" # \seqsplit{} 内では余計な空白が入る
|
|
932
|
-
#"{\\bfseries{}#{yield}}" # \seqsplit{} 内では後続も太字化する
|
|
933
|
-
"\\bfseries{}#{yield}\\mdseries{}" # \seqsplit{} 内でうまく効く
|
|
934
|
-
else
|
|
935
|
-
macro('reviewbold', yield)
|
|
936
|
-
end
|
|
937
|
-
end
|
|
938
|
-
|
|
939
|
-
## @<del>{} が //list や //terminal で効くように上書き
|
|
940
|
-
def inline_del(str)
|
|
941
|
-
on_inline_del { escape(str) }
|
|
942
|
-
end
|
|
943
|
-
def on_inline_del()
|
|
944
|
-
if within_codeblock?()
|
|
945
|
-
#"\\reviewstrike{#{yield}}" # \seqsplit{} 内でエラーになる
|
|
946
|
-
#"{\\reviewstrike{#{yield}}}" # \seqsplit{} 内でもエラーにならないが折り返しされない
|
|
947
|
-
#"{\\reviewstrike{\\seqsplit{#{yield}}}}" # エラーにならないし、折り返しもされる
|
|
948
|
-
"{\\reviewstrike{#{yield}}}"
|
|
949
|
-
else
|
|
950
|
-
macro('reviewstrike', yield)
|
|
951
|
-
end
|
|
952
|
-
end
|
|
953
|
-
|
|
954
|
-
def build_inline_href(url, escaped_label) # compile_href()をベースに改造
|
|
955
|
-
flag_footnote = self.config_starter['linkurl_footnote']
|
|
956
|
-
return _inline_hyperlink(url, escaped_label, flag_footnote)
|
|
957
|
-
end
|
|
958
|
-
|
|
959
|
-
## @<href>{} の代わり
|
|
960
|
-
def inline_hlink(str)
|
|
961
|
-
url, label = str.split(/, /, 2)
|
|
962
|
-
flag_footnote = self.config_starter['hyperlink_footnote']
|
|
963
|
-
label_ = label.present? ? escape(label) : nil
|
|
964
|
-
return _inline_hyperlink(url, label_, flag_footnote)
|
|
965
|
-
end
|
|
966
|
-
|
|
967
|
-
def _inline_hyperlink(url, escaped_label, flag_footnote)
|
|
968
|
-
if /\A[a-z]+:/ !~ url
|
|
969
|
-
"\\ref{#{url}}"
|
|
970
|
-
elsif ! escaped_label.present?
|
|
971
|
-
#"\\url{#{escape_url(url)}}"
|
|
972
|
-
"\\starterurl{#{escape_url(url)}}{#{escape(url)}}"
|
|
973
|
-
elsif ! flag_footnote
|
|
974
|
-
"\\href{#{escape_url(url)}}{#{escaped_label}}"
|
|
975
|
-
elsif within_context?(:footnote)
|
|
976
|
-
#"#{escaped_label}(\\url{#{escape_url(url)}})"
|
|
977
|
-
"#{escaped_label}(\\starterurl{#{escape_url(url)}}{#{escape(url)}})"
|
|
978
|
-
else
|
|
979
|
-
#"#{escaped_label}\\footnote{\\url{#{escape_url(url)}}}"
|
|
980
|
-
#"#{escaped_label}\\footnote{\\starterurl{#{escape_url(url)}}{#{escape(url)}}}"
|
|
981
|
-
url1 = escape_url(url)
|
|
982
|
-
url2 = escape(url)
|
|
983
|
-
"\\href{#{url1}}{#{escaped_label}}\\footnote{\\starterurl{#{url1}}{#{url2}}}"
|
|
984
|
-
end
|
|
985
|
-
end
|
|
986
|
-
private :_inline_hyperlink
|
|
987
|
-
|
|
988
|
-
def build_inline_ruby(escaped_word, escaped_yomi) # compile_ruby()をベースに改造
|
|
989
|
-
"\\ruby{#{escaped_word}}{#{escaped_yomi}}"
|
|
990
|
-
end
|
|
991
|
-
|
|
992
|
-
def inline_bou(str)
|
|
993
|
-
## original
|
|
994
|
-
#str.split(//).map { |c| macro('ruby', escape(c), macro('textgt', BOUTEN)) }.join('\allowbreak')
|
|
995
|
-
## work well with XeLaTeX as well as upLaTeX
|
|
996
|
-
str.split(//).map {|c| "\\ruby{#{escape(c)}}{#{BOUTEN}}" }.join('\allowbreak')
|
|
997
|
-
end
|
|
998
|
-
|
|
999
|
-
protected
|
|
1000
|
-
|
|
1001
|
-
## ノートを参照する
|
|
1002
|
-
def build_noteref(chapter, label, caption)
|
|
1003
|
-
"\\starternoteref{#{label}}{#{escape(caption)}}"
|
|
1004
|
-
end
|
|
1005
|
-
|
|
1006
|
-
## 数式を参照する
|
|
1007
|
-
def build_eq(chapter, label, number)
|
|
1008
|
-
#"\\reviewequationref{#{chapter.number}.#{number}}"
|
|
1009
|
-
escape("#{I18n.t('equation')}#{chapter.number}.#{number}")
|
|
1010
|
-
end
|
|
1011
|
-
|
|
1012
|
-
public
|
|
1013
|
-
|
|
1014
|
-
## 数式を $...$ から \(...\) に変更する。
|
|
1015
|
-
## これで //list の中でも @<m>$...$ が使えるようになる。
|
|
1016
|
-
## ただし '^' や '_' がエスケープされるので、実用性はイマイチ。
|
|
1017
|
-
def inline_m(str)
|
|
1018
|
-
#" $#{str}$ " # original
|
|
1019
|
-
"\\(#{str}\\)"
|
|
1020
|
-
end
|
|
1021
|
-
|
|
1022
|
-
## 「``」と「''」で囲む
|
|
1023
|
-
def on_inline_qq()
|
|
1024
|
-
"``#{yield}''"
|
|
1025
|
-
end
|
|
1026
|
-
|
|
1027
|
-
## 索引に載せる語句 (@<idx>{}, @<term>{})
|
|
1028
|
-
def inline_idx(str)
|
|
1029
|
-
s1, s2 = _compile_term(str)
|
|
1030
|
-
"#{s1}\\index{#{s2}}"
|
|
1031
|
-
end
|
|
1032
|
-
def inline_hidx(str)
|
|
1033
|
-
_, s2 = _compile_term(str)
|
|
1034
|
-
"\\index{#{s2}}"
|
|
1035
|
-
end
|
|
1036
|
-
def inline_term(str)
|
|
1037
|
-
s1, s2 = _compile_term(str)
|
|
1038
|
-
"\\starterterm{#{s1}}\\index{#{s2}}"
|
|
1039
|
-
end
|
|
1040
|
-
def on_inline_termnoidx()
|
|
1041
|
-
"\\starterterm{#{yield}}"
|
|
1042
|
-
end
|
|
1043
|
-
|
|
1044
|
-
def _compile_term(str)
|
|
1045
|
-
arr = []
|
|
1046
|
-
placeholder = "\\starterindexplaceholder{}"
|
|
1047
|
-
display_str, see = parse_term(str, placeholder) do |term, term_e, yomi|
|
|
1048
|
-
if yomi
|
|
1049
|
-
arr << "#{escape_index(escape_latex(yomi))}@#{term_e}"
|
|
1050
|
-
elsif escape_index(term) != term_e
|
|
1051
|
-
arr << "#{escape_index(term)}@#{term_e}"
|
|
1052
|
-
else
|
|
1053
|
-
arr << term_e
|
|
1054
|
-
end
|
|
1055
|
-
end
|
|
1056
|
-
argstr = arr.join('!')
|
|
1057
|
-
argstr += "|see{#{escape_latex(see)}}" if see
|
|
1058
|
-
return display_str, argstr
|
|
1059
|
-
end
|
|
1060
|
-
private :_compile_term
|
|
1061
|
-
|
|
1062
|
-
end
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
end
|