rdtool 0.6.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/COPYING.txt +674 -0
  2. data/Gemfile +9 -0
  3. data/HISTORY +284 -0
  4. data/LICENSE.txt +58 -0
  5. data/MANIFEST +89 -0
  6. data/README.html +44 -0
  7. data/README.ja.html +46 -0
  8. data/README.rd +52 -0
  9. data/README.rd.ja +54 -0
  10. data/Rakefile +29 -0
  11. data/TODO +15 -0
  12. data/VERSION +1 -0
  13. data/bin/rd2 +281 -0
  14. data/bin/rdswap.rb +207 -0
  15. data/doc/rd-draft.rd +479 -0
  16. data/doc/rd-draft.rd.ja +487 -0
  17. data/lib/rd/block-element.rb +114 -0
  18. data/lib/rd/complex-list-item.rb +65 -0
  19. data/lib/rd/desclist.rb +55 -0
  20. data/lib/rd/document-struct.rb +46 -0
  21. data/lib/rd/dot.rd2rc +18 -0
  22. data/lib/rd/element.rb +160 -0
  23. data/lib/rd/filter.rb +255 -0
  24. data/lib/rd/inline-element.rb +233 -0
  25. data/lib/rd/labeled-element.rb +14 -0
  26. data/lib/rd/list.rb +57 -0
  27. data/lib/rd/loose-struct.rb +11 -0
  28. data/lib/rd/methodlist.rb +57 -0
  29. data/lib/rd/output-format-visitor.rb +28 -0
  30. data/lib/rd/package.rb +4 -0
  31. data/lib/rd/parser-util.rb +14 -0
  32. data/lib/rd/post-install +1 -0
  33. data/lib/rd/rbl-file.rb +69 -0
  34. data/lib/rd/rbl-suite.rb +37 -0
  35. data/lib/rd/rd-struct.rb +86 -0
  36. data/lib/rd/rd2html-lib.rb +490 -0
  37. data/lib/rd/rd2html-opt.rb +67 -0
  38. data/lib/rd/rd2man-lib.rb +241 -0
  39. data/lib/rd/rd2rdo-lib.rb +19 -0
  40. data/lib/rd/rd2rmi-lib.rb +32 -0
  41. data/lib/rd/rdblockparser.ry +518 -0
  42. data/lib/rd/rdblockparser.tab.rb +1050 -0
  43. data/lib/rd/rdfmt.rb +15 -0
  44. data/lib/rd/rdinlineparser.ry +503 -0
  45. data/lib/rd/rdinlineparser.tab.rb +1243 -0
  46. data/lib/rd/rdvisitor.rb +214 -0
  47. data/lib/rd/reference-resolver.rb +114 -0
  48. data/lib/rd/search-file.rb +14 -0
  49. data/lib/rd/tree.rb +103 -0
  50. data/lib/rd/version.rb +39 -0
  51. data/lib/rd/visitor.rb +86 -0
  52. data/makerdtool.rb +75 -0
  53. data/setup.rb +1596 -0
  54. data/test.rb +33 -0
  55. data/test/data/includee1.html +1 -0
  56. data/test/data/includee2.html +1 -0
  57. data/test/data/includee3.nothtml +1 -0
  58. data/test/data/includee4.xhtml +0 -0
  59. data/test/data/label.rbl +2 -0
  60. data/test/data/label2.rbl +2 -0
  61. data/test/data/sub/includee2.html +1 -0
  62. data/test/data/sub/includee4.html +0 -0
  63. data/test/dummy-observer.rb +6 -0
  64. data/test/dummy.rb +33 -0
  65. data/test/temp-dir.rb +19 -0
  66. data/test/test-block-parser.rb +46 -0
  67. data/test/test-desclist-item.rb +219 -0
  68. data/test/test-document-element.rb +46 -0
  69. data/test/test-document-struct.rb +66 -0
  70. data/test/test-element.rb +46 -0
  71. data/test/test-headline.rb +80 -0
  72. data/test/test-inline-parser.rb +46 -0
  73. data/test/test-list-item.rb +54 -0
  74. data/test/test-list.rb +53 -0
  75. data/test/test-methodlist-item.rb +73 -0
  76. data/test/test-nonterminal-element.rb +170 -0
  77. data/test/test-nonterminal-inline.rb +33 -0
  78. data/test/test-output-format-visitor.rb +48 -0
  79. data/test/test-parser-util.rb +41 -0
  80. data/test/test-rbl-file.rb +156 -0
  81. data/test/test-rbl-suite.rb +43 -0
  82. data/test/test-rd2html-lib.rb +496 -0
  83. data/test/test-rdtree.rb +17 -0
  84. data/test/test-rdvisitor.rb +29 -0
  85. data/test/test-reference-resolver.rb +202 -0
  86. data/test/test-reference.rb +132 -0
  87. data/test/test-search-file.rb +22 -0
  88. data/test/test-terminal-inline.rb +41 -0
  89. data/test/test-textblock.rb +44 -0
  90. data/test/test-tree.rb +82 -0
  91. data/test/test-version.rb +57 -0
  92. data/test/test-visitor.rb +230 -0
  93. data/utils/rd-mode.el +425 -0
  94. metadata +203 -0
data/lib/rd/rdfmt.rb ADDED
@@ -0,0 +1,15 @@
1
+
2
+ require 'rd/tree'
3
+ require 'rd/rd-struct'
4
+
5
+ module RD
6
+ # for backward-compatibility.
7
+ class RDTree < Tree
8
+ def initialize(src_str, include_paths = [], do_parse = true)
9
+ super(DocumentStructure::RD, src_str, include_paths)
10
+ parse() if do_parse
11
+ end
12
+ end
13
+
14
+ RDElement = Element
15
+ end
@@ -0,0 +1,503 @@
1
+
2
+ class RDInlineParser
3
+
4
+ preclow
5
+ nonassoc EX_LOW
6
+ left QUOTE BAR SLASH BACK_SLASH URL OTHER
7
+ REF_OPEN FOOTNOTE_OPEN FOOTNOTE_CLOSE
8
+ nonassoc EX_HIGH
9
+ prechigh
10
+
11
+ token EM_OPEN EM_CLOSE
12
+ CODE_OPEN CODE_CLOSE
13
+ VAR_OPEN VAR_CLOSE
14
+ KBD_OPEN KBD_CLOSE
15
+ INDEX_OPEN INDEX_CLOSE
16
+ REF_OPEN REF_CLOSE
17
+ FOOTNOTE_OPEN FOOTNOTE_CLOSE
18
+ VERB_OPEN VERB_CLOSE
19
+ BAR QUOTE SLASH BACK_SLASH URL OTHER EX_LOW EX_HIGH
20
+
21
+ rule
22
+ content : elements
23
+ ;
24
+ elements : elements element { result.push(val[1]) }
25
+ | element { result = val }
26
+ ;
27
+ element : emphasis
28
+ | code
29
+ | var
30
+ | keyboard
31
+ | index
32
+ | reference
33
+ | footnote
34
+ | verb
35
+ | normal_str_ele
36
+ ;
37
+
38
+ emphasis : EM_OPEN content EM_CLOSE {
39
+ result = Emphasis.new
40
+ add_children_to_element(result, *val[1])
41
+ }
42
+ ;
43
+ code : CODE_OPEN content CODE_CLOSE {
44
+ result = Code.new
45
+ add_children_to_element(result, *val[1])
46
+ }
47
+ ;
48
+ var : VAR_OPEN content VAR_CLOSE {
49
+ result = Var.new
50
+ add_children_to_element(result, *val[1])
51
+ }
52
+ ;
53
+ keyboard : KBD_OPEN content KBD_CLOSE {
54
+ result = Keyboard.new
55
+ add_children_to_element(result, *val[1])
56
+ }
57
+ ;
58
+ index : INDEX_OPEN content INDEX_CLOSE {
59
+ result = Index.new
60
+ add_children_to_element(result, *val[1])
61
+ }
62
+ ;
63
+
64
+ # Refernce
65
+ # ((<subst|filename/element_label>))
66
+
67
+ reference : REF_OPEN substitute ref_label REF_CLOSE
68
+ { result = Reference.new(val[2])
69
+ add_children_to_element(result, *val[1])
70
+ }
71
+ | REF_OPEN ref_label2 REF_CLOSE
72
+ {
73
+ result = make_reference_from_label(val[1])
74
+ }
75
+ ;
76
+
77
+ ref_label : URL ref_url_strings { result = Reference::URL.new(val[1]) }
78
+ | filename element_label
79
+ { result = Reference::TemporaryLabel.new(val[1],
80
+ val[0]) }
81
+ | element_label
82
+ { result = Reference::TemporaryLabel.new(val[0]) }
83
+ | filename { result = Reference::TemporaryLabel.new([], val[0]) }
84
+ ;
85
+ ref_label2 : URL ref_url_strings { result = Reference::URL.new(val[1]) }
86
+ | filename element_label2
87
+ { result = Reference::TemporaryLabel.new(val[1],
88
+ val[0]) }
89
+ | element_label2
90
+ { result = Reference::TemporaryLabel.new(val[0]) }
91
+ | filename { result = Reference::TemporaryLabel.new([],
92
+ val[0]) }
93
+ ;
94
+ substitute : ref_subst_content BAR
95
+ | QUOTE ref_subst_content_q QUOTE BAR
96
+ { result = val[1] }
97
+ | QUOTE ref_subst_strings_q QUOTE BAR
98
+ { result = [StringElement.new(val[1])] }
99
+ ;
100
+
101
+ filename : ref_subst_strings_first SLASH
102
+ | QUOTE ref_subst_strings_q QUOTE SLASH
103
+ { result = val[1] }
104
+ ;
105
+
106
+ # when substitute part exists
107
+ element_label : ref_subst_strings_first
108
+ { result = [StringElement.new(val[0])] }
109
+ | QUOTE ref_subst_strings_q QUOTE
110
+ { result = [StringElement.new(val[1])] }
111
+ ;
112
+ # when substitute part doesn't exist
113
+ # in this case, element label can contain Inlines
114
+ element_label2 : ref_subst_content
115
+ | QUOTE ref_subst_content_q QUOTE
116
+ { result = val[1] }
117
+ | QUOTE ref_subst_strings_q QUOTE
118
+ { result = [StringElement.new(val[1])] }
119
+ ;
120
+
121
+ ref_subst_content : ref_subst_ele2 ref_subst_eles
122
+ { result = val[1].unshift(val[0]) }
123
+ | ref_subst_str_ele_first ref_subst_eles
124
+ { result = val[1].unshift(val[0]) }
125
+ | ref_subst_str_ele_first
126
+ { result = val }
127
+ | ref_subst_ele2 { result = val }
128
+ ;
129
+ ref_subst_content_q : ref_subst_eles_q
130
+ ;
131
+ ref_subst_eles : ref_subst_eles ref_subst_ele
132
+ { result.push(val[1]) }
133
+ | ref_subst_ele { result = val }
134
+ ;
135
+ ref_subst_eles_q : ref_subst_eles_q ref_subst_ele_q
136
+ { result.push(val[1]) }
137
+ | ref_subst_ele_q { result = val }
138
+ ;
139
+ ref_subst_ele2 : emphasis
140
+ | code
141
+ | var
142
+ | keyboard
143
+ | index
144
+ | verb
145
+ ;
146
+ ref_subst_ele : ref_subst_ele2
147
+ | ref_subst_str_ele
148
+ ;
149
+ ref_subst_ele_q : ref_subst_ele2
150
+ | ref_subst_str_ele_q
151
+ ;
152
+
153
+ ref_subst_str_ele : ref_subst_strings = EX_LOW
154
+ { result = StringElement.new(val[0]) }
155
+ ;
156
+ ref_subst_str_ele_first : ref_subst_strings_first
157
+ { result = StringElement.new(val[0]) }
158
+ ;
159
+ ref_subst_str_ele_q : ref_subst_strings_q = EX_LOW
160
+ { result = StringElement.new(val[0]) }
161
+ ;
162
+
163
+ ref_subst_strings : ref_subst_strings ref_subst_string3
164
+ { result << val[1] }
165
+ | ref_subst_string3
166
+ ;
167
+ # if it is first element of substitute, it can't contain
168
+ # URL on head.
169
+ ref_subst_strings_first : ref_subst_string ref_subst_strings = EX_HIGH
170
+ { result << val[1] }
171
+ | ref_subst_string = EX_LOW
172
+ ;
173
+ ref_subst_strings_q : ref_subst_strings_q ref_subst_string_q
174
+ { result << val[1] }
175
+ | ref_subst_string_q
176
+ ;
177
+
178
+ ref_subst_string : OTHER
179
+ | BACK_SLASH
180
+ | REF_OPEN
181
+ | FOOTNOTE_OPEN
182
+ | FOOTNOTE_CLOSE
183
+ ;
184
+ ref_subst_string2 : ref_subst_string
185
+ | URL
186
+ ;
187
+ ref_subst_string3 : ref_subst_string2
188
+ | QUOTE
189
+ ;
190
+ ref_subst_string_q : ref_subst_string2
191
+ | BAR
192
+ | SLASH
193
+ ;
194
+ # end subst
195
+
196
+ # string in url
197
+ ref_url_strings : ref_url_strings ref_url_string { result << val[1] }
198
+ | ref_url_string
199
+ ;
200
+
201
+ ref_url_string : OTHER
202
+ | BACK_SLASH BACK_SLASH
203
+ | URL
204
+ | SLASH
205
+ | BAR
206
+ | QUOTE
207
+ | EM_OPEN
208
+ | EM_CLOSE
209
+ | CODE_OPEN
210
+ | CODE_CLOSE
211
+ | VAR_OPEN
212
+ | VAR_CLOSE
213
+ | KBD_OPEN
214
+ | KBD_CLOSE
215
+ | INDEX_OPEN
216
+ | INDEX_CLOSE
217
+ | REF_OPEN
218
+ | FOOTNOTE_OPEN
219
+ | FOOTNOTE_CLOSE
220
+ | VERB_OPEN
221
+ | VERB_CLOSE
222
+ ;
223
+
224
+ # end url
225
+ # end Reference
226
+
227
+ footnote : FOOTNOTE_OPEN content FOOTNOTE_CLOSE {
228
+ result = Footnote.new
229
+ add_children_to_element(result, *val[1])
230
+ }
231
+ ;
232
+ verb : VERB_OPEN verb_strings VERB_CLOSE {
233
+ result = Verb.new(val[1]) }
234
+ ;
235
+
236
+
237
+ # normal string
238
+ # OTHER, QUOTE, BAR, SLASH, BACK_SLASH, URL
239
+ normal_string : OTHER
240
+ | QUOTE
241
+ | BAR
242
+ | SLASH
243
+ | BACK_SLASH
244
+ | URL
245
+ ;
246
+ normal_strings : normal_strings normal_string
247
+ { result << val[1] }
248
+
249
+ | normal_string
250
+ ;
251
+ normal_str_ele : normal_strings = EX_LOW
252
+ { result = StringElement.new(val[0]) }
253
+ ;
254
+
255
+ # in verb
256
+ verb_string : verb_normal_string
257
+ | BACK_SLASH verb_normal_string { result = val[1] }
258
+ | BACK_SLASH VERB_CLOSE { result = val[1] }
259
+ | BACK_SLASH BACK_SLASH { result = val[1] }
260
+ ;
261
+
262
+ verb_normal_string : OTHER
263
+ | QUOTE
264
+ | BAR
265
+ | SLASH
266
+ | EM_OPEN
267
+ | EM_CLOSE
268
+ | CODE_OPEN
269
+ | CODE_CLOSE
270
+ | VAR_OPEN
271
+ | VAR_CLOSE
272
+ | KBD_OPEN
273
+ | KBD_CLOSE
274
+ | INDEX_OPEN
275
+ | INDEX_CLOSE
276
+ | REF_OPEN
277
+ | REF_CLOSE
278
+ | FOOTNOTE_OPEN
279
+ | FOOTNOTE_CLOSE
280
+ | VERB_OPEN
281
+ | URL
282
+ ;
283
+
284
+ verb_strings : verb_strings verb_string { result << val[1] }
285
+ | verb_string
286
+ ;
287
+ /* verb_str_ele : verb_strings
288
+ ; */
289
+ end
290
+
291
+ ---- inner
292
+ include ParserUtility
293
+ extend Forwardable
294
+
295
+ EM_OPEN = '((*'
296
+ EM_OPEN_RE = /\A#{Regexp.quote(EM_OPEN)}/
297
+ EM_CLOSE = '*))'
298
+ EM_CLOSE_RE = /\A#{Regexp.quote(EM_CLOSE)}/
299
+ CODE_OPEN = '(({'
300
+ CODE_OPEN_RE = /\A#{Regexp.quote(CODE_OPEN)}/
301
+ CODE_CLOSE = '}))'
302
+ CODE_CLOSE_RE = /\A#{Regexp.quote(CODE_CLOSE)}/
303
+ VAR_OPEN = '((|'
304
+ VAR_OPEN_RE = /\A#{Regexp.quote(VAR_OPEN)}/
305
+ VAR_CLOSE = '|))'
306
+ VAR_CLOSE_RE = /\A#{Regexp.quote(VAR_CLOSE)}/
307
+ KBD_OPEN = '((%'
308
+ KBD_OPEN_RE = /\A#{Regexp.quote(KBD_OPEN)}/
309
+ KBD_CLOSE = '%))'
310
+ KBD_CLOSE_RE = /\A#{Regexp.quote(KBD_CLOSE)}/
311
+ INDEX_OPEN = '((:'
312
+ INDEX_OPEN_RE = /\A#{Regexp.quote(INDEX_OPEN)}/
313
+ INDEX_CLOSE = ':))'
314
+ INDEX_CLOSE_RE = /\A#{Regexp.quote(INDEX_CLOSE)}/
315
+ REF_OPEN = '((<'
316
+ REF_OPEN_RE = /\A#{Regexp.quote(REF_OPEN)}/
317
+ REF_CLOSE = '>))'
318
+ REF_CLOSE_RE = /\A#{Regexp.quote(REF_CLOSE)}/
319
+ FOOTNOTE_OPEN = '((-'
320
+ FOOTNOTE_OPEN_RE = /\A#{Regexp.quote(FOOTNOTE_OPEN)}/
321
+ FOOTNOTE_CLOSE = '-))'
322
+ FOOTNOTE_CLOSE_RE = /\A#{Regexp.quote(FOOTNOTE_CLOSE)}/
323
+ VERB_OPEN = "(('"
324
+ VERB_OPEN_RE = /\A#{Regexp.quote(VERB_OPEN)}/
325
+ VERB_CLOSE = "'))"
326
+ VERB_CLOSE_RE = /\A#{Regexp.quote(VERB_CLOSE)}/
327
+
328
+ BAR = "|"
329
+ BAR_RE = /\A#{Regexp.quote(BAR)}/
330
+ QUOTE = '"'
331
+ QUOTE_RE = /\A#{Regexp.quote(QUOTE)}/
332
+ SLASH = "/"
333
+ SLASH_RE = /\A#{Regexp.quote(SLASH)}/
334
+ BACK_SLASH = "\\"
335
+ BACK_SLASH_RE = /\A#{Regexp.quote(BACK_SLASH)}/
336
+ URL = "URL:"
337
+ URL_RE = /\A#{Regexp.quote(URL)}/
338
+
339
+ # Workaround for Regexp option change of Ruby 1.5.x
340
+ other_re_mode = Regexp::EXTENDED
341
+ if RUBY_VERSION > "1.5"
342
+ other_re_mode |= Regexp::MULTILINE
343
+ else
344
+ other_re_mode |= Regexp::POSIXLINE
345
+ end
346
+
347
+ OTHER_RE = Regexp.new(
348
+ "\\A.+?(?=#{Regexp.quote(EM_OPEN)}|#{Regexp.quote(EM_CLOSE)}|
349
+ #{Regexp.quote(CODE_OPEN)}|#{Regexp.quote(CODE_CLOSE)}|
350
+ #{Regexp.quote(VAR_OPEN)}|#{Regexp.quote(VAR_CLOSE)}|
351
+ #{Regexp.quote(KBD_OPEN)}|#{Regexp.quote(KBD_CLOSE)}|
352
+ #{Regexp.quote(INDEX_OPEN)}|#{Regexp.quote(INDEX_CLOSE)}|
353
+ #{Regexp.quote(REF_OPEN)}|#{Regexp.quote(REF_CLOSE)}|
354
+ #{Regexp.quote(FOOTNOTE_OPEN)}|#{Regexp.quote(FOOTNOTE_CLOSE)}|
355
+ #{Regexp.quote(VERB_OPEN)}|#{Regexp.quote(VERB_CLOSE)}|
356
+ #{Regexp.quote(BAR)}|
357
+ #{Regexp.quote(QUOTE)}|
358
+ #{Regexp.quote(SLASH)}|
359
+ #{Regexp.quote(BACK_SLASH)}|
360
+ #{Regexp.quote(URL)})", other_re_mode)
361
+
362
+ def initialize(bp)
363
+ @blockp = bp
364
+ end
365
+
366
+ def_delegator(:@blockp, :tree)
367
+
368
+ def parse(src)
369
+ @src = StringScanner.new(src)
370
+ @pre = ""
371
+ @yydebug = true
372
+ do_parse
373
+ end
374
+
375
+ def next_token
376
+ return [false, false] if @src.eos?
377
+ # p @src.rest if @yydebug
378
+ if ret = @src.scan(EM_OPEN_RE)
379
+ @pre << ret
380
+ [:EM_OPEN, ret]
381
+ elsif ret = @src.scan(EM_CLOSE_RE)
382
+ @pre << ret
383
+ [:EM_CLOSE, ret]
384
+ elsif ret = @src.scan(CODE_OPEN_RE)
385
+ @pre << ret
386
+ [:CODE_OPEN, ret]
387
+ elsif ret = @src.scan(CODE_CLOSE_RE)
388
+ @pre << ret
389
+ [:CODE_CLOSE, ret]
390
+ elsif ret = @src.scan(VAR_OPEN_RE)
391
+ @pre << ret
392
+ [:VAR_OPEN, ret]
393
+ elsif ret = @src.scan(VAR_CLOSE_RE)
394
+ @pre << ret
395
+ [:VAR_CLOSE, ret]
396
+ elsif ret = @src.scan(KBD_OPEN_RE)
397
+ @pre << ret
398
+ [:KBD_OPEN, ret]
399
+ elsif ret = @src.scan(KBD_CLOSE_RE)
400
+ @pre << ret
401
+ [:KBD_CLOSE, ret]
402
+ elsif ret = @src.scan(INDEX_OPEN_RE)
403
+ @pre << ret
404
+ [:INDEX_OPEN, ret]
405
+ elsif ret = @src.scan(INDEX_CLOSE_RE)
406
+ @pre << ret
407
+ [:INDEX_CLOSE, ret]
408
+ elsif ret = @src.scan(REF_OPEN_RE)
409
+ @pre << ret
410
+ [:REF_OPEN, ret]
411
+ elsif ret = @src.scan(REF_CLOSE_RE)
412
+ @pre << ret
413
+ [:REF_CLOSE, ret]
414
+ elsif ret = @src.scan(FOOTNOTE_OPEN_RE)
415
+ @pre << ret
416
+ [:FOOTNOTE_OPEN, ret]
417
+ elsif ret = @src.scan(FOOTNOTE_CLOSE_RE)
418
+ @pre << ret
419
+ [:FOOTNOTE_CLOSE, ret]
420
+ elsif ret = @src.scan(VERB_OPEN_RE)
421
+ @pre << ret
422
+ [:VERB_OPEN, ret]
423
+ elsif ret = @src.scan(VERB_CLOSE_RE)
424
+ @pre << ret
425
+ [:VERB_CLOSE, ret]
426
+ elsif ret = @src.scan(BAR_RE)
427
+ @pre << ret
428
+ [:BAR, ret]
429
+ elsif ret = @src.scan(QUOTE_RE)
430
+ @pre << ret
431
+ [:QUOTE, ret]
432
+ elsif ret = @src.scan(SLASH_RE)
433
+ @pre << ret
434
+ [:SLASH, ret]
435
+ elsif ret = @src.scan(BACK_SLASH_RE)
436
+ @pre << ret
437
+ [:BACK_SLASH, ret]
438
+ elsif ret = @src.scan(URL_RE)
439
+ @pre << ret
440
+ [:URL, ret]
441
+ elsif ret = @src.scan(OTHER_RE)
442
+ @pre << ret
443
+ [:OTHER, ret]
444
+ else
445
+ ret = @src.rest
446
+ @pre << ret
447
+ @src.terminate
448
+ [:OTHER, ret]
449
+ end
450
+ end
451
+
452
+ def make_reference_from_label(label)
453
+ # Reference.new_from_label_under_document_struct(label, tree.document_struct)
454
+ Reference.new_from_label_without_document_struct(label)
455
+ end
456
+
457
+ def on_error(et, ev, values)
458
+ lines_of_rest = @src.rest.to_a.length
459
+ prev_words = prev_words_on_error(ev)
460
+ at = 4 + prev_words.length
461
+ message = <<-MSG
462
+ RD syntax error: line #{@blockp.line_index - lines_of_rest}:
463
+ ...#{prev_words} #{(ev||'')} #{next_words_on_error()} ...
464
+ MSG
465
+ message << " " * at + "^" * (ev ? ev.length : 0) + "\n"
466
+ raise ParseError, message
467
+ end
468
+
469
+ def prev_words_on_error(ev)
470
+ pre = @pre
471
+ if ev and /#{Regexp.quote(ev)}$/ =~ pre
472
+ pre = $`
473
+ end
474
+ last_line(pre)
475
+ end
476
+
477
+ def last_line(src)
478
+ if n = src.rindex("\n")
479
+ src[(n+1) .. -1]
480
+ else
481
+ src
482
+ end
483
+ end
484
+ private :last_line
485
+
486
+ def next_words_on_error
487
+ if n = @src.rest.index("\n")
488
+ @src.rest[0 .. (n-1)]
489
+ else
490
+ @src.rest
491
+ end
492
+ end
493
+
494
+ ---- header
495
+
496
+ require "rd/parser-util"
497
+ require "forwardable"
498
+ require "strscan"
499
+
500
+ module RD
501
+ ---- footer
502
+ end # end of module RD
503
+