motion-markdown-it 12.3.2 → 13.0.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 +2 -2
- data/lib/motion-markdown-it/parser_core.rb +4 -1
- data/lib/motion-markdown-it/parser_inline.rb +11 -2
- data/lib/motion-markdown-it/presets/commonmark.rb +3 -2
- data/lib/motion-markdown-it/presets/zero.rb +4 -3
- data/lib/motion-markdown-it/rules_block/table.rb +1 -1
- data/lib/motion-markdown-it/rules_core/linkify.rb +11 -1
- data/lib/motion-markdown-it/rules_core/replacements.rb +2 -3
- data/lib/motion-markdown-it/rules_core/text_join.rb +51 -0
- data/lib/motion-markdown-it/rules_inline/entity.rb +27 -22
- data/lib/motion-markdown-it/rules_inline/escape.rb +41 -22
- data/lib/motion-markdown-it/rules_inline/{text_collapse.rb → fragments_join.rb} +23 -22
- data/lib/motion-markdown-it/rules_inline/html_inline.rb +11 -0
- data/lib/motion-markdown-it/rules_inline/link.rb +3 -1
- data/lib/motion-markdown-it/rules_inline/linkify.rb +60 -0
- data/lib/motion-markdown-it/rules_inline/state_inline.rb +5 -1
- data/lib/motion-markdown-it/version.rb +1 -1
- data/lib/motion-markdown-it.rb +4 -2
- data/spec/motion-markdown-it/misc_spec.rb +8 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 527ad2365d9f847959cb068d6483944ece97a6f25198b159c342fd09d340e7f1
|
4
|
+
data.tar.gz: de08e3d6331f1fe3e359df0e935cead71a259bb211885084000e6b93ed9cd909
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7abfc3bd88c7f30e93826a1ae27a00d95c8f47f6f9e634a739ddf597c7a0ffdc73fd295fa353f0e306861e5301b0190aba2f8fd1e56e4ffee5d3c61383be7f45
|
7
|
+
data.tar.gz: 10896d6c58b7d9675b52833ef975c77441fb4fa7c295aa6f38325226dd10de80609c892a1969f431bb0ce4b12565feb36a9ab6bdbfe4277cd116f5e43379dd08
|
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 13.0.1_
|
11
11
|
|
12
12
|
---
|
13
13
|
|
@@ -260,7 +260,7 @@ By default all rules are enabled, but can be restricted by options. On plugin
|
|
260
260
|
load all its rules are enabled automatically.
|
261
261
|
|
262
262
|
```js
|
263
|
-
// Activate/deactivate rules, with
|
263
|
+
// Activate/deactivate rules, with currying
|
264
264
|
var md = require('markdown-it')()
|
265
265
|
.disable([ 'link', 'image' ])
|
266
266
|
.enable([ 'link' ])
|
@@ -10,12 +10,15 @@ module MarkdownIt
|
|
10
10
|
attr_accessor :ruler
|
11
11
|
|
12
12
|
RULES = [
|
13
|
-
[ 'normalize', lambda { |state| RulesCore::Normalize.normalize(state) }
|
13
|
+
[ 'normalize', lambda { |state| RulesCore::Normalize.normalize(state) } ],
|
14
14
|
[ 'block', lambda { |state| RulesCore::Block.block(state) } ],
|
15
15
|
[ 'inline', lambda { |state| RulesCore::Inline.inline(state) } ],
|
16
16
|
[ 'linkify', lambda { |state| RulesCore::Linkify.linkify(state) } ],
|
17
17
|
[ 'replacements', lambda { |state| RulesCore::Replacements.replace(state) } ],
|
18
18
|
[ 'smartquotes', lambda { |state| RulesCore::Smartquotes.smartquotes(state) } ],
|
19
|
+
# `text_join` finds `text_special` tokens (for escape sequences)
|
20
|
+
# and joins them with the rest of the text
|
21
|
+
[ 'text_join', lambda { |state| RulesCore::TextJoin.text_join(state) } ],
|
19
22
|
]
|
20
23
|
|
21
24
|
|
@@ -13,6 +13,7 @@ module MarkdownIt
|
|
13
13
|
|
14
14
|
RULES = [
|
15
15
|
[ 'text', lambda { |state, startLine| RulesInline::Text.text(state, startLine) } ],
|
16
|
+
[ 'linkify', lambda { |state, silent| RulesInline::Linkify.linkify(state, silent) } ],
|
16
17
|
[ 'newline', lambda { |state, startLine| RulesInline::Newline.newline(state, startLine) } ],
|
17
18
|
[ 'escape', lambda { |state, startLine| RulesInline::Escape.escape(state, startLine) } ],
|
18
19
|
[ 'backticks', lambda { |state, startLine| RulesInline::Backticks.backtick(state, startLine) } ],
|
@@ -25,11 +26,19 @@ module MarkdownIt
|
|
25
26
|
[ 'entity', lambda { |state, startLine| RulesInline::Entity.entity(state, startLine) } ],
|
26
27
|
]
|
27
28
|
|
29
|
+
# `rule2` ruleset was created specifically for emphasis/strikethrough
|
30
|
+
# post-processing and may be changed in the future.
|
31
|
+
#
|
32
|
+
# Don't use this for anything except pairs (plugins working with `balance_pairs`).
|
33
|
+
#
|
28
34
|
RULES2 = [
|
29
35
|
[ 'balance_pairs', lambda { |state| RulesInline::BalancePairs.link_pairs(state) } ],
|
30
36
|
[ 'strikethrough', lambda { |state| RulesInline::Strikethrough.postProcess(state) } ],
|
31
37
|
[ 'emphasis', lambda { |state| RulesInline::Emphasis.postProcess(state) } ],
|
32
|
-
[ 'text_collapse', lambda { |state| RulesInline::TextCollapse.text_collapse(state) } ]
|
38
|
+
# [ 'text_collapse', lambda { |state| RulesInline::TextCollapse.text_collapse(state) } ]
|
39
|
+
# rules for pairs separate '**' into its own text tokens, which may be left unused,
|
40
|
+
# rule below merges unused segments back with the rest of the text
|
41
|
+
[ 'fragments_join', lambda { |state| RulesInline::FragmentsJoin.fragments_join(state) } ]
|
33
42
|
];
|
34
43
|
|
35
44
|
#------------------------------------------------------------------------------
|
@@ -154,4 +163,4 @@ module MarkdownIt
|
|
154
163
|
end
|
155
164
|
end
|
156
165
|
end
|
157
|
-
end
|
166
|
+
end
|
@@ -39,7 +39,8 @@ module MarkdownIt
|
|
39
39
|
rules: [
|
40
40
|
'normalize',
|
41
41
|
'block',
|
42
|
-
'inline'
|
42
|
+
'inline',
|
43
|
+
'text_join'
|
43
44
|
]
|
44
45
|
},
|
45
46
|
|
@@ -74,7 +75,7 @@ module MarkdownIt
|
|
74
75
|
rules2: [
|
75
76
|
'balance_pairs',
|
76
77
|
'emphasis',
|
77
|
-
'
|
78
|
+
'fragments_join'
|
78
79
|
]
|
79
80
|
}
|
80
81
|
}
|
@@ -40,7 +40,8 @@ module MarkdownIt
|
|
40
40
|
rules: [
|
41
41
|
'normalize',
|
42
42
|
'block',
|
43
|
-
'inline'
|
43
|
+
'inline',
|
44
|
+
'text_join'
|
44
45
|
]
|
45
46
|
},
|
46
47
|
|
@@ -56,7 +57,7 @@ module MarkdownIt
|
|
56
57
|
],
|
57
58
|
rules2: [
|
58
59
|
'balance_pairs',
|
59
|
-
'
|
60
|
+
'fragments_join'
|
60
61
|
]
|
61
62
|
}
|
62
63
|
}
|
@@ -64,4 +65,4 @@ module MarkdownIt
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
end
|
67
|
-
end
|
68
|
+
end
|
@@ -66,6 +66,16 @@ module MarkdownIt
|
|
66
66
|
level = currentToken.level
|
67
67
|
lastPos = 0
|
68
68
|
|
69
|
+
# forbid escape sequence at the start of the string,
|
70
|
+
# this avoids http\://example.com/ from being linkified as
|
71
|
+
# http:<a href="//example.com/">//example.com/</a>
|
72
|
+
if (links.length > 0 &&
|
73
|
+
links[0].index == 0 &&
|
74
|
+
i > 0 &&
|
75
|
+
tokens[i - 1].type == 'text_special')
|
76
|
+
links = links.slice(1..-1)
|
77
|
+
end
|
78
|
+
|
69
79
|
(0...links.length).each do |ln|
|
70
80
|
url = links[ln].url
|
71
81
|
fullUrl = state.md.normalizeLink.call(url)
|
@@ -133,4 +143,4 @@ module MarkdownIt
|
|
133
143
|
|
134
144
|
end
|
135
145
|
end
|
136
|
-
end
|
146
|
+
end
|
@@ -15,15 +15,14 @@ module MarkdownIt
|
|
15
15
|
|
16
16
|
# TODO (from original)
|
17
17
|
# - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾
|
18
|
-
# -
|
18
|
+
# - multiplications 2 x 4 -> 2 × 4
|
19
19
|
|
20
20
|
RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/
|
21
21
|
|
22
|
-
SCOPED_ABBR_RE = /\((c|tm|r
|
22
|
+
SCOPED_ABBR_RE = /\((c|tm|r)\)/i
|
23
23
|
SCOPED_ABBR = {
|
24
24
|
'c' => '©',
|
25
25
|
'r' => '®',
|
26
|
-
'p' => '§',
|
27
26
|
'tm' => '™'
|
28
27
|
}
|
29
28
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Join raw text tokens with the rest of the text
|
2
|
+
#
|
3
|
+
# This is set as a separate rule to provide an opportunity for plugins
|
4
|
+
# to run text replacements after text join, but before escape join.
|
5
|
+
#
|
6
|
+
# For example, `\:)` shouldn't be replaced with an emoji.
|
7
|
+
#
|
8
|
+
module MarkdownIt
|
9
|
+
module RulesCore
|
10
|
+
class TextJoin
|
11
|
+
def self.text_join(state)
|
12
|
+
blockTokens = state.tokens
|
13
|
+
|
14
|
+
(0...blockTokens.length).each do |j|
|
15
|
+
next if (blockTokens[j].type != 'inline')
|
16
|
+
|
17
|
+
tokens = blockTokens[j].children
|
18
|
+
max = tokens.length
|
19
|
+
|
20
|
+
(0...max).each do |curr|
|
21
|
+
if (tokens[curr].type == 'text_special')
|
22
|
+
tokens[curr].type = 'text'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
last = 0
|
27
|
+
curr = 0
|
28
|
+
while curr < max
|
29
|
+
if (tokens[curr].type == 'text' &&
|
30
|
+
curr + 1 < max &&
|
31
|
+
tokens[curr + 1].type == 'text')
|
32
|
+
|
33
|
+
# collapse two adjacent text nodes
|
34
|
+
tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content
|
35
|
+
else
|
36
|
+
tokens[last] = tokens[curr] if (curr != last)
|
37
|
+
|
38
|
+
last += 1
|
39
|
+
end
|
40
|
+
|
41
|
+
curr += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
if (curr != last)
|
45
|
+
tokens.pop(tokens.length - last)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -8,44 +8,49 @@ module MarkdownIt
|
|
8
8
|
DIGITAL_RE = /^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i
|
9
9
|
NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i
|
10
10
|
|
11
|
-
|
12
11
|
#------------------------------------------------------------------------------
|
13
12
|
def self.entity(state, silent)
|
14
13
|
pos = state.pos
|
15
14
|
max = state.posMax
|
16
15
|
|
17
|
-
return false if charCodeAt(state.src, pos) != 0x26
|
16
|
+
return false if charCodeAt(state.src, pos) != 0x26 # &
|
17
|
+
|
18
|
+
return false if pos + 1 >= max
|
18
19
|
|
19
|
-
|
20
|
-
ch = charCodeAt(state.src, pos + 1)
|
20
|
+
ch = charCodeAt(state.src, pos + 1)
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
if ch == 0x23 # '#'
|
23
|
+
match = state.src[pos..-1].match(DIGITAL_RE)
|
24
|
+
if match
|
25
|
+
if !silent
|
26
|
+
code = match[1][0].downcase == 'x' ? match[1][1..-1].to_i(16) : match[1].to_i
|
27
|
+
|
28
|
+
token = state.push('text_special', '', 0)
|
29
|
+
token.content = isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD)
|
30
|
+
token.markup = match[0]
|
31
|
+
token.info = 'entity'
|
32
|
+
end
|
33
|
+
state.pos += match[0].length
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
else
|
37
|
+
match = state.src[pos..-1].match(NAMED_RE)
|
38
|
+
if match
|
39
|
+
if MarkdownIt::HTMLEntities::MAPPINGS[match[1]]
|
25
40
|
if !silent
|
26
|
-
|
27
|
-
|
41
|
+
token = state.push('text_special', '', 0)
|
42
|
+
token.content += fromCodePoint(MarkdownIt::HTMLEntities::MAPPINGS[match[1]])
|
43
|
+
token.markup = match[0]
|
44
|
+
token.info = 'entity'
|
28
45
|
end
|
29
46
|
state.pos += match[0].length
|
30
47
|
return true
|
31
48
|
end
|
32
|
-
else
|
33
|
-
match = state.src[pos..-1].match(NAMED_RE)
|
34
|
-
if match
|
35
|
-
if MarkdownIt::HTMLEntities::MAPPINGS[match[1]]
|
36
|
-
state.pending += fromCodePoint(MarkdownIt::HTMLEntities::MAPPINGS[match[1]]) if !silent
|
37
|
-
state.pos += match[0].length
|
38
|
-
return true
|
39
|
-
end
|
40
|
-
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
|
44
|
-
|
45
|
-
state.pos += 1
|
46
|
-
return true
|
52
|
+
return false
|
47
53
|
end
|
48
|
-
|
49
54
|
end
|
50
55
|
end
|
51
56
|
end
|
@@ -11,7 +11,6 @@ module MarkdownIt
|
|
11
11
|
|
12
12
|
'\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-'.split('').each { |ch| ESCAPED[ch.ord] = 1 }
|
13
13
|
|
14
|
-
|
15
14
|
#------------------------------------------------------------------------------
|
16
15
|
def self.escape(state, silent)
|
17
16
|
pos = state.pos
|
@@ -21,35 +20,55 @@ module MarkdownIt
|
|
21
20
|
|
22
21
|
pos += 1
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
# '\' at the end of the inline block
|
24
|
+
return false if pos >= max
|
25
|
+
|
26
|
+
ch1 = charCodeAt(state.src, pos)
|
27
|
+
|
28
|
+
if ch1 == 0x0A
|
29
|
+
if !silent
|
30
|
+
state.push('hardbreak', 'br', 0)
|
31
|
+
end
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
33
|
+
pos += 1
|
34
|
+
# skip leading whitespaces from next line
|
35
|
+
while pos < max
|
36
|
+
ch1 = charCodeAt(state.src, pos)
|
37
|
+
break if !isSpace(ch1)
|
38
|
+
pos += 1
|
31
39
|
end
|
32
40
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
state.pos = pos
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
|
45
|
+
escapedStr = state.src[pos]
|
37
46
|
|
47
|
+
if (ch1 >= 0xD800 && ch1 <= 0xDBFF && pos + 1 < max)
|
48
|
+
ch2 = charCodeAt(state.src, pos + 1)
|
49
|
+
|
50
|
+
if (ch2 >= 0xDC00 && ch2 <= 0xDFFF)
|
51
|
+
escapedStr += state.src[pos + 1]
|
38
52
|
pos += 1
|
39
|
-
# skip leading whitespaces from next line
|
40
|
-
while pos < max
|
41
|
-
ch = charCodeAt(state.src, pos)
|
42
|
-
break if !isSpace(ch)
|
43
|
-
pos += 1
|
44
|
-
end
|
45
|
-
|
46
|
-
state.pos = pos
|
47
|
-
return true
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
51
|
-
|
52
|
-
|
56
|
+
origStr = '\\' + escapedStr
|
57
|
+
|
58
|
+
if (!silent)
|
59
|
+
token = state.push('text_special', '', 0)
|
60
|
+
|
61
|
+
if ch1 < 256 && ESCAPED[ch1] != 0
|
62
|
+
token.content = escapedStr
|
63
|
+
else
|
64
|
+
token.content = origStr
|
65
|
+
end
|
66
|
+
|
67
|
+
token.markup = origStr
|
68
|
+
token.info = 'escape'
|
69
|
+
end
|
70
|
+
|
71
|
+
state.pos = pos + 1
|
53
72
|
return true
|
54
73
|
end
|
55
74
|
end
|
@@ -1,47 +1,48 @@
|
|
1
1
|
# Clean up tokens after emphasis and strikethrough postprocessing:
|
2
|
-
#
|
2
|
+
# merge adjacent text nodes into one and re-calculate all token levels
|
3
3
|
#
|
4
4
|
# This is necessary because initially emphasis delimiter markers (*, _, ~)
|
5
5
|
# are treated as their own separate text tokens. Then emphasis rule either
|
6
6
|
# leaves them as text (needed to merge with adjacent text) or turns them
|
7
7
|
# into opening/closing tags (which messes up levels inside).
|
8
|
-
|
8
|
+
#
|
9
9
|
module MarkdownIt
|
10
10
|
module RulesInline
|
11
|
-
class
|
11
|
+
class FragmentsJoin
|
12
|
+
extend Common::Utils
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
max = state.tokens.length
|
14
|
+
def self.fragments_join(state)
|
15
|
+
level = 0
|
16
|
+
tokens = state.tokens
|
17
|
+
max = state.tokens.length
|
18
18
|
|
19
|
-
last =
|
19
|
+
last = 0
|
20
|
+
curr = 0
|
20
21
|
while curr < max
|
21
22
|
# re-calculate levels after emphasis/strikethrough turns some text nodes
|
22
23
|
# into opening/closing tags
|
23
|
-
level -= 1 if tokens[curr].nesting < 0 # closing tag
|
24
|
+
level -= 1 if (tokens[curr].nesting < 0) # closing tag
|
24
25
|
tokens[curr].level = level
|
25
|
-
level +=
|
26
|
-
|
27
|
-
if tokens[curr].type == 'text' &&
|
26
|
+
level +=1 if (tokens[curr].nesting > 0) # opening tag
|
27
|
+
|
28
|
+
if (tokens[curr].type == 'text' &&
|
28
29
|
curr + 1 < max &&
|
29
|
-
tokens[curr + 1].type == 'text'
|
30
|
-
|
30
|
+
tokens[curr + 1].type == 'text')
|
31
|
+
|
31
32
|
# collapse two adjacent text nodes
|
32
33
|
tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content
|
33
34
|
else
|
34
|
-
tokens[last] = tokens[curr] if curr != last
|
35
|
-
|
35
|
+
tokens[last] = tokens[curr] if (curr != last)
|
36
|
+
|
36
37
|
last += 1
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
curr += 1
|
40
41
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
|
43
|
+
if (curr != last)
|
44
|
+
tokens.pop(tokens.length - last)
|
45
|
+
end
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
@@ -6,6 +6,14 @@ module MarkdownIt
|
|
6
6
|
extend Common::Utils
|
7
7
|
include MarkdownIt::Common::HtmlRe
|
8
8
|
|
9
|
+
#------------------------------------------------------------------------------
|
10
|
+
def self.isLinkOpen(str)
|
11
|
+
return !(/^<a[>\s]/i =~ str).nil?
|
12
|
+
end
|
13
|
+
def self.isLinkClose(str)
|
14
|
+
return !(/^<\/a\s*>/i =~ str).nil?
|
15
|
+
end
|
16
|
+
|
9
17
|
#------------------------------------------------------------------------------
|
10
18
|
def self.isLetter(ch)
|
11
19
|
lc = ch | 0x20 # to lower case
|
@@ -39,6 +47,9 @@ module MarkdownIt
|
|
39
47
|
if !silent
|
40
48
|
token = state.push('html_inline', '', 0)
|
41
49
|
token.content = state.src.slice(pos...(pos + match[0].length))
|
50
|
+
|
51
|
+
state.linkLevel += 1 if (isLinkOpen(token.content))
|
52
|
+
state.linkLevel -= 1 if (isLinkClose(token.content))
|
42
53
|
end
|
43
54
|
state.pos += match[0].length
|
44
55
|
return true
|
@@ -132,9 +132,11 @@ module MarkdownIt
|
|
132
132
|
attrs.push([ 'title', title ])
|
133
133
|
end
|
134
134
|
|
135
|
+
state.linkLevel += 1
|
135
136
|
state.md.inline.tokenize(state)
|
137
|
+
state.linkLevel -= 1
|
136
138
|
|
137
|
-
token
|
139
|
+
token = state.push('link_close', 'a', -1)
|
138
140
|
end
|
139
141
|
|
140
142
|
state.pos = pos
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Process links like https://example.org/
|
2
|
+
module MarkdownIt
|
3
|
+
module RulesInline
|
4
|
+
class Linkify
|
5
|
+
extend Common::Utils
|
6
|
+
|
7
|
+
# RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
8
|
+
SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i
|
9
|
+
|
10
|
+
#------------------------------------------------------------------------------
|
11
|
+
def self.linkify(state, silent)
|
12
|
+
return false if (!state.md.options[:linkify])
|
13
|
+
return false if (state.linkLevel > 0)
|
14
|
+
|
15
|
+
pos = state.pos
|
16
|
+
max = state.posMax
|
17
|
+
|
18
|
+
return false if (pos + 3 > max)
|
19
|
+
return false if (charCodeAt(state.src, pos) != 0x3A) # :
|
20
|
+
return false if (charCodeAt(state.src, pos + 1) != 0x2F) # /
|
21
|
+
return false if (charCodeAt(state.src, pos + 2) != 0x2F) # /
|
22
|
+
|
23
|
+
match = state.pending.match(SCHEME_RE)
|
24
|
+
return false if (!match)
|
25
|
+
|
26
|
+
proto = match[1]
|
27
|
+
|
28
|
+
link = state.md.linkify.matchAtStart(state.src.slice((pos - proto.length)..-1))
|
29
|
+
return false if (!link)
|
30
|
+
|
31
|
+
url = link.url
|
32
|
+
|
33
|
+
# disallow '*' at the end of the link (conflicts with emphasis)
|
34
|
+
url = url.sub(/\*+$/, '')
|
35
|
+
|
36
|
+
fullUrl = state.md.normalizeLink.call(url)
|
37
|
+
return false if (!state.md.validateLink.call(fullUrl))
|
38
|
+
|
39
|
+
if (!silent)
|
40
|
+
state.pending = state.pending[0...-proto.length]
|
41
|
+
|
42
|
+
token = state.push('link_open', 'a', 1)
|
43
|
+
token.attrs = [ [ 'href', fullUrl ] ]
|
44
|
+
token.markup = 'linkify'
|
45
|
+
token.info = 'auto'
|
46
|
+
|
47
|
+
token = state.push('text', '', 0)
|
48
|
+
token.content = state.md.normalizeLinkText.call(url)
|
49
|
+
|
50
|
+
token = state.push('link_close', 'a', -1)
|
51
|
+
token.markup = 'linkify'
|
52
|
+
token.info = 'auto'
|
53
|
+
end
|
54
|
+
|
55
|
+
state.pos += url.length - proto.length
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -7,7 +7,7 @@ module MarkdownIt
|
|
7
7
|
|
8
8
|
attr_accessor :src, :env, :md, :tokens, :pos, :posMax, :level, :tokens_meta
|
9
9
|
attr_accessor :pending, :pendingLevel, :cache, :delimiters
|
10
|
-
attr_accessor :backticks, :backticksScanned
|
10
|
+
attr_accessor :backticks, :backticksScanned, :linkLevel
|
11
11
|
|
12
12
|
#------------------------------------------------------------------------------
|
13
13
|
def initialize(src, md, env, outTokens)
|
@@ -36,6 +36,10 @@ module MarkdownIt
|
|
36
36
|
# backtick length => last seen position
|
37
37
|
@backticks = {}
|
38
38
|
@backticksScanned = false
|
39
|
+
|
40
|
+
# Counter used to disable inline linkify-it execution
|
41
|
+
# inside <a> and markdown links
|
42
|
+
@linkLevel = 0
|
39
43
|
end
|
40
44
|
|
41
45
|
|
data/lib/motion-markdown-it.rb
CHANGED
@@ -40,6 +40,7 @@ else
|
|
40
40
|
require 'motion-markdown-it/rules_core/replacements'
|
41
41
|
require 'motion-markdown-it/rules_core/smartquotes'
|
42
42
|
require 'motion-markdown-it/rules_core/state_core'
|
43
|
+
require 'motion-markdown-it/rules_core/text_join'
|
43
44
|
require 'motion-markdown-it/rules_block/blockquote'
|
44
45
|
require 'motion-markdown-it/rules_block/code'
|
45
46
|
require 'motion-markdown-it/rules_block/fence'
|
@@ -58,17 +59,18 @@ else
|
|
58
59
|
require 'motion-markdown-it/rules_inline/emphasis'
|
59
60
|
require 'motion-markdown-it/rules_inline/entity'
|
60
61
|
require 'motion-markdown-it/rules_inline/escape'
|
62
|
+
require 'motion-markdown-it/rules_inline/fragments_join'
|
61
63
|
require 'motion-markdown-it/rules_inline/html_inline'
|
62
64
|
require 'motion-markdown-it/rules_inline/image'
|
63
65
|
require 'motion-markdown-it/rules_inline/link'
|
66
|
+
require 'motion-markdown-it/rules_inline/linkify'
|
64
67
|
require 'motion-markdown-it/rules_inline/newline'
|
65
68
|
require 'motion-markdown-it/rules_inline/state_inline'
|
66
69
|
require 'motion-markdown-it/rules_inline/strikethrough'
|
67
|
-
require 'motion-markdown-it/rules_inline/text_collapse'
|
68
70
|
require 'motion-markdown-it/rules_inline/text'
|
69
71
|
|
70
72
|
require 'motion-markdown-it/ruler'
|
71
73
|
require 'motion-markdown-it/token'
|
72
74
|
require 'motion-markdown-it/index'
|
73
75
|
|
74
|
-
end
|
76
|
+
end
|
@@ -276,6 +276,14 @@ describe 'Misc' do
|
|
276
276
|
# );
|
277
277
|
# end
|
278
278
|
|
279
|
+
# TODO ------------------------------------------------------------------------------
|
280
|
+
# it 'Should escape surrogate pairs (coverage)' do
|
281
|
+
# md = MarkdownIt::Parser.new({})
|
282
|
+
#
|
283
|
+
# expect(md.render("\\\uD835\uDC9C")).to eq "<p>\\\uD835\uDC9C</p>\n"
|
284
|
+
# expect(md.render("\\\uD835x")).to eq "<p>\\\uD835x</p>\n"
|
285
|
+
# expect(md.render("\\\uD835")).to eq "<p>\\\uD835</p>\n"
|
286
|
+
# end
|
279
287
|
end
|
280
288
|
|
281
289
|
|
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: 13.0.1
|
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-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mdurl-rb
|
@@ -113,20 +113,22 @@ files:
|
|
113
113
|
- lib/motion-markdown-it/rules_core/replacements.rb
|
114
114
|
- lib/motion-markdown-it/rules_core/smartquotes.rb
|
115
115
|
- lib/motion-markdown-it/rules_core/state_core.rb
|
116
|
+
- lib/motion-markdown-it/rules_core/text_join.rb
|
116
117
|
- lib/motion-markdown-it/rules_inline/autolink.rb
|
117
118
|
- lib/motion-markdown-it/rules_inline/backticks.rb
|
118
119
|
- lib/motion-markdown-it/rules_inline/balance_pairs.rb
|
119
120
|
- lib/motion-markdown-it/rules_inline/emphasis.rb
|
120
121
|
- lib/motion-markdown-it/rules_inline/entity.rb
|
121
122
|
- lib/motion-markdown-it/rules_inline/escape.rb
|
123
|
+
- lib/motion-markdown-it/rules_inline/fragments_join.rb
|
122
124
|
- lib/motion-markdown-it/rules_inline/html_inline.rb
|
123
125
|
- lib/motion-markdown-it/rules_inline/image.rb
|
124
126
|
- lib/motion-markdown-it/rules_inline/link.rb
|
127
|
+
- lib/motion-markdown-it/rules_inline/linkify.rb
|
125
128
|
- lib/motion-markdown-it/rules_inline/newline.rb
|
126
129
|
- lib/motion-markdown-it/rules_inline/state_inline.rb
|
127
130
|
- lib/motion-markdown-it/rules_inline/strikethrough.rb
|
128
131
|
- lib/motion-markdown-it/rules_inline/text.rb
|
129
|
-
- lib/motion-markdown-it/rules_inline/text_collapse.rb
|
130
132
|
- lib/motion-markdown-it/token.rb
|
131
133
|
- lib/motion-markdown-it/version.rb
|
132
134
|
- spec/motion-markdown-it/commonmark_spec.rb
|