review 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|