codekingpro/portable-devtools
114k
1# Process [link](<to> "stuff")2 3from ..common.utils import isStrSpace, normalizeReference4from .state_inline import StateInline5 6 7def link(state: StateInline, silent: bool) -> bool:8 href = ""9 title = ""10 label = None11 oldPos = state.pos12 maximum = state.posMax13 start = state.pos14 parseReference = True15 16 if state.src[state.pos] != "[":17 return False18 19 labelStart = state.pos + 120 labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, True)21 22 # parser failed to find ']', so it's not a valid link23 if labelEnd < 0:24 return False25 26 pos = labelEnd + 127 28 if pos < maximum and state.src[pos] == "(":29 #30 # Inline link31 #32 33 # might have found a valid shortcut link, disable reference parsing34 parseReference = False35 36 # [link]( <href> "title" )37 # ^^ skipping these spaces38 pos += 139 while pos < maximum:40 ch = state.src[pos]41 if not isStrSpace(ch) and ch != "\n":42 break43 pos += 144 45 if pos >= maximum:46 return False47 48 # [link]( <href> "title" )49 # ^^^^^^ parsing link destination50 start = pos51 res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax)52 if res.ok:53 href = state.md.normalizeLink(res.str)54 if state.md.validateLink(href):55 pos = res.pos56 else:57 href = ""58 59 # [link]( <href> "title" )60 # ^^ skipping these spaces61 start = pos62 while pos < maximum:63 ch = state.src[pos]64 if not isStrSpace(ch) and ch != "\n":65 break66 pos += 167 68 # [link]( <href> "title" )69 # ^^^^^^^ parsing link title70 res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax)71 if pos < maximum and start != pos and res.ok:72 title = res.str73 pos = res.pos74 75 # [link]( <href> "title" )76 # ^^ skipping these spaces77 while pos < maximum:78 ch = state.src[pos]79 if not isStrSpace(ch) and ch != "\n":80 break81 pos += 182 83 if pos >= maximum or state.src[pos] != ")":84 # parsing a valid shortcut link failed, fallback to reference85 parseReference = True86 87 pos += 188 89 if parseReference:90 #91 # Link reference92 #93 if "references" not in state.env:94 return False95 96 if pos < maximum and state.src[pos] == "[":97 start = pos + 198 pos = state.md.helpers.parseLinkLabel(state, pos)99 if pos >= 0:100 label = state.src[start:pos]101 pos += 1102 else:103 pos = labelEnd + 1104 105 else:106 pos = labelEnd + 1107 108 # covers label == '' and label == undefined109 # (collapsed reference link and shortcut reference link respectively)110 if not label:111 label = state.src[labelStart:labelEnd]112 113 label = normalizeReference(label)114 115 ref = state.env["references"].get(label, None)116 if not ref:117 state.pos = oldPos118 return False119 120 href = ref["href"]121 title = ref["title"]122 123 #124 # We found the end of the link, and know for a fact it's a valid link125 # so all that's left to do is to call tokenizer.126 #127 if not silent:128 state.pos = labelStart129 state.posMax = labelEnd130 131 token = state.push("link_open", "a", 1)132 token.attrs = {"href": href}133 134 if title:135 token.attrSet("title", title)136 137 # note, this is not part of markdown-it JS, but is useful for renderers138 if label and state.md.options.get("store_labels", False):139 token.meta["label"] = label140 141 state.linkLevel += 1142 state.md.inline.tokenize(state)143 state.linkLevel -= 1144 145 token = state.push("link_close", "a", -1)146 147 state.pos = pos148 state.posMax = maximum149 return True150 