motion-markdown-it 4.4.0 → 8.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +69 -16
- data/lib/motion-markdown-it.rb +7 -5
- data/lib/motion-markdown-it/common/html_blocks.rb +6 -2
- data/lib/motion-markdown-it/common/utils.rb +19 -4
- data/lib/motion-markdown-it/helpers/helper_wrapper.rb +9 -0
- data/lib/motion-markdown-it/helpers/parse_link_destination.rb +8 -7
- data/lib/motion-markdown-it/index.rb +60 -18
- data/lib/motion-markdown-it/parser_block.rb +7 -10
- data/lib/motion-markdown-it/parser_inline.rb +50 -14
- data/lib/motion-markdown-it/presets/commonmark.rb +7 -1
- data/lib/motion-markdown-it/presets/default.rb +4 -3
- data/lib/motion-markdown-it/presets/zero.rb +6 -1
- data/lib/motion-markdown-it/renderer.rb +46 -14
- data/lib/motion-markdown-it/rules_block/blockquote.rb +167 -31
- data/lib/motion-markdown-it/rules_block/code.rb +4 -3
- data/lib/motion-markdown-it/rules_block/fence.rb +9 -4
- data/lib/motion-markdown-it/rules_block/heading.rb +8 -3
- data/lib/motion-markdown-it/rules_block/hr.rb +10 -5
- data/lib/motion-markdown-it/rules_block/html_block.rb +6 -3
- data/lib/motion-markdown-it/rules_block/lheading.rb +64 -26
- data/lib/motion-markdown-it/rules_block/list.rb +91 -22
- data/lib/motion-markdown-it/rules_block/paragraph.rb +14 -9
- data/lib/motion-markdown-it/rules_block/reference.rb +24 -14
- data/lib/motion-markdown-it/rules_block/state_block.rb +79 -24
- data/lib/motion-markdown-it/rules_block/table.rb +52 -26
- data/lib/motion-markdown-it/rules_core/normalize.rb +1 -23
- data/lib/motion-markdown-it/rules_core/replacements.rb +22 -2
- data/lib/motion-markdown-it/rules_core/smartquotes.rb +41 -12
- data/lib/motion-markdown-it/rules_inline/autolink.rb +5 -4
- data/lib/motion-markdown-it/rules_inline/balance_pairs.rb +48 -0
- data/lib/motion-markdown-it/rules_inline/emphasis.rb +104 -149
- data/lib/motion-markdown-it/rules_inline/entity.rb +2 -2
- data/lib/motion-markdown-it/rules_inline/escape.rb +5 -3
- data/lib/motion-markdown-it/rules_inline/image.rb +12 -23
- data/lib/motion-markdown-it/rules_inline/link.rb +20 -25
- data/lib/motion-markdown-it/rules_inline/newline.rb +2 -1
- data/lib/motion-markdown-it/rules_inline/state_inline.rb +60 -1
- data/lib/motion-markdown-it/rules_inline/strikethrough.rb +81 -97
- data/lib/motion-markdown-it/rules_inline/text_collapse.rb +40 -0
- data/lib/motion-markdown-it/token.rb +46 -1
- data/lib/motion-markdown-it/version.rb +1 -1
- data/spec/motion-markdown-it/markdown_it_spec.rb +2 -2
- data/spec/motion-markdown-it/misc_spec.rb +90 -14
- data/spec/motion-markdown-it/testgen_helper.rb +1 -1
- data/spec/spec_helper.rb +2 -3
- metadata +13 -13
- data/lib/motion-markdown-it/common/url_schemas.rb +0 -173
- data/spec/motion-markdown-it/bench_mark_spec.rb +0 -44
@@ -4,7 +4,7 @@ module MarkdownIt
|
|
4
4
|
module RulesInline
|
5
5
|
class Entity
|
6
6
|
extend Common::Utils
|
7
|
-
|
7
|
+
|
8
8
|
DIGITAL_RE = /^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i
|
9
9
|
NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i
|
10
10
|
|
@@ -33,7 +33,7 @@ module MarkdownIt
|
|
33
33
|
match = state.src.slice_to_end(pos).match(NAMED_RE)
|
34
34
|
if match
|
35
35
|
if HTMLEntities::MAPPINGS[match[1]]
|
36
|
-
state.pending += HTMLEntities::MAPPINGS[match[1]]
|
36
|
+
state.pending += fromCodePoint(HTMLEntities::MAPPINGS[match[1]]) if !silent
|
37
37
|
state.pos += match[0].length
|
38
38
|
return true
|
39
39
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# Process escaped chars and hardbreaks
|
2
2
|
#------------------------------------------------------------------------------
|
3
3
|
module MarkdownIt
|
4
4
|
module RulesInline
|
5
5
|
class Escape
|
6
|
+
extend Common::Utils
|
6
7
|
|
7
8
|
ESCAPED = []
|
8
9
|
|
@@ -36,7 +37,9 @@ module MarkdownIt
|
|
36
37
|
|
37
38
|
pos += 1
|
38
39
|
# skip leading whitespaces from next line
|
39
|
-
while
|
40
|
+
while pos < max
|
41
|
+
ch = state.src.charCodeAt(pos)
|
42
|
+
break if !isSpace(ch)
|
40
43
|
pos += 1
|
41
44
|
end
|
42
45
|
|
@@ -49,7 +52,6 @@ module MarkdownIt
|
|
49
52
|
state.pos += 1
|
50
53
|
return true
|
51
54
|
end
|
52
|
-
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -3,9 +3,6 @@
|
|
3
3
|
module MarkdownIt
|
4
4
|
module RulesInline
|
5
5
|
class Image
|
6
|
-
extend Helpers::ParseLinkDestination
|
7
|
-
extend Helpers::ParseLinkLabel
|
8
|
-
extend Helpers::ParseLinkTitle
|
9
6
|
extend Common::Utils
|
10
7
|
|
11
8
|
#------------------------------------------------------------------------------
|
@@ -18,7 +15,7 @@ module MarkdownIt
|
|
18
15
|
return false if (state.src.charCodeAt(state.pos + 1) != 0x5B) # [
|
19
16
|
|
20
17
|
labelStart = state.pos + 2
|
21
|
-
labelEnd = parseLinkLabel(state, state.pos + 1, false)
|
18
|
+
labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false)
|
22
19
|
|
23
20
|
# parser failed to find ']', so it's not a valid link
|
24
21
|
return false if (labelEnd < 0)
|
@@ -34,7 +31,7 @@ module MarkdownIt
|
|
34
31
|
pos += 1
|
35
32
|
while pos < max
|
36
33
|
code = state.src.charCodeAt(pos)
|
37
|
-
break if (code
|
34
|
+
break if (!isSpace(code) && code != 0x0A)
|
38
35
|
pos += 1
|
39
36
|
end
|
40
37
|
return false if (pos >= max)
|
@@ -42,7 +39,7 @@ module MarkdownIt
|
|
42
39
|
# [link]( <href> "title" )
|
43
40
|
# ^^^^^^ parsing link destination
|
44
41
|
start = pos
|
45
|
-
res = parseLinkDestination(state.src, pos, state.posMax)
|
42
|
+
res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax)
|
46
43
|
if (res[:ok])
|
47
44
|
href = state.md.normalizeLink.call(res[:str])
|
48
45
|
if (state.md.validateLink.call(href))
|
@@ -57,13 +54,13 @@ module MarkdownIt
|
|
57
54
|
start = pos
|
58
55
|
while pos < max
|
59
56
|
code = state.src.charCodeAt(pos)
|
60
|
-
break if (code
|
57
|
+
break if (!isSpace(code) && code != 0x0A)
|
61
58
|
pos += 1
|
62
59
|
end
|
63
60
|
|
64
61
|
# [link]( <href> "title" )
|
65
62
|
# ^^^^^^^ parsing link title
|
66
|
-
res = parseLinkTitle(state.src, pos, state.posMax)
|
63
|
+
res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax)
|
67
64
|
if (pos < max && start != pos && res[:ok])
|
68
65
|
title = res[:str]
|
69
66
|
pos = res[:pos]
|
@@ -72,7 +69,7 @@ module MarkdownIt
|
|
72
69
|
# ^^ skipping these spaces
|
73
70
|
while pos < max
|
74
71
|
code = state.src.charCodeAt(pos);
|
75
|
-
break if (code
|
72
|
+
break if (!isSpace(code) && code != 0x0A)
|
76
73
|
pos += 1
|
77
74
|
end
|
78
75
|
else
|
@@ -90,17 +87,9 @@ module MarkdownIt
|
|
90
87
|
#
|
91
88
|
return false if state.env[:references].nil?
|
92
89
|
|
93
|
-
# [foo] [bar]
|
94
|
-
# ^^ optional whitespace (can include newlines)
|
95
|
-
while pos < max
|
96
|
-
code = state.src.charCodeAt(pos)
|
97
|
-
break if (code != 0x20 && code != 0x0A)
|
98
|
-
pos += 1
|
99
|
-
end
|
100
|
-
|
101
90
|
if (pos < max && state.src.charCodeAt(pos) == 0x5B) # [
|
102
91
|
start = pos + 1
|
103
|
-
pos = parseLinkLabel(state, pos)
|
92
|
+
pos = state.md.helpers.parseLinkLabel(state, pos)
|
104
93
|
if (pos >= 0)
|
105
94
|
label = state.src.slice(start...pos)
|
106
95
|
pos += 1
|
@@ -129,20 +118,20 @@ module MarkdownIt
|
|
129
118
|
# so all that's left to do is to call tokenizer.
|
130
119
|
#
|
131
120
|
if (!silent)
|
132
|
-
state.
|
133
|
-
state.posMax = labelEnd
|
121
|
+
content = state.src.slice(labelStart...labelEnd)
|
134
122
|
|
135
|
-
|
136
|
-
|
123
|
+
state.md.inline.parse(
|
124
|
+
content,
|
137
125
|
state.md,
|
138
126
|
state.env,
|
139
127
|
tokens = []
|
140
128
|
)
|
141
|
-
newState.md.inline.tokenize(newState)
|
142
129
|
|
143
130
|
token = state.push('image', 'img', 0)
|
144
131
|
token.attrs = attrs = [ [ 'src', href ], [ 'alt', '' ] ]
|
145
132
|
token.children = tokens
|
133
|
+
token.content = content;
|
134
|
+
|
146
135
|
unless (title.nil? || title.empty?)
|
147
136
|
attrs.push([ 'title', title ])
|
148
137
|
end
|
@@ -3,22 +3,20 @@
|
|
3
3
|
module MarkdownIt
|
4
4
|
module RulesInline
|
5
5
|
class Link
|
6
|
-
extend Helpers::ParseLinkDestination
|
7
|
-
extend Helpers::ParseLinkLabel
|
8
|
-
extend Helpers::ParseLinkTitle
|
9
6
|
extend Common::Utils
|
10
7
|
|
11
8
|
#------------------------------------------------------------------------------
|
12
9
|
def self.link(state, silent)
|
13
|
-
href
|
14
|
-
oldPos
|
15
|
-
max
|
16
|
-
start
|
10
|
+
href = ''
|
11
|
+
oldPos = state.pos
|
12
|
+
max = state.posMax
|
13
|
+
start = state.pos
|
14
|
+
parseReference = true
|
17
15
|
|
18
16
|
return false if (state.src.charCodeAt(state.pos) != 0x5B) # [
|
19
17
|
|
20
18
|
labelStart = state.pos + 1
|
21
|
-
labelEnd = parseLinkLabel(state, state.pos, true)
|
19
|
+
labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true)
|
22
20
|
|
23
21
|
# parser failed to find ']', so it's not a valid link
|
24
22
|
return false if (labelEnd < 0)
|
@@ -29,12 +27,15 @@ module MarkdownIt
|
|
29
27
|
# Inline link
|
30
28
|
#
|
31
29
|
|
30
|
+
# might have found a valid shortcut link, disable reference parsing
|
31
|
+
parseReference = false
|
32
|
+
|
32
33
|
# [link]( <href> "title" )
|
33
34
|
# ^^ skipping these spaces
|
34
35
|
pos += 1
|
35
36
|
while pos < max
|
36
37
|
code = state.src.charCodeAt(pos)
|
37
|
-
break if (code
|
38
|
+
break if (!isSpace(code) && code != 0x0A)
|
38
39
|
pos += 1
|
39
40
|
end
|
40
41
|
return false if (pos >= max)
|
@@ -42,7 +43,7 @@ module MarkdownIt
|
|
42
43
|
# [link]( <href> "title" )
|
43
44
|
# ^^^^^^ parsing link destination
|
44
45
|
start = pos
|
45
|
-
res = parseLinkDestination(state.src, pos, state.posMax)
|
46
|
+
res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax)
|
46
47
|
if (res[:ok])
|
47
48
|
href = state.md.normalizeLink.call(res[:str])
|
48
49
|
if (state.md.validateLink.call(href))
|
@@ -57,13 +58,13 @@ module MarkdownIt
|
|
57
58
|
start = pos
|
58
59
|
while pos < max
|
59
60
|
code = state.src.charCodeAt(pos)
|
60
|
-
break if (code
|
61
|
+
break if (!isSpace(code) && code != 0x0A)
|
61
62
|
pos += 1
|
62
63
|
end
|
63
64
|
|
64
65
|
# [link]( <href> "title" )
|
65
66
|
# ^^^^^^^ parsing link title
|
66
|
-
res = parseLinkTitle(state.src, pos, state.posMax)
|
67
|
+
res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax)
|
67
68
|
if (pos < max && start != pos && res[:ok])
|
68
69
|
title = res[:str]
|
69
70
|
pos = res[:pos]
|
@@ -72,7 +73,7 @@ module MarkdownIt
|
|
72
73
|
# ^^ skipping these spaces
|
73
74
|
while pos < max
|
74
75
|
code = state.src.charCodeAt(pos)
|
75
|
-
break if (code
|
76
|
+
break if (!isSpace(code) && code != 0x0A)
|
76
77
|
pos += 1
|
77
78
|
end
|
78
79
|
else
|
@@ -80,27 +81,21 @@ module MarkdownIt
|
|
80
81
|
end
|
81
82
|
|
82
83
|
if (pos >= max || state.src.charCodeAt(pos) != 0x29) # )
|
83
|
-
|
84
|
-
|
84
|
+
# parsing a valid shortcut link failed, fallback to reference
|
85
|
+
parseReference = true
|
85
86
|
end
|
86
87
|
pos += 1
|
87
|
-
|
88
|
+
end
|
89
|
+
|
90
|
+
if parseReference
|
88
91
|
#
|
89
92
|
# Link reference
|
90
93
|
#
|
91
94
|
return false if state.env[:references].nil?
|
92
95
|
|
93
|
-
# [foo] [bar]
|
94
|
-
# ^^ optional whitespace (can include newlines)
|
95
|
-
while pos < max
|
96
|
-
code = state.src.charCodeAt(pos);
|
97
|
-
break if (code != 0x20 && code != 0x0A)
|
98
|
-
pos += 1
|
99
|
-
end
|
100
|
-
|
101
96
|
if (pos < max && state.src.charCodeAt(pos) == 0x5B) # [
|
102
97
|
start = pos + 1
|
103
|
-
pos = parseLinkLabel(state, pos)
|
98
|
+
pos = state.md.helpers.parseLinkLabel(state, pos)
|
104
99
|
if (pos >= 0)
|
105
100
|
label = state.src.slice(start...pos)
|
106
101
|
pos += 1
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module MarkdownIt
|
4
4
|
module RulesInline
|
5
5
|
class Newline
|
6
|
+
extend Common::Utils
|
6
7
|
|
7
8
|
#------------------------------------------------------------------------------
|
8
9
|
def self.newline(state, silent)
|
@@ -34,7 +35,7 @@ module MarkdownIt
|
|
34
35
|
pos += 1
|
35
36
|
|
36
37
|
# skip heading spaces for next line
|
37
|
-
while pos < max && state.src.charCodeAt(pos)
|
38
|
+
while pos < max && isSpace(state.src.charCodeAt(pos))
|
38
39
|
pos += 1
|
39
40
|
end
|
40
41
|
|
@@ -3,9 +3,10 @@
|
|
3
3
|
module MarkdownIt
|
4
4
|
module RulesInline
|
5
5
|
class StateInline
|
6
|
+
include MarkdownIt::Common::Utils
|
6
7
|
|
7
8
|
attr_accessor :src, :env, :md, :tokens, :pos, :posMax, :level
|
8
|
-
attr_accessor :pending, :pendingLevel, :cache
|
9
|
+
attr_accessor :pending, :pendingLevel, :cache, :delimiters
|
9
10
|
|
10
11
|
#------------------------------------------------------------------------------
|
11
12
|
def initialize(src, md, env, outTokens)
|
@@ -22,6 +23,7 @@ module MarkdownIt
|
|
22
23
|
|
23
24
|
@cache = {} # Stores { start: end } pairs. Useful for backtrack
|
24
25
|
# optimization of pairs parse (emphasis, strikes).
|
26
|
+
@delimiters = []
|
25
27
|
end
|
26
28
|
|
27
29
|
|
@@ -52,6 +54,63 @@ module MarkdownIt
|
|
52
54
|
return token
|
53
55
|
end
|
54
56
|
|
57
|
+
# Scan a sequence of emphasis-like markers, and determine whether
|
58
|
+
# it can start an emphasis sequence or end an emphasis sequence.
|
59
|
+
#
|
60
|
+
# - start - position to scan from (it should point at a valid marker);
|
61
|
+
# - canSplitWord - determine if these markers can be found inside a word
|
62
|
+
#------------------------------------------------------------------------------
|
63
|
+
def scanDelims(start, canSplitWord)
|
64
|
+
pos = start
|
65
|
+
left_flanking = true
|
66
|
+
right_flanking = true
|
67
|
+
max = @posMax
|
68
|
+
marker = @src.charCodeAt(start)
|
69
|
+
|
70
|
+
# treat beginning of the line as a whitespace
|
71
|
+
lastChar = start > 0 ? @src.charCodeAt(start - 1) : 0x20
|
72
|
+
|
73
|
+
while (pos < max && @src.charCodeAt(pos) == marker)
|
74
|
+
pos += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
count = pos - start
|
78
|
+
|
79
|
+
# treat end of the line as a whitespace
|
80
|
+
nextChar = pos < max ? @src.charCodeAt(pos) : 0x20
|
81
|
+
|
82
|
+
isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(fromCodePoint(lastChar))
|
83
|
+
isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(fromCodePoint(nextChar))
|
84
|
+
|
85
|
+
isLastWhiteSpace = isWhiteSpace(lastChar)
|
86
|
+
isNextWhiteSpace = isWhiteSpace(nextChar)
|
87
|
+
|
88
|
+
if (isNextWhiteSpace)
|
89
|
+
left_flanking = false
|
90
|
+
elsif (isNextPunctChar)
|
91
|
+
if (!(isLastWhiteSpace || isLastPunctChar))
|
92
|
+
left_flanking = false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if isLastWhiteSpace
|
97
|
+
right_flanking = false
|
98
|
+
elsif isLastPunctChar
|
99
|
+
if !(isNextWhiteSpace || isNextPunctChar)
|
100
|
+
right_flanking = false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if !canSplitWord
|
105
|
+
can_open = left_flanking && (!right_flanking || isLastPunctChar)
|
106
|
+
can_close = right_flanking && (!left_flanking || isNextPunctChar)
|
107
|
+
else
|
108
|
+
can_open = left_flanking
|
109
|
+
can_close = right_flanking
|
110
|
+
end
|
111
|
+
|
112
|
+
return { can_open: can_open, can_close: can_close, length: count }
|
113
|
+
end
|
55
114
|
end
|
56
115
|
end
|
57
116
|
end
|
@@ -4,127 +4,111 @@ module MarkdownIt
|
|
4
4
|
module RulesInline
|
5
5
|
class Strikethrough
|
6
6
|
extend Common::Utils
|
7
|
-
|
8
|
-
# parse sequence of markers,
|
9
|
-
# "start" should point at a valid marker
|
10
|
-
def self.scanDelims(state, start)
|
11
|
-
pos = start
|
12
|
-
can_open = true
|
13
|
-
can_close = true
|
14
|
-
max = state.posMax
|
15
|
-
marker = state.src.charCodeAt(start)
|
16
|
-
|
17
|
-
# treat beginning of the line as a whitespace
|
18
|
-
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : 0x20
|
19
|
-
|
20
|
-
while (pos < max && state.src.charCodeAt(pos) == marker)
|
21
|
-
pos += 1
|
22
|
-
end
|
23
7
|
|
24
|
-
|
25
|
-
|
26
|
-
|
8
|
+
# Insert each marker as a separate text token, and add it to delimiter list
|
9
|
+
#------------------------------------------------------------------------------
|
10
|
+
def self.tokenize(state, silent)
|
11
|
+
start = state.pos
|
12
|
+
marker = state.src.charCodeAt(start)
|
27
13
|
|
28
|
-
|
14
|
+
return false if silent
|
29
15
|
|
30
|
-
|
31
|
-
nextChar = pos < max ? state.src.charCodeAt(pos) : 0x20
|
16
|
+
return false if marker != 0x7E # ~
|
32
17
|
|
33
|
-
|
34
|
-
|
18
|
+
scanned = state.scanDelims(state.pos, true)
|
19
|
+
len = scanned[:length]
|
20
|
+
ch = fromCodePoint(marker)
|
35
21
|
|
36
|
-
|
37
|
-
isNextWhiteSpace = isWhiteSpace(nextChar)
|
22
|
+
return false if len < 2
|
38
23
|
|
39
|
-
if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
can_open = false
|
44
|
-
end
|
24
|
+
if len % 2 > 0
|
25
|
+
token = state.push('text', '', 0)
|
26
|
+
token.content = ch
|
27
|
+
len -= 1
|
45
28
|
end
|
46
29
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
30
|
+
i = 0
|
31
|
+
while i < len
|
32
|
+
token = state.push('text', '', 0)
|
33
|
+
token.content = ch + ch
|
34
|
+
|
35
|
+
state.delimiters.push({
|
36
|
+
marker: marker,
|
37
|
+
length: scanned[:length],
|
38
|
+
jump: i,
|
39
|
+
token: state.tokens.length - 1,
|
40
|
+
level: state.level,
|
41
|
+
end: -1,
|
42
|
+
open: scanned[:can_open],
|
43
|
+
close: scanned[:can_close]
|
44
|
+
})
|
45
|
+
i += 2
|
53
46
|
end
|
54
47
|
|
55
|
-
|
48
|
+
state.pos += scanned[:length]
|
49
|
+
|
50
|
+
return true
|
56
51
|
end
|
57
52
|
|
53
|
+
# Walk through delimiter list and replace text tokens with tags
|
58
54
|
#------------------------------------------------------------------------------
|
59
|
-
def self.
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
def self.postProcess(state)
|
56
|
+
loneMarkers = []
|
57
|
+
delimiters = state.delimiters
|
58
|
+
max = state.delimiters.length
|
63
59
|
|
64
|
-
|
65
|
-
|
60
|
+
0.upto(max - 1) do |i|
|
61
|
+
startDelim = delimiters[i]
|
66
62
|
|
67
|
-
|
68
|
-
startCount = res[:delims]
|
69
|
-
if (!res[:can_open])
|
70
|
-
state.pos += startCount
|
71
|
-
# Earlier we checked !silent, but this implementation does not need it
|
72
|
-
state.pending += state.src.slice(start...state.pos)
|
73
|
-
return true
|
74
|
-
end
|
63
|
+
next if startDelim[:marker] != 0x7E # ~
|
75
64
|
|
76
|
-
|
77
|
-
return false if (stack <= 0)
|
78
|
-
state.pos = start + startCount
|
79
|
-
|
80
|
-
while (state.pos < max)
|
81
|
-
if (state.src.charCodeAt(state.pos) == marker)
|
82
|
-
res = scanDelims(state, state.pos)
|
83
|
-
count = res[:delims]
|
84
|
-
tagCount = (count / 2).floor
|
85
|
-
if (res[:can_close])
|
86
|
-
if (tagCount >= stack)
|
87
|
-
state.pos += count - 2
|
88
|
-
found = true
|
89
|
-
break
|
90
|
-
end
|
91
|
-
stack -= tagCount
|
92
|
-
state.pos += count
|
93
|
-
next
|
94
|
-
end
|
95
|
-
|
96
|
-
stack += tagCount if (res[:can_open])
|
97
|
-
state.pos += count
|
98
|
-
next
|
99
|
-
end
|
65
|
+
next if startDelim[:end] == -1
|
100
66
|
|
101
|
-
|
102
|
-
end
|
67
|
+
endDelim = delimiters[startDelim[:end]]
|
103
68
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
69
|
+
token = state.tokens[startDelim[:token]]
|
70
|
+
token.type = 's_open'
|
71
|
+
token.tag = 's'
|
72
|
+
token.nesting = 1
|
73
|
+
token.markup = '~~'
|
74
|
+
token.content = ''
|
109
75
|
|
110
|
-
|
111
|
-
|
112
|
-
|
76
|
+
token = state.tokens[endDelim[:token]]
|
77
|
+
token.type = 's_close'
|
78
|
+
token.tag = 's'
|
79
|
+
token.nesting = -1
|
80
|
+
token.markup = '~~'
|
81
|
+
token.content = ''
|
113
82
|
|
114
|
-
|
115
|
-
|
116
|
-
|
83
|
+
if (state.tokens[endDelim[:token] - 1].type == 'text' &&
|
84
|
+
state.tokens[endDelim[:token] - 1].content == '~')
|
85
|
+
loneMarkers.push(endDelim[:token] - 1)
|
86
|
+
end
|
87
|
+
end
|
117
88
|
|
118
|
-
|
89
|
+
# If a marker sequence has an odd number of characters, it's splitted
|
90
|
+
# like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the
|
91
|
+
# start of the sequence.
|
92
|
+
#
|
93
|
+
# So, we have to move all those markers after subsequent s_close tags.
|
94
|
+
#
|
95
|
+
while loneMarkers.length > 0
|
96
|
+
i = loneMarkers.pop
|
97
|
+
j = i + 1
|
98
|
+
|
99
|
+
while j < state.tokens.length && state.tokens[j].type == 's_close'
|
100
|
+
j += 1
|
101
|
+
end
|
119
102
|
|
120
|
-
|
121
|
-
token.markup = '~~'
|
103
|
+
j -= 1
|
122
104
|
|
123
|
-
|
124
|
-
|
125
|
-
|
105
|
+
if i != j
|
106
|
+
token = state.tokens[j]
|
107
|
+
state.tokens[j] = state.tokens[i]
|
108
|
+
state.tokens[i] = token
|
109
|
+
end
|
110
|
+
end
|
126
111
|
end
|
127
|
-
|
128
112
|
end
|
129
113
|
end
|
130
114
|
end
|