kpeg 1.0.0 → 1.3.1
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.
- checksums.yaml +5 -5
- data/.hoeignore +12 -0
- data/Gemfile +3 -0
- data/History.txt +18 -0
- data/Manifest.txt +9 -1
- data/README.rdoc +8 -8
- data/Rakefile +2 -0
- data/bin/kpeg +12 -5
- data/examples/lua_string/lua_string.kpeg.rb +0 -2
- data/examples/tiny_markdown/Rakefile +3 -0
- data/examples/tiny_markdown/driver.rb +10 -0
- data/examples/tiny_markdown/node.rb +107 -0
- data/examples/tiny_markdown/sample.md +51 -0
- data/examples/tiny_markdown/tiny_markdown.kpeg +199 -0
- data/examples/tiny_markdown/tiny_markdown.kpeg.rb +3892 -0
- data/lib/kpeg/code_generator.rb +1 -1
- data/lib/kpeg/compiled_parser.rb +3 -7
- data/lib/kpeg/format_parser.kpeg +1 -1
- data/lib/kpeg/format_parser.rb +46 -32
- data/lib/kpeg/position.rb +25 -10
- data/lib/kpeg/string_escape.rb +27 -16
- data/lib/kpeg.rb +1 -1
- data/test/test_kpeg_code_generator.rb +3 -3
- data/test/test_kpeg_compiled_parser.rb +10 -1
- data/test/test_kpeg_format.rb +19 -0
- metadata +40 -34
- data/.gemtest +0 -0
- data/.travis.yml +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 69daab2a8357318c67653138ac1279d035305af374c0840164b535d3110a9a34
|
4
|
+
data.tar.gz: 703023a2c28f68a26cf1b84255e4aede05880eb6356ced93ec244bad471f05f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f98d1334465ea3728004aea43b5abe33d8deae27c4100beaa091a87292ac0197a4580207b3036da616054d5dab8f931621597fc6c2294698eb32842be37e5458
|
7
|
+
data.tar.gz: acbd264cfd9de363de5eac6107baa58ef43535b5a071fee6da11ff2b33cdd6c2a378664b137b9bb359504b12b0e2f2060fca8cfde53d8196309c68f3132e6e0f
|
data/.hoeignore
ADDED
data/Gemfile
ADDED
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== 1.3.1 / 2022-01-10
|
2
|
+
|
3
|
+
* File.exists? => File.exist?
|
4
|
+
|
5
|
+
=== 1.3.0 / 2021-10-20
|
6
|
+
|
7
|
+
* Fix current_line calculation
|
8
|
+
|
9
|
+
=== 1.2.0 / 2021-10-20
|
10
|
+
|
11
|
+
* Speed up current_line
|
12
|
+
|
13
|
+
=== 1.2.0 / 2021-10-20
|
14
|
+
|
15
|
+
* Speed up current_line
|
16
|
+
|
17
|
+
=== (entries lost to time)
|
18
|
+
|
1
19
|
=== 0.10 / 2012-04-16
|
2
20
|
|
3
21
|
* Minor enhancements
|
data/Manifest.txt
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
.autotest
|
2
|
-
.
|
2
|
+
.hoeignore
|
3
|
+
Gemfile
|
3
4
|
History.txt
|
4
5
|
LICENSE
|
5
6
|
Manifest.txt
|
@@ -17,6 +18,12 @@ examples/lua_string/lua_string.kpeg.rb
|
|
17
18
|
examples/phone_number/README.md
|
18
19
|
examples/phone_number/phone_number.kpeg
|
19
20
|
examples/phone_number/phone_number.rb
|
21
|
+
examples/tiny_markdown/Rakefile
|
22
|
+
examples/tiny_markdown/driver.rb
|
23
|
+
examples/tiny_markdown/node.rb
|
24
|
+
examples/tiny_markdown/sample.md
|
25
|
+
examples/tiny_markdown/tiny_markdown.kpeg
|
26
|
+
examples/tiny_markdown/tiny_markdown.kpeg.rb
|
20
27
|
examples/upper/README.md
|
21
28
|
examples/upper/upper.kpeg
|
22
29
|
examples/upper/upper.rb
|
@@ -42,5 +49,6 @@ test/test_kpeg_format.rb
|
|
42
49
|
test/test_kpeg_format_parser_round_trip.rb
|
43
50
|
test/test_kpeg_grammar.rb
|
44
51
|
test/test_kpeg_grammar_renderer.rb
|
52
|
+
test/test_kpeg_string_escape.rb
|
45
53
|
vim/syntax_kpeg/ftdetect/kpeg.vim
|
46
54
|
vim/syntax_kpeg/syntax/kpeg.vim
|
data/README.rdoc
CHANGED
@@ -143,13 +143,13 @@ Once you have the generated parser, include that file into your new grammar
|
|
143
143
|
Then create a variable to hold to foreign interface and pass it the class name
|
144
144
|
of your parser. In this case my parser class name is Literal
|
145
145
|
|
146
|
-
%
|
146
|
+
%foreign_grammar = Literal
|
147
147
|
|
148
148
|
You can then use rules defined in the foreign grammar in the local grammar
|
149
149
|
file like so
|
150
150
|
|
151
|
-
sentence = (%
|
152
|
-
%
|
151
|
+
sentence = (%foreign_grammar.alpha %foreign_grammar.space*)+
|
152
|
+
%foreign_grammar.period
|
153
153
|
|
154
154
|
=== Comments
|
155
155
|
|
@@ -240,15 +240,15 @@ For a good example of usage check out Talon[https://github.com/evanphx/talon]
|
|
240
240
|
There are several examples available in the /examples directory. The upper
|
241
241
|
parser has a readme with a step by step description of the grammar.
|
242
242
|
|
243
|
-
== Projects
|
243
|
+
== Projects
|
244
244
|
|
245
|
-
Dang[https://github.com/veganstraightedge/dang]
|
245
|
+
{Dang}[https://github.com/veganstraightedge/dang]
|
246
246
|
|
247
247
|
{Email Address Validator}[https://github.com/larb/email_address_validator]
|
248
248
|
|
249
|
-
Callisto[https://github.com/dwaite/Callisto]
|
249
|
+
{Callisto}[https://github.com/dwaite/Callisto]
|
250
250
|
|
251
|
-
Doodle[https://github.com/vito/doodle]
|
251
|
+
{Doodle}[https://github.com/vito/doodle]
|
252
252
|
|
253
|
-
Kanbanpad[https://kanbanpad.com] (uses kpeg for parsing of the 'enter
|
253
|
+
{Kanbanpad}[https://kanbanpad.com] (uses kpeg for parsing of the 'enter
|
254
254
|
something' bar)
|
data/Rakefile
CHANGED
data/bin/kpeg
CHANGED
@@ -8,7 +8,7 @@ require 'kpeg/grammar_renderer'
|
|
8
8
|
require 'optparse'
|
9
9
|
|
10
10
|
options = {}
|
11
|
-
OptionParser.new do |o|
|
11
|
+
optparser = OptionParser.new do |o|
|
12
12
|
o.banner = "Usage: kpeg [options]"
|
13
13
|
|
14
14
|
o.on("-t", "--test", "Syntax check the file only") do |v|
|
@@ -42,11 +42,18 @@ OptionParser.new do |o|
|
|
42
42
|
o.on("-d", "--debug", "Debug parsing the file") do |v|
|
43
43
|
options[:debug] = v
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end
|
46
|
+
|
47
|
+
optparser.parse!
|
48
|
+
|
49
|
+
if ARGV.empty?
|
50
|
+
puts optparser.help
|
51
|
+
exit 1
|
52
|
+
end
|
46
53
|
|
47
54
|
file = ARGV.shift
|
48
55
|
|
49
|
-
unless File.
|
56
|
+
unless File.exist?(file)
|
50
57
|
puts "File '#{file}' does not exist"
|
51
58
|
exit 1
|
52
59
|
end
|
@@ -68,7 +75,7 @@ if options[:reformat]
|
|
68
75
|
end
|
69
76
|
|
70
77
|
output = options[:output]
|
71
|
-
if File.
|
78
|
+
if File.exist?(output) and !options[:force]
|
72
79
|
puts "Output '#{output}' already exists, not overwriting (use -f)"
|
73
80
|
exit 1
|
74
81
|
end
|
@@ -100,7 +107,7 @@ else
|
|
100
107
|
new_path = "#{file}.rb"
|
101
108
|
end
|
102
109
|
|
103
|
-
if !options[:test] and File.
|
110
|
+
if !options[:test] and File.exist?(new_path) and !options[:force]
|
104
111
|
puts "Path #{new_path} already exists, not overwriting\n"
|
105
112
|
exit 1
|
106
113
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module TinyMarkdown
|
2
|
+
class Node
|
3
|
+
def to_html
|
4
|
+
if !self.respond_to?(:content)
|
5
|
+
return ""
|
6
|
+
end
|
7
|
+
if self.content.kind_of?(Array)
|
8
|
+
self.content.map(&:to_html).join("")
|
9
|
+
elsif self.content.kind_of?(TinyMarkdown::Node)
|
10
|
+
self.content.to_html
|
11
|
+
elsif self.content
|
12
|
+
self.content.to_s
|
13
|
+
else
|
14
|
+
""
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
if self.respond_to?(:content)
|
20
|
+
'#<'+self.class.to_s+' content="'+self.content.to_s+'">'
|
21
|
+
else
|
22
|
+
'#<'+self.class.to_s+'>'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class HeadlineNode
|
28
|
+
def to_html
|
29
|
+
children = self.content.map(&:to_html).join("")
|
30
|
+
"<h#{level}>#{children}</h#{level}>\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TextNode
|
35
|
+
def to_html
|
36
|
+
self.content.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class BlockQuoteNode
|
41
|
+
def to_html
|
42
|
+
children = self.content.map(&:to_html).join("")
|
43
|
+
"<blockquote>#{children}</blockquote>\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class BulletListNode
|
48
|
+
def to_html
|
49
|
+
children = self.content.map(&:to_html).join("")
|
50
|
+
"<ul>\n#{children}</ul>\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class BulletListItemNode
|
55
|
+
def to_html
|
56
|
+
children = self.content.map(&:to_html).join("")
|
57
|
+
"<li>#{children}</li>\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class PlainNode
|
62
|
+
def to_html
|
63
|
+
self.content.map(&:to_html).join("")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class ParaNode
|
68
|
+
def to_html
|
69
|
+
children = self.content.map(&:to_html).join("")
|
70
|
+
"<p>#{children}</p>\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class VerbatimNode
|
75
|
+
def to_html
|
76
|
+
children = self.content.map(&:to_html).join("")
|
77
|
+
"<pre><code>#{children}</code></pre>\n"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class InlineElementNode
|
82
|
+
def to_html
|
83
|
+
children = self.content.map(&:to_html).join("")
|
84
|
+
"<#{self.name}>#{children}</#{self.name}>"
|
85
|
+
end
|
86
|
+
|
87
|
+
def inspect
|
88
|
+
'#<'+self.class.to_s+' name="'+self.name.to_s+'" content="'+self.content.to_s+'">'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class LineBreakNode
|
93
|
+
def to_html
|
94
|
+
"<br />\n"
|
95
|
+
end
|
96
|
+
|
97
|
+
def inspect
|
98
|
+
"\\n"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class HorizontalRuleNode
|
103
|
+
def to_html
|
104
|
+
"<hr />\n"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# test
|
2
|
+
|
3
|
+
## inline
|
4
|
+
|
5
|
+
### strong1
|
6
|
+
|
7
|
+
aaa **bbb** cc *dd*
|
8
|
+
|
9
|
+
### strong2
|
10
|
+
|
11
|
+
ee _fff_ gg __hhh__
|
12
|
+
|
13
|
+
### code
|
14
|
+
|
15
|
+
iii `jjjjj` kk `lll`
|
16
|
+
|
17
|
+
## block
|
18
|
+
|
19
|
+
### bullet
|
20
|
+
|
21
|
+
* mmm
|
22
|
+
* nnnnn
|
23
|
+
* ooo
|
24
|
+
|
25
|
+
### quote
|
26
|
+
|
27
|
+
> pppp
|
28
|
+
> qqqq
|
29
|
+
> rrrr
|
30
|
+
>
|
31
|
+
> inlines are ignored **sss** ttt __uuu__
|
32
|
+
|
33
|
+
### verbatim
|
34
|
+
|
35
|
+
before verbatim.
|
36
|
+
|
37
|
+
yyyy
|
38
|
+
zzzz
|
39
|
+
1111
|
40
|
+
|
41
|
+
this is verbatim
|
42
|
+
2222
|
43
|
+
this is verbatim
|
44
|
+
|
45
|
+
after verbatim.
|
46
|
+
|
47
|
+
### Horizontal Rule
|
48
|
+
|
49
|
+
|
50
|
+
- - - - -
|
51
|
+
|
@@ -0,0 +1,199 @@
|
|
1
|
+
%% name = TinyMarkdown::Parser
|
2
|
+
%% ast-location = ::TinyMarkdown
|
3
|
+
%% document = ast DocumentNode(compiler, position, content)
|
4
|
+
%% para = ast ParaNode(compiler, position, content)
|
5
|
+
%% plain = ast PlainNode(compiler, position, content)
|
6
|
+
%% text = ast TextNode(compiler, position, content)
|
7
|
+
%% headline = ast HeadlineNode(compiler, position, level, content)
|
8
|
+
%% block_quote = ast BlockQuoteNode(compiler, position, content)
|
9
|
+
%% verbatim = ast VerbatimNode(compiler, position, content)
|
10
|
+
%% horizontal_rule = ast HorizontalRuleNode(compiler, position)
|
11
|
+
%% bullet_list = ast BulletListNode(compiler, position, content)
|
12
|
+
%% list = ast ListNode(compiler, position, content)
|
13
|
+
%% bullet_list_item = ast BulletListItemNode(compiler, position, content)
|
14
|
+
%% linebreak = ast LineBreakNode(compiler, position)
|
15
|
+
%% inline_element = ast InlineElementNode(compiler, position, name, content)
|
16
|
+
|
17
|
+
%% {
|
18
|
+
attr_reader :ast
|
19
|
+
|
20
|
+
class Position
|
21
|
+
attr_accessor :pos, :line, :col
|
22
|
+
def initialize(compiler)
|
23
|
+
@pos = compiler.pos
|
24
|
+
@line = compiler.current_line
|
25
|
+
@col = compiler.current_column
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def position
|
30
|
+
Position.new(self)
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
root = Start
|
35
|
+
|
36
|
+
Start = &. Doc:c { @ast = c }
|
37
|
+
|
38
|
+
Doc = Block*:c
|
39
|
+
~document(self, position, c)
|
40
|
+
|
41
|
+
Block = BlankLine*
|
42
|
+
( BlockQuote
|
43
|
+
| Verbatim
|
44
|
+
| HorizontalRule
|
45
|
+
| Heading
|
46
|
+
| BulletList
|
47
|
+
| Para
|
48
|
+
| Plain )
|
49
|
+
|
50
|
+
Para = NonindentSpace Inlines:a BlankLine+ ~para(self, position, a)
|
51
|
+
|
52
|
+
Plain = Inlines:a ~plain(self, position, a)
|
53
|
+
|
54
|
+
AtxInline = !Newline !(Sp '#'* Sp Newline) Inline:c { c }
|
55
|
+
|
56
|
+
AtxStart = < /######|#####|####|###|##|#/ > { text.length }
|
57
|
+
|
58
|
+
AtxHeading = AtxStart:level Sp AtxInline+:c (Sp "#"* Sp)? Newline ~headline(self, position, level, c)
|
59
|
+
|
60
|
+
Heading = AtxHeading
|
61
|
+
|
62
|
+
BlockQuote = BlockQuoteRaw:c ~block_quote(self, position, c)
|
63
|
+
|
64
|
+
BlockQuoteRaw = ( '>' ' '? Line:c { c })+:cc { cc }
|
65
|
+
|
66
|
+
NonblankIndentedLine = !BlankLine IndentedLine:c { c }
|
67
|
+
|
68
|
+
VerbatimChunk = (BlankLine { text(self,position,"\n") } )*:c1
|
69
|
+
(NonblankIndentedLine:c { [c, text(self,position,"\n")] })+:c2 { c1 + c2.flatten }
|
70
|
+
|
71
|
+
Verbatim = VerbatimChunk+:cc ~verbatim(self, position, cc.flatten)
|
72
|
+
|
73
|
+
HorizontalRule = NonindentSpace
|
74
|
+
( '*' Sp '*' Sp '*' (Sp '*')*
|
75
|
+
| '-' Sp '-' Sp '-' (Sp '-')*
|
76
|
+
| '_' Sp '_' Sp '_' (Sp '_')*)
|
77
|
+
Sp Newline BlankLine+ ~horizontal_rule(self, position)
|
78
|
+
|
79
|
+
Bullet = !HorizontalRule NonindentSpace ('+' | '*' | '-') Spacechar+
|
80
|
+
|
81
|
+
BulletList = &Bullet ListTight:c ~bullet_list(self, position, c)
|
82
|
+
|
83
|
+
ListTight = ListItemTight+:cc
|
84
|
+
BlankLine* !Bullet
|
85
|
+
{ cc }
|
86
|
+
|
87
|
+
ListItemTight = Bullet ListBlock:c ~bullet_list_item(self, position, c)
|
88
|
+
|
89
|
+
ListBlock = !BlankLine Line:c ListBlockLine*:cc { cc.unshift(c) }
|
90
|
+
|
91
|
+
ListBlockLine = !BlankLine
|
92
|
+
!( Indent? Bullet )
|
93
|
+
!HorizontalRule
|
94
|
+
OptionallyIndentedLine
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
Inlines = ( !Endline Inline:c { c }
|
99
|
+
| Endline:c &Inline { c } )+:cc Endline?
|
100
|
+
{ cc }
|
101
|
+
|
102
|
+
Inline = Str
|
103
|
+
| Endline
|
104
|
+
| Space
|
105
|
+
| Strong
|
106
|
+
| Emph
|
107
|
+
| Code
|
108
|
+
| Symbol
|
109
|
+
|
110
|
+
Space = Spacechar+:c ~text(self, position, c.join(""))
|
111
|
+
|
112
|
+
Str = NormalChar+:c1
|
113
|
+
StrChunk*:c2
|
114
|
+
~text(self, position, (c1+c2).join(""))
|
115
|
+
|
116
|
+
StrChunk = (NormalChar:c { [c] } | '_'+:c1 NormalChar:c2 { c1.push(c2) } )+:cc { cc.flatten }
|
117
|
+
|
118
|
+
|
119
|
+
Endline = LineBreak | TerminalEndline | NormalEndline
|
120
|
+
|
121
|
+
NormalEndline = Sp Newline !BlankLine !'>' !AtxStart
|
122
|
+
!(Line ('='+ | '-'+) Newline)
|
123
|
+
~text(self, position, "\n")
|
124
|
+
|
125
|
+
TerminalEndline = Sp Newline Eof ~text(self, position, "\n")
|
126
|
+
|
127
|
+
LineBreak = " " NormalEndline ~linebreak(self, position)
|
128
|
+
|
129
|
+
Symbol = SpecialChar:c ~text(self, position, c)
|
130
|
+
|
131
|
+
|
132
|
+
Emph = EmphStar | EmphUl
|
133
|
+
|
134
|
+
Whitespace = Spacechar | Newline
|
135
|
+
|
136
|
+
EmphStar = '*' !Whitespace
|
137
|
+
( !'*' Inline:b { b }
|
138
|
+
| StrongStar:b { b }
|
139
|
+
)+:c
|
140
|
+
'*'
|
141
|
+
~inline_element(self, position, :em, c)
|
142
|
+
|
143
|
+
EmphUl = '_' !Whitespace
|
144
|
+
( !'_' Inline:b { b }
|
145
|
+
| StrongUl:b { b }
|
146
|
+
)+:c
|
147
|
+
'_'
|
148
|
+
~inline_element(self, position, :em, c)
|
149
|
+
|
150
|
+
Strong = StrongStar | StrongUl
|
151
|
+
|
152
|
+
StrongStar = "**" !Whitespace
|
153
|
+
( !"**" Inline:b { b })+:c
|
154
|
+
"**"
|
155
|
+
~inline_element(self, position, :strong, c)
|
156
|
+
|
157
|
+
StrongUl = "__" !Whitespace
|
158
|
+
( !"__" Inline:b { b })+:c
|
159
|
+
"__"
|
160
|
+
~inline_element(self, position, :strong, c)
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
Ticks1 = < /`/ > !'`' { text }
|
165
|
+
Ticks2 = < /``/ > !'`' { text }
|
166
|
+
|
167
|
+
Code = ( Ticks1 Sp
|
168
|
+
( !'`' Nonspacechar )+:c
|
169
|
+
Sp Ticks1 ~text(self, position, c.join(""))
|
170
|
+
| Ticks2 Sp
|
171
|
+
( !'``' Nonspacechar )+:c
|
172
|
+
Sp Ticks2 ~text(self, position, c.join(""))
|
173
|
+
):cc
|
174
|
+
~inline_element(self, position, :code, [cc])
|
175
|
+
|
176
|
+
|
177
|
+
BlankLine = Sp Newline
|
178
|
+
|
179
|
+
Quoted = '"' (!'"' .)* '"' | '\'' (!'\'' .)* '\''
|
180
|
+
Eof = !.
|
181
|
+
Spacechar = < / |\t/ > { text }
|
182
|
+
Nonspacechar = !Spacechar !Newline <.> { text }
|
183
|
+
Newline = "\n" | "\r" "\n"?
|
184
|
+
Sp = Spacechar*
|
185
|
+
Spnl = Sp (Newline Sp)?
|
186
|
+
##SpecialChar = '~' | '*' | '_' | '`' | '&' | '[' | ']' | '(' | ')' | '<' | '!' | '#' | "\\" | "'" | '"'
|
187
|
+
SpecialChar = < /[~*_`&\[\]()<!#\\'"]/ > { text }
|
188
|
+
NormalChar = !( SpecialChar | Spacechar | Newline ) <.> { text }
|
189
|
+
AlphanumericAscii = < /[A-Za-z0-9]/ > { text }
|
190
|
+
Digit = < /[0-9]/ > { text }
|
191
|
+
|
192
|
+
NonindentSpace = < / | | |/ > { text }
|
193
|
+
Indent = < /\t| / > { text }
|
194
|
+
IndentedLine = Indent Line:c { c }
|
195
|
+
OptionallyIndentedLine = Indent? Line
|
196
|
+
|
197
|
+
Line = RawLine:c { c }
|
198
|
+
RawLine = (( < /[^\r\n]*/ > ) Newline { text } | < /.+/ > Eof { text }):c ~text(self, position, c)
|
199
|
+
|