nora_mark 0.2beta7 → 0.2beta8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +149 -73
- data/Rakefile +1 -3
- data/bin/nora2html +1 -1
- data/emacs-mode/noramark-mode.el +497 -0
- data/example/koujin.nora +13 -0
- data/example/nora-simple.css +27 -2
- data/example/noramark-reference-ja.nora +446 -64
- data/example/noramark-reference-ja_00001.xhtml +485 -85
- data/lib/nora_mark.rb +5 -67
- data/lib/nora_mark/document.rb +89 -0
- data/lib/nora_mark/extensions.rb +26 -0
- data/lib/nora_mark/html/context.rb +2 -3
- data/lib/nora_mark/html/default_transformer.rb +151 -0
- data/lib/nora_mark/html/generator.rb +25 -149
- data/lib/nora_mark/html/paragraph_writer.rb +4 -4
- data/lib/nora_mark/html/tag_writer.rb +13 -10
- data/lib/nora_mark/node.rb +196 -72
- data/lib/nora_mark/node_set.rb +13 -0
- data/lib/nora_mark/node_util.rb +29 -16
- data/lib/nora_mark/parser.kpeg +210 -74
- data/lib/nora_mark/parser.kpeg.rb +1353 -401
- data/lib/nora_mark/parser.rb +1 -1
- data/lib/nora_mark/transformer.rb +35 -10
- data/lib/nora_mark/version.rb +1 -1
- data/nora_mark.gemspec +3 -2
- data/spec/node_spec.rb +280 -0
- data/spec/nora_mark_spec.rb +1189 -1025
- data/spec/spec_helper.rb +2 -0
- data/spec/transformer_spec.rb +37 -0
- metadata +27 -6
- data/lib/nora_mark/html/writer_selector.rb +0 -24
- data/lib/nora_mark/node_builder.rb +0 -18
data/lib/nora_mark/node_set.rb
CHANGED
@@ -2,6 +2,7 @@ module NoraMark
|
|
2
2
|
class NodeSet
|
3
3
|
include Enumerable
|
4
4
|
def initialize(list = [])
|
5
|
+
list = list.to_ary if list.is_a? NodeSet
|
5
6
|
@list = list
|
6
7
|
end
|
7
8
|
|
@@ -20,5 +21,17 @@ module NoraMark
|
|
20
21
|
def to_ary
|
21
22
|
@list.dup
|
22
23
|
end
|
24
|
+
|
25
|
+
def first
|
26
|
+
@list.first
|
27
|
+
end
|
28
|
+
|
29
|
+
def last
|
30
|
+
@list.last
|
31
|
+
end
|
32
|
+
|
33
|
+
def text
|
34
|
+
@list.inject('') {|r,n| r << n.text }
|
35
|
+
end
|
23
36
|
end
|
24
37
|
end
|
data/lib/nora_mark/node_util.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module NoraMark
|
2
2
|
module NodeUtil
|
3
|
-
def _node(klass, name,
|
3
|
+
def _node(klass, name, children_ = nil, ids: [], children: nil, classes: [], params: [], n: {}, attrs: [], template: nil, class_if_empty: nil, line_no: nil, body_empty: nil, raw_text: nil)
|
4
4
|
children_arg = children || children_
|
5
5
|
if !children_arg.nil?
|
6
6
|
children_arg = children_arg.to_ary if children_arg.kind_of? NodeSet
|
@@ -8,31 +8,44 @@ module NoraMark
|
|
8
8
|
children_arg = children_arg.map { |node| (node.is_a? String) ? Text.new(node, 0) : node }
|
9
9
|
end
|
10
10
|
if !template.nil?
|
11
|
-
node = klass.new(name, template.ids, template.classes, template.
|
12
|
-
node.ids = (node.ids ||[] + ids) if
|
13
|
-
node.classes = (node.classes || [])
|
14
|
-
node.
|
15
|
-
node.
|
16
|
-
|
11
|
+
node = klass.new(name, template.ids, template.classes, template.params, template.n, template.children, template.line_no)
|
12
|
+
node.ids = (node.ids ||[] + ids) if ids.size > 0
|
13
|
+
node.classes = (node.classes || [])
|
14
|
+
node.classes = node.classes + classes
|
15
|
+
if node.classes.size == 0 && class_if_empty
|
16
|
+
node.classes << class_if_empty
|
17
|
+
end
|
18
|
+
node.params = params if params.size > 0
|
19
|
+
node.n = n if n.size > 0
|
20
|
+
node.children = children_arg if !children_arg.nil?
|
21
|
+
node.attrs = template.attrs || attrs || {}
|
17
22
|
else
|
18
|
-
node = klass.new(name, ids, classes,
|
19
|
-
node.
|
23
|
+
node = klass.new(name, ids, classes || [], params, n, children_arg, 0)
|
24
|
+
node.attrs = attrs || {}
|
25
|
+
if node.classes.size == 0 && class_if_empty
|
26
|
+
node.classes << class_if_empty
|
27
|
+
end
|
20
28
|
end
|
29
|
+
node.line_no = line_no
|
30
|
+
node.body_empty = body_empty
|
31
|
+
node.raw_text = raw_text
|
32
|
+
node.reparent
|
21
33
|
node
|
22
34
|
end
|
23
35
|
|
24
|
-
def block(
|
25
|
-
_node(Block,
|
36
|
+
def block(*args)
|
37
|
+
_node(Block, *args)
|
26
38
|
end
|
27
39
|
|
28
|
-
def
|
29
|
-
|
40
|
+
def inline(*args)
|
41
|
+
_node(Inline, *args)
|
30
42
|
end
|
31
43
|
|
32
|
-
def
|
33
|
-
|
44
|
+
def text value, raw_text: nil
|
45
|
+
text = Text.new(value, 0)
|
46
|
+
text.raw_text = raw_text
|
47
|
+
text
|
34
48
|
end
|
35
49
|
|
36
|
-
|
37
50
|
end
|
38
51
|
end
|
data/lib/nora_mark/parser.kpeg
CHANGED
@@ -1,24 +1,28 @@
|
|
1
1
|
%% name = NoraMark::Parser
|
2
|
-
|
2
|
+
%% {
|
3
|
+
PARAMETER_END = /[,)]/
|
4
|
+
}
|
3
5
|
%% ast-location = ::NoraMark
|
4
6
|
%% text = ast Text(content, line_no)
|
5
|
-
%%
|
6
|
-
%%
|
7
|
+
%% code_inline = ast CodeInline(ids, classes, params, named_params, content, line_no)
|
8
|
+
%% paragraph = ast Paragraph(ids, classes, params, named_params, raw_content, line_no)
|
9
|
+
%% paragraph_group = ast ParagraphGroup(ids, classes, params,named_params, raw_content, line_no)
|
7
10
|
%% br = ast Breakline(line_no)
|
8
|
-
%% block = ast Block(name, ids, classes,
|
9
|
-
%% newpage = ast Newpage(ids, classes,
|
10
|
-
%% inline = ast Inline(name, ids, classes,
|
11
|
-
%% ul_item = ast UlItem(ids, classes,
|
12
|
-
%% unordered_list = ast UnorderedList(ids, classes,
|
13
|
-
%% ol_item = ast OlItem(ids, classes,
|
14
|
-
%% ordered_list = ast OrderedList(ids, classes,
|
15
|
-
%% dl_item = ast DLItem(ids, classes,
|
16
|
-
%% definition_list = ast DefinitionList(ids, classes,
|
17
|
-
%% preformatted_block = ast PreformattedBlock(name, ids, classes,
|
11
|
+
%% block = ast Block(name, ids, classes, params, named_params, raw_content, line_no)
|
12
|
+
%% newpage = ast Newpage(ids, classes, params, named_params, raw_content, line_no)
|
13
|
+
%% inline = ast Inline(name, ids, classes, params, named_params, raw_content, line_no)
|
14
|
+
%% ul_item = ast UlItem(ids, classes, params, named_params, raw_content, line_no)
|
15
|
+
%% unordered_list = ast UnorderedList(ids, classes, params, named_params, raw_content, line_no)
|
16
|
+
%% ol_item = ast OlItem(ids, classes, params, named_params, raw_content, line_no)
|
17
|
+
%% ordered_list = ast OrderedList(ids, classes, params,named_params, raw_content, line_no)
|
18
|
+
%% dl_item = ast DLItem(ids, classes, params, named_params, raw_content, line_no)
|
19
|
+
%% definition_list = ast DefinitionList(ids, classes, params, named_params, raw_content, line_no)
|
20
|
+
%% preformatted_block = ast PreformattedBlock(name, ids, classes, params, named_params, codelanguage, content, line_no)
|
18
21
|
%% frontmatter = ast Frontmatter(content, line_no)
|
19
|
-
%% h_section = ast HeadedSection(level, heading,
|
20
|
-
%% page = ast Page(
|
21
|
-
%% root = ast Root(
|
22
|
+
%% h_section = ast HeadedSection(level, heading, params, named_params, raw_content, line_no)
|
23
|
+
%% page = ast Page(raw_content, line_no)
|
24
|
+
%% root = ast Root(raw_content)
|
25
|
+
|
22
26
|
|
23
27
|
# line number
|
24
28
|
ln = { current_line }
|
@@ -27,14 +31,14 @@ ln = { current_line }
|
|
27
31
|
BOM = /\uFEFF/
|
28
32
|
Eof = !.
|
29
33
|
Space = ' ' | '\t'
|
30
|
-
EofComment = Space* "#" (!Eof .)*
|
31
|
-
Comment = Space* "#" (!Nl .)* Nl EmptyLine*
|
32
34
|
- = Space*
|
35
|
+
EofComment = - "//" (!Eof .)*
|
36
|
+
Comment = - "//" (!Nl .)* Nl EmptyLine*
|
33
37
|
EmptyLine = /^/ - (Nl | Comment | EofComment)
|
34
38
|
|
35
39
|
Nl = /\r?\n/
|
36
40
|
Le = Nl | Eof
|
37
|
-
Word = < /[\
|
41
|
+
Word = < /[\w]/ ( '-' | /[\w]/ )* > { text }
|
38
42
|
Num = < [0-9]+ > { text.to_i }
|
39
43
|
|
40
44
|
#common syntax
|
@@ -43,10 +47,11 @@ ClassNames = (ClassName)*:classnames { classnames }
|
|
43
47
|
IdName = '#' Word:idname { idname }
|
44
48
|
IdNames = (IdName)*:idnames { idnames }
|
45
49
|
|
46
|
-
CommandName = Word:name IdNames?:idnames ClassNames?:classes ln:ln
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
+
CommandName = Word:name IdNames?:idnames ClassNames?:classes ln:ln
|
51
|
+
{ {name: name, ids: idnames, classes: classes, ln:ln } }
|
52
|
+
ParameterNormal = DocumentContentExcept(PARAMETER_END):content { content }
|
53
|
+
ParameterQuoted = '"' DocumentContentExcept('"'):content '"' - &/[,)]/ { content }
|
54
|
+
ParameterSingleQuoted = "'" DocumentContentExcept("'"):content "'" - &/[,)]/ { content }
|
50
55
|
Parameter = (ParameterQuoted
|
51
56
|
| ParameterSingleQuoted
|
52
57
|
| ParameterNormal ):value { value }
|
@@ -65,79 +70,163 @@ NamedParameter = Word:key - ':' - NParameter:parameter { { key.to_sym => paramet
|
|
65
70
|
NamedParameters = NamedParameter:parameter - ',' - NamedParameters:parameters { parameter.merge parameters }
|
66
71
|
| NamedParameter:parameter { parameter }
|
67
72
|
|
68
|
-
Command = CommandName:cn
|
73
|
+
Command = CommandName:cn
|
74
|
+
('(' - Parameters:args - ')')?
|
75
|
+
('[' - NamedParameters:named_args - ']')?
|
76
|
+
{ cn.merge({ args: args || [] , named_args: named_args || {}}) }
|
69
77
|
|
70
78
|
# paragraph
|
71
|
-
ImplicitParagraph =
|
79
|
+
ImplicitParagraph = - !ParagraphDelimiter
|
80
|
+
Comment*
|
81
|
+
DocumentLine:content ln:ln
|
82
|
+
Comment* EofComment?
|
83
|
+
~paragraph([],[], [], {}, content, ln)
|
72
84
|
|
73
85
|
# explicit paragraph
|
74
86
|
ExplicitParagraphCommand = Command:c &{ c[:name] == 'p' }
|
75
|
-
ExplicitParagraph = - ExplicitParagraphCommand:c ':' -
|
87
|
+
ExplicitParagraph = - ExplicitParagraphCommand:c ':' -
|
88
|
+
DocumentContent?:content Le EmptyLine*
|
89
|
+
~paragraph(c[:ids], c[:classes], c[:args], c[:named_args], content, c[:ln])
|
76
90
|
|
77
91
|
Paragraph = ExplicitParagraph | ImplicitParagraph
|
78
92
|
|
79
93
|
# paragraph_group
|
80
|
-
ParagraphGroup = ln:ln
|
94
|
+
ParagraphGroup = ln:ln
|
95
|
+
Paragraph+:p
|
96
|
+
EmptyLine*
|
97
|
+
~paragraph_group([],[],[],{},p, ln)
|
81
98
|
|
82
99
|
# explicit block
|
83
100
|
BlockHead = Command:command - '{' - Nl EmptyLine* { command }
|
84
101
|
BlockEnd = - '}' - Le EmptyLine*
|
85
102
|
BlockBody = (!BlockEnd Block)+:body { body }
|
86
|
-
ExplicitBlock = -
|
103
|
+
ExplicitBlock = - BlockHead:c -
|
104
|
+
BlockBody:content -
|
105
|
+
BlockEnd
|
106
|
+
~block(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], content, c[:ln])
|
87
107
|
|
88
108
|
# preformatted block
|
89
109
|
PreformattedCommand = Command:command &{ ['pre', 'code'].include? command[:name] }
|
90
|
-
PreformattedCommandHeadSimple =
|
91
|
-
|
92
|
-
|
110
|
+
PreformattedCommandHeadSimple =
|
111
|
+
PreformattedCommand:command -
|
112
|
+
'{' - Nl
|
113
|
+
{ command }
|
114
|
+
PreformattedCommandHeadComplex =
|
115
|
+
PreformattedCommand:command -
|
116
|
+
'{//' Word?:codelanguage - Nl
|
117
|
+
{ command.merge({codelanguage: codelanguage}) }
|
118
|
+
PreformattedFence = - "```" Word?:codelanguage
|
119
|
+
('(' - Parameters:args - ')')?
|
120
|
+
('[' - NamedParameters:named_args - ']')? - Nl
|
121
|
+
{ {codelanguage: codelanguage,
|
122
|
+
args: args || [],
|
123
|
+
named_args: named_args || {} } }
|
124
|
+
|
125
|
+
PreformattedCommandHead = PreformattedCommandHeadComplex |
|
126
|
+
PreformattedCommandHeadSimple |
|
127
|
+
PreformattedFence
|
93
128
|
PreformatEndSimple = - '}' - Le EmptyLine*
|
94
129
|
PreformatEndComplex = - '//}' - Le EmptyLine*
|
95
130
|
|
96
|
-
PreformattedBlockSimple = -
|
97
|
-
|
131
|
+
PreformattedBlockSimple = - PreformattedCommandHeadSimple:c
|
132
|
+
(!PreformatEndSimple (CharString Nl))+:content
|
133
|
+
PreformatEndSimple
|
134
|
+
~preformatted_block(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], c[:codelanguage], content, c[:ln])
|
98
135
|
|
99
|
-
PreformattedBlockComplex = - PreformattedCommandHeadComplex:c
|
100
|
-
|
136
|
+
PreformattedBlockComplex = - PreformattedCommandHeadComplex:c
|
137
|
+
(!PreformatEndComplex (CharString Nl))+:content
|
138
|
+
PreformatEndComplex
|
139
|
+
~preformatted_block(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], c[:codelanguage], content, c[:ln])
|
101
140
|
|
102
|
-
|
141
|
+
PreformattedBlockFence = - ln:ln PreformattedFence:c
|
142
|
+
(!"```" CharString Nl)+:content
|
143
|
+
- "```" - Le EmptyLine*
|
144
|
+
~preformatted_block('code', [], [], c[:args], c[:named_args], c[:codelanguage], content, ln)
|
145
|
+
|
146
|
+
PreformattedBlock = PreformattedBlockComplex |
|
147
|
+
PreformattedBlockSimple |
|
148
|
+
PreformattedBlockFence
|
103
149
|
|
104
150
|
# inline command
|
105
|
-
Inline = ImgInline | CommonInline
|
106
|
-
CommonInline = '[' Command:c
|
151
|
+
Inline = EscapedChar | ImgInline | MediaInline | CodeInline | CommonInline | FenceInline
|
152
|
+
CommonInline = '[' Command:c
|
153
|
+
'{' - DocumentContentExcept('}'):content '}'
|
154
|
+
']'
|
155
|
+
~inline(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], content, c[:ln])
|
156
|
+
|
107
157
|
ImgCommand = Command:c &{ c[:name] == 'img' && c[:args].size == 2}
|
108
|
-
ImgInline = '[' ImgCommand:c ']'
|
158
|
+
ImgInline = '[' ImgCommand:c ']'
|
159
|
+
~inline(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], nil, c[:ln])
|
160
|
+
|
161
|
+
MediaCommand
|
162
|
+
= Command:c &{ (c[:name] == 'video' || c[:name] == 'audio') && c[:args].size > 0}
|
163
|
+
MediaInline
|
164
|
+
= '[' MediaCommand:c
|
165
|
+
('{' - DocumentContentExcept('}'):content '}')?
|
166
|
+
']'
|
167
|
+
~inline(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], content, c[:ln])
|
168
|
+
|
169
|
+
FenceInline = '`' ln:ln CharStringExcept('`'):content '`' ~code_inline([], [], [], {}, content, ln)
|
170
|
+
CodeCommand = Command:c &{ c[:name] == 'code' }
|
171
|
+
CodeInline = '[' CodeCommand:c
|
172
|
+
'{' - CharStringExcept('}'):content '}'
|
173
|
+
']'
|
174
|
+
~code_inline(c[:ids], c[:classes], c[:args], c[:named_args], content, c[:ln])
|
175
|
+
|
176
|
+
|
177
|
+
EscapedChar = "\\" < /[`]/ > ln:ln ~text(text, ln)
|
178
|
+
|
109
179
|
|
110
180
|
# special line commands
|
111
181
|
CommandNameForSpecialLineCommand = NewpageCommand | ExplicitParagraphCommand
|
112
182
|
|
113
183
|
# newpage
|
114
184
|
NewpageCommand = Command:command &{ command[:name] == 'newpage' }
|
115
|
-
Newpage = -
|
185
|
+
Newpage = - NewpageCommand:c ':' -
|
186
|
+
DocumentContent?:content - Nl
|
187
|
+
~newpage(c[:ids],c[:classes],c[:args], c[:named_args], content, c[:ln])
|
116
188
|
|
117
189
|
|
118
190
|
# unordered list
|
119
|
-
|
120
|
-
|
121
|
-
|
191
|
+
UnorderedStart(n) = /^/ - < (/\*+/) > &{ text.length == n && text.size < 5 }
|
192
|
+
UnorderedList(n) = ln:ln UnorderedItem(n)+:items ~unordered_list([],[],[],{}, items, ln)
|
193
|
+
UnorderedItem(n) = UnorderedStart(n) ln:ln -
|
194
|
+
UnorderedItemBody(n):content
|
195
|
+
~ul_item([], [], [], {}, content, ln)
|
196
|
+
|
197
|
+
UnorderedItemBody(n) = DocumentContent:content Nl
|
198
|
+
- &UnorderedStart(n + 1) ln:ln UnorderedList(n + 1):sub_ul
|
199
|
+
{ content << sub_ul }
|
200
|
+
| DocumentContent:content Le { content }
|
122
201
|
# ordered list
|
123
|
-
OrderedList = ln:ln OrderedItem+:items ~ordered_list([],[],[],
|
124
|
-
OrderedItem = ln:ln Num '
|
202
|
+
OrderedList = ln:ln OrderedItem+:items ~ordered_list([],[],[], {}, items, ln)
|
203
|
+
OrderedItem = - ln:ln Num '.' - DocumentContent:content Le ~ol_item([], [], [], {}, content, ln)
|
125
204
|
|
126
205
|
# definition list
|
127
|
-
DefinitionList = ln:ln DefinitionItem+:items ~definition_list([], [], [],
|
128
|
-
DefinitionItem = - ln:ln
|
206
|
+
DefinitionList = ln:ln DefinitionItem+:items ~definition_list([], [], [], {}, items, ln)
|
207
|
+
DefinitionItem = - ln:ln - ';:' -
|
208
|
+
DocumentContentExcept(':'):term ':' -
|
209
|
+
DocumentContent:definition Le
|
210
|
+
~dl_item([], [], [term], {}, definition, ln)
|
129
211
|
|
130
212
|
# long definition list
|
131
|
-
LongDefinitionList = ln:ln LongDefinitionItem+:items
|
132
|
-
|
133
|
-
|
134
|
-
|
213
|
+
LongDefinitionList = ln:ln LongDefinitionItem+:items
|
214
|
+
~definition_list([], [], [], {}, items, ln)
|
215
|
+
LongDefinitionItem = - ln:ln ';:' -
|
216
|
+
DocumentContentExcept('{'):term '{' - Nl
|
217
|
+
- BlockBody:definition -
|
218
|
+
BlockEnd
|
219
|
+
~dl_item([], [], [term], {}, definition, ln)
|
220
|
+
|
221
|
+
ItemsList = (UnorderedList(1)
|
135
222
|
| OrderedList
|
136
223
|
| DefinitionList
|
137
224
|
| LongDefinitionList)
|
138
225
|
|
139
226
|
# generic line command
|
140
|
-
LineCommand = - !CommandNameForSpecialLineCommand Command:c ':' -
|
227
|
+
LineCommand = - !CommandNameForSpecialLineCommand Command:c ':' -
|
228
|
+
DocumentContent?:content - Le EmptyLine*
|
229
|
+
~block(c[:name], c[:ids], c[:classes], c[:args], c[:named_args], content, c[:ln])
|
141
230
|
|
142
231
|
# blocks
|
143
232
|
LineBlock = ItemsList | LineCommand
|
@@ -151,37 +240,80 @@ Block =
|
|
151
240
|
{block}
|
152
241
|
|
153
242
|
BlockDelimiter = BlockHead | BlockEnd
|
154
|
-
ParagraphDelimiter = BlockDelimiter |
|
243
|
+
ParagraphDelimiter = BlockDelimiter |
|
244
|
+
PreformattedCommandHead |
|
245
|
+
LineBlock |
|
246
|
+
Newpage |
|
247
|
+
HeadedStart
|
155
248
|
|
156
249
|
# markdown-style headings
|
157
|
-
HStartMark(n) = < '
|
158
|
-
HMarkupTerminator(n) = - < '
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
250
|
+
HStartMark(n) = - < '#'+ > &{ text.length == n }
|
251
|
+
HMarkupTerminator(n) = - < '#'+ > - CharString:cs Le
|
252
|
+
&{ text.length <= n && !cs.strip.end_with?('{') } |
|
253
|
+
- Eof
|
254
|
+
HStartCommand(n)
|
255
|
+
= - HStartMark(n)
|
256
|
+
('(' - Parameters:args - ')')?
|
257
|
+
('[' - NamedParameters:named_args - ']')?
|
258
|
+
{ { args: args || [] , named_args: named_args || {}} }
|
259
|
+
|
260
|
+
HStart(n) =
|
261
|
+
- HStartCommand(n):hsc
|
262
|
+
ln:ln - DocumentContent:s Le { hsc.merge({ level: n, heading: s, ln: ln}) }
|
263
|
+
|
264
|
+
HSection(n) = HStart(n):h
|
265
|
+
EmptyLine*
|
266
|
+
(!HMarkupTerminator(n) Block)*:content
|
267
|
+
EmptyLine*
|
268
|
+
~h_section(h[:level], h[:heading], h[:args], h[:named_args], content, h[:ln])
|
269
|
+
|
270
|
+
BlockHStart(n) = - HStartCommand(n):hsc ln:ln -
|
271
|
+
DocumentContentExcept('{'):s - '{' - Nl
|
272
|
+
{ hsc.merge({ level: n, heading: s, ln: ln}) }
|
273
|
+
ExplicitHSection(n) = BlockHStart(n):h
|
274
|
+
EmptyLine* -
|
275
|
+
BlockBody:content -
|
276
|
+
BlockEnd
|
277
|
+
~h_section(h[:level], h[:heading], h[:args], h[:named_args], content, h[:ln])
|
278
|
+
|
279
|
+
HeadedStart = HStart(6)
|
167
280
|
| HStart(5)
|
168
|
-
| HStart(
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
281
|
+
| HStart(4)
|
282
|
+
| HStart(3)
|
283
|
+
| HStart(2)
|
284
|
+
| HStart(1)
|
285
|
+
| BlockHStart(6)
|
286
|
+
| BlockHStart(5)
|
287
|
+
| BlockHStart(4)
|
288
|
+
| BlockHStart(3)
|
289
|
+
| BlockHStart(2)
|
290
|
+
| BlockHStart(1)
|
291
|
+
|
292
|
+
HeadedSection = ExplicitHSection(6)
|
293
|
+
| ExplicitHSection(5)
|
294
|
+
| ExplicitHSection(4)
|
295
|
+
| ExplicitHSection(3)
|
296
|
+
| ExplicitHSection(2)
|
297
|
+
| ExplicitHSection(1)
|
175
298
|
| HSection(6)
|
299
|
+
| HSection(5)
|
300
|
+
| HSection(4)
|
301
|
+
| HSection(3)
|
302
|
+
| HSection(2)
|
303
|
+
| HSection(1)
|
176
304
|
|
177
305
|
# frontmatter
|
178
306
|
FrontmatterSeparator = - '---' - Nl
|
179
|
-
Frontmatter = FrontmatterSeparator ln:ln
|
307
|
+
Frontmatter = FrontmatterSeparator ln:ln
|
308
|
+
(!FrontmatterSeparator ( CharString Nl))+:yaml
|
309
|
+
FrontmatterSeparator EmptyLine*
|
310
|
+
~frontmatter(yaml, ln)
|
180
311
|
|
181
312
|
# texts
|
182
313
|
Char = < /[[:print:]]/ > { text }
|
183
314
|
CharString = < Char* > { text }
|
184
|
-
CharExcept(e) = Char:c &{ c
|
315
|
+
CharExcept(e) = Char:c &{ e.is_a?(Regexp) ? e !~ c : e != c }
|
316
|
+
CharStringExcept(e) = < CharExcept(e)+ > { text }
|
185
317
|
DocumentTextExcept(e) = < (!Inline CharExcept(e))+ > ln:ln ~text(text, ln)
|
186
318
|
DocumentContentExcept(e) = (Inline | DocumentTextExcept(e))+:content { content }
|
187
319
|
DocumentText = < (!Inline Char)+ > ln:ln ~text(text, ln)
|
@@ -189,8 +321,12 @@ DocumentContent = (Inline | DocumentText)+:content { content }
|
|
189
321
|
DocumentLine = DocumentContent:content Le { content }
|
190
322
|
|
191
323
|
#page
|
192
|
-
Page = Frontmatter?:frontmatter -
|
193
|
-
|
324
|
+
Page = Frontmatter?:frontmatter -
|
325
|
+
(!Newpage Block)*:blocks
|
326
|
+
EmptyLine*
|
327
|
+
~page(([frontmatter] + blocks).select{ |x| !x.nil?}, 1)
|
328
|
+
|
329
|
+
Pages = Page:page Newpage:newpage Pages:pages { pages.unshift(page) }
|
194
330
|
| Page:page { [ page ] }
|
195
331
|
|
196
332
|
#root
|