Server IP : 85.214.239.14 / Your IP : 13.58.53.112 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/self/root/lib/python3/dist-packages/markdown_it/rules_block/ |
Upload File : |
import logging from ..common.utils import charCodeAt, isSpace, normalizeReference from .state_block import StateBlock LOGGER = logging.getLogger(__name__) def reference(state: StateBlock, startLine, _endLine, silent): LOGGER.debug( "entering reference: %s, %s, %s, %s", state, startLine, _endLine, silent ) lines = 0 pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] nextLine = startLine + 1 # if it's indented more than 3 spaces, it should be a code block if state.sCount[startLine] - state.blkIndent >= 4: return False if state.srcCharCode[pos] != 0x5B: # /* [ */ return False # Simple check to quickly interrupt scan on [link](url) at the start of line. # Can be useful on practice: https:#github.com/markdown-it/markdown-it/issues/54 while pos < maximum: # /* ] */ /* \ */ /* : */ if state.srcCharCode[pos] == 0x5D and state.srcCharCode[pos - 1] != 0x5C: if pos + 1 == maximum: return False if state.srcCharCode[pos + 1] != 0x3A: return False break pos += 1 endLine = state.lineMax # jump line-by-line until empty one or EOF terminatorRules = state.md.block.ruler.getRules("reference") oldParentType = state.parentType state.parentType = "reference" while nextLine < endLine and not state.isEmpty(nextLine): # this would be a code block normally, but after paragraph # it's considered a lazy continuation regardless of what's there if state.sCount[nextLine] - state.blkIndent > 3: nextLine += 1 continue # quirk for blockquotes, this line should already be checked by that rule if state.sCount[nextLine] < 0: nextLine += 1 continue # Some tags can terminate paragraph without empty line. terminate = False for terminatorRule in terminatorRules: if terminatorRule(state, nextLine, endLine, True): terminate = True break if terminate: break nextLine += 1 string = state.getLines(startLine, nextLine, state.blkIndent, False).strip() maximum = len(string) labelEnd = None pos = 1 while pos < maximum: ch = charCodeAt(string, pos) if ch == 0x5B: # /* [ */ return False elif ch == 0x5D: # /* ] */ labelEnd = pos break elif ch == 0x0A: # /* \n */ lines += 1 elif ch == 0x5C: # /* \ */ pos += 1 if pos < maximum and charCodeAt(string, pos) == 0x0A: lines += 1 pos += 1 if ( labelEnd is None or labelEnd < 0 or charCodeAt(string, labelEnd + 1) != 0x3A ): # /* : */ return False # [label]: destination 'title' # ^^^ skip optional whitespace here pos = labelEnd + 2 while pos < maximum: ch = charCodeAt(string, pos) if ch == 0x0A: lines += 1 elif isSpace(ch): pass else: break pos += 1 # [label]: destination 'title' # ^^^^^^^^^^^ parse this res = state.md.helpers.parseLinkDestination(string, pos, maximum) if not res.ok: return False href = state.md.normalizeLink(res.str) if not state.md.validateLink(href): return False pos = res.pos lines += res.lines # save cursor state, we could require to rollback later destEndPos = pos destEndLineNo = lines # [label]: destination 'title' # ^^^ skipping those spaces start = pos while pos < maximum: ch = charCodeAt(string, pos) if ch == 0x0A: lines += 1 elif isSpace(ch): pass else: break pos += 1 # [label]: destination 'title' # ^^^^^^^ parse this res = state.md.helpers.parseLinkTitle(string, pos, maximum) if pos < maximum and start != pos and res.ok: title = res.str pos = res.pos lines += res.lines else: title = "" pos = destEndPos lines = destEndLineNo # skip trailing spaces until the rest of the line while pos < maximum: ch = charCodeAt(string, pos) if not isSpace(ch): break pos += 1 if pos < maximum and charCodeAt(string, pos) != 0x0A: if title: # garbage at the end of the line after title, # but it could still be a valid reference if we roll back title = "" pos = destEndPos lines = destEndLineNo while pos < maximum: ch = charCodeAt(string, pos) if not isSpace(ch): break pos += 1 if pos < maximum and charCodeAt(string, pos) != 0x0A: # garbage at the end of the line return False label = normalizeReference(string[1:labelEnd]) if not label: # CommonMark 0.20 disallows empty labels return False # Reference can not terminate anything. This check is for safety only. if silent: return True if "references" not in state.env: state.env["references"] = {} state.line = startLine + lines + 1 # note, this is not part of markdown-it JS, but is useful for renderers if state.md.options.get("inline_definitions", False): token = state.push("definition", "", 0) token.meta = { "id": label, "title": title, "url": href, "label": string[1:labelEnd], } token.map = [startLine, state.line] if label not in state.env["references"]: state.env["references"][label] = { "title": title, "href": href, "map": [startLine, state.line], } else: state.env.setdefault("duplicate_refs", []).append( { "title": title, "href": href, "label": label, "map": [startLine, state.line], } ) state.parentType = oldParentType return True