1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# Process ![image](<src> "title")
from __future__ import annotations
from ..common.utils import isStrSpace, normalizeReference
from ..token import Token
from .state_inline import StateInline
def image(state: StateInline, silent: bool) -> bool:
label = None
href = ""
oldPos = state.pos
max = state.posMax
if state.src[state.pos] != "!":
return False
if state.pos + 1 < state.posMax and state.src[state.pos + 1] != "[":
return False
labelStart = state.pos + 2
labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, False)
# parser failed to find ']', so it's not a valid link
if labelEnd < 0:
return False
pos = labelEnd + 1
if pos < max and state.src[pos] == "(":
#
# Inline link
#
# [link]( <href> "title" )
# ^^ skipping these spaces
pos += 1
while pos < max:
ch = state.src[pos]
if not isStrSpace(ch) and ch != "\n":
break
pos += 1
if pos >= max:
return False
# [link]( <href> "title" )
# ^^^^^^ parsing link destination
start = pos
res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax)
if res.ok:
href = state.md.normalizeLink(res.str)
if state.md.validateLink(href):
pos = res.pos
else:
href = ""
# [link]( <href> "title" )
# ^^ skipping these spaces
start = pos
while pos < max:
ch = state.src[pos]
if not isStrSpace(ch) and ch != "\n":
break
pos += 1
# [link]( <href> "title" )
# ^^^^^^^ parsing link title
res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax)
if pos < max and start != pos and res.ok:
title = res.str
pos = res.pos
# [link]( <href> "title" )
# ^^ skipping these spaces
while pos < max:
ch = state.src[pos]
if not isStrSpace(ch) and ch != "\n":
break
pos += 1
else:
title = ""
if pos >= max or state.src[pos] != ")":
state.pos = oldPos
return False
pos += 1
else:
#
# Link reference
#
if "references" not in state.env:
return False
# /* [ */
if pos < max and state.src[pos] == "[":
start = pos + 1
pos = state.md.helpers.parseLinkLabel(state, pos)
if pos >= 0:
label = state.src[start:pos]
pos += 1
else:
pos = labelEnd + 1
else:
pos = labelEnd + 1
# covers label == '' and label == undefined
# (collapsed reference link and shortcut reference link respectively)
if not label:
label = state.src[labelStart:labelEnd]
label = normalizeReference(label)
ref = state.env["references"].get(label, None)
if not ref:
state.pos = oldPos
return False
href = ref["href"]
title = ref["title"]
#
# We found the end of the link, and know for a fact it's a valid link
# so all that's left to do is to call tokenizer.
#
if not silent:
content = state.src[labelStart:labelEnd]
tokens: list[Token] = []
state.md.inline.parse(content, state.md, state.env, tokens)
token = state.push("image", "img", 0)
token.attrs = {"src": href, "alt": ""}
token.children = tokens or None
token.content = content
if title:
token.attrSet("title", title)
# note, this is not part of markdown-it JS, but is useful for renderers
if label and state.md.options.get("store_labels", False):
token.meta["label"] = label
state.pos = pos
state.posMax = max
return True
|