review 2.3.0 → 2.4.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/.rubocop.yml +90 -66
- data/.travis.yml +1 -1
- data/Gemfile +0 -1
- data/NEWS.ja.md +82 -0
- data/NEWS.md +83 -0
- data/README.md +5 -3
- data/Rakefile +8 -8
- data/bin/review +1 -5
- data/bin/review-catalog-converter +22 -27
- data/bin/review-check +36 -43
- data/bin/review-checkdep +10 -15
- data/bin/review-compile +37 -55
- data/bin/review-epubmaker +4 -5
- data/bin/review-index +21 -29
- data/bin/review-init +26 -37
- data/bin/review-pdfmaker +0 -2
- data/bin/review-preproc +25 -45
- data/bin/review-validate +19 -18
- data/bin/review-vol +15 -27
- data/doc/config.yml.sample +5 -2
- data/doc/format.ja.md +20 -1
- data/doc/format.md +21 -5
- data/doc/images/review-generate.png +0 -0
- data/lib/epubmaker.rb +1 -3
- data/lib/epubmaker/content.rb +24 -27
- data/lib/epubmaker/epubcommon.rb +135 -148
- data/lib/epubmaker/epubv2.rb +39 -46
- data/lib/epubmaker/epubv3.rb +93 -103
- data/lib/epubmaker/producer.rb +138 -151
- data/lib/epubmaker/zip_exporter.rb +21 -26
- data/lib/review/book.rb +3 -6
- data/lib/review/book/base.rb +78 -103
- data/lib/review/book/chapter.rb +36 -40
- data/lib/review/book/compilable.rb +28 -31
- data/lib/review/book/image_finder.rb +6 -13
- data/lib/review/book/index.rb +100 -121
- data/lib/review/book/page_metric.rb +2 -7
- data/lib/review/book/part.rb +18 -20
- data/lib/review/book/volume.rb +9 -13
- data/lib/review/builder.rb +81 -116
- data/lib/review/catalog.rb +15 -19
- data/lib/review/compiler.rb +64 -83
- data/lib/review/configure.rb +87 -97
- data/lib/review/converter.rb +2 -7
- data/lib/review/epubbuilder.rb +1 -3
- data/lib/review/epubmaker.rb +213 -205
- data/lib/review/exception.rb +2 -4
- data/lib/review/extentions.rb +0 -1
- data/lib/review/extentions/hash.rb +2 -2
- data/lib/review/extentions/string.rb +5 -30
- data/lib/review/htmlbuilder.rb +320 -375
- data/lib/review/htmltoc.rb +4 -7
- data/lib/review/htmlutils.rb +29 -32
- data/lib/review/i18n.rb +33 -44
- data/lib/review/i18n.yml +3 -3
- data/lib/review/idgxmlbuilder.rb +309 -345
- data/lib/review/latexbuilder.rb +175 -212
- data/lib/review/latexindex.rb +2 -8
- data/lib/review/latexutils.rb +33 -43
- data/lib/review/lineinput.rb +1 -1
- data/lib/review/logger.rb +21 -0
- data/lib/review/makerhelper.rb +1 -4
- data/lib/review/markdownbuilder.rb +44 -53
- data/lib/review/md2inaobuilder.rb +6 -12
- data/lib/review/pdfmaker.rb +143 -173
- data/lib/review/preprocessor.rb +64 -101
- data/lib/review/rstbuilder.rb +126 -158
- data/lib/review/sec_counter.rb +18 -34
- data/lib/review/template.rb +4 -5
- data/lib/review/textbuilder.rb +2 -3
- data/lib/review/textutils.rb +7 -13
- data/lib/review/tocparser.rb +31 -56
- data/lib/review/tocprinter.rb +26 -52
- data/lib/review/topbuilder.rb +219 -247
- data/lib/review/unfold.rb +15 -24
- data/lib/review/version.rb +1 -1
- data/lib/review/webmaker.rb +75 -99
- data/lib/review/webtocprinter.rb +15 -20
- data/lib/review/yamlloader.rb +13 -15
- data/review.gemspec +20 -22
- data/templates/latex/layout.tex.erb +2 -2
- data/templates/opf/epubv2.opf.erb +7 -7
- data/templates/opf/epubv3.opf.erb +7 -7
- data/templates/web/html/layout-html5.html.erb +2 -2
- data/test/assets/black.eps +280 -0
- data/test/assets/fit.png +0 -0
- data/test/assets/large.gif +0 -0
- data/test/assets/large.jpg +0 -0
- data/test/assets/large.png +0 -0
- data/test/assets/large.svg +65 -0
- data/test/assets/test_template.tex +1 -1
- data/test/book_test_helper.rb +2 -2
- data/test/run_test.rb +4 -4
- data/test/sample-book/src/Rakefile +21 -22
- data/test/syntax-book/Gemfile +4 -0
- data/test/syntax-book/Rakefile +72 -0
- data/test/syntax-book/appA.re +22 -0
- data/test/syntax-book/bib.re +6 -0
- data/test/syntax-book/catalog.yml +15 -0
- data/test/syntax-book/ch01.re +136 -0
- data/test/syntax-book/ch02.re +351 -0
- data/test/syntax-book/ch03.re +82 -0
- data/test/syntax-book/config.yml +35 -0
- data/test/syntax-book/images/ball.png +0 -0
- data/test/syntax-book/images/cover.jpg +0 -0
- data/test/syntax-book/images/fractal.png +0 -0
- data/test/syntax-book/images/img3-1.png +0 -0
- data/test/syntax-book/images/inlineicon.jpg +0 -0
- data/test/syntax-book/images/logic.png +0 -0
- data/test/syntax-book/images/logic2.png +0 -0
- data/test/syntax-book/images/puzzle.jpg +0 -0
- data/test/syntax-book/images/table.jpg +0 -0
- data/test/syntax-book/part2.re +6 -0
- data/test/syntax-book/pre01.re +26 -0
- data/test/syntax-book/review-ext.rb +14 -0
- data/test/syntax-book/sty/jumoline.sty +310 -0
- data/test/syntax-book/sty/reviewmacro.sty +39 -0
- data/test/syntax-book/style.css +494 -0
- data/test/syntax-book/syntax.dic +2 -0
- data/test/test_book.rb +106 -111
- data/test/test_book_chapter.rb +21 -22
- data/test/test_book_part.rb +3 -5
- data/test/test_builder.rb +11 -22
- data/test/test_catalog.rb +17 -18
- data/test/test_catalog_converter_cmd.rb +5 -5
- data/test/test_compiler.rb +18 -16
- data/test/test_configure.rb +35 -38
- data/test/test_converter.rb +3 -4
- data/test/test_epub3maker.rb +136 -117
- data/test/test_epubmaker.rb +107 -114
- data/test/test_epubmaker_cmd.rb +2 -4
- data/test/test_extentions_hash.rb +32 -33
- data/test/test_helper.rb +9 -11
- data/test/test_htmlbuilder.rb +454 -420
- data/test/test_htmltoc.rb +8 -12
- data/test/test_htmlutils.rb +0 -2
- data/test/test_i18n.rb +159 -150
- data/test/test_idgxmlbuilder.rb +190 -197
- data/test/test_image_finder.rb +21 -22
- data/test/test_index.rb +24 -29
- data/test/test_latexbuilder.rb +274 -264
- data/test/test_lineinput.rb +7 -10
- data/test/test_location.rb +7 -7
- data/test/test_makerhelper.rb +13 -25
- data/test/test_markdownbuilder.rb +23 -26
- data/test/test_md2inaobuilder.rb +8 -11
- data/test/test_pdfmaker.rb +114 -123
- data/test/test_pdfmaker_cmd.rb +1 -3
- data/test/test_review_ext.rb +3 -5
- data/test/test_rstbuilder.rb +92 -97
- data/test/test_template.rb +3 -7
- data/test/test_textutils.rb +27 -27
- data/test/test_tocparser.rb +2 -2
- data/test/test_topbuilder.rb +98 -103
- data/test/test_webtocprinter.rb +5 -6
- data/test/test_yamlloader.rb +42 -42
- data/test/test_zip_exporter.rb +12 -18
- metadata +86 -9
- data/lib/review/ewbbuilder.rb +0 -382
data/lib/review/catalog.rb
CHANGED
|
@@ -12,45 +12,41 @@ module ReVIEW
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def predef
|
|
15
|
-
return
|
|
16
|
-
@yaml[
|
|
15
|
+
return '' unless @yaml['PREDEF']
|
|
16
|
+
@yaml['PREDEF'].join("\n")
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def chaps
|
|
20
|
-
return
|
|
20
|
+
return '' unless @yaml['CHAPS']
|
|
21
21
|
|
|
22
|
-
@yaml[
|
|
23
|
-
if entry.is_a?
|
|
22
|
+
@yaml['CHAPS'].map do |entry|
|
|
23
|
+
if entry.is_a?(String)
|
|
24
24
|
entry
|
|
25
|
-
elsif entry.is_a?
|
|
25
|
+
elsif entry.is_a?(Hash)
|
|
26
26
|
entry.values # chaps in a part
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
end.flatten.join("\n")
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def parts
|
|
32
|
-
return
|
|
32
|
+
return '' unless @yaml['CHAPS']
|
|
33
33
|
|
|
34
|
-
@yaml[
|
|
35
|
-
if entry.is_a? Hash
|
|
36
|
-
entry.keys
|
|
37
|
-
end
|
|
38
|
-
}.flatten.compact.join("\n")
|
|
34
|
+
@yaml['CHAPS'].map { |entry| entry.keys if entry.is_a?(Hash) }.flatten.compact.join("\n")
|
|
39
35
|
end
|
|
40
36
|
|
|
41
37
|
def parts_with_chaps
|
|
42
|
-
return
|
|
43
|
-
@yaml[
|
|
38
|
+
return '' unless @yaml['CHAPS']
|
|
39
|
+
@yaml['CHAPS'].flatten.compact
|
|
44
40
|
end
|
|
45
41
|
|
|
46
42
|
def appendix
|
|
47
|
-
return
|
|
48
|
-
@yaml[
|
|
43
|
+
return '' unless @yaml['APPENDIX']
|
|
44
|
+
@yaml['APPENDIX'].join("\n")
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
def postdef
|
|
52
|
-
return
|
|
53
|
-
@yaml[
|
|
48
|
+
return '' unless @yaml['POSTDEF']
|
|
49
|
+
@yaml['POSTDEF'].join("\n")
|
|
54
50
|
end
|
|
55
51
|
end
|
|
56
52
|
end
|
data/lib/review/compiler.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
# Copyright (c) 2002-2007 Minero Aoki
|
|
4
1
|
# Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
|
|
2
|
+
# Copyright (c) 2002-2007 Minero Aoki
|
|
5
3
|
#
|
|
6
4
|
# This program is free software.
|
|
7
5
|
# You can distribute or modify this program under the terms of
|
|
@@ -14,7 +12,6 @@ require 'review/exception'
|
|
|
14
12
|
require 'strscan'
|
|
15
13
|
|
|
16
14
|
module ReVIEW
|
|
17
|
-
|
|
18
15
|
class Location
|
|
19
16
|
def initialize(filename, f)
|
|
20
17
|
@filename = filename
|
|
@@ -38,9 +35,7 @@ module ReVIEW
|
|
|
38
35
|
alias_method :to_s, :string
|
|
39
36
|
end
|
|
40
37
|
|
|
41
|
-
|
|
42
38
|
class Compiler
|
|
43
|
-
|
|
44
39
|
def initialize(strategy)
|
|
45
40
|
@strategy = strategy
|
|
46
41
|
end
|
|
@@ -64,9 +59,7 @@ module ReVIEW
|
|
|
64
59
|
attr_reader :name
|
|
65
60
|
|
|
66
61
|
def check_args(args)
|
|
67
|
-
unless @argc_spec === args.size
|
|
68
|
-
raise CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})"
|
|
69
|
-
end
|
|
62
|
+
raise CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})" unless @argc_spec === args.size
|
|
70
63
|
@checker.call(*args) if @checker
|
|
71
64
|
end
|
|
72
65
|
|
|
@@ -75,7 +68,7 @@ module ReVIEW
|
|
|
75
68
|
when Range then @argc_spec.begin
|
|
76
69
|
when Integer then @argc_spec
|
|
77
70
|
else
|
|
78
|
-
raise TypeError, "argc_spec is not Range/Integer: #{inspect
|
|
71
|
+
raise TypeError, "argc_spec is not Range/Integer: #{inspect}"
|
|
79
72
|
end
|
|
80
73
|
end
|
|
81
74
|
|
|
@@ -90,18 +83,22 @@ module ReVIEW
|
|
|
90
83
|
|
|
91
84
|
SYNTAX = {}
|
|
92
85
|
|
|
93
|
-
def
|
|
86
|
+
def self.defblock(name, argc, optional = false, &block)
|
|
94
87
|
defsyntax name, (optional ? :optional : :block), argc, &block
|
|
95
88
|
end
|
|
96
89
|
|
|
97
|
-
def
|
|
90
|
+
def self.defsingle(name, argc, &block)
|
|
98
91
|
defsyntax name, :line, argc, &block
|
|
99
92
|
end
|
|
100
93
|
|
|
101
|
-
def
|
|
94
|
+
def self.defsyntax(name, type, argc, &block)
|
|
102
95
|
SYNTAX[name] = SyntaxElement.new(name, type, argc, &block)
|
|
103
96
|
end
|
|
104
97
|
|
|
98
|
+
def self.definline(name)
|
|
99
|
+
INLINE[name] = InlineSyntaxElement.new(name)
|
|
100
|
+
end
|
|
101
|
+
|
|
105
102
|
def syntax_defined?(name)
|
|
106
103
|
SYNTAX.key?(name.to_sym)
|
|
107
104
|
end
|
|
@@ -120,10 +117,6 @@ module ReVIEW
|
|
|
120
117
|
|
|
121
118
|
INLINE = {}
|
|
122
119
|
|
|
123
|
-
def Compiler.definline(name)
|
|
124
|
-
INLINE[name] = InlineSyntaxElement.new(name)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
120
|
def inline_defined?(name)
|
|
128
121
|
INLINE.key?(name.to_sym)
|
|
129
122
|
end
|
|
@@ -146,6 +139,8 @@ module ReVIEW
|
|
|
146
139
|
defblock :talk, 0
|
|
147
140
|
defblock :texequation, 0
|
|
148
141
|
defblock :graph, 1..3
|
|
142
|
+
defblock :indepimage, 1..3, true
|
|
143
|
+
defblock :numberlessimage, 1..3, true
|
|
149
144
|
|
|
150
145
|
defblock :address, 0
|
|
151
146
|
defblock :blockquote, 0
|
|
@@ -168,8 +163,6 @@ module ReVIEW
|
|
|
168
163
|
defsingle :noindent, 0
|
|
169
164
|
defsingle :linebreak, 0
|
|
170
165
|
defsingle :pagebreak, 0
|
|
171
|
-
defsingle :indepimage, 1..3
|
|
172
|
-
defsingle :numberlessimage, 1..3
|
|
173
166
|
defsingle :hr, 0
|
|
174
167
|
defsingle :parasep, 0
|
|
175
168
|
defsingle :label, 1
|
|
@@ -233,6 +226,7 @@ module ReVIEW
|
|
|
233
226
|
definline :include
|
|
234
227
|
definline :tcy
|
|
235
228
|
definline :embed
|
|
229
|
+
definline :pageref
|
|
236
230
|
|
|
237
231
|
private
|
|
238
232
|
|
|
@@ -246,16 +240,16 @@ module ReVIEW
|
|
|
246
240
|
f.gets # Nothing to do
|
|
247
241
|
when /\A=+[\[\s\{]/
|
|
248
242
|
compile_headline f.gets
|
|
249
|
-
when
|
|
243
|
+
when /\A\s+\*/
|
|
250
244
|
compile_ulist f
|
|
251
|
-
when
|
|
245
|
+
when /\A\s+\d+\./
|
|
252
246
|
compile_olist f
|
|
253
|
-
when
|
|
247
|
+
when /\A\s*:\s/
|
|
254
248
|
compile_dlist f
|
|
255
|
-
when %r
|
|
249
|
+
when %r{\A//\}}
|
|
256
250
|
f.gets
|
|
257
251
|
error 'block end seen but not opened'
|
|
258
|
-
when %r
|
|
252
|
+
when %r{\A//[a-z]+}
|
|
259
253
|
name, args, lines = read_command(f)
|
|
260
254
|
syntax = syntax_descriptor(name)
|
|
261
255
|
unless syntax
|
|
@@ -264,11 +258,11 @@ module ReVIEW
|
|
|
264
258
|
next
|
|
265
259
|
end
|
|
266
260
|
compile_command syntax, args, lines
|
|
267
|
-
when %r
|
|
261
|
+
when %r{\A//}
|
|
268
262
|
line = f.gets
|
|
269
263
|
warn "`//' seen but is not valid command: #{line.strip.inspect}"
|
|
270
264
|
if block_open?(line)
|
|
271
|
-
warn
|
|
265
|
+
warn 'skipping block...'
|
|
272
266
|
read_block(f, false)
|
|
273
267
|
end
|
|
274
268
|
else
|
|
@@ -291,21 +285,19 @@ module ReVIEW
|
|
|
291
285
|
caption = m[4].strip
|
|
292
286
|
index = level - 1
|
|
293
287
|
if tag
|
|
294
|
-
if tag !~
|
|
288
|
+
if tag !~ %r{\A/}
|
|
289
|
+
warn 'headline is empty.' if caption.empty?
|
|
295
290
|
close_current_tagged_section(level)
|
|
296
291
|
open_tagged_section(tag, level, label, caption)
|
|
297
292
|
else
|
|
298
293
|
open_tag = tag[1..-1]
|
|
299
294
|
prev_tag_info = @tagged_section.pop
|
|
300
|
-
|
|
301
|
-
raise CompileError, "#{open_tag} is not opened."
|
|
302
|
-
end
|
|
295
|
+
error "#{open_tag} is not opened." if prev_tag_info.nil? || prev_tag_info.first != open_tag
|
|
303
296
|
close_tagged_section(*prev_tag_info)
|
|
304
297
|
end
|
|
305
298
|
else
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
end
|
|
299
|
+
warn 'headline is empty.' if caption.empty?
|
|
300
|
+
@headline_indexs = @headline_indexs[0..index] if @headline_indexs.size > (index + 1)
|
|
309
301
|
@headline_indexs[index] = 0 if @headline_indexs[index].nil?
|
|
310
302
|
@headline_indexs[index] += 1
|
|
311
303
|
close_current_tagged_section(level)
|
|
@@ -348,9 +340,7 @@ module ReVIEW
|
|
|
348
340
|
end
|
|
349
341
|
|
|
350
342
|
def close_all_tagged_section
|
|
351
|
-
until @tagged_section.empty?
|
|
352
|
-
close_tagged_section(* @tagged_section.pop)
|
|
353
|
-
end
|
|
343
|
+
close_tagged_section(* @tagged_section.pop) until @tagged_section.empty?
|
|
354
344
|
end
|
|
355
345
|
|
|
356
346
|
def compile_ulist(f)
|
|
@@ -359,9 +349,7 @@ module ReVIEW
|
|
|
359
349
|
next if line =~ /\A\#@/
|
|
360
350
|
|
|
361
351
|
buf = [text(line.sub(/\*+/, '').strip)]
|
|
362
|
-
f.while_match(/\A\s+(?!\*)\S/)
|
|
363
|
-
buf.push text(cont.strip)
|
|
364
|
-
end
|
|
352
|
+
f.while_match(/\A\s+(?!\*)\S/) { |cont| buf.push text(cont.strip) }
|
|
365
353
|
|
|
366
354
|
line =~ /\A\s+(\*+)/
|
|
367
355
|
current_level = $1.size
|
|
@@ -373,17 +361,17 @@ module ReVIEW
|
|
|
373
361
|
level_diff = current_level - level
|
|
374
362
|
level = current_level
|
|
375
363
|
(1..(level_diff - 1)).to_a.reverse_each do |i|
|
|
376
|
-
@strategy.ul_begin {i}
|
|
364
|
+
@strategy.ul_begin { i }
|
|
377
365
|
@strategy.ul_item_begin []
|
|
378
366
|
end
|
|
379
|
-
@strategy.ul_begin {level}
|
|
367
|
+
@strategy.ul_begin { level }
|
|
380
368
|
@strategy.ul_item_begin buf
|
|
381
369
|
elsif level > current_level # up
|
|
382
370
|
level_diff = level - current_level
|
|
383
371
|
level = current_level
|
|
384
372
|
(1..level_diff).to_a.reverse_each do |i|
|
|
385
373
|
@strategy.ul_item_end
|
|
386
|
-
@strategy.ul_end {level + i}
|
|
374
|
+
@strategy.ul_end { level + i }
|
|
387
375
|
end
|
|
388
376
|
@strategy.ul_item_end
|
|
389
377
|
# body
|
|
@@ -393,7 +381,7 @@ module ReVIEW
|
|
|
393
381
|
|
|
394
382
|
(1..level).to_a.reverse_each do |i|
|
|
395
383
|
@strategy.ul_item_end
|
|
396
|
-
@strategy.ul_end {i}
|
|
384
|
+
@strategy.ul_end { i }
|
|
397
385
|
end
|
|
398
386
|
end
|
|
399
387
|
|
|
@@ -404,9 +392,7 @@ module ReVIEW
|
|
|
404
392
|
|
|
405
393
|
num = line.match(/(\d+)\./)[1]
|
|
406
394
|
buf = [text(line.sub(/\d+\./, '').strip)]
|
|
407
|
-
f.while_match(/\A\s+(?!\d+\.)\S/)
|
|
408
|
-
buf.push text(cont.strip)
|
|
409
|
-
end
|
|
395
|
+
f.while_match(/\A\s+(?!\d+\.)\S/) { |cont| buf.push text(cont.strip) }
|
|
410
396
|
@strategy.ol_item buf, num
|
|
411
397
|
end
|
|
412
398
|
@strategy.ol_end
|
|
@@ -416,7 +402,7 @@ module ReVIEW
|
|
|
416
402
|
@strategy.dl_begin
|
|
417
403
|
while /\A\s*:/ =~ f.peek
|
|
418
404
|
@strategy.dt text(f.gets.sub(/\A\s*:/, '').strip)
|
|
419
|
-
@strategy.dd(f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map {|line| text(line.strip) })
|
|
405
|
+
@strategy.dd(f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) })
|
|
420
406
|
f.skip_blank_lines
|
|
421
407
|
f.skip_comment_lines
|
|
422
408
|
end
|
|
@@ -425,9 +411,9 @@ module ReVIEW
|
|
|
425
411
|
|
|
426
412
|
def compile_paragraph(f)
|
|
427
413
|
buf = []
|
|
428
|
-
f.until_match(%r
|
|
414
|
+
f.until_match(%r{\A//|\A\#@}) do |line|
|
|
429
415
|
break if line.strip.empty?
|
|
430
|
-
buf.push text(line.sub(/^(\t+)\s*/) {|m|
|
|
416
|
+
buf.push text(line.sub(/^(\t+)\s*/) { |m| '<!ESCAPETAB!>' * m.size }.strip.gsub('<!ESCAPETAB!>', "\t"))
|
|
431
417
|
end
|
|
432
418
|
@strategy.paragraph buf
|
|
433
419
|
end
|
|
@@ -436,28 +422,27 @@ module ReVIEW
|
|
|
436
422
|
line = f.gets
|
|
437
423
|
name = line.slice(/[a-z]+/).to_sym
|
|
438
424
|
ignore_inline = (name == :embed)
|
|
439
|
-
args = parse_args(line.sub(%r
|
|
425
|
+
args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name)
|
|
440
426
|
lines = block_open?(line) ? read_block(f, ignore_inline) : nil
|
|
441
|
-
|
|
427
|
+
|
|
428
|
+
[name, args, lines]
|
|
442
429
|
end
|
|
443
430
|
|
|
444
431
|
def block_open?(line)
|
|
445
|
-
line.rstrip[-1,1] == '{'
|
|
432
|
+
line.rstrip[-1, 1] == '{'
|
|
446
433
|
end
|
|
447
434
|
|
|
448
435
|
def read_block(f, ignore_inline)
|
|
449
436
|
head = f.lineno
|
|
450
437
|
buf = []
|
|
451
|
-
f.until_match(%r
|
|
438
|
+
f.until_match(%r{\A//\}}) do |line|
|
|
452
439
|
if ignore_inline
|
|
453
440
|
buf.push line
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
buf.push text(line.rstrip)
|
|
457
|
-
end
|
|
441
|
+
elsif line !~ /\A\#@/
|
|
442
|
+
buf.push text(line.rstrip)
|
|
458
443
|
end
|
|
459
444
|
end
|
|
460
|
-
unless %r
|
|
445
|
+
unless %r{\A//\}} =~ f.peek
|
|
461
446
|
error "unexpected EOF (block begins at: #{head})"
|
|
462
447
|
return buf
|
|
463
448
|
end
|
|
@@ -465,22 +450,22 @@ module ReVIEW
|
|
|
465
450
|
buf
|
|
466
451
|
end
|
|
467
452
|
|
|
468
|
-
def parse_args(str,
|
|
453
|
+
def parse_args(str, _name = nil)
|
|
469
454
|
return [] if str.empty?
|
|
470
455
|
scanner = StringScanner.new(str)
|
|
471
456
|
words = []
|
|
472
457
|
while word = scanner.scan(/(\[\]|\[.*?[^\\]\])/)
|
|
473
|
-
w2 = word[1..-2].gsub(/\\(.)/)
|
|
458
|
+
w2 = word[1..-2].gsub(/\\(.)/) do
|
|
474
459
|
ch = $1
|
|
475
|
-
(ch ==
|
|
476
|
-
|
|
460
|
+
(ch == ']' or ch == '\\') ? ch : '\\' + ch
|
|
461
|
+
end
|
|
477
462
|
words << w2
|
|
478
463
|
end
|
|
479
|
-
|
|
464
|
+
unless scanner.eos?
|
|
480
465
|
error "argument syntax error: #{scanner.rest} in #{str.inspect}"
|
|
481
466
|
return []
|
|
482
467
|
end
|
|
483
|
-
|
|
468
|
+
words
|
|
484
469
|
end
|
|
485
470
|
|
|
486
471
|
def compile_command(syntax, args, lines)
|
|
@@ -498,9 +483,7 @@ module ReVIEW
|
|
|
498
483
|
if syntax.block_allowed?
|
|
499
484
|
compile_block syntax, args, lines
|
|
500
485
|
else
|
|
501
|
-
if lines
|
|
502
|
-
error "block is not allowed for command //#{syntax.name}; ignore"
|
|
503
|
-
end
|
|
486
|
+
error "block is not allowed for command //#{syntax.name}; ignore" if lines
|
|
504
487
|
compile_single syntax, args
|
|
505
488
|
end
|
|
506
489
|
end
|
|
@@ -514,9 +497,7 @@ module ReVIEW
|
|
|
514
497
|
end
|
|
515
498
|
|
|
516
499
|
def default_block(syntax)
|
|
517
|
-
if syntax.block_required?
|
|
518
|
-
error "block is required for //#{syntax.name}; use empty block"
|
|
519
|
-
end
|
|
500
|
+
error "block is required for //#{syntax.name}; use empty block" if syntax.block_required?
|
|
520
501
|
[]
|
|
521
502
|
end
|
|
522
503
|
|
|
@@ -524,18 +505,24 @@ module ReVIEW
|
|
|
524
505
|
@strategy.__send__(syntax.name, *args)
|
|
525
506
|
end
|
|
526
507
|
|
|
508
|
+
def replace_fence(str)
|
|
509
|
+
str.gsub(/@<(\w+)>([$|])(.+?)(\2)/) do
|
|
510
|
+
op = $1
|
|
511
|
+
arg = $3.gsub('@', "\x01").gsub('\\}') { '\\\\}' }.gsub('}') { '\}' }.sub(/(?:\\)+$/) { |m| '\\\\' * m.size }
|
|
512
|
+
"@<#{op}>{#{arg}}"
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
527
516
|
def text(str)
|
|
528
517
|
return '' if str.empty?
|
|
529
|
-
words = str.split(/(@<\w+>\{(?:[^\}\\]|\\.)*?\})/, -1)
|
|
530
|
-
words.each
|
|
531
|
-
error "`@<xxx>' seen but is not valid inline op: #{w}" if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w)
|
|
532
|
-
end
|
|
518
|
+
words = replace_fence(str).split(/(@<\w+>\{(?:[^\}\\]|\\.)*?\})/, -1)
|
|
519
|
+
words.each { |w| error "`@<xxx>' seen but is not valid inline op: #{w}" if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w) }
|
|
533
520
|
result = @strategy.nofunc_text(words.shift)
|
|
534
521
|
until words.empty?
|
|
535
522
|
result << compile_inline(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\'))
|
|
536
523
|
result << @strategy.nofunc_text(words.shift)
|
|
537
524
|
end
|
|
538
|
-
result
|
|
525
|
+
result.gsub("\x01", '@')
|
|
539
526
|
rescue => err
|
|
540
527
|
error err.message
|
|
541
528
|
end
|
|
@@ -543,12 +530,8 @@ module ReVIEW
|
|
|
543
530
|
|
|
544
531
|
def compile_inline(str)
|
|
545
532
|
op, arg = /\A@<(\w+)>\{(.*?)\}\z/.match(str).captures
|
|
546
|
-
unless inline_defined?(op)
|
|
547
|
-
|
|
548
|
-
end
|
|
549
|
-
unless @strategy.respond_to?("inline_#{op}")
|
|
550
|
-
raise "strategy does not support inline op: @<#{op}>"
|
|
551
|
-
end
|
|
533
|
+
raise CompileError, "no such inline op: #{op}" unless inline_defined?(op)
|
|
534
|
+
raise "strategy does not support inline op: @<#{op}>" unless @strategy.respond_to?("inline_#{op}")
|
|
552
535
|
@strategy.__send__("inline_#{op}", arg)
|
|
553
536
|
rescue => err
|
|
554
537
|
error err.message
|
|
@@ -562,7 +545,5 @@ module ReVIEW
|
|
|
562
545
|
def error(msg)
|
|
563
546
|
@strategy.error msg
|
|
564
547
|
end
|
|
565
|
-
|
|
566
548
|
end
|
|
567
|
-
|
|
568
549
|
end # module ReVIEW
|
data/lib/review/configure.rb
CHANGED
|
@@ -1,86 +1,84 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
require 'securerandom'
|
|
3
2
|
|
|
4
3
|
module ReVIEW
|
|
5
4
|
class Configure < Hash
|
|
6
|
-
|
|
7
5
|
attr_accessor :maker
|
|
8
6
|
|
|
9
7
|
def self.values
|
|
10
8
|
conf = Configure[
|
|
11
9
|
# These parameters can be overridden by YAML file.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
10
|
+
'bookname' => 'example', # it defines epub file name also
|
|
11
|
+
'booktitle' => 'Re:VIEW Sample Book',
|
|
12
|
+
'title' => nil,
|
|
13
|
+
'aut' => nil, # author
|
|
14
|
+
'prt' => nil, # printer(publisher)
|
|
15
|
+
'asn' => nil, # associated name
|
|
16
|
+
'ant' => nil, # bibliographic antecedent
|
|
17
|
+
'clb' => nil, # Collaborator
|
|
18
|
+
'edt' => nil, # Editor
|
|
19
|
+
'dsr' => nil, # Designer
|
|
20
|
+
'ill' => nil, # Illustrator
|
|
21
|
+
'pht' => nil, # Photographer
|
|
22
|
+
'trl' => nil, # Translator
|
|
23
|
+
'date' => Time.now.strftime('%Y-%m-%d'), # publishing date
|
|
24
|
+
'rights' => nil, # Copyright messages
|
|
25
|
+
'description' => nil, # Description
|
|
26
|
+
'urnid' => "urn:uid:#{SecureRandom.uuid}", # Identifier
|
|
27
|
+
'stylesheet' => 'stylesheet.css', # stylesheet file
|
|
28
|
+
'coverfile' => nil, # content file of body of cover page
|
|
29
|
+
'mytoc' => nil, # whether make own table of contents or not
|
|
30
|
+
'params' => '', # specify review2html parameters
|
|
31
|
+
'toclevel' => 3, # level of toc
|
|
32
|
+
'secnolevel' => 2, # level of section #
|
|
33
|
+
'epubversion' => 3,
|
|
34
|
+
'titlepage' => true, # Use title page
|
|
35
|
+
'toc' => nil, # Use table of contents in body
|
|
36
|
+
'colophon' => nil, # Use colophon
|
|
37
|
+
'debug' => nil, # debug flag
|
|
38
|
+
'catalogfile' => 'catalog.yml',
|
|
39
|
+
'language' => 'ja', # XXX default language should be JA??
|
|
40
|
+
'mathml' => nil, # for HTML
|
|
41
|
+
'imgmath' => nil, # for HTML
|
|
42
|
+
'htmlext' => 'html',
|
|
43
|
+
'htmlversion' => 5,
|
|
44
|
+
'imagedir' => 'images',
|
|
45
|
+
'image_ext' => %w[png gif jpg jpeg svg ttf woff otf],
|
|
46
|
+
'fontdir' => 'fonts',
|
|
47
|
+
'chapter_file' => 'CHAPS',
|
|
48
|
+
'part_file' => 'PART',
|
|
49
|
+
'reject_file' => 'REJECT',
|
|
50
|
+
'predef_file' => 'PREDEF',
|
|
51
|
+
'postdef_file' => 'POSTDEF',
|
|
52
|
+
'page_metric' => ReVIEW::Book::PageMetric::A5,
|
|
53
|
+
'ext' => '.re',
|
|
54
|
+
'image_dir' => 'images',
|
|
55
|
+
'image_types' => %w[.ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg],
|
|
56
|
+
'image_scale2width' => true, # for LaTeX
|
|
57
|
+
'bib_file' => 'bib.re',
|
|
58
|
+
'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt],
|
|
59
|
+
'externallink' => true,
|
|
60
|
+
'tableopt' => nil, # for IDGXML
|
|
61
|
+
'listinfo' => nil, # for IDGXML
|
|
62
|
+
'nolf' => true, # for IDGXML
|
|
63
|
+
'chapref' => nil, # for IDGXML
|
|
64
|
+
'structuredxml' => nil, # for IDGXML
|
|
65
|
+
'pt_to_mm_unit' => 0.3528, # for IDGXML (DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm)
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
'footnotetext' => nil, # for LaTeX
|
|
68
|
+
'texcommand' => 'uplatex', # for LaTeX
|
|
69
|
+
'texdocumentclass' => ['jsbook', 'uplatex,oneside'], # for LaTeX
|
|
70
|
+
'dvicommand' => 'dvipdfmx', # for LaTeX
|
|
71
|
+
'dvioptions' => '-d 5', # for LaTeX
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
73
|
+
'pdfmaker' => {
|
|
74
|
+
'makeindex' => nil, # Make index page
|
|
75
|
+
'makeindex_command' => 'mendex', # works only when makeindex is true
|
|
76
|
+
'makeindex_options' => '-f -r -I utf8',
|
|
77
|
+
'makeindex_sty' => nil,
|
|
78
|
+
'makeindex_dic' => nil,
|
|
79
|
+
'makeindex_mecab' => true,
|
|
80
|
+
'makeindex_mecab_opts' => '-Oyomi'
|
|
81
|
+
}
|
|
84
82
|
]
|
|
85
83
|
conf.maker = nil
|
|
86
84
|
conf
|
|
@@ -88,49 +86,41 @@ module ReVIEW
|
|
|
88
86
|
|
|
89
87
|
def [](key)
|
|
90
88
|
maker = self.maker
|
|
91
|
-
if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if self.key?(key)
|
|
95
|
-
return self.fetch(key)
|
|
96
|
-
end
|
|
89
|
+
return self.fetch(maker).fetch(key, nil) if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key)
|
|
90
|
+
return self.fetch(key) if self.key?(key)
|
|
91
|
+
nil
|
|
97
92
|
end
|
|
98
93
|
|
|
99
94
|
def check_version(version)
|
|
100
|
-
unless self.key?(
|
|
101
|
-
raise ReVIEW::ConfigError, "configuration file has no review_version property."
|
|
102
|
-
end
|
|
95
|
+
raise ReVIEW::ConfigError, 'configuration file has no review_version property.' unless self.key?('review_version')
|
|
103
96
|
|
|
104
|
-
if self[
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
elsif self["review_version"].to_f > version.to_f ## minor version
|
|
109
|
-
raise ReVIEW::ConfigError, "Re:VIEW version '#{version}' is older than configuration file's version '#{self["review_version"]}'."
|
|
110
|
-
end
|
|
97
|
+
return true if self['review_version'].blank?
|
|
98
|
+
|
|
99
|
+
raise ReVIEW::ConfigError, 'major version of configuration file is different.' if self['review_version'].to_i != version.to_i ## major version
|
|
100
|
+
raise ReVIEW::ConfigError, "Re:VIEW version '#{version}' is older than configuration file's version '#{self['review_version']}'." if self['review_version'].to_f > version.to_f ## minor version
|
|
111
101
|
end
|
|
112
102
|
|
|
113
103
|
def name_of(key)
|
|
114
|
-
if self[key].
|
|
115
|
-
self[key].join(
|
|
116
|
-
elsif self[key].
|
|
117
|
-
self[key][
|
|
104
|
+
if self[key].is_a?(Array)
|
|
105
|
+
self[key].join(',') # i18n?
|
|
106
|
+
elsif self[key].is_a?(Hash)
|
|
107
|
+
self[key]['name']
|
|
118
108
|
else
|
|
119
109
|
self[key]
|
|
120
110
|
end
|
|
121
111
|
end
|
|
122
112
|
|
|
123
113
|
def names_of(key)
|
|
124
|
-
if self[key].
|
|
114
|
+
if self[key].is_a?(Array)
|
|
125
115
|
self[key].map do |a|
|
|
126
|
-
if a.
|
|
127
|
-
a[
|
|
116
|
+
if a.is_a?(Hash)
|
|
117
|
+
a['name']
|
|
128
118
|
else
|
|
129
119
|
a
|
|
130
120
|
end
|
|
131
121
|
end
|
|
132
|
-
elsif self[key].
|
|
133
|
-
[self[key][
|
|
122
|
+
elsif self[key].is_a?(Hash)
|
|
123
|
+
[self[key]['name']]
|
|
134
124
|
else
|
|
135
125
|
[self[key]]
|
|
136
126
|
end
|