review 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +90 -66
  3. data/.travis.yml +1 -1
  4. data/Gemfile +0 -1
  5. data/NEWS.ja.md +82 -0
  6. data/NEWS.md +83 -0
  7. data/README.md +5 -3
  8. data/Rakefile +8 -8
  9. data/bin/review +1 -5
  10. data/bin/review-catalog-converter +22 -27
  11. data/bin/review-check +36 -43
  12. data/bin/review-checkdep +10 -15
  13. data/bin/review-compile +37 -55
  14. data/bin/review-epubmaker +4 -5
  15. data/bin/review-index +21 -29
  16. data/bin/review-init +26 -37
  17. data/bin/review-pdfmaker +0 -2
  18. data/bin/review-preproc +25 -45
  19. data/bin/review-validate +19 -18
  20. data/bin/review-vol +15 -27
  21. data/doc/config.yml.sample +5 -2
  22. data/doc/format.ja.md +20 -1
  23. data/doc/format.md +21 -5
  24. data/doc/images/review-generate.png +0 -0
  25. data/lib/epubmaker.rb +1 -3
  26. data/lib/epubmaker/content.rb +24 -27
  27. data/lib/epubmaker/epubcommon.rb +135 -148
  28. data/lib/epubmaker/epubv2.rb +39 -46
  29. data/lib/epubmaker/epubv3.rb +93 -103
  30. data/lib/epubmaker/producer.rb +138 -151
  31. data/lib/epubmaker/zip_exporter.rb +21 -26
  32. data/lib/review/book.rb +3 -6
  33. data/lib/review/book/base.rb +78 -103
  34. data/lib/review/book/chapter.rb +36 -40
  35. data/lib/review/book/compilable.rb +28 -31
  36. data/lib/review/book/image_finder.rb +6 -13
  37. data/lib/review/book/index.rb +100 -121
  38. data/lib/review/book/page_metric.rb +2 -7
  39. data/lib/review/book/part.rb +18 -20
  40. data/lib/review/book/volume.rb +9 -13
  41. data/lib/review/builder.rb +81 -116
  42. data/lib/review/catalog.rb +15 -19
  43. data/lib/review/compiler.rb +64 -83
  44. data/lib/review/configure.rb +87 -97
  45. data/lib/review/converter.rb +2 -7
  46. data/lib/review/epubbuilder.rb +1 -3
  47. data/lib/review/epubmaker.rb +213 -205
  48. data/lib/review/exception.rb +2 -4
  49. data/lib/review/extentions.rb +0 -1
  50. data/lib/review/extentions/hash.rb +2 -2
  51. data/lib/review/extentions/string.rb +5 -30
  52. data/lib/review/htmlbuilder.rb +320 -375
  53. data/lib/review/htmltoc.rb +4 -7
  54. data/lib/review/htmlutils.rb +29 -32
  55. data/lib/review/i18n.rb +33 -44
  56. data/lib/review/i18n.yml +3 -3
  57. data/lib/review/idgxmlbuilder.rb +309 -345
  58. data/lib/review/latexbuilder.rb +175 -212
  59. data/lib/review/latexindex.rb +2 -8
  60. data/lib/review/latexutils.rb +33 -43
  61. data/lib/review/lineinput.rb +1 -1
  62. data/lib/review/logger.rb +21 -0
  63. data/lib/review/makerhelper.rb +1 -4
  64. data/lib/review/markdownbuilder.rb +44 -53
  65. data/lib/review/md2inaobuilder.rb +6 -12
  66. data/lib/review/pdfmaker.rb +143 -173
  67. data/lib/review/preprocessor.rb +64 -101
  68. data/lib/review/rstbuilder.rb +126 -158
  69. data/lib/review/sec_counter.rb +18 -34
  70. data/lib/review/template.rb +4 -5
  71. data/lib/review/textbuilder.rb +2 -3
  72. data/lib/review/textutils.rb +7 -13
  73. data/lib/review/tocparser.rb +31 -56
  74. data/lib/review/tocprinter.rb +26 -52
  75. data/lib/review/topbuilder.rb +219 -247
  76. data/lib/review/unfold.rb +15 -24
  77. data/lib/review/version.rb +1 -1
  78. data/lib/review/webmaker.rb +75 -99
  79. data/lib/review/webtocprinter.rb +15 -20
  80. data/lib/review/yamlloader.rb +13 -15
  81. data/review.gemspec +20 -22
  82. data/templates/latex/layout.tex.erb +2 -2
  83. data/templates/opf/epubv2.opf.erb +7 -7
  84. data/templates/opf/epubv3.opf.erb +7 -7
  85. data/templates/web/html/layout-html5.html.erb +2 -2
  86. data/test/assets/black.eps +280 -0
  87. data/test/assets/fit.png +0 -0
  88. data/test/assets/large.gif +0 -0
  89. data/test/assets/large.jpg +0 -0
  90. data/test/assets/large.png +0 -0
  91. data/test/assets/large.svg +65 -0
  92. data/test/assets/test_template.tex +1 -1
  93. data/test/book_test_helper.rb +2 -2
  94. data/test/run_test.rb +4 -4
  95. data/test/sample-book/src/Rakefile +21 -22
  96. data/test/syntax-book/Gemfile +4 -0
  97. data/test/syntax-book/Rakefile +72 -0
  98. data/test/syntax-book/appA.re +22 -0
  99. data/test/syntax-book/bib.re +6 -0
  100. data/test/syntax-book/catalog.yml +15 -0
  101. data/test/syntax-book/ch01.re +136 -0
  102. data/test/syntax-book/ch02.re +351 -0
  103. data/test/syntax-book/ch03.re +82 -0
  104. data/test/syntax-book/config.yml +35 -0
  105. data/test/syntax-book/images/ball.png +0 -0
  106. data/test/syntax-book/images/cover.jpg +0 -0
  107. data/test/syntax-book/images/fractal.png +0 -0
  108. data/test/syntax-book/images/img3-1.png +0 -0
  109. data/test/syntax-book/images/inlineicon.jpg +0 -0
  110. data/test/syntax-book/images/logic.png +0 -0
  111. data/test/syntax-book/images/logic2.png +0 -0
  112. data/test/syntax-book/images/puzzle.jpg +0 -0
  113. data/test/syntax-book/images/table.jpg +0 -0
  114. data/test/syntax-book/part2.re +6 -0
  115. data/test/syntax-book/pre01.re +26 -0
  116. data/test/syntax-book/review-ext.rb +14 -0
  117. data/test/syntax-book/sty/jumoline.sty +310 -0
  118. data/test/syntax-book/sty/reviewmacro.sty +39 -0
  119. data/test/syntax-book/style.css +494 -0
  120. data/test/syntax-book/syntax.dic +2 -0
  121. data/test/test_book.rb +106 -111
  122. data/test/test_book_chapter.rb +21 -22
  123. data/test/test_book_part.rb +3 -5
  124. data/test/test_builder.rb +11 -22
  125. data/test/test_catalog.rb +17 -18
  126. data/test/test_catalog_converter_cmd.rb +5 -5
  127. data/test/test_compiler.rb +18 -16
  128. data/test/test_configure.rb +35 -38
  129. data/test/test_converter.rb +3 -4
  130. data/test/test_epub3maker.rb +136 -117
  131. data/test/test_epubmaker.rb +107 -114
  132. data/test/test_epubmaker_cmd.rb +2 -4
  133. data/test/test_extentions_hash.rb +32 -33
  134. data/test/test_helper.rb +9 -11
  135. data/test/test_htmlbuilder.rb +454 -420
  136. data/test/test_htmltoc.rb +8 -12
  137. data/test/test_htmlutils.rb +0 -2
  138. data/test/test_i18n.rb +159 -150
  139. data/test/test_idgxmlbuilder.rb +190 -197
  140. data/test/test_image_finder.rb +21 -22
  141. data/test/test_index.rb +24 -29
  142. data/test/test_latexbuilder.rb +274 -264
  143. data/test/test_lineinput.rb +7 -10
  144. data/test/test_location.rb +7 -7
  145. data/test/test_makerhelper.rb +13 -25
  146. data/test/test_markdownbuilder.rb +23 -26
  147. data/test/test_md2inaobuilder.rb +8 -11
  148. data/test/test_pdfmaker.rb +114 -123
  149. data/test/test_pdfmaker_cmd.rb +1 -3
  150. data/test/test_review_ext.rb +3 -5
  151. data/test/test_rstbuilder.rb +92 -97
  152. data/test/test_template.rb +3 -7
  153. data/test/test_textutils.rb +27 -27
  154. data/test/test_tocparser.rb +2 -2
  155. data/test/test_topbuilder.rb +98 -103
  156. data/test/test_webtocprinter.rb +5 -6
  157. data/test/test_yamlloader.rb +42 -42
  158. data/test/test_zip_exporter.rb +12 -18
  159. metadata +86 -9
  160. data/lib/review/ewbbuilder.rb +0 -382
@@ -12,45 +12,41 @@ module ReVIEW
12
12
  end
13
13
 
14
14
  def predef
15
- return "" unless @yaml["PREDEF"]
16
- @yaml["PREDEF"].join("\n")
15
+ return '' unless @yaml['PREDEF']
16
+ @yaml['PREDEF'].join("\n")
17
17
  end
18
18
 
19
19
  def chaps
20
- return "" unless @yaml["CHAPS"]
20
+ return '' unless @yaml['CHAPS']
21
21
 
22
- @yaml["CHAPS"].map {|entry|
23
- if entry.is_a? String
22
+ @yaml['CHAPS'].map do |entry|
23
+ if entry.is_a?(String)
24
24
  entry
25
- elsif entry.is_a? Hash
25
+ elsif entry.is_a?(Hash)
26
26
  entry.values # chaps in a part
27
27
  end
28
- }.flatten.join("\n")
28
+ end.flatten.join("\n")
29
29
  end
30
30
 
31
31
  def parts
32
- return "" unless @yaml["CHAPS"]
32
+ return '' unless @yaml['CHAPS']
33
33
 
34
- @yaml["CHAPS"].map {|entry|
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 "" unless @yaml["CHAPS"]
43
- @yaml["CHAPS"].flatten.compact
38
+ return '' unless @yaml['CHAPS']
39
+ @yaml['CHAPS'].flatten.compact
44
40
  end
45
41
 
46
42
  def appendix
47
- return "" unless @yaml["APPENDIX"]
48
- @yaml["APPENDIX"].join("\n")
43
+ return '' unless @yaml['APPENDIX']
44
+ @yaml['APPENDIX'].join("\n")
49
45
  end
50
46
 
51
47
  def postdef
52
- return "" unless @yaml["POSTDEF"]
53
- @yaml["POSTDEF"].join("\n")
48
+ return '' unless @yaml['POSTDEF']
49
+ @yaml['POSTDEF'].join("\n")
54
50
  end
55
51
  end
56
52
  end
@@ -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 Compiler.defblock(name, argc, optional = false, &block)
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 Compiler.defsingle(name, argc, &block)
90
+ def self.defsingle(name, argc, &block)
98
91
  defsyntax name, :line, argc, &block
99
92
  end
100
93
 
101
- def Compiler.defsyntax(name, type, argc, &block)
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 %r<\A\s+\*>
243
+ when /\A\s+\*/
250
244
  compile_ulist f
251
- when %r<\A\s+\d+\.>
245
+ when /\A\s+\d+\./
252
246
  compile_olist f
253
- when %r<\A\s*:\s>
247
+ when /\A\s*:\s/
254
248
  compile_dlist f
255
- when %r<\A//\}>
249
+ when %r{\A//\}}
256
250
  f.gets
257
251
  error 'block end seen but not opened'
258
- when %r<\A//[a-z]+>
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<\A//>
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 "skipping block..."
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 !~ /\A\//
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
- unless prev_tag_info.first == open_tag
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
- if @headline_indexs.size > (index + 1)
307
- @headline_indexs = @headline_indexs[0..index]
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/) do |cont|
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/) do |cont|
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<\A//|\A\#@>) do |line|
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| "<!ESCAPETAB!>" * m.size}.strip.gsub(/<!ESCAPETAB!>/, "\t"))
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<\A//[a-z]+>, '').rstrip.chomp('{'), name)
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
- return name, args, lines
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<\A//\}>) do |line|
438
+ f.until_match(%r{\A//\}}) do |line|
452
439
  if ignore_inline
453
440
  buf.push line
454
- else
455
- unless line =~ /\A\#@/
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<\A//\}> =~ f.peek
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, name=nil)
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 == "]" or ch == "\\") ? ch : "\\" + ch
476
- }
460
+ (ch == ']' or ch == '\\') ? ch : '\\' + ch
461
+ end
477
462
  words << w2
478
463
  end
479
- if !scanner.eos?
464
+ unless scanner.eos?
480
465
  error "argument syntax error: #{scanner.rest} in #{str.inspect}"
481
466
  return []
482
467
  end
483
- return words
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 do |w|
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
- raise CompileError, "no such inline op: #{op}"
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
@@ -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
- "bookname"=> "example", # it defines epub file name also
13
- "booktitle" => "Re:VIEW Sample Book",
14
- "title" => nil,
15
- "aut" => nil, # author
16
- "prt" => nil, # printer(publisher)
17
- "asn" => nil, # associated name
18
- "ant" => nil, # bibliographic antecedent
19
- "clb" => nil, # Collaborator
20
- "edt" => nil, # Editor
21
- "dsr" => nil, # Designer
22
- "ill" => nil, # Illustrator
23
- "pht" => nil, # Photographer
24
- "trl" => nil, # Translator
25
- "date" => nil, # publishing date
26
- "rights" => nil, # Copyright messages
27
- "description" => nil, # Description
28
- "urnid" => "urn:uid:#{SecureRandom.uuid}", # Identifier
29
- "stylesheet" => "stylesheet.css", # stylesheet file
30
- "coverfile" => nil, # content file of body of cover page
31
- "mytoc" => nil, # whether make own table of contents or not
32
- "params" => "", # specify review2html parameters
33
- "toclevel" => 3, # level of toc
34
- "secnolevel" => 2, # level of section #
35
- "epubversion" => 3,
36
- "titlepage" => true, # Use title page
37
- "toc" => nil, # Use table of contents in body
38
- "colophon" => nil, # Use colophon
39
- "debug" => nil, # debug flag
40
- "catalogfile" => 'catalog.yml',
41
- "language" => 'ja', # XXX default language should be JA??
42
- "mathml" => nil, # for HTML
43
- "htmlext" => "html",
44
- "htmlversion" => 5,
45
- "imagedir" => "images",
46
- "image_ext" => %w(png gif jpg jpeg svg ttf woff otf),
47
- "fontdir" => "fonts",
48
-
49
- "chapter_file" => 'CHAPS',
50
- "part_file" => 'PART',
51
- "reject_file" => 'REJECT',
52
- "predef_file" => 'PREDEF',
53
- "postdef_file" => 'POSTDEF',
54
- "page_metric" => ReVIEW::Book::PageMetric::A5,
55
- "ext" => '.re',
56
- "image_dir" => 'images',
57
- "image_types" => %w(.ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg),
58
- "image_scale2width" => true, # for LaTeX
59
- "bib_file" => "bib.re",
60
- "colophon_order" => %w(aut csl trl dsr ill cov edt pbl contact prt),
61
- "externallink" => true,
62
- "tableopt" => nil, # for IDGXML
63
- "listinfo" => nil, # for IDGXML
64
- "nolf" => true, # for IDGXML
65
- "chapref" => nil, # for IDGXML
66
- "structuredxml" => nil, # for IDGXML
67
- "pt_to_mm_unit" => 0.3528, # for IDGXML (DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm)
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
- "footnotetext" => nil, # for LaTeX
70
- "texcommand" => "uplatex", # for LaTeX
71
- "texdocumentclass" => ["jsbook", "uplatex,oneside"], # for LaTeX
72
- "dvicommand" => "dvipdfmx", # for LaTeX
73
- "dvioptions" => "-d 5", # for LaTeX
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
- "pdfmaker" => {
76
- "makeindex" => nil, # Make index page
77
- "makeindex_command" => "mendex", # works only when makeindex is true
78
- "makeindex_options" => "-f -r -I utf8",
79
- "makeindex_sty" => nil,
80
- "makeindex_dic" => nil,
81
- "makeindex_mecab" => true,
82
- "makeindex_mecab_opts" => "-Oyomi",
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
- return self.fetch(maker).fetch(key, nil)
93
- end
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?("review_version")
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["review_version"].blank?
105
- # do nothing
106
- elsif self["review_version"].to_i != version.to_i ## major version
107
- raise ReVIEW::ConfigError, "major version of configuration file is different."
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].kind_of?(Array)
115
- self[key].join(",") # i18n?
116
- elsif self[key].kind_of?(Hash)
117
- self[key]["name"]
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].kind_of?(Array)
114
+ if self[key].is_a?(Array)
125
115
  self[key].map do |a|
126
- if a.kind_of?(Hash)
127
- a["name"]
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].kind_of?(Hash)
133
- [self[key]["name"]]
122
+ elsif self[key].is_a?(Hash)
123
+ [self[key]['name']]
134
124
  else
135
125
  [self[key]]
136
126
  end