Spaces:
Running
Running
File size: 4,318 Bytes
f7c08b1 |
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 149 150 151 152 |
# Process [link](<to> "stuff")
from ..common.utils import isStrSpace, normalizeReference
from .state_inline import StateInline
def link(state: StateInline, silent: bool) -> bool:
href = ""
title = ""
label = None
oldPos = state.pos
maximum = state.posMax
start = state.pos
parseReference = True
if state.src[state.pos] != "[":
return False
labelStart = state.pos + 1
labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, True)
# parser failed to find ']', so it's not a valid link
if labelEnd < 0:
return False
pos = labelEnd + 1
if pos < maximum and state.src[pos] == "(":
#
# Inline link
#
# might have found a valid shortcut link, disable reference parsing
parseReference = False
# [link]( <href> "title" )
# ^^ skipping these spaces
pos += 1
while pos < maximum:
ch = state.src[pos]
if not isStrSpace(ch) and ch != "\n":
break
pos += 1
if pos >= maximum:
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 < maximum:
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 < maximum and start != pos and res.ok:
title = res.str
pos = res.pos
# [link]( <href> "title" )
# ^^ skipping these spaces
while pos < maximum:
ch = state.src[pos]
if not isStrSpace(ch) and ch != "\n":
break
pos += 1
if pos >= maximum or state.src[pos] != ")":
# parsing a valid shortcut link failed, fallback to reference
parseReference = True
pos += 1
if parseReference:
#
# Link reference
#
if "references" not in state.env:
return False
if pos < maximum 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"][label] if label in state.env["references"] else 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:
state.pos = labelStart
state.posMax = labelEnd
token = state.push("link_open", "a", 1)
token.attrs = {"href": href}
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.linkLevel += 1
state.md.inline.tokenize(state)
state.linkLevel -= 1
token = state.push("link_close", "a", -1)
state.pos = pos
state.posMax = maximum
return True
|