precedent 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,7 @@
1
+ 1. Fork the [master branch of the respository](https://github.com/BlackacreLabs/precedent/tree/master)
2
+ 2. Create a feature branch (`git checkout -b my-new-feature`).
3
+ 3. Add specifications and make your changes.
4
+ 4. Regenerate Treetop parsers and run specs (`rake clobber spec`).
5
+ 5. Commit your changes (`git commit -am 'Add some feature'`).
6
+ 6. Push to your feature branch (`git push origin my-new-feature`).
7
+ 7. Send a pull request via [GitHub](https://github.com).
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in precedent.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ # guard-rspec does not play nice with later versions of rb-inotify
8
+ gem 'rb-inotify', '0.8.8', :require => false
9
+ gem 'rb-fsevent', :require => false
10
+ gem 'rb-fchange', :require => false
11
+ end
data/Guardfile ADDED
@@ -0,0 +1,13 @@
1
+ guard :bundler do
2
+ watch("precedent.gemspec")
3
+ end
4
+
5
+ require './lib/precedent/treetop_patch.rb'
6
+ guard :treetop do
7
+ watch('**/*.treetop')
8
+ end
9
+
10
+ guard :rspec, bundler: false do
11
+ watch(%r{^spec/.+_spec\.rb$})
12
+ watch(%r{^lib/(.+)\.rb$})
13
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ # License
2
+
3
+ Copyright 2013 Blackacre Labs, a Texas non-profit corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included
14
+ in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # Precedent
2
+
3
+ Lightweight markup for legal documents, inspired by the print style of
4
+ the United States Reports.
5
+
6
+ - Mixed symbolic (*, †, ‡) and numeric, non-sequential footnotes.
7
+ - Elegant control of paragraph indentation (flush or indented)
8
+ - Document-level metadata
9
+ - Elegant citation identification
10
+ - Small capitals
11
+
12
+ See `SYNTAX.md` for more details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ # Treetop grammars
4
+
5
+ GRAMMARS = FileList.new('**/*.treetop').sub('.treetop', '.rb')
6
+
7
+ desc "Generate Treetop grammars"
8
+ task :grammars => GRAMMARS
9
+
10
+ require 'rake/clean'
11
+ CLEAN.include('tmp')
12
+ CLOBBER.include(GRAMMARS)
13
+
14
+ compiler = nil
15
+ rule '.rb' => '.treetop' do |t|
16
+ unless defined? Treetop
17
+ require 'treetop'
18
+ require './lib/precedent/treetop_patch.rb'
19
+ end
20
+ compiler ||= Treetop::Compiler::GrammarCompiler.new
21
+ compiler.compile(t.source, t.name)
22
+ end
23
+
24
+ # Performance
25
+
26
+ desc 'Profile a program run'
27
+ task :profile do
28
+ require 'ruby-prof'
29
+ require_relative 'lib/precedent.rb'
30
+ result = RubyProf.profile do
31
+ Precedent.new(File.read('spec/fixtures/long_opinion.pre')).to_hashes
32
+ end
33
+ printer = RubyProf::GraphPrinter.new(result)
34
+ printer.print(STDOUT, {})
35
+ end
36
+
37
+ # Specifications
38
+
39
+ require 'rspec/core/rake_task'
40
+ RSpec::Core::RakeTask.new(:spec => [:grammars])
41
+
42
+ # Coverage
43
+ desc 'Measure test suite code coverage'
44
+ RSpec::Core::RakeTask.new(:coverage => [:grammars]) do
45
+ ENV['COVERAGE'] = 'true'
46
+ end
47
+
48
+ task :default => :spec
data/SYNTAX.md ADDED
@@ -0,0 +1,142 @@
1
+ Precedent Syntax Guide
2
+ ----------------------
3
+
4
+ ## Headings, Paragraphs, Quotes, Footnotes, and Rules
5
+
6
+ Document elements can span multiple lines, but are separated by blank
7
+ (empty) lines.
8
+
9
+ ### Headings
10
+
11
+ ```
12
+ # A top-level heading
13
+
14
+ ## A subheading
15
+
16
+ ### A sub-subheading
17
+ ```
18
+
19
+ ### Paragraphs
20
+
21
+ The style of a paragraph is determined by the indentation of its first
22
+ line:
23
+
24
+ - 0 Spaces: Flush with the left margin (useful after block quotations)
25
+ - 2 Spaces: Indented (most paragraphs should be indented this way)
26
+ - 4 Spaces: Flush block quotation paragraphs
27
+ - 6 Spaces: Indented block quotation paragraphs
28
+ - 8 Spaces: Ragged-left (right-aligned) paragraphs
29
+
30
+ ```
31
+ This first line of this paragraph will be rendered indented. It can
32
+ continue on multiple lines.
33
+
34
+ This is a flush blockquote paragraph
35
+
36
+ And this is an indented blockquote paragraph.
37
+
38
+ This paragraph follows the block quotation, and will be rendered without
39
+ indentation, i.e. flush with the left margin. This is still part of the
40
+ flush paragraph, as no blank line separates it from previous lines.
41
+
42
+ This paragraph will be set flush against the right margin, or
43
+ ragged left.
44
+
45
+ And finally, here is another standard indented paragraph.
46
+ ```
47
+
48
+ ### Footnotes
49
+
50
+ Footnote paragraphs are all indented paragraphs. The first paragraph in
51
+ a footnote begins with a caret (`^`) and a marker, followed by at least
52
+ one space before the text of the paragraph begins. The marker can be an
53
+ integer, asterisk (`*`), dagger (`†`), or double dagger (`‡`). That
54
+ marker should appear elsewhere within a footnote reference (discussed
55
+ below).
56
+
57
+ For example:
58
+
59
+ ```
60
+ This is a body paragraph.[[12]] It has a footnote reference referring
61
+ to a footnote with the marker "12".
62
+
63
+ ^12 This is the first paragraph in footnote twelve.
64
+
65
+ ^ This is another paragraph in the same footnote.
66
+ ```
67
+
68
+ Footnote paragraphs need not appear at the end of the document, nor must
69
+ they appear immediately after the paragraph containing the corresponding
70
+ reference. Footnotes can also appear in any order in the document.
71
+
72
+ ### Horizontal Rules
73
+
74
+ Rules, written `* * *` can appear in body text or block quotations:
75
+
76
+ ```
77
+ A standard paragraph.
78
+
79
+ * * *
80
+
81
+ Another standard paragraph.
82
+
83
+ A blockquote paragraph.
84
+
85
+ * * *
86
+
87
+ A flush blockquote paragrap.
88
+
89
+ A flush body paragraph.
90
+ ```
91
+
92
+ ## Formatting Text
93
+
94
+ Within a paragraph, the following can be used to format text:
95
+
96
+ ```
97
+ This is a paragraph. The final word in this sentence is //emphasized//.
98
+ Small capitals can be set with the less-than and greater-than characters
99
+ <<like so>>. Citations can be identified with double curly brackes and
100
+ contain other formatting. {{//Id.//}} Page breaks@@2@@can be notated
101
+ with at-signs. Footnote references appear in double brackets.[[1]]
102
+
103
+ ^1 The text of the footnote.
104
+ ```
105
+
106
+ ## Metadata
107
+
108
+ Metadata blocks permit non-content information about a document to be
109
+ embedded within it.
110
+
111
+ Metadata blocks are composed of lines containing:
112
+
113
+ - a key, composed of alphabet letters and starting with a capital letter
114
+ - a colon
115
+ - optional spaces
116
+ - content of any kind, running to the end of the line
117
+
118
+ For example:
119
+
120
+ ```
121
+ Style: Sebelius v. Auburn Regional Medical Center et al.
122
+ Number: 11–1231
123
+ Argued: 2012-12-04
124
+ Decided: 2013-01-22
125
+ ```
126
+
127
+ Metadata must appear at the top of a document, before any content text.
128
+
129
+ ### Special Metadata Types
130
+
131
+ Content composed only of digits will be interpreted as an integer
132
+ number.
133
+
134
+ ```
135
+ Opinions: 3
136
+ ```
137
+
138
+ Content of the form `YYYY-MM-DD` will be interpreted as a calendar date.
139
+
140
+ ```
141
+ Filed: 2013-01-01
142
+ ```
data/bin/precedent ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/precedent/cli'
4
+ Precedent::CLI.start(ARGV)
data/lib/precedent.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'treetop/runtime'
2
+
3
+ require_relative 'precedent/version'
4
+ require_relative 'precedent/translator'
5
+
6
+ module Precedent
7
+ def self.new(input)
8
+ Translator.new(input)
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ require 'thor'
2
+
3
+ require_relative '../precedent'
4
+
5
+ module Precedent
6
+ class CLI < Thor
7
+ default_task :translate
8
+
9
+ option :pretty,
10
+ :aliases => '-p',
11
+ :type => :boolean,
12
+ :default => false,
13
+ :desc => "Pretty output"
14
+
15
+ OUTPUT_FORMATS = {
16
+ :json => lambda { |hashes, pretty|
17
+ require 'json'
18
+ message = pretty ? :pretty_generate : :generate
19
+ JSON.send(message, hashes)
20
+ },
21
+ :yaml => lambda { |hashes, pretty|
22
+ require 'yaml'
23
+ hashes.to_yaml
24
+ }
25
+ }
26
+
27
+ option :format,
28
+ :aliases => '-f',
29
+ :default => OUTPUT_FORMATS.keys.first,
30
+ :desc => "Output format: " + OUTPUT_FORMATS.keys.join('|')
31
+
32
+ desc "translate [FILE]", "Translate Precedent markup"
33
+
34
+ def translate(file=STDIN)
35
+ input = file.is_a?(String) ? File.read(file) : file.read
36
+ parsed = Precedent.new(input).to_hashes
37
+ output = OUTPUT_FORMATS[options[:format].to_sym].call(parsed, options[:pretty])
38
+ STDOUT.write(output)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,762 @@
1
+ # encoding: UTF-8
2
+ # Autogenerated from a Treetop grammar. Edits may be lost.
3
+
4
+
5
+
6
+ module Precedent
7
+ module Inline
8
+ include Treetop::Runtime
9
+
10
+ def root
11
+ @root ||= :inline
12
+ end
13
+
14
+ module Inline0
15
+ def inline_element
16
+ elements[1]
17
+ end
18
+ end
19
+
20
+ module Inline1
21
+ def first
22
+ elements[0]
23
+ end
24
+
25
+ def subsequent
26
+ elements[1]
27
+ end
28
+ end
29
+
30
+ module Inline2
31
+ def build
32
+ elems = subsequent.elements.map(&:build).flatten
33
+ # Members of `subsequent` come in [nil, Node] lists when there
34
+ # is no preceding line break. The car values can't be ignored,
35
+ # as we need to convert newlines to spaces when they occur.
36
+ ret = elems.reduce([first.build]) do |mem, e|
37
+ last = mem.last
38
+ # Start the output list with the first element
39
+ if e.nil?
40
+ mem
41
+ # Concatenate contiguous strings
42
+ elsif last.is_a?(String) && e.is_a?(String)
43
+ mem + [mem.pop + e]
44
+ else # Hash
45
+ mem + [e]
46
+ end
47
+ end
48
+ # If there is just one content element, give the element
49
+ # rather than a one-element list.
50
+ ret.count == 1 ? ret.first : ret
51
+ end
52
+ end
53
+
54
+ def _nt_inline
55
+ start_index = index
56
+ if node_cache[:inline].has_key?(index)
57
+ cached = node_cache[:inline][index]
58
+ if cached
59
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
60
+ @index = cached.interval.end
61
+ end
62
+ return cached
63
+ end
64
+
65
+ i0, s0 = index, []
66
+ r1 = _nt_inline_element
67
+ s0 << r1
68
+ if r1
69
+ s2, i2 = [], index
70
+ loop do
71
+ i3, s3 = index, []
72
+ r5 = _nt_single_newline
73
+ if r5
74
+ r4 = r5
75
+ else
76
+ r4 = instantiate_node(SyntaxNode,input, index...index)
77
+ end
78
+ s3 << r4
79
+ if r4
80
+ r6 = _nt_inline_element
81
+ s3 << r6
82
+ end
83
+ if s3.last
84
+ r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
85
+ r3.extend(Inline0)
86
+ else
87
+ @index = i3
88
+ r3 = nil
89
+ end
90
+ if r3
91
+ s2 << r3
92
+ else
93
+ break
94
+ end
95
+ end
96
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
97
+ s0 << r2
98
+ end
99
+ if s0.last
100
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
101
+ r0.extend(Inline1)
102
+ r0.extend(Inline2)
103
+ else
104
+ @index = i0
105
+ r0 = nil
106
+ end
107
+
108
+ node_cache[:inline][start_index] = r0
109
+
110
+ r0
111
+ end
112
+
113
+ def _nt_inline_element
114
+ start_index = index
115
+ if node_cache[:inline_element].has_key?(index)
116
+ cached = node_cache[:inline_element][index]
117
+ if cached
118
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
119
+ @index = cached.interval.end
120
+ end
121
+ return cached
122
+ end
123
+
124
+ i0 = index
125
+ r1 = _nt_citation
126
+ if r1
127
+ r0 = r1
128
+ else
129
+ r2 = _nt_emphasis
130
+ if r2
131
+ r0 = r2
132
+ else
133
+ r3 = _nt_smallcaps
134
+ if r3
135
+ r0 = r3
136
+ else
137
+ r4 = _nt_reference
138
+ if r4
139
+ r0 = r4
140
+ else
141
+ r5 = _nt_page_break
142
+ if r5
143
+ r0 = r5
144
+ else
145
+ r6 = _nt_space
146
+ if r6
147
+ r0 = r6
148
+ else
149
+ r7 = _nt_word
150
+ if r7
151
+ r0 = r7
152
+ else
153
+ @index = i0
154
+ r0 = nil
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ node_cache[:inline_element][start_index] = r0
164
+
165
+ r0
166
+ end
167
+
168
+ module Smallcaps0
169
+ def content
170
+ elements[1]
171
+ end
172
+
173
+ end
174
+
175
+ module Smallcaps1
176
+ def build
177
+ { :type => :smallcaps,
178
+ :content => content.build }
179
+ end
180
+ end
181
+
182
+ def _nt_smallcaps
183
+ start_index = index
184
+ if node_cache[:smallcaps].has_key?(index)
185
+ cached = node_cache[:smallcaps][index]
186
+ if cached
187
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
188
+ @index = cached.interval.end
189
+ end
190
+ return cached
191
+ end
192
+
193
+ i0, s0 = index, []
194
+ if has_terminal?('<<', false, index)
195
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 2))
196
+ @index += 2
197
+ else
198
+ terminal_parse_failure('<<')
199
+ r1 = nil
200
+ end
201
+ s0 << r1
202
+ if r1
203
+ r2 = _nt_inline
204
+ s0 << r2
205
+ if r2
206
+ if has_terminal?('>>', false, index)
207
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 2))
208
+ @index += 2
209
+ else
210
+ terminal_parse_failure('>>')
211
+ r3 = nil
212
+ end
213
+ s0 << r3
214
+ end
215
+ end
216
+ if s0.last
217
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
218
+ r0.extend(Smallcaps0)
219
+ r0.extend(Smallcaps1)
220
+ else
221
+ @index = i0
222
+ r0 = nil
223
+ end
224
+
225
+ node_cache[:smallcaps][start_index] = r0
226
+
227
+ r0
228
+ end
229
+
230
+ module Emphasis0
231
+ def content
232
+ elements[1]
233
+ end
234
+
235
+ end
236
+
237
+ module Emphasis1
238
+ def build
239
+ { :type => :emphasis,
240
+ :content => content.build }
241
+ end
242
+ end
243
+
244
+ def _nt_emphasis
245
+ start_index = index
246
+ if node_cache[:emphasis].has_key?(index)
247
+ cached = node_cache[:emphasis][index]
248
+ if cached
249
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
250
+ @index = cached.interval.end
251
+ end
252
+ return cached
253
+ end
254
+
255
+ i0, s0 = index, []
256
+ if has_terminal?('\\\\', false, index)
257
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 2))
258
+ @index += 2
259
+ else
260
+ terminal_parse_failure('\\\\')
261
+ r1 = nil
262
+ end
263
+ s0 << r1
264
+ if r1
265
+ r2 = _nt_inline
266
+ s0 << r2
267
+ if r2
268
+ if has_terminal?('\\\\', false, index)
269
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 2))
270
+ @index += 2
271
+ else
272
+ terminal_parse_failure('\\\\')
273
+ r3 = nil
274
+ end
275
+ s0 << r3
276
+ end
277
+ end
278
+ if s0.last
279
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
280
+ r0.extend(Emphasis0)
281
+ r0.extend(Emphasis1)
282
+ else
283
+ @index = i0
284
+ r0 = nil
285
+ end
286
+
287
+ node_cache[:emphasis][start_index] = r0
288
+
289
+ r0
290
+ end
291
+
292
+ module Citation0
293
+ def content
294
+ elements[1]
295
+ end
296
+
297
+ end
298
+
299
+ module Citation1
300
+ def build
301
+ { :type => :citation,
302
+ :content => content.build }
303
+ end
304
+ end
305
+
306
+ def _nt_citation
307
+ start_index = index
308
+ if node_cache[:citation].has_key?(index)
309
+ cached = node_cache[:citation][index]
310
+ if cached
311
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
312
+ @index = cached.interval.end
313
+ end
314
+ return cached
315
+ end
316
+
317
+ i0, s0 = index, []
318
+ if has_terminal?('{{', false, index)
319
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 2))
320
+ @index += 2
321
+ else
322
+ terminal_parse_failure('{{')
323
+ r1 = nil
324
+ end
325
+ s0 << r1
326
+ if r1
327
+ r2 = _nt_inline
328
+ s0 << r2
329
+ if r2
330
+ if has_terminal?('}}', false, index)
331
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 2))
332
+ @index += 2
333
+ else
334
+ terminal_parse_failure('}}')
335
+ r3 = nil
336
+ end
337
+ s0 << r3
338
+ end
339
+ end
340
+ if s0.last
341
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
342
+ r0.extend(Citation0)
343
+ r0.extend(Citation1)
344
+ else
345
+ @index = i0
346
+ r0 = nil
347
+ end
348
+
349
+ node_cache[:citation][start_index] = r0
350
+
351
+ r0
352
+ end
353
+
354
+ module PageBreak0
355
+ def page
356
+ elements[1]
357
+ end
358
+
359
+ end
360
+
361
+ module PageBreak1
362
+ def build
363
+ { :type => :break,
364
+ :page => page.text_value.to_i }
365
+ end
366
+ end
367
+
368
+ def _nt_page_break
369
+ start_index = index
370
+ if node_cache[:page_break].has_key?(index)
371
+ cached = node_cache[:page_break][index]
372
+ if cached
373
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
374
+ @index = cached.interval.end
375
+ end
376
+ return cached
377
+ end
378
+
379
+ i0, s0 = index, []
380
+ if has_terminal?('@@', false, index)
381
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 2))
382
+ @index += 2
383
+ else
384
+ terminal_parse_failure('@@')
385
+ r1 = nil
386
+ end
387
+ s0 << r1
388
+ if r1
389
+ s2, i2 = [], index
390
+ loop do
391
+ if has_terminal?('\G[0-9]', true, index)
392
+ r3 = true
393
+ @index += 1
394
+ else
395
+ r3 = nil
396
+ end
397
+ if r3
398
+ s2 << r3
399
+ else
400
+ break
401
+ end
402
+ end
403
+ if s2.empty?
404
+ @index = i2
405
+ r2 = nil
406
+ else
407
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
408
+ end
409
+ s0 << r2
410
+ if r2
411
+ if has_terminal?('@@', false, index)
412
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 2))
413
+ @index += 2
414
+ else
415
+ terminal_parse_failure('@@')
416
+ r4 = nil
417
+ end
418
+ s0 << r4
419
+ end
420
+ end
421
+ if s0.last
422
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
423
+ r0.extend(PageBreak0)
424
+ r0.extend(PageBreak1)
425
+ else
426
+ @index = i0
427
+ r0 = nil
428
+ end
429
+
430
+ node_cache[:page_break][start_index] = r0
431
+
432
+ r0
433
+ end
434
+
435
+ module Reference0
436
+ def marker
437
+ elements[1]
438
+ end
439
+
440
+ end
441
+
442
+ module Reference1
443
+ def build
444
+ { :type => :reference,
445
+ :marker => marker.text_value }
446
+ end
447
+ end
448
+
449
+ def _nt_reference
450
+ start_index = index
451
+ if node_cache[:reference].has_key?(index)
452
+ cached = node_cache[:reference][index]
453
+ if cached
454
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
455
+ @index = cached.interval.end
456
+ end
457
+ return cached
458
+ end
459
+
460
+ i0, s0 = index, []
461
+ if has_terminal?('[[', false, index)
462
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 2))
463
+ @index += 2
464
+ else
465
+ terminal_parse_failure('[[')
466
+ r1 = nil
467
+ end
468
+ s0 << r1
469
+ if r1
470
+ s2, i2 = [], index
471
+ loop do
472
+ if has_terminal?('\G[0-9*†‡]', true, index)
473
+ r3 = true
474
+ @index += 1
475
+ else
476
+ r3 = nil
477
+ end
478
+ if r3
479
+ s2 << r3
480
+ else
481
+ break
482
+ end
483
+ end
484
+ if s2.empty?
485
+ @index = i2
486
+ r2 = nil
487
+ else
488
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
489
+ end
490
+ s0 << r2
491
+ if r2
492
+ if has_terminal?(']]', false, index)
493
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 2))
494
+ @index += 2
495
+ else
496
+ terminal_parse_failure(']]')
497
+ r4 = nil
498
+ end
499
+ s0 << r4
500
+ end
501
+ end
502
+ if s0.last
503
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
504
+ r0.extend(Reference0)
505
+ r0.extend(Reference1)
506
+ else
507
+ @index = i0
508
+ r0 = nil
509
+ end
510
+
511
+ node_cache[:reference][start_index] = r0
512
+
513
+ r0
514
+ end
515
+
516
+ module SingleNewline0
517
+ def build
518
+ ' '
519
+ end
520
+ end
521
+
522
+ def _nt_single_newline
523
+ start_index = index
524
+ if node_cache[:single_newline].has_key?(index)
525
+ cached = node_cache[:single_newline][index]
526
+ if cached
527
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
528
+ @index = cached.interval.end
529
+ end
530
+ return cached
531
+ end
532
+
533
+ if has_terminal?("\n", false, index)
534
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
535
+ r0.extend(SingleNewline0)
536
+ @index += 1
537
+ else
538
+ terminal_parse_failure("\n")
539
+ r0 = nil
540
+ end
541
+
542
+ node_cache[:single_newline][start_index] = r0
543
+
544
+ r0
545
+ end
546
+
547
+ module Word0
548
+ def char
549
+ elements[1]
550
+ end
551
+ end
552
+
553
+ module Word1
554
+ def build
555
+ text_value
556
+ end
557
+ end
558
+
559
+ def _nt_word
560
+ start_index = index
561
+ if node_cache[:word].has_key?(index)
562
+ cached = node_cache[:word][index]
563
+ if cached
564
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
565
+ @index = cached.interval.end
566
+ end
567
+ return cached
568
+ end
569
+
570
+ s0, i0 = [], index
571
+ loop do
572
+ i1, s1 = index, []
573
+ i2 = index
574
+ i3 = index
575
+ if has_terminal?('{{', false, index)
576
+ r4 = instantiate_node(SyntaxNode,input, index...(index + 2))
577
+ @index += 2
578
+ else
579
+ terminal_parse_failure('{{')
580
+ r4 = nil
581
+ end
582
+ if r4
583
+ r3 = r4
584
+ else
585
+ if has_terminal?('}}', false, index)
586
+ r5 = instantiate_node(SyntaxNode,input, index...(index + 2))
587
+ @index += 2
588
+ else
589
+ terminal_parse_failure('}}')
590
+ r5 = nil
591
+ end
592
+ if r5
593
+ r3 = r5
594
+ else
595
+ if has_terminal?('<<', false, index)
596
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 2))
597
+ @index += 2
598
+ else
599
+ terminal_parse_failure('<<')
600
+ r6 = nil
601
+ end
602
+ if r6
603
+ r3 = r6
604
+ else
605
+ if has_terminal?('>>', false, index)
606
+ r7 = instantiate_node(SyntaxNode,input, index...(index + 2))
607
+ @index += 2
608
+ else
609
+ terminal_parse_failure('>>')
610
+ r7 = nil
611
+ end
612
+ if r7
613
+ r3 = r7
614
+ else
615
+ if has_terminal?('[[', false, index)
616
+ r8 = instantiate_node(SyntaxNode,input, index...(index + 2))
617
+ @index += 2
618
+ else
619
+ terminal_parse_failure('[[')
620
+ r8 = nil
621
+ end
622
+ if r8
623
+ r3 = r8
624
+ else
625
+ if has_terminal?(']]', false, index)
626
+ r9 = instantiate_node(SyntaxNode,input, index...(index + 2))
627
+ @index += 2
628
+ else
629
+ terminal_parse_failure(']]')
630
+ r9 = nil
631
+ end
632
+ if r9
633
+ r3 = r9
634
+ else
635
+ if has_terminal?('\\\\', false, index)
636
+ r10 = instantiate_node(SyntaxNode,input, index...(index + 2))
637
+ @index += 2
638
+ else
639
+ terminal_parse_failure('\\\\')
640
+ r10 = nil
641
+ end
642
+ if r10
643
+ r3 = r10
644
+ else
645
+ if has_terminal?('@@', false, index)
646
+ r11 = instantiate_node(SyntaxNode,input, index...(index + 2))
647
+ @index += 2
648
+ else
649
+ terminal_parse_failure('@@')
650
+ r11 = nil
651
+ end
652
+ if r11
653
+ r3 = r11
654
+ else
655
+ @index = i3
656
+ r3 = nil
657
+ end
658
+ end
659
+ end
660
+ end
661
+ end
662
+ end
663
+ end
664
+ end
665
+ if r3
666
+ r2 = nil
667
+ else
668
+ @index = i2
669
+ r2 = instantiate_node(SyntaxNode,input, index...index)
670
+ end
671
+ s1 << r2
672
+ if r2
673
+ r12 = _nt_char
674
+ s1 << r12
675
+ end
676
+ if s1.last
677
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
678
+ r1.extend(Word0)
679
+ else
680
+ @index = i1
681
+ r1 = nil
682
+ end
683
+ if r1
684
+ s0 << r1
685
+ else
686
+ break
687
+ end
688
+ end
689
+ if s0.empty?
690
+ @index = i0
691
+ r0 = nil
692
+ else
693
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
694
+ r0.extend(Word1)
695
+ end
696
+
697
+ node_cache[:word][start_index] = r0
698
+
699
+ r0
700
+ end
701
+
702
+ module Space0
703
+ def build
704
+ ' '
705
+ end
706
+ end
707
+
708
+ def _nt_space
709
+ start_index = index
710
+ if node_cache[:space].has_key?(index)
711
+ cached = node_cache[:space][index]
712
+ if cached
713
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
714
+ @index = cached.interval.end
715
+ end
716
+ return cached
717
+ end
718
+
719
+ if has_terminal?(' ', false, index)
720
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
721
+ r0.extend(Space0)
722
+ @index += 1
723
+ else
724
+ terminal_parse_failure(' ')
725
+ r0 = nil
726
+ end
727
+
728
+ node_cache[:space][start_index] = r0
729
+
730
+ r0
731
+ end
732
+
733
+ def _nt_char
734
+ start_index = index
735
+ if node_cache[:char].has_key?(index)
736
+ cached = node_cache[:char][index]
737
+ if cached
738
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
739
+ @index = cached.interval.end
740
+ end
741
+ return cached
742
+ end
743
+
744
+ if has_terminal?('\G[\\S]', true, index)
745
+ r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
746
+ @index += 1
747
+ else
748
+ r0 = nil
749
+ end
750
+
751
+ node_cache[:char][start_index] = r0
752
+
753
+ r0
754
+ end
755
+
756
+ end
757
+
758
+ class InlineParser < Treetop::Runtime::CompiledParser
759
+ include Inline
760
+ end
761
+
762
+ end