motion-markdown-it 12.3.2 → 13.0.1
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 +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
|