review 1.7.2 → 2.0.0.beta1

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