motion-markdown-it 11.0.0 → 12.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -11
- data/lib/motion-markdown-it/common/html_blocks.rb +1 -2
- data/lib/motion-markdown-it/common/html_re.rb +2 -2
- data/lib/motion-markdown-it/helpers/parse_link_destination.rb +3 -0
- data/lib/motion-markdown-it/helpers/parse_link_title.rb +3 -1
- data/lib/motion-markdown-it/index.rb +2 -1
- data/lib/motion-markdown-it/parser_block.rb +2 -2
- data/lib/motion-markdown-it/renderer.rb +9 -3
- data/lib/motion-markdown-it/rules_block/blockquote.rb +6 -7
- data/lib/motion-markdown-it/rules_block/table.rb +74 -47
- data/lib/motion-markdown-it/rules_core/smartquotes.rb +2 -2
- data/lib/motion-markdown-it/rules_inline/autolink.rb +17 -13
- data/lib/motion-markdown-it/rules_inline/backticks.rb +21 -3
- data/lib/motion-markdown-it/rules_inline/balance_pairs.rb +7 -7
- data/lib/motion-markdown-it/rules_inline/link.rb +2 -3
- data/lib/motion-markdown-it/rules_inline/state_inline.rb +7 -2
- data/lib/motion-markdown-it/rules_inline/strikethrough.rb +2 -2
- data/lib/motion-markdown-it/token.rb +4 -1
- data/lib/motion-markdown-it/version.rb +1 -1
- data/spec/motion-markdown-it/misc_spec.rb +21 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74ae9a8bfdbc637f5e2127d34919298661b7d4f32b55830053a0c30012cd1ddf
|
4
|
+
data.tar.gz: 5787ec92937c5e8ef19fead547c0fae14b0de4507c0098cb5e8a79720dab611e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72214978791be3e608c627bfa80db56a1ca30df9650a1df85bef0c2a99fb68b822a1464261595779f16385a9e69cf9898fbd15966ba5e00ad969d4a0568c028a
|
7
|
+
data.tar.gz: 5e2ede784f3386d45b930789abb2c0a05ee8bc2dffb707d736c437e48fe722b9084dc75f2032bea6a8d47b723d0daac43428fb059e1ac1f7c6fa92dfad4a83e7
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ Ruby/RubyMotion version of Markdown-it (CommonMark compliant and extendable)
|
|
7
7
|
|
8
8
|
This gem is a port of the [markdown-it Javascript package](https://github.com/markdown-it/markdown-it) by Vitaly Puzrin and Alex Kocharin.
|
9
9
|
|
10
|
-
_Currently synced with markdown-it
|
10
|
+
_Currently synced with markdown-it 12.0.6_
|
11
11
|
|
12
12
|
---
|
13
13
|
|
@@ -54,15 +54,14 @@ redcarpet 3.4.0 0.0065
|
|
54
54
|
|
55
55
|
## Table of content
|
56
56
|
|
57
|
-
- [
|
58
|
-
|
59
|
-
- [
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
- [License](#license)
|
57
|
+
- [Install](#install)
|
58
|
+
- [Usage examples](#usage-examples)
|
59
|
+
- [Simple](#simple)
|
60
|
+
- [Init with presets and options](#init-with-presets-and-options)
|
61
|
+
- [Plugins](#plugins)
|
62
|
+
- [Upgrading](#upgrading)
|
63
|
+
- [References / Thanks](#references--thanks)
|
64
|
+
- [License](#license)
|
66
65
|
|
67
66
|
<!--
|
68
67
|
- [API](#api)
|
@@ -134,6 +133,7 @@ parser = MarkdownIt::Parser.new({
|
|
134
133
|
linkify: false, # Autoconvert URL-like text to links
|
135
134
|
|
136
135
|
# Enable some language-neutral replacement + quotes beautification
|
136
|
+
# For the full list of replacements, see https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js
|
137
137
|
typographer: false,
|
138
138
|
|
139
139
|
# Double + single quotes replacement pairs, when typographer enabled,
|
@@ -221,7 +221,7 @@ var md = require('markdown-it')({
|
|
221
221
|
configure linkify-it, access the linkify instance through `md.linkify`:
|
222
222
|
|
223
223
|
```js
|
224
|
-
md.linkify.
|
224
|
+
md.linkify.set({ fuzzyEmail: false }); // disables converting email to link
|
225
225
|
```
|
226
226
|
|
227
227
|
|
@@ -17,7 +17,7 @@ module MarkdownIt
|
|
17
17
|
|
18
18
|
CLOSE_TAG = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'
|
19
19
|
COMMENT = '<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->'
|
20
|
-
PROCESSING = '<[?]
|
20
|
+
PROCESSING = '<[?][\\s\\S]*?[?]>'
|
21
21
|
DECLARATION = '<![A-Z]+\\s+[^>]*>'
|
22
22
|
CDATA = '<!\\[CDATA\\[[\\s\\S]*?\\]\\]>'
|
23
23
|
|
@@ -27,4 +27,4 @@ module MarkdownIt
|
|
27
27
|
HTML_OPEN_CLOSE_TAG_RE = Regexp.new('^(?:' + OPEN_TAG + '|' + CLOSE_TAG + ')')
|
28
28
|
end
|
29
29
|
end
|
30
|
-
end
|
30
|
+
end
|
@@ -16,6 +16,7 @@ module MarkdownIt
|
|
16
16
|
while (pos < max)
|
17
17
|
code = charCodeAt(str, pos)
|
18
18
|
return result if (code == 0x0A) # \n
|
19
|
+
return result if (code == 0x3C) # <
|
19
20
|
if (code == 0x3E) # >
|
20
21
|
result[:pos] = pos + 1
|
21
22
|
result[:str] = unescapeAll(str.slice((start + 1)...pos))
|
@@ -46,12 +47,14 @@ module MarkdownIt
|
|
46
47
|
break if (code < 0x20 || code == 0x7F)
|
47
48
|
|
48
49
|
if (code == 0x5C && pos + 1 < max) # \
|
50
|
+
break if (charCodeAt(str, pos + 1) == 0x20)
|
49
51
|
pos += 2
|
50
52
|
next
|
51
53
|
end
|
52
54
|
|
53
55
|
if (code == 0x28) # (
|
54
56
|
level += 1
|
57
|
+
return result if (level > 32)
|
55
58
|
end
|
56
59
|
|
57
60
|
if (code == 0x29) # )
|
@@ -29,6 +29,8 @@ module MarkdownIt
|
|
29
29
|
result[:str] = unescapeAll(str.slice((start + 1)...pos))
|
30
30
|
result[:ok] = true
|
31
31
|
return result
|
32
|
+
elsif (code == 0x28 && marker == 0x29) # ( and )
|
33
|
+
return result
|
32
34
|
elsif (code == 0x0A)
|
33
35
|
lines += 1
|
34
36
|
elsif (code == 0x5C && pos + 1 < max) # \
|
@@ -45,4 +47,4 @@ module MarkdownIt
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
48
|
-
end
|
50
|
+
end
|
@@ -69,7 +69,8 @@ NORMALIZE_LINK_TEXT = lambda do |url|
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
|
72
|
+
# add '%' to exclude list because of https://github.com/markdown-it/markdown-it/issues/720
|
73
|
+
return MDUrl::Decode.decode(MDUrl::Format.format(parsed), MDUrl::Decode::DEFTAULT_CHARS + '%')
|
73
74
|
end
|
74
75
|
|
75
76
|
|
@@ -18,9 +18,9 @@ module MarkdownIt
|
|
18
18
|
[ 'hr', lambda { |state, startLine, endLine, silent| RulesBlock::Hr.hr(state, startLine, endLine, silent) }, [ 'paragraph', 'reference', 'blockquote', 'list' ] ],
|
19
19
|
[ 'list', lambda { |state, startLine, endLine, silent| RulesBlock::List.list(state, startLine, endLine, silent) }, [ 'paragraph', 'reference', 'blockquote' ] ],
|
20
20
|
[ 'reference', lambda { |state, startLine, endLine, silent| RulesBlock::Reference.reference(state, startLine, endLine, silent) } ],
|
21
|
+
[ 'html_block', lambda { |state, startLine, endLine, silent| RulesBlock::HtmlBlock.html_block(state, startLine, endLine, silent) }, [ 'paragraph', 'reference', 'blockquote' ] ],
|
21
22
|
[ 'heading', lambda { |state, startLine, endLine, silent| RulesBlock::Heading.heading(state, startLine, endLine, silent) }, [ 'paragraph', 'reference', 'blockquote' ] ],
|
22
23
|
[ 'lheading', lambda { |state, startLine, endLine, silent| RulesBlock::Lheading.lheading(state, startLine, endLine, silent) } ],
|
23
|
-
[ 'html_block', lambda { |state, startLine, endLine, silent| RulesBlock::HtmlBlock.html_block(state, startLine, endLine, silent) }, [ 'paragraph', 'reference', 'blockquote' ] ],
|
24
24
|
[ 'paragraph', lambda { |state, startLine, endLine, silent| RulesBlock::Paragraph.paragraph(state, startLine) } ]
|
25
25
|
]
|
26
26
|
|
@@ -107,4 +107,4 @@ module MarkdownIt
|
|
107
107
|
end
|
108
108
|
|
109
109
|
end
|
110
|
-
end
|
110
|
+
end
|
@@ -35,13 +35,16 @@ module MarkdownIt
|
|
35
35
|
token = tokens[idx]
|
36
36
|
info = token.info ? unescapeAll(token.info).strip : ''
|
37
37
|
langName = ''
|
38
|
+
langAttrs = ''
|
38
39
|
|
39
40
|
if !info.empty?
|
40
|
-
|
41
|
+
arr = info.split(/\s+/)
|
42
|
+
langName = arr[0]
|
43
|
+
langAttrs = arr[1..-1].join(' ')
|
41
44
|
end
|
42
45
|
|
43
46
|
if options[:highlight]
|
44
|
-
highlighted = options[:highlight].call(token.content, langName) || escapeHtml(token.content)
|
47
|
+
highlighted = options[:highlight].call(token.content, langName, langAttrs) || escapeHtml(token.content)
|
45
48
|
else
|
46
49
|
highlighted = escapeHtml(token.content)
|
47
50
|
end
|
@@ -51,7 +54,7 @@ module MarkdownIt
|
|
51
54
|
end
|
52
55
|
|
53
56
|
# If language exists, inject class gently, without modifying original token.
|
54
|
-
# May be, one day we will add .
|
57
|
+
# May be, one day we will add .deepClone() for token and simplify this part, but
|
55
58
|
# now we prefer to keep things local.
|
56
59
|
if !info.empty?
|
57
60
|
i = token.attrIndex('class')
|
@@ -60,6 +63,7 @@ module MarkdownIt
|
|
60
63
|
if i < 0
|
61
64
|
tmpAttrs.push([ 'class', options[:langPrefix] + langName ])
|
62
65
|
else
|
66
|
+
tmpAttrs[i] = tmpAttrs[i].slice(0..-1)
|
63
67
|
tmpAttrs[i][1] += ' ' + options[:langPrefix] + langName
|
64
68
|
end
|
65
69
|
|
@@ -283,6 +287,8 @@ module MarkdownIt
|
|
283
287
|
result += tokens[i].content
|
284
288
|
elsif tokens[i].type == 'image'
|
285
289
|
result += renderInlineAsText(tokens[i].children, options, env)
|
290
|
+
elsif tokens[i].type == 'softbreak'
|
291
|
+
result += "\n"
|
286
292
|
end
|
287
293
|
end
|
288
294
|
|
@@ -22,8 +22,8 @@ module MarkdownIt
|
|
22
22
|
# so no point trying to find the end of it in silent mode
|
23
23
|
return true if silent
|
24
24
|
|
25
|
-
#
|
26
|
-
initial = offset = state.sCount[startLine] +
|
25
|
+
# set offset past spaces and ">"
|
26
|
+
initial = offset = state.sCount[startLine] + 1
|
27
27
|
|
28
28
|
# skip one optional space after '>'
|
29
29
|
if charCodeAt(state.src, pos) == 0x20 # space
|
@@ -88,7 +88,6 @@ module MarkdownIt
|
|
88
88
|
|
89
89
|
oldParentType = state.parentType
|
90
90
|
state.parentType = 'blockquote'
|
91
|
-
wasOutdented = false
|
92
91
|
|
93
92
|
# Search the end of the block
|
94
93
|
#
|
@@ -118,7 +117,7 @@ module MarkdownIt
|
|
118
117
|
# > current blockquote
|
119
118
|
# 2. checking this line
|
120
119
|
# ```
|
121
|
-
|
120
|
+
isOutdented = state.sCount[nextLine] < state.blkIndent
|
122
121
|
|
123
122
|
pos = state.bMarks[nextLine] + state.tShift[nextLine]
|
124
123
|
max = state.eMarks[nextLine]
|
@@ -128,12 +127,12 @@ module MarkdownIt
|
|
128
127
|
break
|
129
128
|
end
|
130
129
|
|
131
|
-
if charCodeAt(state.src, pos) == 0x3E && !
|
130
|
+
if charCodeAt(state.src, pos) == 0x3E && !isOutdented # >
|
132
131
|
pos += 1
|
133
132
|
# This line is inside the blockquote.
|
134
133
|
|
135
|
-
#
|
136
|
-
initial = offset = state.sCount[nextLine] +
|
134
|
+
# set offset past spaces and ">"
|
135
|
+
initial = offset = state.sCount[nextLine] + 1
|
137
136
|
|
138
137
|
# skip one optional space after '>'
|
139
138
|
if charCodeAt(state.src, pos) == 0x20 # space
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# GFM table,
|
1
|
+
# GFM table, https://github.github.com/gfm/#tables-extension-
|
2
2
|
#------------------------------------------------------------------------------
|
3
3
|
module MarkdownIt
|
4
4
|
module RulesBlock
|
@@ -7,7 +7,7 @@ module MarkdownIt
|
|
7
7
|
|
8
8
|
#------------------------------------------------------------------------------
|
9
9
|
def self.getLine(state, line)
|
10
|
-
pos = state.bMarks[line] + state.
|
10
|
+
pos = state.bMarks[line] + state.tShift[line]
|
11
11
|
max = state.eMarks[line]
|
12
12
|
|
13
13
|
return state.src[pos, max - pos]
|
@@ -18,51 +18,37 @@ module MarkdownIt
|
|
18
18
|
result = []
|
19
19
|
pos = 0
|
20
20
|
max = str.length
|
21
|
-
|
21
|
+
isEscaped = false
|
22
22
|
lastPos = 0
|
23
|
-
|
24
|
-
lastBackTick = 0
|
23
|
+
current = ''
|
25
24
|
|
26
25
|
ch = charCodeAt(str, pos)
|
27
26
|
|
28
27
|
while (pos < max)
|
29
|
-
if ch ==
|
30
|
-
if (
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
if ch == 0x7c # |
|
29
|
+
if (!isEscaped)
|
30
|
+
# pipe separating cells, '|'
|
31
|
+
result.push(current + str[lastPos...pos])
|
32
|
+
current = ''
|
33
|
+
lastPos = pos + 1
|
34
|
+
else
|
35
|
+
# escaped pipe, '\|'
|
36
|
+
current += str[lastPos...(pos - 1)]
|
37
|
+
lastPos = pos
|
38
38
|
end
|
39
|
-
elsif (ch == 0x7c && (escapes % 2 == 0) && !backTicked) # '|'
|
40
|
-
result.push(str[lastPos...pos])
|
41
|
-
lastPos = pos + 1
|
42
|
-
end
|
43
|
-
|
44
|
-
if ch == 0x5c # '\'
|
45
|
-
escapes += 1
|
46
|
-
else
|
47
|
-
escapes = 0
|
48
39
|
end
|
49
40
|
|
41
|
+
isEscaped = (ch == 0x5c) # '\'
|
50
42
|
pos += 1
|
51
|
-
|
52
|
-
|
53
|
-
if (pos == max && backTicked)
|
54
|
-
backTicked = false
|
55
|
-
pos = lastBackTick + 1
|
56
|
-
end
|
57
|
-
ch = charCodeAt(str, pos)
|
43
|
+
|
44
|
+
ch = charCodeAt(str, pos)
|
58
45
|
end
|
59
46
|
|
60
|
-
result.push(str[lastPos..-1])
|
47
|
+
result.push(current + str[lastPos..-1])
|
61
48
|
|
62
49
|
return result
|
63
50
|
end
|
64
51
|
|
65
|
-
|
66
52
|
#------------------------------------------------------------------------------
|
67
53
|
def self.table(state, startLine, endLine, silent)
|
68
54
|
# should have at least two lines
|
@@ -82,9 +68,19 @@ module MarkdownIt
|
|
82
68
|
pos = state.bMarks[nextLine] + state.tShift[nextLine]
|
83
69
|
return false if (pos >= state.eMarks[nextLine])
|
84
70
|
|
85
|
-
|
71
|
+
firstCh = charCodeAt(state.src, pos)
|
72
|
+
pos += 1
|
73
|
+
return false if (firstCh != 0x7C && firstCh != 0x2D && firstCh != 0x3A) # | or - or :
|
74
|
+
|
75
|
+
return false if (pos >= state.eMarks[nextLine])
|
76
|
+
|
77
|
+
secondCh = charCodeAt(state.src, pos)
|
86
78
|
pos += 1
|
87
|
-
return false if (
|
79
|
+
return false if (secondCh != 0x7C && secondCh != 0x2D && secondCh != 0x3A && !isSpace(secondCh)) # | or - or :
|
80
|
+
|
81
|
+
# if first character is '-', then second character must not be a space
|
82
|
+
# (due to parsing ambiguity with list)
|
83
|
+
return false if (firstCh === 0x2D && isSpace(secondCh)) # -
|
88
84
|
|
89
85
|
while pos < state.eMarks[nextLine]
|
90
86
|
ch = charCodeAt(state.src, pos)
|
@@ -122,15 +118,25 @@ module MarkdownIt
|
|
122
118
|
lineText = getLine(state, startLine).strip
|
123
119
|
return false if !lineText.include?('|')
|
124
120
|
return false if state.sCount[startLine] - state.blkIndent >= 4
|
125
|
-
columns = self.escapedSplit(lineText
|
121
|
+
columns = self.escapedSplit(lineText)
|
122
|
+
|
123
|
+
columns.shift if (columns.length && columns[0] == '')
|
124
|
+
columns.pop if (columns.length && columns[columns.length - 1] == '')
|
126
125
|
|
127
126
|
# header row will define an amount of columns in the entire table,
|
128
|
-
# and align row
|
127
|
+
# and align row should be exactly the same (the rest of the rows can differ)
|
129
128
|
columnCount = columns.length
|
130
|
-
return false if columnCount
|
129
|
+
return false if columnCount == 0 || columnCount != aligns.length
|
131
130
|
|
132
131
|
return true if silent
|
133
132
|
|
133
|
+
oldParentType = state.parentType
|
134
|
+
state.parentType = 'table'
|
135
|
+
|
136
|
+
# use 'blockquote' lists for termination because it's
|
137
|
+
# the most similar to tables
|
138
|
+
terminatorRules = state.md.block.ruler.getRules('blockquote')
|
139
|
+
|
134
140
|
token = state.push('table_open', 'table', 1)
|
135
141
|
token.map = tableLines = [ startLine, 0 ]
|
136
142
|
|
@@ -142,14 +148,12 @@ module MarkdownIt
|
|
142
148
|
|
143
149
|
(0...columns.length).each do |i|
|
144
150
|
token = state.push('th_open', 'th', 1)
|
145
|
-
token.map = [ startLine, startLine + 1 ]
|
146
151
|
unless aligns[i].empty?
|
147
152
|
token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]
|
148
153
|
end
|
149
154
|
|
150
155
|
token = state.push('inline', '', 0)
|
151
156
|
token.content = columns[i].strip
|
152
|
-
token.map = [ startLine, startLine + 1 ]
|
153
157
|
token.children = []
|
154
158
|
|
155
159
|
token = state.push('th_close', 'th', -1)
|
@@ -158,21 +162,38 @@ module MarkdownIt
|
|
158
162
|
token = state.push('tr_close', 'tr', -1)
|
159
163
|
token = state.push('thead_close', 'thead', -1)
|
160
164
|
|
161
|
-
token = state.push('tbody_open', 'tbody', 1)
|
162
|
-
token.map = tbodyLines = [ startLine + 2, 0 ]
|
163
|
-
|
164
165
|
nextLine = startLine + 2
|
165
166
|
while nextLine < endLine
|
166
167
|
break if (state.sCount[nextLine] < state.blkIndent)
|
167
168
|
|
169
|
+
terminate = false
|
170
|
+
(0...terminatorRules.length).each do |i|
|
171
|
+
if (terminatorRules[i].call(state, nextLine, endLine, true))
|
172
|
+
terminate = true
|
173
|
+
break
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
break if (terminate)
|
178
|
+
|
168
179
|
lineText = getLine(state, nextLine).strip
|
169
|
-
break if
|
180
|
+
break if lineText.empty?
|
170
181
|
break if state.sCount[nextLine] - state.blkIndent >= 4
|
171
|
-
columns = self.escapedSplit(lineText
|
182
|
+
columns = self.escapedSplit(lineText)
|
183
|
+
columns.shift if (columns.length && columns[0] == '')
|
184
|
+
columns.pop if (columns.length && columns[columns.length - 1] == '')
|
185
|
+
|
186
|
+
if (nextLine == startLine + 2)
|
187
|
+
token = state.push('tbody_open', 'tbody', 1)
|
188
|
+
token.map = tbodyLines = [ startLine + 2, 0 ]
|
189
|
+
end
|
190
|
+
|
191
|
+
token = state.push('tr_open', 'tr', 1)
|
192
|
+
token.map = [ nextLine, nextLine + 1 ]
|
172
193
|
|
173
|
-
token = state.push('tr_open', 'tr', 1)
|
174
194
|
(0...columnCount).each do |i|
|
175
195
|
token = state.push('td_open', 'td', 1)
|
196
|
+
token.map = [ nextLine, nextLine + 1 ]
|
176
197
|
unless aligns[i].empty?
|
177
198
|
token.attrs = [ [ 'style', 'text-align:' + aligns[i] ] ]
|
178
199
|
end
|
@@ -186,10 +207,16 @@ module MarkdownIt
|
|
186
207
|
token = state.push('tr_close', 'tr', -1)
|
187
208
|
nextLine += 1
|
188
209
|
end
|
189
|
-
|
210
|
+
|
211
|
+
if (tbodyLines)
|
212
|
+
token = state.push('tbody_close', 'tbody', -1)
|
213
|
+
tbodyLines[1] = nextLine
|
214
|
+
end
|
215
|
+
|
190
216
|
token = state.push('table_close', 'table', -1)
|
217
|
+
tableLines[1] = nextLine
|
191
218
|
|
192
|
-
|
219
|
+
state.parentType = oldParentType
|
193
220
|
state.line = nextLine
|
194
221
|
return true
|
195
222
|
end
|
@@ -59,7 +59,7 @@ module MarkdownIt
|
|
59
59
|
else
|
60
60
|
(i - 1).downto(0) do |j|
|
61
61
|
break if tokens[j].type == 'softbreak' || tokens[j].type == 'hardbreak' # lastChar defaults to 0x20
|
62
|
-
next if tokens[j].
|
62
|
+
next if tokens[j].content.empty? # should skip all tokens except 'text', 'html_inline' or 'code_inline'
|
63
63
|
|
64
64
|
lastChar = charCodeAt(tokens[j].content, tokens[j].content.length - 1)
|
65
65
|
break
|
@@ -76,7 +76,7 @@ module MarkdownIt
|
|
76
76
|
else
|
77
77
|
(i + 1).upto(tokens.length - 1) do |j|
|
78
78
|
break if tokens[j].type == 'softbreak' || tokens[j].type == 'hardbreak' # nextChar defaults to 0x20
|
79
|
-
next if tokens[j].
|
79
|
+
next if tokens[j].content.empty? # should skip all tokens except 'text', 'html_inline' or 'code_inline'
|
80
80
|
|
81
81
|
nextChar = charCodeAt(tokens[j].content, 0)
|
82
82
|
break
|
@@ -5,8 +5,8 @@ module MarkdownIt
|
|
5
5
|
class Autolink
|
6
6
|
extend Common::Utils
|
7
7
|
|
8
|
-
EMAIL_RE =
|
9
|
-
AUTOLINK_RE =
|
8
|
+
EMAIL_RE = /^([a-zA-Z0-9.!#$\%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/
|
9
|
+
AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$/
|
10
10
|
|
11
11
|
#------------------------------------------------------------------------------
|
12
12
|
def self.autolink(state, silent)
|
@@ -14,14 +14,21 @@ module MarkdownIt
|
|
14
14
|
|
15
15
|
return false if (charCodeAt(state.src, pos) != 0x3C) # <
|
16
16
|
|
17
|
-
|
17
|
+
start = state.pos
|
18
|
+
max = state.posMax
|
18
19
|
|
19
|
-
|
20
|
+
loop do
|
21
|
+
return false if ((pos += 1) >= max)
|
20
22
|
|
21
|
-
|
22
|
-
linkMatch = tail.match(AUTOLINK_RE)
|
23
|
+
ch = charCodeAt(state.src, pos)
|
23
24
|
|
24
|
-
|
25
|
+
return false if (ch == 0x3C) # <
|
26
|
+
break if (ch == 0x3E) # >
|
27
|
+
end
|
28
|
+
|
29
|
+
url = state.src.slice((start + 1)...pos)
|
30
|
+
|
31
|
+
if (AUTOLINK_RE =~ url)
|
25
32
|
fullUrl = state.md.normalizeLink.call(url)
|
26
33
|
return false if (!state.md.validateLink.call(fullUrl))
|
27
34
|
|
@@ -39,14 +46,11 @@ module MarkdownIt
|
|
39
46
|
token.info = 'auto'
|
40
47
|
end
|
41
48
|
|
42
|
-
state.pos +=
|
49
|
+
state.pos += url.length + 2
|
43
50
|
return true
|
44
51
|
end
|
45
52
|
|
46
|
-
if (EMAIL_RE =~
|
47
|
-
emailMatch = tail.match(EMAIL_RE)
|
48
|
-
|
49
|
-
url = emailMatch[0].slice(1...-1)
|
53
|
+
if (EMAIL_RE =~ url)
|
50
54
|
fullUrl = state.md.normalizeLink.call('mailto:' + url)
|
51
55
|
return false if (!state.md.validateLink.call(fullUrl))
|
52
56
|
|
@@ -64,7 +68,7 @@ module MarkdownIt
|
|
64
68
|
token.info = 'auto'
|
65
69
|
end
|
66
70
|
|
67
|
-
state.pos +=
|
71
|
+
state.pos += url.length + 2
|
68
72
|
return true
|
69
73
|
end
|
70
74
|
|
@@ -16,22 +16,35 @@ module MarkdownIt
|
|
16
16
|
pos += 1
|
17
17
|
max = state.posMax
|
18
18
|
|
19
|
+
# scan marker length
|
19
20
|
while (pos < max && charCodeAt(state.src, pos) == 0x60) # `
|
20
21
|
pos += 1
|
21
22
|
end
|
22
23
|
|
23
24
|
marker = state.src.slice(start...pos)
|
25
|
+
openerLength = marker.length
|
26
|
+
|
27
|
+
if (state.backticksScanned && (state.backticks[openerLength] || 0) <= start)
|
28
|
+
state.pending += marker if (!silent)
|
29
|
+
state.pos += openerLength
|
30
|
+
return true
|
31
|
+
end
|
24
32
|
|
25
33
|
matchStart = matchEnd = pos
|
26
34
|
|
35
|
+
# Nothing found in the cache, scan until the end of the line (or until marker is found)
|
27
36
|
while ((matchStart = state.src.index('`', matchEnd)) != nil)
|
28
37
|
matchEnd = matchStart + 1
|
29
38
|
|
39
|
+
# scan marker length
|
30
40
|
while (matchEnd < max && charCodeAt(state.src, matchEnd) == 0x60) # `
|
31
41
|
matchEnd += 1
|
32
42
|
end
|
33
43
|
|
34
|
-
|
44
|
+
closerLength = matchEnd - matchStart
|
45
|
+
|
46
|
+
if (closerLength == openerLength)
|
47
|
+
# Found matching closer length.
|
35
48
|
if (!silent)
|
36
49
|
token = state.push('code_inline', 'code', 0)
|
37
50
|
token.markup = marker
|
@@ -42,13 +55,18 @@ module MarkdownIt
|
|
42
55
|
state.pos = matchEnd
|
43
56
|
return true
|
44
57
|
end
|
58
|
+
|
59
|
+
# Some different length found, put it in cache as upper limit of where closer can be found
|
60
|
+
state.backticks[closerLength] = matchStart
|
45
61
|
end
|
46
62
|
|
63
|
+
# Scanned through the end, didn't find anything
|
64
|
+
state.backticksScanned = true
|
65
|
+
|
47
66
|
state.pending += marker if (!silent)
|
48
|
-
state.pos +=
|
67
|
+
state.pos += openerLength
|
49
68
|
return true
|
50
69
|
end
|
51
|
-
|
52
70
|
end
|
53
71
|
end
|
54
72
|
end
|
@@ -27,20 +27,20 @@ module MarkdownIt
|
|
27
27
|
end
|
28
28
|
|
29
29
|
minOpenerIdx = openersBottom[closer[:marker]][closer[:length] % 3]
|
30
|
-
newMinOpenerIdx = -1
|
31
30
|
|
32
31
|
openerIdx = closerIdx - closer[:jump] - 1
|
33
|
-
|
32
|
+
|
33
|
+
# avoid crash if `closer.jump` is pointing outside of the array, see #742
|
34
|
+
openerIdx = -1 if (openerIdx < -1)
|
35
|
+
|
36
|
+
newMinOpenerIdx = openerIdx
|
37
|
+
|
34
38
|
while openerIdx > minOpenerIdx
|
35
39
|
opener = delimiters[openerIdx]
|
36
40
|
|
37
41
|
(openerIdx -= opener[:jump] + 1) && next if (opener[:marker] != closer[:marker])
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
if (opener[:open] &&
|
42
|
-
opener[:end] < 0 &&
|
43
|
-
opener[:level] == closer[:level])
|
43
|
+
if (opener[:open] && opener[:end] < 0)
|
44
44
|
|
45
45
|
isOddMatch = false
|
46
46
|
|
@@ -8,6 +8,7 @@ module MarkdownIt
|
|
8
8
|
#------------------------------------------------------------------------------
|
9
9
|
def self.link(state, silent)
|
10
10
|
href = ''
|
11
|
+
title = ''
|
11
12
|
oldPos = state.pos
|
12
13
|
max = state.posMax
|
13
14
|
start = state.pos
|
@@ -76,8 +77,6 @@ module MarkdownIt
|
|
76
77
|
break if (!isSpace(code) && code != 0x0A)
|
77
78
|
pos += 1
|
78
79
|
end
|
79
|
-
else
|
80
|
-
title = ''
|
81
80
|
end
|
82
81
|
|
83
82
|
if (pos >= max || charCodeAt(state.src, pos) != 0x29) # )
|
@@ -145,4 +144,4 @@ module MarkdownIt
|
|
145
144
|
|
146
145
|
end
|
147
146
|
end
|
148
|
-
end
|
147
|
+
end
|
@@ -5,8 +5,9 @@ module MarkdownIt
|
|
5
5
|
class StateInline
|
6
6
|
include MarkdownIt::Common::Utils
|
7
7
|
|
8
|
-
attr_accessor
|
9
|
-
attr_accessor
|
8
|
+
attr_accessor :src, :env, :md, :tokens, :pos, :posMax, :level, :tokens_meta
|
9
|
+
attr_accessor :pending, :pendingLevel, :cache, :delimiters
|
10
|
+
attr_accessor :backticks, :backticksScanned
|
10
11
|
|
11
12
|
#------------------------------------------------------------------------------
|
12
13
|
def initialize(src, md, env, outTokens)
|
@@ -31,6 +32,10 @@ module MarkdownIt
|
|
31
32
|
|
32
33
|
# Stack of delimiter lists for upper level tags
|
33
34
|
@_prev_delimiters = [];
|
35
|
+
|
36
|
+
# backtick length => last seen position
|
37
|
+
@backticks = {}
|
38
|
+
@backticksScanned = false
|
34
39
|
end
|
35
40
|
|
36
41
|
|
@@ -34,8 +34,8 @@ module MarkdownIt
|
|
34
34
|
|
35
35
|
state.delimiters.push({
|
36
36
|
marker: marker,
|
37
|
-
length: 0,
|
38
|
-
jump: i,
|
37
|
+
length: 0, # disable "rule of 3" length checks meant for emphasis
|
38
|
+
jump: i / 2, # for `~~` 1 marker = 2 characters
|
39
39
|
token: state.tokens.length - 1,
|
40
40
|
end: -1,
|
41
41
|
open: scanned[:can_open],
|
@@ -63,7 +63,10 @@ module MarkdownIt
|
|
63
63
|
|
64
64
|
# * Token#info -> String
|
65
65
|
# *
|
66
|
-
# *
|
66
|
+
# * Additional information:
|
67
|
+
# *
|
68
|
+
# * - Info string for "fence" tokens
|
69
|
+
# * - The value "auto" for autolink "link_open" and "link_close" tokens
|
67
70
|
@info = ''
|
68
71
|
|
69
72
|
# * Token#meta -> Object
|
@@ -48,7 +48,7 @@ describe 'API' do
|
|
48
48
|
#------------------------------------------------------------------------------
|
49
49
|
it 'highlight' do
|
50
50
|
md = MarkdownIt::Parser.new({
|
51
|
-
highlight: lambda do |str, obj|
|
51
|
+
highlight: lambda do |str, obj, attrs|
|
52
52
|
return '<pre><code>==' + str + '==</code></pre>'
|
53
53
|
end
|
54
54
|
})
|
@@ -58,12 +58,24 @@ describe 'API' do
|
|
58
58
|
|
59
59
|
#------------------------------------------------------------------------------
|
60
60
|
it 'highlight escape by default' do
|
61
|
-
md = MarkdownIt::Parser.new({highlight: lambda {|value, obj| return nil }})
|
61
|
+
md = MarkdownIt::Parser.new({highlight: lambda {|value, obj, attrs| return nil }})
|
62
62
|
|
63
|
-
# assert.strictEqual(md.render("```\n&\n```"), "<pre><code>&\n</code></pre>\n");
|
64
63
|
expect(md.render("```\n&\n```")).to eq "<pre><code>&\n</code></pre>\n"
|
65
64
|
end
|
66
65
|
|
66
|
+
#------------------------------------------------------------------------------
|
67
|
+
it 'highlight arguments' do
|
68
|
+
md = MarkdownIt::Parser.new({
|
69
|
+
highlight: lambda do |str, lang, attrs|
|
70
|
+
expect(lang).to eq 'a'
|
71
|
+
expect(attrs).to eq 'b c d'
|
72
|
+
return '<pre><code>==' + str + '==</code></pre>'
|
73
|
+
end
|
74
|
+
})
|
75
|
+
|
76
|
+
expect(md.render("``` a b c d \nhl\n```")).to eq"<pre><code>==hl\n==</code></pre>\n"
|
77
|
+
end
|
78
|
+
|
67
79
|
#------------------------------------------------------------------------------
|
68
80
|
it 'force hardbreaks' do
|
69
81
|
md = MarkdownIt::Parser.new({ breaks: false })
|
@@ -281,12 +293,12 @@ describe 'Url normalization' do
|
|
281
293
|
return 'TEXT'
|
282
294
|
end
|
283
295
|
|
284
|
-
expect(md.render('foo@example.com')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
285
|
-
expect(md.render('http://example.com')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
286
|
-
expect(md.render('<foo@example.com>')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
287
|
-
expect(md.render('<http://example.com>')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
296
|
+
# expect(md.render('foo@example.com')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
297
|
+
# expect(md.render('http://example.com')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
298
|
+
# expect(md.render('<foo@example.com>')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
299
|
+
# expect(md.render('<http://example.com>')).to eq "<p><a href=\"LINK\">TEXT</a></p>\n"
|
288
300
|
expect(md.render('[test](http://example.com)')).to eq "<p><a href=\"LINK\">test</a></p>\n"
|
289
|
-
expect(md.render('')).to eq "<p><img src=\"LINK\" alt=\"test\"></p>\n"
|
301
|
+
# expect(md.render('')).to eq "<p><img src=\"LINK\" alt=\"test\"></p>\n"
|
290
302
|
end
|
291
303
|
|
292
304
|
end
|
@@ -403,4 +415,4 @@ describe 'Token attributes' do
|
|
403
415
|
|
404
416
|
expect(t.attrGet('myattr')).to eq 'myvalue'
|
405
417
|
end
|
406
|
-
end
|
418
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-markdown-it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 12.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Walker
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-01-
|
13
|
+
date: 2023-01-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mdurl-rb
|