review 1.7.2 → 2.0.0.beta1

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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -43
  3. data/.travis.yml +0 -9
  4. data/ChangeLog +0 -16
  5. data/Gemfile +1 -0
  6. data/README.rdoc +1 -1
  7. data/Rakefile +12 -1
  8. data/bin/review-check +21 -8
  9. data/bin/review-compile +15 -9
  10. data/bin/review-epubmaker-legacy +6 -6
  11. data/bin/review-index +13 -2
  12. data/bin/review-init +18 -12
  13. data/bin/review-preproc +14 -1
  14. data/bin/review-validate +1 -1
  15. data/bin/review-vol +13 -1
  16. data/doc/quickstart.ja.md +1 -1
  17. data/doc/quickstart.md +1 -1
  18. data/lib/epubmaker/content.rb +3 -3
  19. data/lib/epubmaker/epubcommon.rb +108 -91
  20. data/lib/epubmaker/epubv2.rb +67 -14
  21. data/lib/epubmaker/epubv3.rb +59 -25
  22. data/lib/epubmaker/producer.rb +1 -13
  23. data/lib/lineinput.rb +0 -48
  24. data/lib/review/book/base.rb +4 -12
  25. data/lib/review/book/compilable.rb +3 -1
  26. data/lib/review/book/index.rb +4 -4
  27. data/lib/review/builder.rb +54 -47
  28. data/lib/review/compiler.rb +4662 -326
  29. data/lib/review/compiler/literals_1_8.kpeg +19 -0
  30. data/lib/review/compiler/literals_1_8.rb +432 -0
  31. data/lib/review/compiler/literals_1_9.kpeg +22 -0
  32. data/lib/review/compiler/literals_1_9.rb +435 -0
  33. data/lib/review/configure.rb +8 -20
  34. data/lib/review/epubbuilder.rb +1 -1
  35. data/lib/review/epubmaker.rb +122 -52
  36. data/lib/review/ewbbuilder.rb +4 -4
  37. data/lib/review/exception.rb +1 -1
  38. data/lib/review/extentions.rb +1 -0
  39. data/lib/review/extentions/array.rb +25 -0
  40. data/lib/review/htmlbuilder.rb +286 -275
  41. data/lib/review/htmllayout.rb +0 -2
  42. data/lib/review/htmlutils.rb +4 -4
  43. data/lib/review/i18n.rb +2 -6
  44. data/lib/review/i18n.yml +1 -1
  45. data/lib/review/idgxmlbuilder.rb +239 -204
  46. data/lib/review/inaobuilder.rb +75 -73
  47. data/lib/review/latexbuilder.rb +265 -219
  48. data/lib/review/latexutils.rb +6 -6
  49. data/lib/review/layout.tex.erb +1 -1
  50. data/lib/review/location.rb +24 -0
  51. data/lib/review/markdownbuilder.rb +124 -79
  52. data/lib/review/node.rb +267 -0
  53. data/lib/review/pdfmaker.rb +92 -92
  54. data/lib/review/preprocessor.rb +51 -14
  55. data/lib/review/review.kpeg +724 -0
  56. data/lib/review/textbuilder.rb +1 -1
  57. data/lib/review/textutils.rb +24 -18
  58. data/lib/review/tocparser.rb +3 -3
  59. data/lib/review/tocprinter.rb +31 -8
  60. data/lib/review/topbuilder.rb +119 -111
  61. data/lib/review/unfold.rb +2 -2
  62. data/lib/review/version.rb +1 -1
  63. data/review.gemspec +2 -2
  64. data/rubocop-todo.yml +456 -0
  65. data/test/assets/test_template.tex +1 -1
  66. data/test/sample-book/src/config.yml +0 -1
  67. data/test/test.re +1 -1
  68. data/test/test_book.rb +4 -4
  69. data/test/test_book_chapter.rb +70 -0
  70. data/test/test_book_part.rb +1 -1
  71. data/test/test_builder.rb +6 -28
  72. data/test/test_compiler.rb +59 -14
  73. data/test/test_helper.rb +47 -4
  74. data/test/test_htmlbuilder.rb +104 -73
  75. data/test/test_i18n.rb +5 -3
  76. data/test/test_idgxmlbuilder.rb +5 -2
  77. data/test/test_inaobuilder.rb +4 -2
  78. data/test/test_latexbuilder.rb +18 -37
  79. data/test/test_lineinput.rb +25 -4
  80. data/test/test_markdownbuilder.rb +4 -22
  81. data/test/test_pdfmaker.rb +12 -11
  82. data/test/test_textutils.rb +0 -36
  83. data/test/test_topbuilder.rb +2 -0
  84. metadata +14 -28
  85. data/.rubocop_todo.yml +0 -605
  86. data/Dockerfile +0 -22
  87. data/doc/NEWS.ja.md +0 -362
  88. data/doc/NEWS.md +0 -366
  89. data/lib/review/htmltoc.rb +0 -45
  90. data/lib/review/template.rb +0 -21
  91. data/templates/html/layout-html5.html.erb +0 -17
  92. data/templates/html/layout-xhtml1.html.erb +0 -20
  93. data/templates/ncx/epubv2.ncx.erb +0 -11
  94. data/templates/opf/epubv2.opf.erb +0 -21
  95. data/templates/opf/epubv3.opf.erb +0 -18
  96. data/templates/xml/container.xml.erb +0 -6
  97. data/test/assets/test.xml.erb +0 -3
  98. data/test/sample-book/src/config-epub2.yml +0 -186
  99. data/test/test_configure.rb +0 -50
  100. data/test/test_htmltoc.rb +0 -32
  101. data/test/test_template.rb +0 -26
@@ -0,0 +1,22 @@
1
+ %% name = ReVIEW::Compiler::Literals
2
+
3
+ %% header {
4
+ # coding: UTF-8
5
+
6
+ ##
7
+ #--
8
+ # This set of literals is for Ruby 1.9 regular expressions and gives full
9
+ # unicode support.
10
+ #
11
+ # Unlike peg-markdown, this set of literals recognizes Unicode alphanumeric
12
+ # characters, newlines and spaces.
13
+ }
14
+
15
+ Alphanumeric = /\p{Word}/
16
+ AlphanumericAscii = /[A-Za-z0-9]/
17
+ LowerAlphabetAscii = /[a-z]/
18
+ Digit = /[0-9]/
19
+ BOM = "\uFEFF"
20
+ Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/
21
+ NonAlphanumeric = /\p{^Word}/
22
+ Spacechar = /\t|\p{Zs}/
@@ -0,0 +1,435 @@
1
+ # coding: UTF-8
2
+
3
+ ##
4
+ #--
5
+ # This set of literals is for Ruby 1.9 regular expressions and gives full
6
+ # unicode support.
7
+ #
8
+ # Unlike peg-markdown, this set of literals recognizes Unicode alphanumeric
9
+ # characters, newlines and spaces.
10
+ class ReVIEW::Compiler::Literals
11
+ # :stopdoc:
12
+
13
+ # This is distinct from setup_parser so that a standalone parser
14
+ # can redefine #initialize and still have access to the proper
15
+ # parser setup code.
16
+ def initialize(str, debug=false)
17
+ setup_parser(str, debug)
18
+ end
19
+
20
+
21
+
22
+ # Prepares for parsing +str+. If you define a custom initialize you must
23
+ # call this method before #parse
24
+ def setup_parser(str, debug=false)
25
+ set_string str, 0
26
+ @memoizations = Hash.new { |h,k| h[k] = {} }
27
+ @result = nil
28
+ @failed_rule = nil
29
+ @failing_rule_offset = -1
30
+
31
+ setup_foreign_grammar
32
+ end
33
+
34
+ attr_reader :string
35
+ attr_reader :failing_rule_offset
36
+ attr_accessor :result, :pos
37
+
38
+ def current_column(target=pos)
39
+ if c = string.rindex("\n", target-1)
40
+ return target - c - 1
41
+ end
42
+
43
+ target + 1
44
+ end
45
+
46
+ def current_line(target=pos)
47
+ cur_offset = 0
48
+ cur_line = 0
49
+
50
+ string.each_line do |line|
51
+ cur_line += 1
52
+ cur_offset += line.size
53
+ return cur_line if cur_offset >= target
54
+ end
55
+
56
+ -1
57
+ end
58
+
59
+ def lines
60
+ lines = []
61
+ string.each_line { |l| lines << l }
62
+ lines
63
+ end
64
+
65
+
66
+
67
+ def get_text(start)
68
+ @string[start..@pos-1]
69
+ end
70
+
71
+ # Sets the string and current parsing position for the parser.
72
+ def set_string string, pos
73
+ @string = string
74
+ @string_size = string ? string.size : 0
75
+ @pos = pos
76
+ end
77
+
78
+ def show_pos
79
+ width = 10
80
+ if @pos < width
81
+ "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
82
+ else
83
+ "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
84
+ end
85
+ end
86
+
87
+ def failure_info
88
+ l = current_line @failing_rule_offset
89
+ c = current_column @failing_rule_offset
90
+
91
+ if @failed_rule.kind_of? Symbol
92
+ info = self.class::Rules[@failed_rule]
93
+ "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
94
+ else
95
+ "line #{l}, column #{c}: failed rule '#{@failed_rule}'"
96
+ end
97
+ end
98
+
99
+ def failure_caret
100
+ l = current_line @failing_rule_offset
101
+ c = current_column @failing_rule_offset
102
+
103
+ line = lines[l-1]
104
+ "#{line}\n#{' ' * (c - 1)}^"
105
+ end
106
+
107
+ def failure_character
108
+ l = current_line @failing_rule_offset
109
+ c = current_column @failing_rule_offset
110
+ lines[l-1][c-1, 1]
111
+ end
112
+
113
+ def failure_oneline
114
+ l = current_line @failing_rule_offset
115
+ c = current_column @failing_rule_offset
116
+
117
+ char = lines[l-1][c-1, 1]
118
+
119
+ if @failed_rule.kind_of? Symbol
120
+ info = self.class::Rules[@failed_rule]
121
+ "@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
122
+ else
123
+ "@#{l}:#{c} failed rule '#{@failed_rule}', got '#{char}'"
124
+ end
125
+ end
126
+
127
+ class ParseError < RuntimeError
128
+ end
129
+
130
+ def raise_error
131
+ raise ParseError, failure_oneline
132
+ end
133
+
134
+ def show_error(io=STDOUT)
135
+ error_pos = @failing_rule_offset
136
+ line_no = current_line(error_pos)
137
+ col_no = current_column(error_pos)
138
+
139
+ io.puts "On line #{line_no}, column #{col_no}:"
140
+
141
+ if @failed_rule.kind_of? Symbol
142
+ info = self.class::Rules[@failed_rule]
143
+ io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
144
+ else
145
+ io.puts "Failed to match rule '#{@failed_rule}'"
146
+ end
147
+
148
+ io.puts "Got: #{string[error_pos,1].inspect}"
149
+ line = lines[line_no-1]
150
+ io.puts "=> #{line}"
151
+ io.print(" " * (col_no + 3))
152
+ io.puts "^"
153
+ end
154
+
155
+ def set_failed_rule(name)
156
+ if @pos > @failing_rule_offset
157
+ @failed_rule = name
158
+ @failing_rule_offset = @pos
159
+ end
160
+ end
161
+
162
+ attr_reader :failed_rule
163
+
164
+ def match_string(str)
165
+ len = str.size
166
+ if @string[pos,len] == str
167
+ @pos += len
168
+ return str
169
+ end
170
+
171
+ return nil
172
+ end
173
+
174
+ def scan(reg)
175
+ if m = reg.match(@string[@pos..-1])
176
+ width = m.end(0)
177
+ @pos += width
178
+ return true
179
+ end
180
+
181
+ return nil
182
+ end
183
+
184
+ if "".respond_to? :ord
185
+ def get_byte
186
+ if @pos >= @string_size
187
+ return nil
188
+ end
189
+
190
+ s = @string[@pos].ord
191
+ @pos += 1
192
+ s
193
+ end
194
+ else
195
+ def get_byte
196
+ if @pos >= @string_size
197
+ return nil
198
+ end
199
+
200
+ s = @string[@pos]
201
+ @pos += 1
202
+ s
203
+ end
204
+ end
205
+
206
+ def parse(rule=nil)
207
+ # We invoke the rules indirectly via apply
208
+ # instead of by just calling them as methods because
209
+ # if the rules use left recursion, apply needs to
210
+ # manage that.
211
+
212
+ if !rule
213
+ apply(:_root)
214
+ else
215
+ method = rule.gsub("-","_hyphen_")
216
+ apply :"_#{method}"
217
+ end
218
+ end
219
+
220
+ class MemoEntry
221
+ def initialize(ans, pos)
222
+ @ans = ans
223
+ @pos = pos
224
+ @result = nil
225
+ @set = false
226
+ @left_rec = false
227
+ end
228
+
229
+ attr_reader :ans, :pos, :result, :set
230
+ attr_accessor :left_rec
231
+
232
+ def move!(ans, pos, result)
233
+ @ans = ans
234
+ @pos = pos
235
+ @result = result
236
+ @set = true
237
+ @left_rec = false
238
+ end
239
+ end
240
+
241
+ def external_invoke(other, rule, *args)
242
+ old_pos = @pos
243
+ old_string = @string
244
+
245
+ set_string other.string, other.pos
246
+
247
+ begin
248
+ if val = __send__(rule, *args)
249
+ other.pos = @pos
250
+ other.result = @result
251
+ else
252
+ other.set_failed_rule "#{self.class}##{rule}"
253
+ end
254
+ val
255
+ ensure
256
+ set_string old_string, old_pos
257
+ end
258
+ end
259
+
260
+ def apply_with_args(rule, *args)
261
+ memo_key = [rule, args]
262
+ if m = @memoizations[memo_key][@pos]
263
+ @pos = m.pos
264
+ if !m.set
265
+ m.left_rec = true
266
+ return nil
267
+ end
268
+
269
+ @result = m.result
270
+
271
+ return m.ans
272
+ else
273
+ m = MemoEntry.new(nil, @pos)
274
+ @memoizations[memo_key][@pos] = m
275
+ start_pos = @pos
276
+
277
+ ans = __send__ rule, *args
278
+
279
+ lr = m.left_rec
280
+
281
+ m.move! ans, @pos, @result
282
+
283
+ # Don't bother trying to grow the left recursion
284
+ # if it's failing straight away (thus there is no seed)
285
+ if ans and lr
286
+ return grow_lr(rule, args, start_pos, m)
287
+ else
288
+ return ans
289
+ end
290
+
291
+ return ans
292
+ end
293
+ end
294
+
295
+ def apply(rule)
296
+ if m = @memoizations[rule][@pos]
297
+ @pos = m.pos
298
+ if !m.set
299
+ m.left_rec = true
300
+ return nil
301
+ end
302
+
303
+ @result = m.result
304
+
305
+ return m.ans
306
+ else
307
+ m = MemoEntry.new(nil, @pos)
308
+ @memoizations[rule][@pos] = m
309
+ start_pos = @pos
310
+
311
+ ans = __send__ rule
312
+
313
+ lr = m.left_rec
314
+
315
+ m.move! ans, @pos, @result
316
+
317
+ # Don't bother trying to grow the left recursion
318
+ # if it's failing straight away (thus there is no seed)
319
+ if ans and lr
320
+ return grow_lr(rule, nil, start_pos, m)
321
+ else
322
+ return ans
323
+ end
324
+
325
+ return ans
326
+ end
327
+ end
328
+
329
+ def grow_lr(rule, args, start_pos, m)
330
+ while true
331
+ @pos = start_pos
332
+ @result = m.result
333
+
334
+ if args
335
+ ans = __send__ rule, *args
336
+ else
337
+ ans = __send__ rule
338
+ end
339
+ return nil unless ans
340
+
341
+ break if @pos <= m.pos
342
+
343
+ m.move! ans, @pos, @result
344
+ end
345
+
346
+ @result = m.result
347
+ @pos = m.pos
348
+ return m.ans
349
+ end
350
+
351
+ class RuleInfo
352
+ def initialize(name, rendered)
353
+ @name = name
354
+ @rendered = rendered
355
+ end
356
+
357
+ attr_reader :name, :rendered
358
+ end
359
+
360
+ def self.rule_info(name, rendered)
361
+ RuleInfo.new(name, rendered)
362
+ end
363
+
364
+
365
+ # :startdoc:
366
+ # :stopdoc:
367
+ def setup_foreign_grammar; end
368
+
369
+ # Alphanumeric = /\p{Word}/
370
+ def _Alphanumeric
371
+ _tmp = scan(/\A(?-mix:\p{Word})/)
372
+ set_failed_rule :_Alphanumeric unless _tmp
373
+ return _tmp
374
+ end
375
+
376
+ # AlphanumericAscii = /[A-Za-z0-9]/
377
+ def _AlphanumericAscii
378
+ _tmp = scan(/\A(?-mix:[A-Za-z0-9])/)
379
+ set_failed_rule :_AlphanumericAscii unless _tmp
380
+ return _tmp
381
+ end
382
+
383
+ # LowerAlphabetAscii = /[a-z]/
384
+ def _LowerAlphabetAscii
385
+ _tmp = scan(/\A(?-mix:[a-z])/)
386
+ set_failed_rule :_LowerAlphabetAscii unless _tmp
387
+ return _tmp
388
+ end
389
+
390
+ # Digit = /[0-9]/
391
+ def _Digit
392
+ _tmp = scan(/\A(?-mix:[0-9])/)
393
+ set_failed_rule :_Digit unless _tmp
394
+ return _tmp
395
+ end
396
+
397
+ # BOM = "uFEFF"
398
+ def _BOM
399
+ _tmp = match_string("uFEFF")
400
+ set_failed_rule :_BOM unless _tmp
401
+ return _tmp
402
+ end
403
+
404
+ # Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/
405
+ def _Newline
406
+ _tmp = scan(/\A(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/)
407
+ set_failed_rule :_Newline unless _tmp
408
+ return _tmp
409
+ end
410
+
411
+ # NonAlphanumeric = /\p{^Word}/
412
+ def _NonAlphanumeric
413
+ _tmp = scan(/\A(?-mix:\p{^Word})/)
414
+ set_failed_rule :_NonAlphanumeric unless _tmp
415
+ return _tmp
416
+ end
417
+
418
+ # Spacechar = /\t|\p{Zs}/
419
+ def _Spacechar
420
+ _tmp = scan(/\A(?-mix:\t|\p{Zs})/)
421
+ set_failed_rule :_Spacechar unless _tmp
422
+ return _tmp
423
+ end
424
+
425
+ Rules = {}
426
+ Rules[:_Alphanumeric] = rule_info("Alphanumeric", "/\\p{Word}/")
427
+ Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "/[A-Za-z0-9]/")
428
+ Rules[:_LowerAlphabetAscii] = rule_info("LowerAlphabetAscii", "/[a-z]/")
429
+ Rules[:_Digit] = rule_info("Digit", "/[0-9]/")
430
+ Rules[:_BOM] = rule_info("BOM", "\"uFEFF\"")
431
+ Rules[:_Newline] = rule_info("Newline", "/\\n|\\r\\n?|\\p{Zl}|\\p{Zp}/")
432
+ Rules[:_NonAlphanumeric] = rule_info("NonAlphanumeric", "/\\p{^Word}/")
433
+ Rules[:_Spacechar] = rule_info("Spacechar", "/\\t|\\p{Zs}/")
434
+ # :startdoc:
435
+ end