Esempio n. 1
0
def footnote_ref(state: StateInline, silent: bool):
    """Process footnote references ([^...])"""

    maximum = state.posMax
    start = state.pos

    # should be at least 4 chars - "[^x]"
    if start + 3 > maximum:
        return False

    if "footnotes" not in state.env or "refs" not in state.env["footnotes"]:
        return False
    if state.srcCharCode[start] != 0x5B:  # /* [ */
        return False
    if state.srcCharCode[start + 1] != 0x5E:  # /* ^ */
        return False

    pos = start + 2
    while pos < maximum:
        if state.srcCharCode[pos] == 0x20:
            return False
        if state.srcCharCode[pos] == 0x0A:
            return False
        if state.srcCharCode[pos] == 0x5D:  # /* ] */
            break
        pos += 1

    if pos == start + 2:  # no empty footnote labels
        return False
    if pos >= maximum:
        return False
    pos += 1

    label = state.src[start + 2:pos - 1]
    if (":" + label) not in state.env["footnotes"]["refs"]:
        return False

    if not silent:
        if "list" not in state.env["footnotes"]:
            state.env["footnotes"]["list"] = {}

        if state.env["footnotes"]["refs"][":" + label] < 0:
            footnoteId = len(state.env["footnotes"]["list"])
            state.env["footnotes"]["list"][footnoteId] = {
                "label": label,
                "count": 0
            }
            state.env["footnotes"]["refs"][":" + label] = footnoteId
        else:
            footnoteId = state.env["footnotes"]["refs"][":" + label]

        footnoteSubId = state.env["footnotes"]["list"][footnoteId]["count"]
        state.env["footnotes"]["list"][footnoteId]["count"] += 1

        token = state.push("footnote_ref", "", 0)
        token.meta = {"id": footnoteId, "subId": footnoteSubId, "label": label}

    state.pos = pos
    state.posMax = maximum
    return True
Esempio n. 2
0
def footnote_inline(state: StateInline, silent: bool):
    """Process inline footnotes (^[...])"""

    maximum = state.posMax
    start = state.pos

    if start + 2 >= maximum:
        return False
    if state.srcCharCode[start] != 0x5E:  # /* ^ */
        return False
    if state.srcCharCode[start + 1] != 0x5B:  # /* [ */
        return False

    labelStart = start + 2
    labelEnd = parseLinkLabel(state, start + 1)

    # parser failed to find ']', so it's not a valid note
    if labelEnd < 0:
        return False

    # 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:
        refs = state.env.setdefault("footnotes", {}).setdefault("list", {})
        footnoteId = len(refs)

        tokens = []
        state.md.inline.parse(state.src[labelStart:labelEnd], state.md,
                              state.env, tokens)

        token = state.push("footnote_ref", "", 0)
        token.meta = {"id": footnoteId}

        refs[footnoteId] = {
            "content": state.src[labelStart:labelEnd],
            "tokens": tokens
        }

    state.pos = labelEnd + 1
    state.posMax = maximum
    return True