Skip to content

Commit 4a97b09

Browse files
committed
Fix bug caused by a misalignment of index 'i'
1 parent e0d4b67 commit 4a97b09

File tree

1 file changed

+76
-63
lines changed

1 file changed

+76
-63
lines changed

markdown_it/rules_core/linkify.py

Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ def linkify(state: StateCore):
4444
# We scan from the end, to keep position when new tags added.
4545
# Use reversed logic in links start/end match
4646
assert tokens is not None
47-
for i in range(len(tokens))[::-1]:
47+
i = len(tokens)
48+
while i >= 0:
49+
i -= 1
50+
if i < 0:
51+
break
52+
assert isinstance(tokens, list)
4853
currentToken = tokens[i]
4954

5055
# Skip content of markdown links
@@ -57,74 +62,82 @@ def linkify(state: StateCore):
5762
i -= 1
5863
continue
5964

60-
# Skip content of html tag links
61-
if currentToken.type == "html_inline":
62-
if isLinkOpen(currentToken.content) and htmlLinkLevel > 0:
63-
htmlLinkLevel -= 1
64-
if isLinkClose(currentToken.content):
65-
htmlLinkLevel += 1
66-
if htmlLinkLevel > 0:
67-
continue
68-
69-
if currentToken.type == "text" and state.md.linkify.test(currentToken.content):
70-
text = currentToken.content
71-
links = state.md.linkify.match(text)
72-
73-
# Now split string to nodes
74-
nodes = []
75-
level = currentToken.level
76-
lastPos = 0
65+
# Skip content of html tag links
66+
if currentToken.type == "html_inline":
67+
if isLinkOpen(currentToken.content) and htmlLinkLevel > 0:
68+
htmlLinkLevel -= 1
69+
if isLinkClose(currentToken.content):
70+
htmlLinkLevel += 1
71+
if htmlLinkLevel > 0:
72+
continue
7773

78-
for ln in range(len(links)):
79-
url = links[ln].url
80-
fullUrl = normalizeLink(url)
81-
if not validateLink(fullUrl):
82-
continue
74+
if currentToken.type == "text" and state.md.linkify.test(
75+
currentToken.content
76+
):
77+
text = currentToken.content
78+
links = state.md.linkify.match(text)
79+
80+
# Now split string to nodes
81+
nodes = []
82+
level = currentToken.level
83+
lastPos = 0
84+
85+
for ln in range(len(links)):
86+
url = links[ln].url
87+
fullUrl = normalizeLink(url)
88+
if not validateLink(fullUrl):
89+
continue
90+
91+
urlText = links[ln].text
92+
93+
# Linkifier might send raw hostnames like "example.com", where url
94+
# starts with domain name. So we prepend http:// in those cases,
95+
# and remove it afterwards.
96+
if not links[ln].schema:
97+
urlText = HTTP_RE.sub(
98+
"", normalizeLinkText("http://" + urlText)
99+
)
100+
elif links[ln].schema == "mailto:" and TEST_MAILTO_RE.search(
101+
urlText
102+
):
103+
urlText = MAILTO_RE.sub(
104+
"", normalizeLinkText("mailto:" + urlText)
105+
)
106+
else:
107+
urlText = normalizeLinkText(urlText)
108+
109+
pos = links[ln].index
110+
111+
if pos > lastPos:
112+
token = Token("text", "", 0)
113+
token.content = text[lastPos:pos]
114+
token.level = level
115+
nodes.append(token)
116+
117+
token = Token("link_open", "a", 1)
118+
token.attrs = [["href", fullUrl]]
119+
token.level = level + 1
120+
token.markup = "linkify"
121+
token.info = "auto"
122+
nodes.append(token)
83123

84-
urlText = links[ln].text
124+
token = Token("text", "", 0)
125+
token.content = urlText
126+
token.level = level
127+
nodes.append(token)
85128

86-
# Linkifier might send raw hostnames like "example.com", where url
87-
# starts with domain name. So we prepend http:// in those cases,
88-
# and remove it afterwards.
89-
if not links[ln].schema:
90-
urlText = HTTP_RE.sub("", normalizeLinkText("http://" + urlText))
91-
elif links[ln].schema == "mailto:" and TEST_MAILTO_RE.search(urlText):
92-
urlText = MAILTO_RE.sub("", normalizeLinkText("mailto:" + urlText))
93-
else:
94-
urlText = normalizeLinkText(urlText)
129+
token = Token("link_close", "a", -1)
130+
token.level = level - 1
131+
token.markup = "linkify"
132+
token.info = "auto"
133+
nodes.append(token)
95134

96-
pos = links[ln].index
135+
lastPos = links[ln].last_index
97136

98-
if pos > lastPos:
137+
if lastPos < len(text):
99138
token = Token("text", "", 0)
100-
token.content = text[lastPos:pos]
139+
token.content = text[lastPos:]
101140
token.level = level
102141
nodes.append(token)
103142

104-
token = Token("link_open", "a", 1)
105-
token.attrs = [["href", fullUrl]]
106-
token.level = level + 1
107-
token.markup = "linkify"
108-
token.info = "auto"
109-
nodes.append(token)
110-
111-
token = Token("text", "", 0)
112-
token.content = urlText
113-
token.level = level
114-
nodes.append(token)
115-
116-
token = Token("link_close", "a", -1)
117-
token.level = level - 1
118-
token.markup = "linkify"
119-
token.info = "auto"
120-
nodes.append(token)
121-
122-
lastPos = links[ln].last_index
123-
124-
if lastPos < len(text):
125-
token = Token("text", "", 0)
126-
token.content = text[lastPos:]
127-
token.level = level
128-
nodes.append(token)
129-
130-
blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes)
143+
blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes)

0 commit comments

Comments
 (0)