コード例 #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
コード例 #2
0
def myst_role(state: StateInline, silent: bool):
    try:
        if state.srcCharCode[state.pos - 1] == 0x5C:  # /* \ */
            # escaped (this could be improved in the case of edge case '\\{')
            return False
    except IndexError:
        pass

    match = PATTERN.search(state.src[state.pos:])
    if not match:
        return False
    state.pos += match.end()

    if not silent:
        token = state.push("myst_role", "", 0)
        token.meta = {"name": match.group(1)}
        token.content = match.group(3)

    return True
コード例 #3
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
コード例 #4
0
def myst_role(state: StateInline, silent: bool):

    # check name
    match = VALID_NAME_PATTERN.match(state.src[state.pos:])
    if not match:
        return False
    name = match.group(1)

    # check for starting backslash escape
    try:
        if state.srcCharCode[state.pos - 1] == 0x5C:  # /* \ */
            # escaped (this could be improved in the case of edge case '\\{')
            return False
    except IndexError:
        pass

    # scan opening tick length
    start = pos = state.pos + match.end()
    try:
        while state.src[pos] == "`":
            pos += 1
    except IndexError:
        return False

    tick_length = pos - start
    if not tick_length:
        return False

    # search for closing ticks
    match = re.search("`" * tick_length, state.src[pos + 1:])
    if not match:
        return False
    content = state.src[pos:pos + match.start() + 1].replace("\n", " ")

    if not silent:
        token = state.push("myst_role", "", 0)
        token.meta = {"name": name}
        token.content = content

    state.pos = pos + match.end() + 1

    return True
コード例 #5
0
    def _substitution_inline(state: StateInline, silent: bool):
        try:
            if (state.srcCharCode[state.pos] != start_char
                    or state.srcCharCode[state.pos + 1] != start_char):
                return False
        except IndexError:
            return False

        pos = state.pos + 2
        found_closing = False
        while True:
            try:
                end = state.srcCharCode.index(end_char, pos)
            except ValueError:
                return False
            try:
                if state.srcCharCode[end + 1] == end_char:
                    found_closing = True
                    break
            except IndexError:
                return False
            pos = end + 2

        if not found_closing:
            return False

        text = state.src[state.pos + 2:end].strip()
        state.pos = end + 2

        if silent:
            return True

        token = state.push("substitution_inline", "span", 0)
        token.block = False
        token.content = text
        token.attrSet("class", "substitution")
        token.attrSet("text", text)
        token.markup = f"{start_delimiter}{end_delimiter}"

        return True
コード例 #6
0
    def _math_inline_dollar(state: StateInline, silent: bool) -> bool:
        """Inline dollar rule.

        - Initial check:
            - check if first character is a $
            - check if the first character is escaped
            - check if the next character is a space (if not allow_space)
            - check if the next character is a digit (if not allow_digits)
        - Advance one, if allow_double
        - Find closing (advance one, if allow_double)
        - Check closing:
            - check if the previous character is a space (if not allow_space)
            - check if the next character is a digit (if not allow_digits)
        - Check empty content
        """

        # TODO options:
        # even/odd backslash escaping

        if state.srcCharCode[state.pos] != 0x24:  # /* $ */
            return False

        if not allow_space:
            # whitespace not allowed straight after opening $
            try:
                if isWhiteSpace(state.srcCharCode[state.pos + 1]):
                    return False
            except IndexError:
                return False

        if not allow_digits:
            # digit not allowed straight before opening $
            try:
                if state.src[state.pos - 1].isdigit():
                    return False
            except IndexError:
                pass

        if is_escaped(state, state.pos):
            return False

        try:
            is_double = allow_double and state.srcCharCode[state.pos +
                                                           1] == 0x24
        except IndexError:
            return False

        # find closing $
        pos = state.pos + 1 + (1 if is_double else 0)
        found_closing = False
        while not found_closing:
            try:
                end = state.srcCharCode.index(0x24, pos)
            except ValueError:
                return False

            if is_escaped(state, end):
                pos = end + 1
                continue

            try:
                if is_double and not state.srcCharCode[end + 1] == 0x24:
                    pos = end + 1
                    continue
            except IndexError:
                return False

            if is_double:
                end += 1

            found_closing = True

        if not found_closing:
            return False

        if not allow_space:
            # whitespace not allowed straight before closing $
            try:
                if isWhiteSpace(state.srcCharCode[end - 1]):
                    return False
            except IndexError:
                return False

        if not allow_digits:
            # digit not allowed straight after closing $
            try:
                if state.src[end + 1].isdigit():
                    return False
            except IndexError:
                pass

        text = (state.src[state.pos + 2:end -
                          1] if is_double else state.src[state.pos + 1:end])

        # ignore empty
        if not text:
            return False

        if not silent:
            token = state.push(
                "math_inline_double" if is_double else "math_inline", "math",
                0)
            token.content = text
            token.markup = "$$" if is_double else "$"

        state.pos = end + 1

        return True
コード例 #7
0
ファイル: index.py プロジェクト: wna-se/markdown-it-py
    def _math_inline_dollar(state: StateInline, silent: bool):

        # TODO options:
        # even/odd backslash escaping
        # allow $$ blocks

        if state.srcCharCode[state.pos] != 0x24:  # /* $ */
            return False

        if not allow_space:
            # whitespace not allowed straight after opening $
            try:
                if isWhiteSpace(state.srcCharCode[state.pos + 1]):
                    return False
            except IndexError:
                return False

        if not allow_digits:
            # digit not allowed straight before opening $
            try:
                if state.src[state.pos - 1].isdigit():
                    return False
            except IndexError:
                pass

        if is_escaped(state, state.pos):
            return False

        # find closing $
        pos = state.pos + 1
        found_closing = False
        while True:
            try:
                end = state.srcCharCode.index(0x24, pos)
            except ValueError:
                return False

            if is_escaped(state, end):
                pos = end + 1
            else:
                found_closing = True
                break

        if not found_closing:
            return False

        if not allow_space:
            # whitespace not allowed straight before closing $
            try:
                if isWhiteSpace(state.srcCharCode[end - 1]):
                    return False
            except IndexError:
                return False

        if not allow_digits:
            # digit not allowed straight after closing $
            try:
                if state.src[end + 1].isdigit():
                    return False
            except IndexError:
                pass

        text = state.src[state.pos + 1 : end]

        # ignore empty
        if not text:
            return False

        if not silent:
            token = state.push("math_inline", "math", 0)
            token.content = text
            token.markup = "$"

        state.pos = end + 1

        return True