koara 0.9.0

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.
@@ -0,0 +1,203 @@
1
+ class KoaraRenderer
2
+
3
+ def visit_document(node)
4
+ @left = Array.new
5
+ @out = StringIO.new
6
+ node.children_accept(self)
7
+ end
8
+
9
+ def visit_heading(node)
10
+ if !node.is_first_child
11
+ indent
12
+ end
13
+ node.value.times {
14
+ @out << '='
15
+ }
16
+ if node.has_children
17
+ @out << ' '
18
+ node.children_accept(self)
19
+ end
20
+ @out << "\n"
21
+ if !node.is_last_child
22
+ indent
23
+ @out << "\n"
24
+ end
25
+ end
26
+
27
+ def visit_blockquote(node)
28
+ if !node.is_first_child
29
+ indent
30
+ end
31
+ if node.has_children
32
+ @out << '> '
33
+ @left.push('> ')
34
+ node.children_accept(self)
35
+ @left.pop
36
+ else
37
+ @out << ">\n"
38
+ end
39
+ if !node.nested
40
+ @out << "\n"
41
+ end
42
+ end
43
+
44
+ def visit_list_block(node)
45
+ node.children_accept(self)
46
+ if !node.is_last_child
47
+ indent
48
+ @out << "\n"
49
+ next_node = node.next
50
+ if next_node.instance_of?(ListBlock) && next_node.ordered == node.ordered
51
+ @out << "\n"
52
+ end
53
+ end
54
+ end
55
+
56
+ def visit_list_item(node)
57
+ if !node.parent.nested || !node.is_first_child || !node.parent.is_first_child
58
+ indent
59
+ end
60
+ @left.push(' ')
61
+ if node.number
62
+ @out << node.number + '.'
63
+ else
64
+ @out << '-'
65
+ end
66
+ if node.has_children
67
+ @out << ' '
68
+ node.children_accept(self)
69
+ else
70
+ @out << "\n"
71
+ end
72
+ @left.pop
73
+ end
74
+
75
+ def visit_codeblock(node)
76
+ str = StringIO.new
77
+ @left.each { |s| str << s }
78
+ @out << '```'
79
+ if node.language
80
+ @out << node.language
81
+ end
82
+ @out << "\n"
83
+ @out << node.value.gsub(/^/, str.string)
84
+ @out << "\n"
85
+ indent
86
+ @out << '```'
87
+ @out << "\n"
88
+ if !node.is_last_child
89
+ indent
90
+ @out << "\n"
91
+ end
92
+ end
93
+
94
+ def visit_paragraph(node)
95
+ if !node.is_first_child
96
+ indent
97
+ end
98
+
99
+ node.children_accept(self)
100
+ @out << "\n"
101
+ if !node.nested || ((node.parent.instance_of?(ListItem) && node.next.instance_of?(Paragraph)) && !node.is_last_child)
102
+ @out << "\n"
103
+ elsif node.parent.instance_of?(BlockQuote) && node.next.instance_of?(Paragraph)
104
+ indent
105
+ @out << "\n"
106
+ end
107
+ end
108
+
109
+ def visit_blockelement(node)
110
+ if !node.is_first_child
111
+ indent
112
+ end
113
+ node.children_accept(self)
114
+ @out << "\n"
115
+ if !node.nested || (node.parent.instance_of? ListItem && (node.next.instance_of? Paragraph) && !node.is_last_child())
116
+ @out << "\n"
117
+ elsif node.parent.instance_of?(BlockQuote) && node.next.instance_of?(Paragraph)
118
+ indent
119
+ @out << "\n"
120
+ end
121
+ end
122
+
123
+ def visit_image(node)
124
+ @out << '[image: '
125
+ node.children_accept(self)
126
+ @out << ']'
127
+ if node.value && node.value.strip.length > 0
128
+ @out << '('
129
+ @out << escape_url(node.value)
130
+ @out << ')'
131
+ end
132
+ end
133
+
134
+ def visit_link(node)
135
+ @out << '['
136
+ node.children_accept(self)
137
+ @out << ']'
138
+ if node.value && node.value.strip.length > 0
139
+ @out << '('
140
+ @out << escape_url(node.value)
141
+ @out << ')'
142
+ end
143
+ end
144
+
145
+ def visit_text(node)
146
+ if node.parent.instance_of? Code
147
+ @out << node.value.to_s;
148
+ else
149
+ @out << escape(node.value.to_s);
150
+ end
151
+ end
152
+
153
+ def visit_strong(node)
154
+ @out << '*'
155
+ node.children_accept(self)
156
+ @out << '*'
157
+ end
158
+
159
+ def visit_em(node)
160
+ @out << '_'
161
+ node.children_accept(self)
162
+ @out << '_'
163
+ end
164
+
165
+ def visit_code(node)
166
+ @out << '`'
167
+ node.children_accept(self)
168
+ @out << '`'
169
+ end
170
+
171
+ def visit_linebreak(node)
172
+ @out << "\n"
173
+ indent
174
+ end
175
+
176
+ def escape_url(text)
177
+ return text.gsub(/\(/, "\\\\(")
178
+ .gsub(/\)/, "\\\\)")
179
+ end
180
+
181
+ def escape(text)
182
+ return text.gsub(/\[/, "\\\\[")
183
+ .gsub(/\]/, "\\\\]")
184
+ .gsub(/\*/, "\\\\*")
185
+ .gsub(/_/, "\\\\_")
186
+ .sub(/`/, "\\\\`")
187
+ .sub(/=/, "\\\\=")
188
+ .sub(/>/, "\\\\>")
189
+ .sub(/-/, "\\\\-")
190
+ .sub(/(\d+)\./) { |m| "\\#{$1}." }
191
+ end
192
+
193
+ def indent
194
+ @left.each { |s|
195
+ @out << s
196
+ }
197
+ end
198
+
199
+ def output
200
+ @out.string.strip
201
+ end
202
+
203
+ end
@@ -0,0 +1,4 @@
1
+ class LookaheadSuccess < StandardError
2
+
3
+
4
+ end
@@ -0,0 +1,2475 @@
1
+ require_relative 'charstream'
2
+ require_relative 'ast/blockelement'
3
+ require_relative 'ast/blockquote'
4
+ require_relative 'ast/code'
5
+ require_relative 'ast/codeblock'
6
+ require_relative 'ast/heading'
7
+ require_relative 'ast/paragraph'
8
+ require_relative 'ast/linebreak'
9
+ require_relative 'ast/listblock'
10
+ require_relative 'ast/listitem'
11
+ require_relative 'ast/link'
12
+ require_relative 'ast/em'
13
+ require_relative 'ast/text'
14
+ require_relative 'ast/image'
15
+ require_relative 'ast/strong'
16
+ require_relative 'io/stringreader'
17
+ require_relative 'io/filereader'
18
+ require_relative 'lookahead_success'
19
+ require_relative 'token'
20
+ require_relative 'token_manager'
21
+ require_relative 'tree_state'
22
+ require 'stringio'
23
+
24
+ class Parser
25
+ attr_reader :modules
26
+
27
+ def initialize
28
+ @current_block_level = 0
29
+ @current_quote_level = 0
30
+ @look_ahead_success = LookaheadSuccess.new
31
+ @modules = %w(paragraphs headings lists links images formatting blockquotes code)
32
+ end
33
+
34
+ def parse(text)
35
+ return parse_reader(StringReader.new(text))
36
+ end
37
+
38
+ def parse_file(file)
39
+ if File.basename(file).downcase.reverse[0,3].reverse.to_s != '.kd'
40
+ raise(ArgumentError, "Can only parse files with extension .kd")
41
+ end
42
+ parse_reader(FileReader.new(file))
43
+ end
44
+
45
+ def parse_reader(reader)
46
+ @cs = CharStream.new(reader)
47
+ @tm = TokenManager.new(@cs)
48
+ @token = Token.new
49
+ @tree = TreeState.new
50
+ @next_token_kind = -1
51
+ document = Document.new
52
+ @tree.open_scope
53
+
54
+ while get_next_token_kind == TokenManager::EOL
55
+ consume_token(TokenManager::EOL)
56
+ end
57
+ white_space
58
+ if has_any_block_elements_ahead
59
+ block_element
60
+ while block_ahead(0)
61
+ while get_next_token_kind == TokenManager::EOL
62
+ consume_token(TokenManager::EOL)
63
+ white_space
64
+ end
65
+ block_element
66
+ end
67
+ while get_next_token_kind == TokenManager::EOL
68
+ consume_token(TokenManager::EOL)
69
+ end
70
+ white_space
71
+ end
72
+ consume_token(TokenManager::EOF)
73
+ @tree.close_scope(document)
74
+ document
75
+ end
76
+
77
+ def block_element
78
+ @current_block_level += 1
79
+ if modules.include?('headings') && heading_ahead(1)
80
+ heading
81
+ elsif modules.include?('blockquotes') && get_next_token_kind == TokenManager::GT
82
+ block_quote
83
+ elsif modules.include?('lists') && get_next_token_kind == TokenManager::DASH
84
+ unordered_list
85
+ elsif modules.include?('lists') && has_ordered_list_ahead
86
+ ordered_list
87
+ elsif modules.include?('code') && has_fenced_code_block_ahead
88
+ fenced_code_block
89
+ else
90
+ paragraph
91
+ end
92
+ @current_block_level -= 1
93
+ end
94
+
95
+ def heading
96
+ heading = Heading.new
97
+ @tree.open_scope
98
+ heading_level = 0
99
+
100
+ while get_next_token_kind == TokenManager::EQ
101
+ consume_token(TokenManager::EQ)
102
+ heading_level += 1
103
+ end
104
+ white_space
105
+ while heading_has_inline_elements_ahead
106
+ if has_text_ahead
107
+ text
108
+ elsif modules.include?('images') && has_image_ahead
109
+ image
110
+ elsif modules.include?('links') && has_link_ahead
111
+ link
112
+ elsif modules.include?('formatting') && has_strong_ahead
113
+ strong
114
+ elsif modules.include?('formatting') && has_em_ahead
115
+ em
116
+ elsif modules.include?('code') && has_code_ahead
117
+ code
118
+ else
119
+ loose_char
120
+ end
121
+ end
122
+ heading.value = heading_level
123
+ @tree.close_scope(heading)
124
+ end
125
+
126
+ def block_quote
127
+ blockquote = BlockQuote.new
128
+ @tree.open_scope
129
+ @current_quote_level += 1
130
+ consume_token(TokenManager::GT)
131
+ while block_quote_has_empty_line_ahead
132
+ block_quote_empty_line
133
+ end
134
+ white_space
135
+ if block_quote_has_any_block_elements_ahead
136
+ block_element
137
+ while block_ahead(0)
138
+ while get_next_token_kind == TokenManager::EOL
139
+ consume_token(TokenManager::EOL)
140
+ white_space
141
+ block_quote_prefix
142
+ end
143
+ block_element
144
+ end
145
+ end
146
+ while has_block_quote_empty_lines_ahead
147
+ block_quote_empty_line
148
+ end
149
+ @current_quote_level -= 1
150
+ @tree.close_scope(blockquote)
151
+ end
152
+
153
+ def block_quote_prefix
154
+ i = 0
155
+ loop do
156
+ consume_token(TokenManager::GT)
157
+ white_space
158
+ i+=1
159
+ break if (i >= @current_quote_level)
160
+ end
161
+ end
162
+
163
+ def block_quote_empty_line
164
+ consume_token(TokenManager::EOL)
165
+ white_space
166
+ loop do
167
+ consume_token(TokenManager::GT)
168
+ white_space
169
+ break if (get_next_token_kind != TokenManager::GT)
170
+ end
171
+ end
172
+
173
+ def unordered_list
174
+ list = ListBlock.new(false)
175
+ @tree.open_scope
176
+ list_begin_column = unordered_list_item
177
+ while list_item_ahead(list_begin_column, false)
178
+ while get_next_token_kind == TokenManager::EOL
179
+ consume_token(TokenManager::EOL)
180
+ end
181
+ white_space
182
+ if @current_quote_level > 0
183
+ block_quote_prefix
184
+ end
185
+ unordered_list_item
186
+ end
187
+ @tree.close_scope(list)
188
+ end
189
+
190
+ def unordered_list_item
191
+ list_item = ListItem.new
192
+ @tree.open_scope
193
+
194
+ t = consume_token(TokenManager::DASH)
195
+ white_space
196
+ if list_item_has_inline_elements
197
+ block_element
198
+ while block_ahead(t.begin_column)
199
+ while get_next_token_kind == TokenManager::EOL
200
+ consume_token(TokenManager::EOL)
201
+ white_space
202
+ if @current_quote_level > 0
203
+ block_quote_prefix
204
+ end
205
+ end
206
+ block_element
207
+ end
208
+ end
209
+ @tree.close_scope(list_item)
210
+ t.begin_column
211
+ end
212
+
213
+ def ordered_list
214
+ list = ListBlock.new(true)
215
+ @tree.open_scope
216
+ list_begin_column = ordered_list_item
217
+ while list_item_ahead(list_begin_column, true)
218
+ while get_next_token_kind == TokenManager::EOL
219
+ consume_token(TokenManager::EOL)
220
+ end
221
+ white_space
222
+ if @current_quote_level > 0
223
+ block_quote_prefix
224
+ end
225
+ ordered_list_item
226
+ end
227
+ @tree.close_scope(list)
228
+ end
229
+
230
+ def ordered_list_item
231
+ list_item = ListItem.new
232
+ @tree.open_scope
233
+ t = consume_token(TokenManager::DIGITS)
234
+ consume_token(TokenManager::DOT)
235
+ white_space
236
+ if list_item_has_inline_elements
237
+ block_element
238
+ while block_ahead(t.begin_column)
239
+ while get_next_token_kind == TokenManager::EOL
240
+ consume_token(TokenManager::EOL)
241
+ white_space
242
+ if @current_quote_level > 0
243
+ block_quote_prefix
244
+ end
245
+ end
246
+ block_element
247
+ end
248
+ end
249
+ list_item.number = t.image
250
+ @tree.close_scope(list_item)
251
+ t.begin_column
252
+ end
253
+
254
+ def fenced_code_block
255
+ code_block = CodeBlock.new
256
+ @tree.open_scope
257
+ s = StringIO.new('')
258
+ begin_column = consume_token(TokenManager::BACKTICK).begin_column
259
+ loop do
260
+ consume_token(TokenManager::BACKTICK)
261
+ break if (get_next_token_kind != TokenManager::BACKTICK)
262
+ end
263
+ white_space
264
+ if get_next_token_kind == TokenManager::CHAR_SEQUENCE
265
+ code_block.language = code_language
266
+ end
267
+ if get_next_token_kind != TokenManager::EOF && !fences_ahead
268
+ consume_token(TokenManager::EOL)
269
+ level_white_space(begin_column)
270
+ end
271
+
272
+ kind = get_next_token_kind
273
+ while kind != TokenManager::EOF && ((kind != TokenManager::EOL && kind != TokenManager::BACKTICK) || !fences_ahead)
274
+
275
+ case kind
276
+ when TokenManager::CHAR_SEQUENCE
277
+ s << consume_token(TokenManager::CHAR_SEQUENCE).image
278
+ when TokenManager::ASTERISK
279
+ s << consume_token(TokenManager::ASTERISK).image
280
+ when TokenManager::BACKSLASH
281
+ s << consume_token(TokenManager::BACKSLASH).image
282
+ when TokenManager::COLON
283
+ s << consume_token(TokenManager::COLON).image
284
+ when TokenManager::DASH
285
+ s << consume_token(TokenManager::DASH).image
286
+ when TokenManager::DIGITS
287
+ s << consume_token(TokenManager::DIGITS).image
288
+ when TokenManager::DOT
289
+ s << consume_token(TokenManager::DOT).image
290
+ when TokenManager::EQ
291
+ s << consume_token(TokenManager::EQ).image
292
+ when TokenManager::ESCAPED_CHAR
293
+ s << consume_token(TokenManager::ESCAPED_CHAR).image
294
+ when TokenManager::IMAGE_LABEL
295
+ s << consume_token(TokenManager::IMAGE_LABEL).image
296
+ when TokenManager::LT
297
+ s << consume_token(TokenManager::LT).image
298
+ when TokenManager::GT
299
+ s << consume_token(TokenManager::GT).image
300
+ when TokenManager::LBRACK
301
+ s << consume_token(TokenManager::LBRACK).image
302
+ when TokenManager::RBRACK
303
+ s << consume_token(TokenManager::RBRACK).image
304
+ when TokenManager::LPAREN
305
+ s << consume_token(TokenManager::LPAREN).image
306
+ when TokenManager::RPAREN
307
+ s << consume_token(TokenManager::RPAREN).image
308
+ when TokenManager::UNDERSCORE
309
+ s << consume_token(TokenManager::UNDERSCORE).image
310
+ when TokenManager::BACKTICK
311
+ s << consume_token(TokenManager::BACKTICK).image
312
+ else
313
+ if !next_after_space(TokenManager::EOL, TokenManager::EOF)
314
+ case kind
315
+ when TokenManager::SPACE
316
+ s << consume_token(TokenManager::SPACE).image
317
+ when TokenManager::TAB
318
+ consume_token(TokenManager::TAB)
319
+ s << ' '
320
+ end
321
+ elsif !fences_ahead
322
+ consume_token(TokenManager::EOL)
323
+ s << "\n"
324
+ level_white_space(begin_column)
325
+ end
326
+ end
327
+ kind = get_next_token_kind
328
+ end
329
+ if fences_ahead
330
+ consume_token(TokenManager::EOL)
331
+ block_quote_prefix
332
+ white_space
333
+ while get_next_token_kind == TokenManager::BACKTICK
334
+ consume_token(TokenManager::BACKTICK)
335
+ end
336
+ end
337
+ code_block.value = s.string
338
+ @tree.close_scope(code_block)
339
+ end
340
+
341
+ def paragraph
342
+ paragraph = @modules.include?('paragraphs') ? Paragraph.new : BlockElement.new
343
+ @tree.open_scope
344
+ inline
345
+ while text_ahead
346
+ line_break
347
+ white_space
348
+ if modules.include?('blockquotes')
349
+ while get_next_token_kind == TokenManager::GT
350
+ consume_token(TokenManager::GT)
351
+ white_space
352
+ end
353
+ end
354
+ inline
355
+ end
356
+ @tree.close_scope(paragraph)
357
+ end
358
+
359
+ def text
360
+ text = Text.new
361
+ @tree.open_scope
362
+ s = StringIO.new('')
363
+ while text_has_tokens_ahead
364
+ case get_next_token_kind
365
+ when TokenManager::CHAR_SEQUENCE
366
+ s << consume_token(TokenManager::CHAR_SEQUENCE).image
367
+ when TokenManager::BACKSLASH
368
+ s << consume_token(TokenManager::BACKSLASH).image
369
+ when TokenManager::COLON
370
+ s << consume_token(TokenManager::COLON).image
371
+ when TokenManager::DASH
372
+ s << consume_token(TokenManager::DASH).image
373
+ when TokenManager::DIGITS
374
+ s << consume_token(TokenManager::DIGITS).image
375
+ when TokenManager::DOT
376
+ s << consume_token(TokenManager::DOT).image
377
+ when TokenManager::EQ
378
+ s << consume_token(TokenManager::EQ).image
379
+ when TokenManager::ESCAPED_CHAR
380
+ s << consume_token(TokenManager::ESCAPED_CHAR).image[1..-1]
381
+ when TokenManager::GT
382
+ s << consume_token(TokenManager::GT).image
383
+ when TokenManager::IMAGE_LABEL
384
+ s << consume_token(TokenManager::IMAGE_LABEL).image
385
+ when TokenManager::LPAREN
386
+ s << consume_token(TokenManager::LPAREN).image
387
+ when TokenManager::LT
388
+ s << consume_token(TokenManager::LT).image
389
+ when TokenManager::RBRACK
390
+ s << consume_token(TokenManager::RBRACK).image
391
+ when TokenManager::RPAREN
392
+ s << consume_token(TokenManager::RPAREN).image
393
+ else
394
+ case get_next_token_kind
395
+ when TokenManager::SPACE
396
+ s << consume_token(TokenManager::SPACE).image
397
+ when TokenManager::TAB
398
+ consume_token(TokenManager::TAB)
399
+ s << ' '
400
+ end unless next_after_space(TokenManager::EOL, TokenManager::EOF)
401
+ end
402
+ end
403
+ text.value = s.string
404
+ @tree.close_scope(text)
405
+ end
406
+
407
+ def image
408
+ image = Image.new
409
+ @tree.open_scope
410
+ ref = ''
411
+ consume_token(TokenManager::LBRACK)
412
+ white_space
413
+ consume_token(TokenManager::IMAGE_LABEL)
414
+ white_space
415
+ while image_has_any_elements
416
+ if has_text_ahead
417
+ resource_text
418
+ else
419
+ loose_char
420
+ end
421
+ end
422
+ white_space
423
+ consume_token(TokenManager::RBRACK)
424
+ if has_resource_url_ahead
425
+ ref = resource_url
426
+ end
427
+ image.value = ref
428
+ @tree.close_scope(image)
429
+ end
430
+
431
+ def link
432
+ link = Link.new
433
+ @tree.open_scope
434
+ ref = ''
435
+ consume_token(TokenManager::LBRACK)
436
+ white_space
437
+ while link_has_any_elements
438
+ if modules.include?('images') && has_image_ahead
439
+ image
440
+ elsif modules.include?('formatting') && has_strong_ahead
441
+ strong
442
+ elsif modules.include?('formatting') && has_em_ahead
443
+ em
444
+ elsif modules.include?('code') && has_code_ahead
445
+ code
446
+ elsif has_resource_text_ahead
447
+ resource_text
448
+ else
449
+ loose_char
450
+ end
451
+ end
452
+ white_space
453
+ consume_token(TokenManager::RBRACK)
454
+ if has_resource_url_ahead
455
+ ref = resource_url
456
+ end
457
+ link.value = ref
458
+ @tree.close_scope(link)
459
+ end
460
+
461
+ def strong
462
+ strong = Strong.new
463
+ @tree.open_scope
464
+ consume_token(TokenManager::ASTERISK)
465
+ while strong_has_elements
466
+ if has_text_ahead
467
+ text
468
+ elsif modules.include?('images') && has_image
469
+ image
470
+ elsif modules.include?('links') && has_link_ahead
471
+ link
472
+ elsif modules.include?('code') && multiline_ahead(TokenManager::BACKTICK)
473
+ code_multiline
474
+ elsif strong_em_within_strong_ahead
475
+ em_within_strong
476
+ else
477
+ case get_next_token_kind
478
+ when TokenManager::BACKTICK
479
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
480
+ when TokenManager::LBRACK
481
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
482
+ when TokenManager::UNDERSCORE
483
+ @tree.add_single_value(Text.new, consume_token(TokenManager::UNDERSCORE))
484
+ else
485
+ break
486
+ end
487
+ end
488
+ end
489
+ consume_token(TokenManager::ASTERISK)
490
+ @tree.close_scope(strong)
491
+ end
492
+
493
+ def em
494
+ em = Em.new
495
+ @tree.open_scope
496
+ consume_token(TokenManager::UNDERSCORE)
497
+ while em_has_elements
498
+ if has_text_ahead
499
+ text
500
+ elsif modules.include?('images') && has_image
501
+ image
502
+ elsif modules.include?('links') && has_link_ahead
503
+ link
504
+ elsif modules.include?('code') && has_code_ahead
505
+ code
506
+ elsif em_has_strong_within_em
507
+ strong_within_em
508
+ else
509
+ case get_next_token_kind
510
+ when TokenManager::ASTERISK
511
+ @tree.add_single_value(Text.new, consume_token(TokenManager::ASTERISK))
512
+ when TokenManager::BACKTICK
513
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
514
+ when TokenManager::LBRACK
515
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
516
+ else
517
+ break
518
+ end
519
+ end
520
+ end
521
+ consume_token(TokenManager::UNDERSCORE)
522
+ @tree.close_scope(em)
523
+ end
524
+
525
+ def code
526
+ code = Code.new
527
+ @tree.open_scope
528
+ consume_token(TokenManager::BACKTICK)
529
+ code_text
530
+ consume_token(TokenManager::BACKTICK)
531
+ @tree.close_scope(code)
532
+ end
533
+
534
+ def code_text
535
+ text = Text.new
536
+ @tree.open_scope
537
+ s = StringIO.new('')
538
+ loop do
539
+ case get_next_token_kind
540
+ when TokenManager::CHAR_SEQUENCE
541
+ s << consume_token(TokenManager::CHAR_SEQUENCE).image
542
+ when TokenManager::ASTERISK
543
+ s << consume_token(TokenManager::ASTERISK).image
544
+ when TokenManager::BACKSLASH
545
+ s << consume_token(TokenManager::BACKSLASH).image
546
+ when TokenManager::COLON
547
+ s << consume_token(TokenManager::COLON).image
548
+ when TokenManager::DASH
549
+ s << consume_token(TokenManager::DASH).image
550
+ when TokenManager::DIGITS
551
+ s << consume_token(TokenManager::DIGITS).image
552
+ when TokenManager::DOT
553
+ s << consume_token(TokenManager::DOT).image
554
+ when TokenManager::EQ
555
+ s << consume_token(TokenManager::EQ).image
556
+ when TokenManager::ESCAPED_CHAR
557
+ s << consume_token(TokenManager::ESCAPED_CHAR).image
558
+ when TokenManager::IMAGE_LABEL
559
+ s << consume_token(TokenManager::IMAGE_LABEL).image
560
+ when TokenManager::LT
561
+ s << consume_token(TokenManager::LT).image
562
+ when TokenManager::LBRACK
563
+ s << consume_token(TokenManager::LBRACK).image
564
+ when TokenManager::RBRACK
565
+ s << consume_token(TokenManager::RBRACK).image
566
+ when TokenManager::LPAREN
567
+ s << consume_token(TokenManager::LPAREN).image
568
+ when TokenManager::GT
569
+ s << consume_token(TokenManager::GT).image
570
+ when TokenManager::RPAREN
571
+ s << consume_token(TokenManager::RPAREN).image
572
+ when TokenManager::UNDERSCORE
573
+ s << consume_token(TokenManager::UNDERSCORE).image
574
+ else
575
+ unless next_after_space(TokenManager::EOL, TokenManager::EOF)
576
+ case get_next_token_kind
577
+ when TokenManager::SPACE
578
+ s << consume_token(TokenManager::SPACE).image
579
+ when TokenManager::TAB
580
+ consume_token(TokenManager::TAB)
581
+ s << ' '
582
+ end
583
+ end
584
+ end
585
+
586
+ break unless code_text_has_any_token_ahead
587
+ end
588
+ text.value = s.string
589
+ @tree.close_scope(text)
590
+ end
591
+
592
+ def loose_char
593
+ text = Text.new
594
+ @tree.open_scope
595
+ case get_next_token_kind
596
+ when TokenManager::ASTERISK
597
+ text.value = consume_token(TokenManager::ASTERISK).image
598
+ when TokenManager::BACKTICK
599
+ text.value = consume_token(TokenManager::BACKTICK).image
600
+ when TokenManager::LBRACK
601
+ text.value = consume_token(TokenManager::LBRACK).image
602
+ when TokenManager::UNDERSCORE
603
+ text.value = consume_token(TokenManager::UNDERSCORE).image
604
+ end
605
+ @tree.close_scope(text)
606
+ end
607
+
608
+ def line_break
609
+ linebreak = LineBreak.new
610
+ @tree.open_scope
611
+ while get_next_token_kind == TokenManager::SPACE || get_next_token_kind == TokenManager::TAB
612
+ consume_token(get_next_token_kind)
613
+ end
614
+ consume_token(TokenManager::EOL)
615
+ @tree.close_scope(linebreak)
616
+ end
617
+
618
+ def level_white_space(threshold)
619
+ current_pos = 1
620
+ while get_next_token_kind == TokenManager::GT
621
+ consume_token(get_next_token_kind)
622
+ end
623
+ while (get_next_token_kind == TokenManager::SPACE || get_next_token_kind == TokenManager::TAB) && current_pos < (threshold - 1)
624
+ current_pos = consume_token(get_next_token_kind).begin_column
625
+ end
626
+ end
627
+
628
+ def code_language
629
+ s = StringIO.new('')
630
+ loop do
631
+ case get_next_token_kind
632
+ when TokenManager::CHAR_SEQUENCE
633
+ s << consume_token(TokenManager::CHAR_SEQUENCE).image
634
+ when TokenManager::ASTERISK
635
+ s << consume_token(TokenManager::ASTERISK).image
636
+ when TokenManager::BACKSLASH
637
+ s << consume_token(TokenManager::BACKSLASH).image
638
+ when TokenManager::BACKTICK
639
+ s << consume_token(TokenManager::BACKTICK).image
640
+ when TokenManager::COLON
641
+ s << consume_token(TokenManager::COLON).image
642
+ when TokenManager::DASH
643
+ s << consume_token(TokenManager::DASH).image
644
+ when TokenManager::DIGITS
645
+ s << consume_token(TokenManager::DIGITS).image
646
+ when TokenManager::DOT
647
+ s << consume_token(TokenManager::DOT).image
648
+ when TokenManager::EQ
649
+ s << consume_token(TokenManager::EQ).image
650
+ when TokenManager::ESCAPED_CHAR
651
+ s << consume_token(TokenManager::ESCAPED_CHAR).image
652
+ when TokenManager::IMAGE_LABEL
653
+ s << consume_token(TokenManager::IMAGE_LABEL).image
654
+ when TokenManager::LT
655
+ s << consume_token(TokenManager::LT).image
656
+ when TokenManager::GT
657
+ s << consume_token(TokenManager::GT).image
658
+ when TokenManager::LBRACK
659
+ s << consume_token(TokenManager::LBRACK).image
660
+ when TokenManager::RBRACK
661
+ s << consume_token(TokenManager::RBRACK).image
662
+ when TokenManager::LPAREN
663
+ s << consume_token(TokenManager::LPAREN).image
664
+ when TokenManager::RPAREN
665
+ s << consume_token(TokenManager::RPAREN).image
666
+ when TokenManager::UNDERSCORE
667
+ s << consume_token(TokenManager::UNDERSCORE).image
668
+ when TokenManager::SPACE
669
+ s << consume_token(TokenManager::SPACE).image
670
+ when TokenManager::TAB
671
+ consume_token(TokenManager::TAB)
672
+ s << ' '
673
+ end
674
+ break if get_next_token_kind == TokenManager::EOL || get_next_token_kind == TokenManager::EOF
675
+ end
676
+ s.string
677
+ end
678
+
679
+ def inline
680
+ loop do
681
+ if has_inline_text_ahead
682
+ text
683
+ elsif @modules.include?('images') && has_image_ahead
684
+ image
685
+ elsif @modules.include?('links') && has_link_ahead
686
+ link
687
+ elsif @modules.include?('formatting') && multiline_ahead(TokenManager::ASTERISK)
688
+ strong_multiline
689
+ elsif @modules.include?('formatting') && multiline_ahead(TokenManager::UNDERSCORE)
690
+ em_multiline
691
+ elsif @modules.include?('code') && multiline_ahead(TokenManager::BACKTICK)
692
+ code_multiline
693
+ else
694
+ loose_char
695
+ end
696
+ break unless has_inline_element_ahead
697
+ end
698
+ end
699
+
700
+ def resource_text
701
+ text = Text.new
702
+ @tree.open_scope
703
+ s = StringIO.new('')
704
+ loop do
705
+ case get_next_token_kind
706
+ when TokenManager::CHAR_SEQUENCE
707
+ s << consume_token(TokenManager::CHAR_SEQUENCE).image
708
+ when TokenManager::BACKSLASH
709
+ s << consume_token(TokenManager::BACKSLASH).image
710
+ when TokenManager::COLON
711
+ s << consume_token(TokenManager::COLON).image
712
+ when TokenManager::DASH
713
+ s << consume_token(TokenManager::DASH).image
714
+ when TokenManager::DIGITS
715
+ s << consume_token(TokenManager::DIGITS).image
716
+ when TokenManager::DOT
717
+ s << consume_token(TokenManager::DOT).image
718
+ when TokenManager::EQ
719
+ s << consume_token(TokenManager::EQ).image
720
+ when TokenManager::ESCAPED_CHAR
721
+ s << consume_token(TokenManager::ESCAPED_CHAR).image[1..-1]
722
+ when TokenManager::IMAGE_LABEL
723
+ s << consume_token(TokenManager::IMAGE_LABEL).image
724
+ when TokenManager::GT
725
+ s << consume_token(TokenManager::GT).image
726
+ when TokenManager::LPAREN
727
+ s << consume_token(TokenManager::LPAREN).image
728
+ when TokenManager::LT
729
+ s << consume_token(TokenManager::LT).image
730
+ when TokenManager::RPAREN
731
+ s << consume_token(TokenManager::RPAREN).image
732
+ else
733
+ unless next_after_space(TokenManager::RBRACK)
734
+ case get_next_token_kind
735
+ when TokenManager::SPACE
736
+ s << consume_token(TokenManager::SPACE).image
737
+ when TokenManager::TAB
738
+ consume_token(TokenManager::TAB)
739
+ s << ' '
740
+ end
741
+ end
742
+ end
743
+ break unless resource_has_element_ahead
744
+ end
745
+ text.value = s.string
746
+ @tree.close_scope(text)
747
+ end
748
+
749
+ def resource_url
750
+ consume_token(TokenManager::LPAREN)
751
+ white_space
752
+ ref = resource_url_text
753
+ white_space
754
+ consume_token(TokenManager::RPAREN)
755
+ ref
756
+ end
757
+
758
+ def resource_url_text
759
+ s = StringIO.new('')
760
+ while resource_text_has_elements_ahead
761
+ case get_next_token_kind
762
+ when TokenManager::CHAR_SEQUENCE
763
+ s << consume_token(TokenManager::CHAR_SEQUENCE).image
764
+ when TokenManager::ASTERISK
765
+ s << consume_token(TokenManager::ASTERISK).image
766
+ when TokenManager::BACKSLASH
767
+ s << consume_token(TokenManager::BACKSLASH).image
768
+ when TokenManager::BACKTICK
769
+ s << consume_token(TokenManager::BACKTICK).image
770
+ when TokenManager::COLON
771
+ s << consume_token(TokenManager::COLON).image
772
+ when TokenManager::DASH
773
+ s << consume_token(TokenManager::DASH).image
774
+ when TokenManager::DIGITS
775
+ s << consume_token(TokenManager::DIGITS).image
776
+ when TokenManager::DOT
777
+ s << consume_token(TokenManager::DOT).image
778
+ when TokenManager::EQ
779
+ s << consume_token(TokenManager::EQ).image
780
+ when TokenManager::ESCAPED_CHAR
781
+ s << consume_token(TokenManager::ESCAPED_CHAR).image[1..-1]
782
+ when TokenManager::IMAGE_LABEL
783
+ s << consume_token(TokenManager::IMAGE_LABEL).image
784
+ when TokenManager::GT
785
+ s << consume_token(TokenManager::GT).image
786
+ when TokenManager::LBRACK
787
+ s << consume_token(TokenManager::LBRACK).image
788
+ when TokenManager::LPAREN
789
+ s << consume_token(TokenManager::LPAREN).image
790
+ when TokenManager::LT
791
+ s << consume_token(TokenManager::LT).image
792
+ when TokenManager::RBRACK
793
+ s << consume_token(TokenManager::RBRACK).image
794
+ when TokenManager::UNDERSCORE
795
+ s << consume_token(TokenManager::UNDERSCORE).image
796
+ else
797
+ unless next_after_space(TokenManager::RPAREN)
798
+ case get_next_token_kind
799
+ when TokenManager::SPACE
800
+ s << (consume_token(TokenManager::SPACE).image)
801
+ when TokenManager::TAB
802
+ consume_token(TokenManager::TAB)
803
+ s << ' '
804
+ end
805
+ end
806
+ end
807
+ end
808
+ s.string
809
+ end
810
+
811
+ def strong_multiline
812
+ strong = Strong.new
813
+ @tree.open_scope
814
+ consume_token(TokenManager::ASTERISK)
815
+ strong_multiline_content
816
+ while text_ahead
817
+ line_break
818
+ white_space
819
+ strong_multiline_content
820
+ end
821
+ consume_token(TokenManager::ASTERISK)
822
+ @tree.close_scope(strong)
823
+ end
824
+
825
+ def strong_multiline_content
826
+ loop do
827
+ if has_text_ahead
828
+ text
829
+ elsif modules.include?('images') && has_image_ahead
830
+ image
831
+ elsif modules.include?('links') && has_link_ahead
832
+ link
833
+ elsif modules.include?('code') && has_code_ahead
834
+ code
835
+ elsif has_em_within_strong_multiline
836
+ em_within_strong_multiline
837
+ else
838
+ case get_next_token_kind
839
+ when TokenManager::BACKTICK
840
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
841
+ when TokenManager::LBRACK
842
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
843
+ when TokenManager::UNDERSCORE
844
+ @tree.add_single_value(Text.new, consume_token(TokenManager::UNDERSCORE))
845
+ end
846
+ end
847
+ break unless strong_multiline_has_elements_ahead
848
+ end
849
+ end
850
+
851
+ def strong_within_em_multiline
852
+ strong = Strong.new
853
+ @tree.open_scope
854
+ consume_token(TokenManager::ASTERISK)
855
+ strong_within_em_multiline_content
856
+ while text_ahead
857
+ line_break
858
+ strong_within_em_multiline_content
859
+ end
860
+ consume_token(TokenManager::ASTERISK)
861
+ @tree.close_scope(strong)
862
+ end
863
+
864
+ def strong_within_em_multiline_content
865
+ loop do
866
+ if has_text_ahead
867
+ text
868
+ elsif modules.include?('images') && has_image_ahead
869
+ image
870
+ elsif modules.include?('links') && has_link_ahead
871
+ link
872
+ elsif modules.include?('code') && has_code_ahead
873
+ code
874
+ else
875
+ case get_next_token_kind
876
+ when TokenManager::BACKTICK
877
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
878
+ when TokenManager::LBRACK
879
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
880
+ when TokenManager::UNDERSCORE
881
+ @tree.add_single_value(Text.new, consume_token(TokenManager::UNDERSCORE))
882
+ end
883
+ end
884
+ break unless strong_within_em_multiline_has_elements_ahead
885
+ end
886
+ end
887
+
888
+ def strong_within_em
889
+ strong = Strong.new
890
+ @tree.open_scope
891
+ consume_token(TokenManager::ASTERISK)
892
+ loop do
893
+ if has_text_ahead
894
+ text
895
+ elsif modules.include?('images') && has_image_ahead
896
+ image
897
+ elsif modules.include?('links') && has_link_ahead
898
+ link
899
+ elsif modules.include?('code') && has_code_ahead
900
+ code
901
+ else
902
+ case get_next_token_kind
903
+ when TokenManager::BACKTICK
904
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
905
+ when TokenManager::LBRACK
906
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
907
+ when TokenManager::UNDERSCORE
908
+ @tree.add_single_value(Text.new, consume_token(TokenManager::UNDERSCORE))
909
+ end
910
+ end
911
+ break unless strong_within_em_has_elements_ahead
912
+ end
913
+ consume_token(TokenManager::ASTERISK)
914
+ @tree.close_scope(strong)
915
+ end
916
+
917
+ def em_multiline
918
+ em = Em.new
919
+ @tree.open_scope
920
+ consume_token(TokenManager::UNDERSCORE)
921
+ em_multiline_content
922
+ while text_ahead
923
+ line_break
924
+ white_space
925
+ em_multiline_content
926
+ end
927
+ consume_token(TokenManager::UNDERSCORE)
928
+ @tree.close_scope(em)
929
+ end
930
+
931
+ def em_multiline_content
932
+ loop do
933
+ if has_text_ahead
934
+ text
935
+ elsif modules.include?('images') && has_image_ahead
936
+ image
937
+ elsif modules.include?('links') && has_link_ahead
938
+ link
939
+ elsif modules.include?('code') && multiline_ahead(TokenManager::BACKTICK)
940
+ code_multiline
941
+ elsif has_strong_within_em_multiline_ahead
942
+ strong_within_em_multiline
943
+ else
944
+ case get_next_token_kind
945
+ when TokenManager::ASTERISK
946
+ @tree.add_single_value(Text.new, consume_token(TokenManager::ASTERISK))
947
+ when TokenManager::BACKTICK
948
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
949
+ when TokenManager::LBRACK
950
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
951
+ end
952
+ end
953
+ break unless em_multiline_content_has_elements_ahead
954
+ end
955
+ end
956
+
957
+ def em_within_strong_multiline
958
+ em = Em.new
959
+ @tree.open_scope
960
+ consume_token(TokenManager::UNDERSCORE)
961
+ em_within_strong_multiline_content
962
+ while text_ahead
963
+ line_break
964
+ em_within_strong_multiline_content
965
+ end
966
+ consume_token(TokenManager::UNDERSCORE)
967
+ @tree.close_scope(em)
968
+ end
969
+
970
+ def em_within_strong_multiline_content
971
+ loop do
972
+ if has_text_ahead
973
+ text
974
+ elsif modules.include?('images') && has_image_ahead
975
+ image
976
+ elsif modules.include?('links') && has_link_ahead
977
+ link
978
+ elsif modules.include?('code') && has_code_ahead
979
+ code
980
+ else
981
+ case get_next_token_kind
982
+ when TokenManager::ASTERISK
983
+ @tree.add_single_value(Text.new, consume_token(TokenManager::ASTERISK))
984
+ when TokenManager::BACKTICK
985
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
986
+ when TokenManager::LBRACK
987
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
988
+ end
989
+ end
990
+ break if !em_within_strong_multiline_content_has_elements_ahead
991
+ end
992
+ end
993
+
994
+ def em_within_strong
995
+ em = Em.new
996
+ @tree.open_scope
997
+ consume_token(TokenManager::UNDERSCORE)
998
+ loop do
999
+ if has_text_ahead
1000
+ text
1001
+ elsif modules.include?('images') && has_image_ahead
1002
+ image
1003
+ elsif modules.include?('links') && has_link_ahead
1004
+ link
1005
+ elsif modules.include?('code') && has_code_ahead
1006
+ code
1007
+ else
1008
+ case get_next_token_kind
1009
+ when TokenManager::ASTERISK
1010
+ @tree.add_single_value(Text.new, consume_token(TokenManager::ASTERISK))
1011
+ when TokenManager::BACKTICK
1012
+ @tree.add_single_value(Text.new, consume_token(TokenManager::BACKTICK))
1013
+ when TokenManager::LBRACK
1014
+ @tree.add_single_value(Text.new, consume_token(TokenManager::LBRACK))
1015
+ end
1016
+ end
1017
+ break unless em_within_strong_has_elements_ahead
1018
+ end
1019
+ consume_token(TokenManager::UNDERSCORE)
1020
+ @tree.close_scope(em)
1021
+ end
1022
+
1023
+ def code_multiline
1024
+ code = Code.new
1025
+ @tree.open_scope
1026
+ consume_token(TokenManager::BACKTICK)
1027
+ code_text
1028
+ while text_ahead
1029
+ line_break
1030
+ white_space
1031
+ while get_next_token_kind == TokenManager::GT
1032
+ consume_token(TokenManager::GT)
1033
+ white_space
1034
+ end
1035
+ code_text
1036
+ end
1037
+ consume_token(TokenManager::BACKTICK)
1038
+ @tree.close_scope(code)
1039
+ end
1040
+
1041
+ def white_space
1042
+ while get_next_token_kind == TokenManager::SPACE || get_next_token_kind == TokenManager::TAB
1043
+ consume_token(get_next_token_kind)
1044
+ end
1045
+ end
1046
+
1047
+ def has_any_block_elements_ahead
1048
+ begin
1049
+ @look_ahead = 1
1050
+ @last_position = @scan_position = @token
1051
+ return !scan_more_block_elements
1052
+ rescue LookaheadSuccess
1053
+ return true
1054
+ end
1055
+ end
1056
+
1057
+ def block_ahead(block_begin_column)
1058
+ if get_next_token_kind == TokenManager::EOL
1059
+ i = 2
1060
+ t = nil
1061
+ loop do
1062
+ quote_level = 0
1063
+ loop do
1064
+ t = get_token(i)
1065
+ i+=1
1066
+ if t.kind == TokenManager::GT
1067
+ if t.begin_column == 1 && @current_block_level > 0 && @current_quote_level == 0
1068
+ return false
1069
+ end
1070
+ quote_level+=1
1071
+ end
1072
+ break if t.kind != TokenManager::GT && t.kind != TokenManager::SPACE && t.kind != TokenManager::TAB
1073
+ end
1074
+ return true if quote_level > @current_quote_level
1075
+ return false if quote_level < @current_quote_level
1076
+ break if t.kind != TokenManager::EOL
1077
+ end
1078
+ return t.kind != TokenManager::EOF && (@current_block_level == 0 || t.begin_column >= (block_begin_column + 2))
1079
+ end
1080
+ false
1081
+ end
1082
+
1083
+ def multiline_ahead(token)
1084
+ if get_next_token_kind == token && get_token(2).kind != token && get_token(2).kind != TokenManager::EOL
1085
+ i=2
1086
+ loop do
1087
+ t = get_token(i)
1088
+ if t.kind == token
1089
+ return true
1090
+ elsif t.kind == TokenManager::EOL
1091
+ i = skip(i + 1, TokenManager::SPACE, TokenManager::TAB)
1092
+ quote_level = new_quote_level(i)
1093
+ if quote_level == @current_quote_level
1094
+ i = skip(i, TokenManager::SPACE, TokenManager::TAB, TokenManager::GT)
1095
+ if get_token(i).kind == token || get_token(i).kind == TokenManager::EOL || get_token(i).kind == TokenManager::DASH \
1096
+ || (get_token(i).kind == TokenManager::DIGITS && get_token(i + 1).kind == TokenManager::DOT) \
1097
+ || (get_token(i).kind == TokenManager::BACKTICK && get_token(i + 1).kind == TokenManager::BACKTICK && get_token(i + 2).kind == TokenManager::BACKTICK) \
1098
+ || heading_ahead(i)
1099
+ return false
1100
+ end
1101
+ else
1102
+ return false
1103
+ end
1104
+ elsif t.kind == TokenManager::EOF
1105
+ return false
1106
+ end
1107
+ i += 1
1108
+ end
1109
+ end
1110
+ false
1111
+ end
1112
+
1113
+ def fences_ahead
1114
+ i = skip(2, TokenManager::SPACE, TokenManager::TAB, TokenManager::GT)
1115
+ if get_token(i).kind == TokenManager::BACKTICK && get_token(i + 1).kind == TokenManager::BACKTICK && get_token(i + 2).kind == TokenManager::BACKTICK
1116
+ i = skip(i + 3, TokenManager::SPACE, TokenManager::TAB)
1117
+ return get_token(i).kind == TokenManager::EOL || get_token(i).kind == TokenManager::EOF
1118
+ end
1119
+ false
1120
+ end
1121
+
1122
+ def heading_ahead(offset)
1123
+ if get_token(offset).kind == TokenManager::EQ
1124
+ heading = 1
1125
+
1126
+ i = offset + 1
1127
+ loop do
1128
+ if get_token(i).kind != TokenManager::EQ
1129
+ return true
1130
+ end
1131
+ if (heading+=1) > 6
1132
+ return false
1133
+ end
1134
+ i+= 1
1135
+ end
1136
+ end
1137
+ false
1138
+ end
1139
+
1140
+ def list_item_ahead(list_begin_column, ordered)
1141
+ if get_next_token_kind == TokenManager::EOL
1142
+ i = 2
1143
+ eol = 1
1144
+ loop do
1145
+ t = get_token(i)
1146
+ if t.kind == TokenManager::EOL && (eol+=1) > 2
1147
+ return false
1148
+ elsif t.kind != TokenManager::SPACE && t.kind != TokenManager::TAB && t.kind != TokenManager::GT && t.kind != TokenManager::EOL
1149
+ if ordered
1150
+ return t.kind == TokenManager::DIGITS && get_token(i + 1).kind == TokenManager::DOT && t.begin_column >= list_begin_column
1151
+ end
1152
+ return t.kind == TokenManager::DASH && t.begin_column >= list_begin_column
1153
+ end
1154
+ i+=1
1155
+ end
1156
+ end
1157
+ false
1158
+ end
1159
+
1160
+ def text_ahead
1161
+ if get_next_token_kind == TokenManager::EOL && get_token(2).kind != TokenManager::EOL
1162
+ i = skip(2, TokenManager::SPACE, TokenManager::TAB)
1163
+ quote_level = new_quote_level(i)
1164
+ if (quote_level == @current_quote_level || !@modules.include?('blockquotes'))
1165
+ i = skip(i, TokenManager::SPACE, TokenManager::TAB, TokenManager::GT)
1166
+
1167
+ t = get_token(i)
1168
+ return get_token(i).kind != TokenManager::EOL && !(@modules.include?('lists') && t.kind == TokenManager::DASH) \
1169
+ && !(@modules.include?('lists') && t.kind == TokenManager::DIGITS && get_token(i + 1).kind == TokenManager::DOT) \
1170
+ && !(get_token(i).kind == TokenManager::BACKTICK && get_token(i + 1).kind == TokenManager::BACKTICK && get_token(i + 2).kind == TokenManager::BACKTICK) \
1171
+ && !(@modules.include?('headings') && heading_ahead(i))
1172
+ end
1173
+ end
1174
+ false
1175
+ end
1176
+
1177
+ def next_after_space(*tokens)
1178
+ i = skip(1, TokenManager::SPACE, TokenManager::TAB)
1179
+ tokens.include?(get_token(i).kind)
1180
+ end
1181
+
1182
+ def new_quote_level(offset)
1183
+ quote_level = 0
1184
+ i = offset
1185
+ loop do
1186
+ t = get_token(i)
1187
+ if t.kind == TokenManager::GT
1188
+ quote_level+=1
1189
+ elsif t.kind != TokenManager::SPACE && t.kind != TokenManager::TAB
1190
+ return quote_level
1191
+ end
1192
+ i+=1
1193
+ end
1194
+ end
1195
+
1196
+ def skip(offset, *tokens)
1197
+ i = offset
1198
+ loop do
1199
+ t = get_token(i)
1200
+ unless tokens.include?(t.kind)
1201
+ return i
1202
+ end
1203
+ i+=1
1204
+ end
1205
+ end
1206
+
1207
+ def has_ordered_list_ahead
1208
+ @look_ahead = 2
1209
+ @last_position = @scan_position = @token
1210
+ begin
1211
+ return !scan_token(TokenManager::DIGITS) && !scan_token(TokenManager::DOT)
1212
+ rescue LookaheadSuccess
1213
+ return true
1214
+ end
1215
+ end
1216
+
1217
+ def has_fenced_code_block_ahead
1218
+ @look_ahead = 3
1219
+ @last_position = @scan_position = @token
1220
+ begin
1221
+ return !scan_fenced_code_block
1222
+ rescue LookaheadSuccess
1223
+ return true
1224
+ end
1225
+ end
1226
+
1227
+ def heading_has_inline_elements_ahead
1228
+ @look_ahead = 1
1229
+ @last_position = @scan_position = @token
1230
+ begin
1231
+ xsp = @scan_position
1232
+ if scan_text_tokens
1233
+ @scan_position = xsp
1234
+ if scan_image
1235
+ @scan_position = xsp
1236
+ if scan_link
1237
+ @scan_position = xsp
1238
+ if scan_strong
1239
+ @scan_position = xsp
1240
+ if scan_em
1241
+ @scan_position = xsp
1242
+ if scan_code
1243
+ @scan_position = xsp
1244
+ return false if scan_loose_char
1245
+ end
1246
+ end
1247
+ end
1248
+ end
1249
+ end
1250
+ end
1251
+ return true
1252
+ rescue LookaheadSuccess
1253
+ return true
1254
+ end
1255
+ end
1256
+
1257
+ def has_text_ahead
1258
+ @look_ahead = 1
1259
+ @last_position = @scan_position = @token
1260
+ begin
1261
+ return !scan_text_tokens
1262
+ end
1263
+ rescue LookaheadSuccess
1264
+ return true
1265
+ end
1266
+
1267
+ def has_image_ahead
1268
+ @look_ahead = 2147483647
1269
+ @last_position = @scan_position = @token
1270
+ begin
1271
+ return !scan_image
1272
+ rescue LookaheadSuccess
1273
+ return true
1274
+ end
1275
+ end
1276
+
1277
+ def block_quote_has_empty_line_ahead
1278
+ @look_ahead = 2147483647
1279
+ @last_position = @scan_position = @token
1280
+ begin
1281
+ return !scan_block_quote_empty_line
1282
+ rescue LookaheadSuccess
1283
+ return true
1284
+ end
1285
+ end
1286
+
1287
+ def has_strong_ahead
1288
+ @look_ahead = 2147483647
1289
+ @last_position = @scan_position = @token
1290
+ begin
1291
+ return !scan_strong
1292
+ rescue LookaheadSuccess
1293
+ return true
1294
+ end
1295
+ end
1296
+
1297
+ def has_em_ahead
1298
+ @look_ahead = 2147483647
1299
+ @last_position = @scan_position = @token
1300
+ begin
1301
+ return !scan_em
1302
+ rescue LookaheadSuccess
1303
+ return true
1304
+ end
1305
+ end
1306
+
1307
+ def has_code_ahead
1308
+ @look_ahead = 2147483647
1309
+ @last_position = @scan_position = @token
1310
+ begin
1311
+ return !scan_code
1312
+ rescue LookaheadSuccess
1313
+ return true
1314
+ end
1315
+ end
1316
+
1317
+ def block_quote_has_any_block_elements_ahead
1318
+ @look_ahead = 1
1319
+ @last_position = @scan_position = @token
1320
+ begin
1321
+ return !scan_more_block_elements
1322
+ rescue LookaheadSuccess
1323
+ return true
1324
+ end
1325
+ end
1326
+
1327
+ def has_block_quote_empty_lines_ahead
1328
+ @look_ahead = 2147483647
1329
+ @last_position = @scan_position = @token
1330
+ begin
1331
+ return !scan_block_quote_empty_lines
1332
+ rescue LookaheadSuccess
1333
+ return true
1334
+ end
1335
+ end
1336
+
1337
+ def list_item_has_inline_elements
1338
+ @look_ahead = 1
1339
+ @last_position = @scan_position = @token
1340
+ begin
1341
+ return !scan_more_block_elements
1342
+ rescue LookaheadSuccess
1343
+ return true
1344
+ end
1345
+ end
1346
+
1347
+ def has_inline_text_ahead
1348
+ @look_ahead = 1
1349
+ @last_position = @scan_position = @token
1350
+
1351
+ begin
1352
+ return !scan_text_tokens
1353
+ rescue LookaheadSuccess
1354
+ return true
1355
+ end
1356
+ end
1357
+
1358
+ def has_inline_element_ahead
1359
+ @look_ahead = 1
1360
+ @last_position = @scan_position = @token
1361
+ begin
1362
+ return !scan_inline_element
1363
+ rescue LookaheadSuccess
1364
+ return true
1365
+ end
1366
+ end
1367
+
1368
+ def image_has_any_elements
1369
+ @look_ahead = 1
1370
+ @last_position = @scan_position = @token
1371
+ begin
1372
+ return !scan_image_element
1373
+ rescue LookaheadSuccess
1374
+ return true
1375
+ end
1376
+ end
1377
+
1378
+ def has_resource_text_ahead
1379
+ @look_ahead = 1
1380
+ @last_position = @scan_position = @token
1381
+ begin
1382
+ return !scan_resource_elements
1383
+ rescue LookaheadSuccess
1384
+ return true
1385
+ end
1386
+ end
1387
+
1388
+ def link_has_any_elements
1389
+ @look_ahead = 1
1390
+ @last_position = @scan_position = @token
1391
+ begin
1392
+ return !scan_link_element
1393
+ rescue LookaheadSuccess
1394
+ return true
1395
+ end
1396
+ end
1397
+
1398
+ def has_resource_url_ahead
1399
+ @look_ahead = 2147483647
1400
+ @last_position = @scan_position = @token
1401
+ begin
1402
+ return !scan_resource_url
1403
+ rescue LookaheadSuccess
1404
+ return true
1405
+ end
1406
+ end
1407
+
1408
+ def resource_has_element_ahead
1409
+ @look_ahead = 2
1410
+ @last_position = @scan_position = @token
1411
+ begin
1412
+ return !scan_resource_element
1413
+ rescue LookaheadSuccess
1414
+ return true
1415
+ end
1416
+ end
1417
+
1418
+ def resource_text_has_elements_ahead
1419
+ @look_ahead = 1
1420
+ @last_position = @scan_position = @token
1421
+ begin
1422
+ return !scan_resource_text_element
1423
+ rescue LookaheadSuccess
1424
+ return true
1425
+ end
1426
+ end
1427
+
1428
+ def has_em_within_strong_multiline
1429
+ @look_ahead = 2147483647
1430
+ @last_position = @scan_position = @token
1431
+ begin
1432
+ return !scan_em_within_strong_multiline
1433
+ rescue LookaheadSuccess
1434
+ return true
1435
+ end
1436
+ end
1437
+
1438
+ def strong_multiline_has_elements_ahead
1439
+ @look_ahead = 1
1440
+ @last_position = @scan_position = @token
1441
+ begin
1442
+ return !scan_strong_multiline_elements
1443
+ rescue LookaheadSuccess
1444
+ return true
1445
+ end
1446
+ end
1447
+
1448
+ def strong_within_em_multiline_has_elements_ahead
1449
+ @look_ahead = 1
1450
+ @last_position = @scan_position = @token
1451
+ begin
1452
+ return !scan_strong_within_em_multiline_elements
1453
+ rescue LookaheadSuccess
1454
+ return true
1455
+ end
1456
+ end
1457
+
1458
+ def has_image
1459
+ @look_ahead = 2147483647
1460
+ @last_position = @scan_position = @token
1461
+ begin
1462
+ return !scan_image
1463
+ rescue LookaheadSuccess
1464
+ return true
1465
+ end
1466
+ end
1467
+
1468
+ def has_link_ahead
1469
+ @look_ahead = 2147483647
1470
+ @last_position = @scan_position = @token
1471
+ begin
1472
+ return !scan_link
1473
+ rescue LookaheadSuccess
1474
+ return true
1475
+ end
1476
+ end
1477
+
1478
+ def strong_em_within_strong_ahead
1479
+ @look_ahead = 2147483647
1480
+ @last_position = @scan_position = @token
1481
+ begin
1482
+ return !scan_em_within_strong
1483
+ rescue LookaheadSuccess
1484
+ return true
1485
+ end
1486
+ end
1487
+
1488
+ def strong_has_elements
1489
+ @look_ahead = 1
1490
+ @last_position = @scan_position = @token
1491
+ begin
1492
+ return !scan_strong_elements
1493
+ rescue LookaheadSuccess
1494
+ return true
1495
+ end
1496
+ end
1497
+
1498
+ def strong_within_em_has_elements_ahead
1499
+ @look_ahead = 1
1500
+ @last_position = @scan_position = @token
1501
+ begin
1502
+ return !scan_strong_within_em_elements
1503
+ rescue LookaheadSuccess
1504
+ return true
1505
+ end
1506
+ end
1507
+
1508
+ def has_strong_within_em_multiline_ahead
1509
+ @look_ahead = 2147483647
1510
+ @last_position = @scan_position = @token
1511
+ begin
1512
+ return !scan_strong_within_em_multiline
1513
+ rescue LookaheadSuccess
1514
+ return true
1515
+ end
1516
+ end
1517
+
1518
+ def em_multiline_content_has_elements_ahead
1519
+ @look_ahead = 1
1520
+ @last_position = @scan_position = @token
1521
+ begin
1522
+ return !scan_em_multiline_content_elements
1523
+ rescue LookaheadSuccess
1524
+ return true
1525
+ end
1526
+ end
1527
+
1528
+ def em_within_strong_multiline_content_has_elements_ahead
1529
+ @look_ahead = 1
1530
+ @last_position = @scan_position = @token
1531
+ begin
1532
+ return !scan_em_within_strong_multiline_content
1533
+ rescue LookaheadSuccess
1534
+ return true
1535
+ end
1536
+ end
1537
+
1538
+ def em_has_strong_within_em
1539
+ @look_ahead = 2147483647
1540
+ @last_position = @scan_position = @token
1541
+ begin
1542
+ return !scan_strong_within_em
1543
+ rescue LookaheadSuccess
1544
+ return true
1545
+ end
1546
+ end
1547
+
1548
+ def em_has_elements
1549
+ @look_ahead = 1
1550
+ @last_position = @scan_position = @token
1551
+ begin
1552
+ return !scan_em_elements
1553
+ rescue LookaheadSuccess
1554
+ return true
1555
+ end
1556
+ end
1557
+
1558
+ def em_within_strong_has_elements_ahead
1559
+ @look_ahead = 1
1560
+ @last_position = @scan_position = @token
1561
+ begin
1562
+ return !scan_em_within_strong_elements
1563
+ rescue LookaheadSuccess
1564
+ return true
1565
+ end
1566
+ end
1567
+
1568
+ def code_text_has_any_token_ahead
1569
+ @look_ahead = 1
1570
+ @last_position = @scan_position = @token
1571
+ begin
1572
+ return !scan_code_text_tokens
1573
+ rescue LookaheadSuccess
1574
+ return true
1575
+ end
1576
+ end
1577
+
1578
+ def text_has_tokens_ahead
1579
+ @look_ahead = 1
1580
+ @last_position = @scan_position = @token
1581
+ begin
1582
+ return !scan_text
1583
+ rescue LookaheadSuccess
1584
+ return true
1585
+ end
1586
+ end
1587
+
1588
+ def scan_loose_char
1589
+ xsp = @scan_position
1590
+ if scan_token(TokenManager::ASTERISK)
1591
+ @scan_position = xsp
1592
+ if scan_token(TokenManager::BACKTICK)
1593
+ @scan_position = xsp
1594
+ if scan_token(TokenManager::LBRACK)
1595
+ @scan_position = xsp
1596
+ return scan_token(TokenManager::UNDERSCORE)
1597
+ end
1598
+ end
1599
+ end
1600
+ false
1601
+ end
1602
+
1603
+ def scan_text
1604
+ xsp = @scan_position
1605
+ if scan_token(TokenManager::BACKSLASH)
1606
+ @scan_position = xsp
1607
+ if scan_token(TokenManager::CHAR_SEQUENCE)
1608
+ @scan_position = xsp
1609
+ if scan_token(TokenManager::COLON)
1610
+ @scan_position = xsp
1611
+ if scan_token(TokenManager::DASH)
1612
+ @scan_position = xsp
1613
+ if scan_token(TokenManager::DIGITS)
1614
+ @scan_position = xsp
1615
+ if scan_token(TokenManager::DOT)
1616
+ @scan_position = xsp
1617
+ if scan_token(TokenManager::EQ)
1618
+ @scan_position = xsp
1619
+ if scan_token(TokenManager::ESCAPED_CHAR)
1620
+ @scan_position = xsp
1621
+ if scan_token(TokenManager::GT)
1622
+ @scan_position = xsp
1623
+ if scan_token(TokenManager::IMAGE_LABEL)
1624
+ @scan_position = xsp
1625
+ if scan_token(TokenManager::LPAREN)
1626
+ @scan_position = xsp
1627
+ if scan_token(TokenManager::LT)
1628
+ @scan_position = xsp
1629
+ if scan_token(TokenManager::RBRACK)
1630
+ @scan_position = xsp
1631
+ if scan_token(TokenManager::RPAREN)
1632
+ @scan_position = xsp
1633
+ @looking_ahead = true
1634
+ @semantic_look_ahead = !next_after_space(TokenManager::EOL, TokenManager::EOF)
1635
+ @looking_ahead = false
1636
+ return (!@semantic_look_ahead || scan_whitespace_token)
1637
+ end
1638
+ end
1639
+ end
1640
+ end
1641
+ end
1642
+ end
1643
+ end
1644
+ end
1645
+ end
1646
+ end
1647
+ end
1648
+ end
1649
+ end
1650
+ end
1651
+ false
1652
+ end
1653
+
1654
+ def scan_text_tokens
1655
+ return true if scan_text
1656
+ while true
1657
+ xsp = @scan_position
1658
+ if scan_text
1659
+ @scan_position = xsp
1660
+ break
1661
+ end
1662
+ end
1663
+ false
1664
+ end
1665
+
1666
+ def scan_code_text_tokens
1667
+ xsp = @scan_position
1668
+ if scan_token(TokenManager::ASTERISK)
1669
+ @scan_position = xsp
1670
+ if scan_token(TokenManager::BACKSLASH)
1671
+ @scan_position = xsp
1672
+ if scan_token(TokenManager::CHAR_SEQUENCE)
1673
+ @scan_position = xsp
1674
+ if scan_token(TokenManager::COLON)
1675
+ @scan_position = xsp
1676
+ if scan_token(TokenManager::DASH)
1677
+ @scan_position = xsp
1678
+ if scan_token(TokenManager::DIGITS)
1679
+ @scan_position = xsp
1680
+ if scan_token(TokenManager::DOT)
1681
+ @scan_position = xsp
1682
+ if scan_token(TokenManager::EQ)
1683
+ @scan_position = xsp
1684
+ if scan_token(TokenManager::ESCAPED_CHAR)
1685
+ @scan_position = xsp
1686
+ if scan_token(TokenManager::IMAGE_LABEL)
1687
+ @scan_position = xsp
1688
+ if scan_token(TokenManager::LT)
1689
+ @scan_position = xsp
1690
+ if scan_token(TokenManager::LBRACK)
1691
+ @scan_position = xsp
1692
+ if scan_token(TokenManager::RBRACK)
1693
+ @scan_position = xsp
1694
+ if scan_token(TokenManager::LPAREN)
1695
+ @scan_position = xsp
1696
+ if scan_token(TokenManager::GT)
1697
+ @scan_position = xsp
1698
+ if scan_token(TokenManager::RPAREN)
1699
+ @scan_position = xsp
1700
+ if scan_token(TokenManager::UNDERSCORE)
1701
+ @scan_position = xsp
1702
+ @looking_ahead = true
1703
+ @semantic_look_ahead = !next_after_space(TokenManager::EOL, TokenManager::EOF)
1704
+ @looking_ahead = false
1705
+ return (!@semantic_look_ahead || scan_whitespace_token)
1706
+ end
1707
+ end
1708
+ end
1709
+ end
1710
+ end
1711
+ end
1712
+ end
1713
+ end
1714
+ end
1715
+ end
1716
+ end
1717
+ end
1718
+ end
1719
+ end
1720
+ end
1721
+ end
1722
+ end
1723
+ false
1724
+ end
1725
+
1726
+ def scan_code
1727
+ scan_token(TokenManager::BACKTICK) || scan_code_text_tokens_ahead() || scan_token(TokenManager::BACKTICK)
1728
+ end
1729
+
1730
+ def scan_code_multiline
1731
+ if scan_token(TokenManager::BACKTICK) || scan_code_text_tokens_ahead
1732
+ return true
1733
+ end
1734
+ while true
1735
+ xsp = @scan_position
1736
+ if has_code_text_on_next_line_ahead
1737
+ @scan_position = xsp
1738
+ break
1739
+ end
1740
+ end
1741
+ scan_token(TokenManager::BACKTICK)
1742
+ end
1743
+
1744
+ def scan_code_text_tokens_ahead
1745
+ return true if scan_code_text_tokens
1746
+ while true
1747
+ xsp = @scan_position
1748
+ if scan_code_text_tokens
1749
+ @scan_position = xsp
1750
+ break
1751
+ end
1752
+ end
1753
+ false
1754
+ end
1755
+
1756
+ def has_code_text_on_next_line_ahead
1757
+ return true if scan_whitespace_token_before_eol
1758
+ while true
1759
+ xsp = @scan_position
1760
+ if scan_token(TokenManager::GT)
1761
+ @scan_position = xsp
1762
+ break
1763
+ end
1764
+ end
1765
+ scan_code_text_tokens_ahead
1766
+ end
1767
+
1768
+ def scan_whitespace_tokens
1769
+ while true
1770
+ xsp = @scan_position
1771
+ if scan_whitespace_token
1772
+ @scan_position = xsp
1773
+ break
1774
+ end
1775
+ end
1776
+ false
1777
+ end
1778
+
1779
+ def scan_whitespace_token_before_eol
1780
+ return scan_whitespace_tokens || scan_token(TokenManager::EOL)
1781
+ end
1782
+
1783
+ def scan_em_within_strong_elements
1784
+ xsp = @scan_position
1785
+ if scan_text_tokens
1786
+ @scan_position = xsp
1787
+ if scan_image
1788
+ @scan_position = xsp
1789
+ if scan_link
1790
+ @scan_position = xsp
1791
+ if scan_code
1792
+ @scan_position = xsp
1793
+ if scan_token(TokenManager::ASTERISK)
1794
+ @scan_position = xsp
1795
+ if scan_token(TokenManager::BACKTICK)
1796
+ @scan_position = xsp
1797
+ return scan_token(TokenManager::LBRACK)
1798
+ end
1799
+ end
1800
+ end
1801
+ end
1802
+ end
1803
+ end
1804
+ false
1805
+ end
1806
+
1807
+ def scan_em_within_strong
1808
+ return true if scan_token(TokenManager::UNDERSCORE) || scan_em_within_strong_elements
1809
+ while true
1810
+ xsp = @scan_position
1811
+ if scan_em_within_strong_elements
1812
+ @scan_position = xsp
1813
+ break
1814
+ end
1815
+ end
1816
+ scan_token(TokenManager::UNDERSCORE)
1817
+ end
1818
+
1819
+ def scan_em_elements
1820
+ xsp = @scan_position
1821
+ if scan_text_tokens
1822
+ @scan_position = xsp
1823
+ if scan_image
1824
+ @scan_position = xsp
1825
+ if scan_link
1826
+ @scan_position = xsp
1827
+ if scan_code
1828
+ @scan_position = xsp
1829
+ if scan_strong_within_em
1830
+ @scan_position = xsp
1831
+ if scan_token(TokenManager::ASTERISK)
1832
+ @scan_position = xsp
1833
+ if scan_token(TokenManager::BACKTICK)
1834
+ @scan_position = xsp
1835
+ return scan_token(TokenManager::LBRACK)
1836
+ end
1837
+ end
1838
+ end
1839
+ end
1840
+ end
1841
+ end
1842
+ end
1843
+ false
1844
+ end
1845
+
1846
+ def scan_em
1847
+ return true if scan_token(TokenManager::UNDERSCORE) || scan_em_elements
1848
+ while true
1849
+ xsp = @scan_position
1850
+ if scan_em_elements
1851
+ @scan_position = xsp
1852
+ break
1853
+ end
1854
+ end
1855
+ scan_token(TokenManager::UNDERSCORE)
1856
+ end
1857
+
1858
+ def scan_em_within_strong_multiline_content
1859
+ xsp = @scan_position
1860
+ if scan_text_tokens
1861
+ @scan_position = xsp
1862
+ if scan_image
1863
+ @scan_position = xsp
1864
+ if scan_link
1865
+ @scan_position = xsp
1866
+ if scan_code
1867
+ @scan_position = xsp
1868
+ if scan_token(TokenManager::ASTERISK)
1869
+ @scan_position = xsp
1870
+ if scan_token(TokenManager::BACKTICK)
1871
+ @scan_position = xsp
1872
+ return scan_token(TokenManager::LBRACK)
1873
+ end
1874
+ end
1875
+ end
1876
+ end
1877
+ end
1878
+ end
1879
+ false
1880
+ end
1881
+
1882
+ def has_no_em_within_strong_multiline_content_ahead
1883
+ if scan_em_within_strong_multiline_content
1884
+ return true
1885
+ end
1886
+ while true
1887
+ xsp = @scan_position
1888
+ if scan_em_within_strong_multiline_content
1889
+ @scan_position = xsp
1890
+ break
1891
+ end
1892
+ end
1893
+ false
1894
+ end
1895
+
1896
+ def scan_em_within_strong_multiline
1897
+ if scan_token(TokenManager::UNDERSCORE) || has_no_em_within_strong_multiline_content_ahead
1898
+ return true
1899
+ end
1900
+ while true
1901
+ xsp = @scan_position
1902
+ if scan_whitespace_token_before_eol || has_no_em_within_strong_multiline_content_ahead
1903
+ @scan_position = xsp
1904
+ break
1905
+ end
1906
+ end
1907
+ scan_token(TokenManager::UNDERSCORE)
1908
+ end
1909
+
1910
+ def scan_em_multiline_content_elements
1911
+ xsp = @scan_position
1912
+ if scan_text_tokens
1913
+ @scan_position = xsp
1914
+ if scan_image
1915
+ @scan_position = xsp
1916
+ if scan_link
1917
+ @scan_position = xsp
1918
+ @looking_ahead = true
1919
+ @semantic_look_ahead = multiline_ahead(TokenManager::BACKTICK)
1920
+ @looking_ahead = false
1921
+ if !@semantic_look_ahead || scan_code_multiline
1922
+ @scan_position = xsp
1923
+ if scan_strong_within_em_multiline
1924
+ @scan_position = xsp
1925
+ if scan_token(TokenManager::ASTERISK)
1926
+ @scan_position = xsp
1927
+ if scan_token(TokenManager::BACKTICK)
1928
+ @scan_position = xsp
1929
+ return scan_token(TokenManager::LBRACK)
1930
+ end
1931
+ end
1932
+ end
1933
+ end
1934
+ end
1935
+ end
1936
+ end
1937
+ false
1938
+ end
1939
+
1940
+ def scan_strong_within_em_elements
1941
+ xsp = @scan_position
1942
+ if scan_text_tokens
1943
+ @scan_position = xsp
1944
+ if scan_image
1945
+ @scan_position = xsp
1946
+ if scan_link
1947
+ @scan_position = xsp
1948
+ if scan_code
1949
+ @scan_position = xsp
1950
+ if scan_token(TokenManager::BACKTICK)
1951
+ @scan_position = xsp
1952
+ if scan_token(TokenManager::LBRACK)
1953
+ @scan_position = xsp
1954
+ return scan_token(TokenManager::UNDERSCORE)
1955
+ end
1956
+ end
1957
+ end
1958
+ end
1959
+ end
1960
+ end
1961
+ false
1962
+ end
1963
+
1964
+ def scan_strong_within_em
1965
+ return true if scan_token(TokenManager::ASTERISK) || scan_strong_within_em_elements
1966
+ while true
1967
+ xsp = @scan_position
1968
+ if scan_strong_within_em_elements
1969
+ @scan_position = xsp
1970
+ break
1971
+ end
1972
+ end
1973
+ scan_token(TokenManager::ASTERISK)
1974
+ end
1975
+
1976
+ def scan_strong_elements
1977
+ xsp = @scan_position
1978
+ if scan_text_tokens
1979
+ @scan_position = xsp
1980
+ if scan_image
1981
+ @scan_position = xsp
1982
+ if scan_link
1983
+ @scan_position = xsp
1984
+ @looking_ahead = true
1985
+ @semantic_look_ahead = multiline_ahead(TokenManager::BACKTICK)
1986
+ @looking_ahead = false
1987
+ if !@semantic_look_ahead || scan_code_multiline
1988
+ @scan_position = xsp
1989
+ if scan_em_within_strong
1990
+ @scan_position = xsp
1991
+ if scan_token(TokenManager::BACKTICK)
1992
+ @scan_position = xsp
1993
+ if scan_token(TokenManager::LBRACK)
1994
+ @scan_position = xsp
1995
+ return scan_token(TokenManager::UNDERSCORE)
1996
+ end
1997
+ end
1998
+ end
1999
+ end
2000
+ end
2001
+ end
2002
+ end
2003
+ false
2004
+ end
2005
+
2006
+ def scan_strong
2007
+ return true if scan_token(TokenManager::ASTERISK) || scan_strong_elements
2008
+ while true
2009
+ xsp = @scan_position
2010
+ if scan_strong_elements
2011
+ @scan_position = xsp
2012
+ break
2013
+ end
2014
+ end
2015
+ scan_token(TokenManager::ASTERISK)
2016
+ end
2017
+
2018
+ def scan_strong_within_em_multiline_elements
2019
+ xsp = @scan_position
2020
+ if scan_text_tokens
2021
+ @scan_position = xsp
2022
+ if scan_image
2023
+ @scan_position = xsp
2024
+ if scan_link
2025
+ @scan_position = xsp
2026
+ if scan_code
2027
+ @scan_position = xsp
2028
+ if scan_token(TokenManager::BACKTICK)
2029
+ @scan_position = xsp
2030
+ if scan_token(TokenManager::LBRACK)
2031
+ @scan_position = xsp
2032
+ return scan_token(TokenManager::UNDERSCORE)
2033
+ end
2034
+ end
2035
+ end
2036
+ end
2037
+ end
2038
+ end
2039
+ false
2040
+ end
2041
+
2042
+ def scan_for_more_strong_within_em_multiline_elements
2043
+ return true if scan_strong_within_em_multiline_elements
2044
+ loop do
2045
+ xsp = @scan_position
2046
+ if scan_strong_within_em_multiline_elements
2047
+ @scan_position = xsp
2048
+ break
2049
+ end
2050
+ end
2051
+ false
2052
+ end
2053
+
2054
+ def scan_strong_within_em_multiline
2055
+ return true if scan_token(TokenManager::ASTERISK) || scan_for_more_strong_within_em_multiline_elements
2056
+ while true
2057
+ xsp = @scan_position
2058
+ if scan_whitespace_token_before_eol || scan_for_more_strong_within_em_multiline_elements
2059
+ @scan_position = xsp
2060
+ break
2061
+ end
2062
+ end
2063
+ scan_token(TokenManager::ASTERISK)
2064
+ end
2065
+
2066
+ def scan_strong_multiline_elements
2067
+ xsp = @scan_position
2068
+ if scan_text_tokens
2069
+ @scan_position = xsp
2070
+ if scan_image
2071
+ @scan_position = xsp
2072
+ if scan_link
2073
+ @scan_position = xsp
2074
+ if scan_code
2075
+ @scan_position = xsp
2076
+ if scan_em_within_strong_multiline
2077
+ @scan_position = xsp
2078
+ if scan_token(TokenManager::BACKTICK)
2079
+ @scan_position = xsp
2080
+ if scan_token(TokenManager::LBRACK)
2081
+ @scan_position = xsp
2082
+ return scan_token(TokenManager::UNDERSCORE)
2083
+ end
2084
+ end
2085
+ end
2086
+ end
2087
+ end
2088
+ end
2089
+ end
2090
+ false
2091
+ end
2092
+
2093
+ def scan_resource_text_element
2094
+ xsp = @scan_position
2095
+ if scan_token(TokenManager::ASTERISK)
2096
+ @scan_position = xsp
2097
+ if scan_token(TokenManager::BACKSLASH)
2098
+ @scan_position = xsp
2099
+ if scan_token(TokenManager::BACKTICK)
2100
+ @scan_position = xsp
2101
+ if scan_token(TokenManager::CHAR_SEQUENCE)
2102
+ @scan_position = xsp
2103
+ if scan_token(TokenManager::COLON)
2104
+ @scan_position = xsp
2105
+ if scan_token(TokenManager::DASH)
2106
+ @scan_position = xsp
2107
+ if scan_token(TokenManager::DIGITS)
2108
+ @scan_position = xsp
2109
+ if scan_token(TokenManager::DOT)
2110
+ @scan_position = xsp
2111
+ if scan_token(TokenManager::EQ)
2112
+ @scan_position = xsp
2113
+ if scan_token(TokenManager::ESCAPED_CHAR)
2114
+ @scan_position = xsp
2115
+ if scan_token(TokenManager::IMAGE_LABEL)
2116
+ @scan_position = xsp
2117
+ if scan_token(TokenManager::GT)
2118
+ @scan_position = xsp
2119
+ if scan_token(TokenManager::LBRACK)
2120
+ @scan_position = xsp
2121
+ if scan_token(TokenManager::LPAREN)
2122
+ @scan_position = xsp
2123
+ if scan_token(TokenManager::LT)
2124
+ @scan_position = xsp
2125
+ if scan_token(TokenManager::RBRACK)
2126
+ @scan_position = xsp
2127
+ if scan_token(TokenManager::UNDERSCORE)
2128
+ @scan_position = xsp
2129
+ @looking_ahead = true
2130
+ @semantic_look_ahead = !next_after_space(TokenManager::RPAREN)
2131
+ @looking_ahead = false
2132
+ return !@semantic_look_ahead || scan_whitespace_token
2133
+ end
2134
+ end
2135
+ end
2136
+ end
2137
+ end
2138
+ end
2139
+ end
2140
+ end
2141
+ end
2142
+ end
2143
+ end
2144
+ end
2145
+ end
2146
+ end
2147
+ end
2148
+ end
2149
+ end
2150
+ false
2151
+ end
2152
+
2153
+ def scan_image_element
2154
+ xsp = @scan_position
2155
+ if scan_resource_elements
2156
+ @scan_position = xsp
2157
+ return true if scan_loose_char
2158
+ end
2159
+ false
2160
+ end
2161
+
2162
+ def scan_resource_text_elements
2163
+ while true
2164
+ xsp = @scan_position
2165
+ if scan_resource_text_element
2166
+ @scan_position = xsp
2167
+ break
2168
+ end
2169
+ end
2170
+ false
2171
+ end
2172
+
2173
+ def scan_resource_url
2174
+ scan_token(TokenManager::LPAREN) || scan_whitespace_tokens || scan_resource_text_elements || scan_whitespace_tokens || scan_token(TokenManager::RPAREN)
2175
+ end
2176
+
2177
+ def scan_link_element
2178
+ xsp = @scan_position
2179
+ if scan_image
2180
+ @scan_position = xsp
2181
+ if scan_strong
2182
+ @scan_position = xsp
2183
+ if scan_em
2184
+ @scan_position = xsp
2185
+ if scan_code
2186
+ @scan_position = xsp
2187
+ if scan_resource_elements
2188
+ @scan_position = xsp
2189
+ return scan_loose_char
2190
+ end
2191
+ end
2192
+ end
2193
+ end
2194
+ end
2195
+ false
2196
+ end
2197
+
2198
+ def scan_resource_element
2199
+ xsp = @scan_position
2200
+ if scan_token(TokenManager::BACKSLASH)
2201
+ @scan_position = xsp
2202
+ if scan_token(TokenManager::COLON)
2203
+ @scan_position = xsp
2204
+ if scan_token(TokenManager::CHAR_SEQUENCE)
2205
+ @scan_position = xsp
2206
+ if scan_token(TokenManager::DASH)
2207
+ @scan_position = xsp
2208
+ if scan_token(TokenManager::DIGITS)
2209
+ @scan_position = xsp
2210
+ if scan_token(TokenManager::DOT)
2211
+ @scan_position = xsp
2212
+ if scan_token(TokenManager::EQ)
2213
+ @scan_position = xsp
2214
+ if scan_token(TokenManager::ESCAPED_CHAR)
2215
+ @scan_position = xsp
2216
+ if scan_token(TokenManager::IMAGE_LABEL)
2217
+ @scan_position = xsp
2218
+ if scan_token(TokenManager::GT)
2219
+ @scan_position = xsp
2220
+ if scan_token(TokenManager::LPAREN)
2221
+ @scan_position = xsp
2222
+ if scan_token(TokenManager::LT)
2223
+ @scan_position = xsp
2224
+ if scan_token(TokenManager::RPAREN)
2225
+ @scan_position = xsp
2226
+ @looking_ahead = true
2227
+ @semantic_look_ahead = !next_after_space(TokenManager::RBRACK)
2228
+ @looking_ahead = false
2229
+ return !@semantic_look_ahead || scan_whitespace_token
2230
+ end
2231
+ end
2232
+ end
2233
+ end
2234
+ end
2235
+ end
2236
+ end
2237
+ end
2238
+ end
2239
+ end
2240
+ end
2241
+ end
2242
+ end
2243
+ return false
2244
+ end
2245
+
2246
+ def scan_resource_elements
2247
+ return true if scan_resource_element
2248
+ loop do
2249
+ xsp = @scan_position
2250
+ if scan_resource_element
2251
+ @scan_position = xsp
2252
+ break
2253
+ end
2254
+ end
2255
+ false
2256
+ end
2257
+
2258
+ def scan_link
2259
+ if scan_token(TokenManager::LBRACK) || scan_whitespace_tokens || scan_link_element
2260
+ return true
2261
+ end
2262
+ while true
2263
+ xsp = @scan_position
2264
+ if scan_link_element
2265
+ @scan_position = xsp
2266
+ break
2267
+ end
2268
+ end
2269
+ if scan_whitespace_tokens || scan_token(TokenManager::RBRACK)
2270
+ return true
2271
+ end
2272
+ xsp = @scan_position
2273
+ if scan_resource_url
2274
+ @scan_position = xsp
2275
+ end
2276
+ false
2277
+ end
2278
+
2279
+ def scan_image
2280
+ if scan_token(TokenManager::LBRACK) || scan_whitespace_tokens || scan_token(TokenManager::IMAGE_LABEL) || scan_image_element
2281
+ return true
2282
+ end
2283
+ while true
2284
+ xsp = @scan_position
2285
+ if scan_image_element
2286
+ @scan_position = xsp
2287
+ break
2288
+ end
2289
+ end
2290
+ if scan_whitespace_tokens || scan_token(TokenManager::RBRACK)
2291
+ return true
2292
+ end
2293
+ xsp = @scan_position
2294
+ if scan_resource_url
2295
+ @scan_position = xsp
2296
+ end
2297
+ false
2298
+ end
2299
+
2300
+ def scan_inline_element
2301
+ xsp = @scan_position
2302
+ if scan_text_tokens
2303
+ @scan_position = xsp
2304
+ if scan_image
2305
+ @scan_position = xsp
2306
+ if scan_link
2307
+ @scan_position = xsp
2308
+ @looking_ahead = true
2309
+ @semantic_look_ahead = multiline_ahead(TokenManager::ASTERISK)
2310
+ @looking_ahead = false
2311
+ if !@semantic_look_ahead || scan_token(TokenManager::ASTERISK)
2312
+ @scan_position = xsp
2313
+ @looking_ahead = true
2314
+ @semantic_look_ahead = multiline_ahead(TokenManager::UNDERSCORE)
2315
+ @looking_ahead = false
2316
+ if !@semantic_look_ahead || scan_token(TokenManager::UNDERSCORE)
2317
+ @scan_position = xsp
2318
+ @looking_ahead = true
2319
+ @semantic_look_ahead = multiline_ahead(TokenManager::BACKTICK)
2320
+ @looking_ahead = false
2321
+ if !@semantic_look_ahead || scan_code_multiline
2322
+ @scan_position = xsp
2323
+ return scan_loose_char
2324
+ end
2325
+ end
2326
+ end
2327
+ end
2328
+ end
2329
+ end
2330
+ false
2331
+ end
2332
+
2333
+ def scan_paragraph
2334
+ if scan_inline_element
2335
+ return true
2336
+ end
2337
+ while true
2338
+ xsp = @scan_position
2339
+ if scan_inline_element
2340
+ @scan_position = xsp
2341
+ break
2342
+ end
2343
+ end
2344
+ false
2345
+ end
2346
+
2347
+ def scan_whitespace_token
2348
+ xsp = @scan_position
2349
+ if scan_token(TokenManager::SPACE)
2350
+ @scan_position = xsp
2351
+ return true if scan_token(TokenManager::TAB)
2352
+ end
2353
+ false
2354
+ end
2355
+
2356
+ def scan_fenced_code_block
2357
+ scan_token(TokenManager::BACKTICK) || scan_token(TokenManager::BACKTICK) || scan_token(TokenManager::BACKTICK)
2358
+ end
2359
+
2360
+ def scan_block_quote_empty_lines
2361
+ scan_block_quote_empty_line || scan_token(TokenManager::EOL)
2362
+ end
2363
+
2364
+ def scan_block_quote_empty_line
2365
+ return true if scan_token(TokenManager::EOL) || scan_whitespace_tokens || scan_token(TokenManager::GT) || scan_whitespace_tokens
2366
+ while true
2367
+ xsp = @scan_position
2368
+ if scan_token(TokenManager::GT) || scan_whitespace_tokens
2369
+ @scan_position = xsp
2370
+ break
2371
+ end
2372
+ end
2373
+ false
2374
+ end
2375
+
2376
+ def scan_for_headersigns
2377
+ return true if scan_token(TokenManager::EQ)
2378
+ while true
2379
+ xsp = @scan_position
2380
+ if scan_token(TokenManager::EQ)
2381
+ @scan_position = xsp
2382
+ break
2383
+ end
2384
+ end
2385
+ false
2386
+ end
2387
+
2388
+ def scan_more_block_elements
2389
+ xsp = @scan_position
2390
+ @looking_ahead = true
2391
+ @semantic_look_ahead = heading_ahead(1)
2392
+ @looking_ahead = false
2393
+ if !@semantic_look_ahead || scan_for_headersigns
2394
+ @scan_position = xsp
2395
+ if scan_token(TokenManager::GT)
2396
+ @scan_position = xsp
2397
+ if scan_token(TokenManager::DASH)
2398
+ @scan_position = xsp
2399
+ if scan_token(TokenManager::DIGITS) || scan_token(TokenManager::DOT)
2400
+ @scan_position = xsp
2401
+ if scan_fenced_code_block
2402
+ @scan_position = xsp
2403
+ return scan_paragraph
2404
+ end
2405
+ end
2406
+ end
2407
+ end
2408
+ end
2409
+ false
2410
+ end
2411
+
2412
+ def scan_token(kind)
2413
+ if @scan_position == @last_position
2414
+ @look_ahead -= 1
2415
+ if @scan_position.next.nil?
2416
+ @last_position = @scan_position = @scan_position.next = @tm.get_next_token
2417
+ else
2418
+ @last_position = @scan_position = @scan_position.next
2419
+ end
2420
+ else
2421
+ @scan_position = @scan_position.next
2422
+ end
2423
+ if @scan_position.kind != kind
2424
+ return true
2425
+ end
2426
+
2427
+ if (@look_ahead == 0) && (@scan_position == @last_position)
2428
+ raise @look_ahead_success
2429
+ end
2430
+ false
2431
+ end
2432
+
2433
+ def get_next_token_kind
2434
+ if @next_token_kind != -1
2435
+ return @next_token_kind
2436
+ elsif (@next_token = @token.next).nil?
2437
+ @token.next = @tm.get_next_token
2438
+ return (@next_token_kind = @token.next.kind)
2439
+ end
2440
+ @next_token_kind = @next_token.kind
2441
+ end
2442
+
2443
+ def consume_token(kind)
2444
+ old = @token
2445
+
2446
+ if !@token.next.nil?
2447
+ @token = @token.next
2448
+ else
2449
+ @token = @token.next = @tm.get_next_token
2450
+ end
2451
+
2452
+ @next_token_kind = -1
2453
+ return @token if @token.kind == kind
2454
+ @token = old
2455
+ @token
2456
+ end
2457
+
2458
+ def get_token(index)
2459
+ t = @looking_ahead ? @scan_position : @token
2460
+ 0.upto(index - 1) do
2461
+ if !t.next.nil?
2462
+ t = t.next
2463
+ else
2464
+ t = t.next = @tm.get_next_token
2465
+ end
2466
+ end
2467
+ t
2468
+ end
2469
+
2470
+ def modules=(modules)
2471
+ @modules = modules
2472
+ end
2473
+
2474
+
2475
+ end