Exemple #1
0
def _render(self, tokens, idx, options, env):
    token = tokens[idx]
    info = unescapeAll(token.info).strip() if token.info else ""
    content = escapeHtml(token.content)
    block_name = ""

    if info:
        block_name = info.split()[0]

    return ("<pre><code" +
            (f' class="block-{block_name}" ' if block_name else "") + ">" +
            content + "</code></pre>\n")
Exemple #2
0
    def fence(self, tokens, idx, options, env):
        token = tokens[idx]
        # TODO : Later, add correct highlights for languages
        # info = unescapeAll(token.info).strip() if token.info else ""
        # langName = ""

        # if info:
        #     langName = info.split()[0]

        highlighted = escapeHtml(token.content)

        if token.attrs:
            return pre(code(highlighted), **token.attr)
        else:
            return pre(code(highlighted))
Exemple #3
0
    def _render(self, tokens, options, env):
        """ Recursive function parsing each token into the right Dominate tag.
        """
        pending_tags = []
        pending_content = [[]]
        for t, token in enumerate(tokens):
            if token.type == "fence":  # Special case
                pending_content[-1].append(self.fence(tokens, t, options, env))
            elif token.tag != "":
                if not token.nesting:  # Directly append to content
                    c = [token.content] if token.content else []
                    tag = getattr(dominate.tags, token.tag)
                    tag = tag(
                        *c) if token.attrs is None else tag(*c, **token.attrs)
                    pending_content[-1].append(tag)
                elif len(pending_tags) > 0 and pending_tags[
                        -1] == token.tag:  # Closing tag
                    t = pending_tags.pop()
                    c = pending_content.pop()
                    tag = getattr(dominate.tags, t)
                    tag = tag(c) if token.attrs is None else tag(
                        c, **token.attrs)
                    pending_content[-1].append(tag)
                else:  # Opening tag
                    if token.tag == "p" and len(
                            pending_tags) > 0 and pending_tags[-1] == "li":
                        continue

                    pending_tags.append(token.tag)
                    pending_content.append([])
            elif token.children is not None:
                assert len(token.children) > 0
                pending_content[-1].extend(
                    self._render(token.children, options, env))
            else:
                if not token.hidden:
                    pending_content[-1].append(escapeHtml(token.content))

        assert len(pending_tags) == 0, pending_tags
        assert len(pending_content) == 1, pending_content

        return pending_content[-1]
def amsmath_plugin(md: MarkdownIt,
                   *,
                   renderer: Optional[Callable[[str], str]] = None):
    """Parses TeX math equations, without any surrounding delimiters,
    only for top-level `amsmath <https://ctan.org/pkg/amsmath>`__ environments:

    .. code-block:: latex

        \\begin{gather*}
        a_1=b_1+c_1\\\\
        a_2=b_2+c_2-d_2+e_2
        \\end{gather*}

    :param renderer: Function to render content, by default escapes HTML

    """
    md.block.ruler.before(
        "blockquote",
        "amsmath",
        amsmath_block,
        {
            "alt":
            ["paragraph", "reference", "blockquote", "list", "footnote_def"]
        },
    )

    if renderer is None:
        _renderer = lambda content: escapeHtml(content)
    else:
        _renderer = renderer

    def render_amsmath_block(self, tokens, idx, options, env):
        content = _renderer(str(tokens[idx].content))
        return f'<div class="math amsmath">\n{content}\n</div>\n'

    md.add_render_rule("amsmath", render_amsmath_block)
Exemple #5
0
 def render_autolink(self, token):
     refuri = target = escapeHtml(token.attrGet("href"))
     ref_node = nodes.reference(target, target, refuri=refuri)
     self.add_line_and_source_path(ref_node, token)
     self.current_node.append(ref_node)
def dollarmath_plugin(
    md: MarkdownIt,
    *,
    allow_labels: bool = True,
    allow_space: bool = True,
    allow_digits: bool = True,
    double_inline: bool = False,
    label_normalizer: Optional[Callable[[str], str]] = None,
    renderer: Optional[Callable[[str, Dict[str, Any]], str]] = None,
    label_renderer: Optional[Callable[[str], str]] = None,
) -> None:
    """Plugin for parsing dollar enclosed math,
    e.g. inline: ``$a=1$``, block: ``$$b=2$$``

    This is an improved version of ``texmath``; it is more performant,
    and handles ``\\`` escaping properly and allows for more configuration.

    :param allow_labels: Capture math blocks with label suffix, e.g. ``$$a=1$$ (eq1)``
    :param allow_space: Parse inline math when there is space
        after/before the opening/closing ``$``, e.g. ``$ a $``
    :param allow_digits: Parse inline math when there is a digit
        before/after the opening/closing ``$``, e.g. ``1$`` or ``$2``.
        This is useful when also using currency.
    :param double_inline: Search for double-dollar math within inline contexts
    :param label_normalizer: Function to normalize the label,
        by default replaces whitespace with `-`
    :param renderer: Function to render content: `(str, {"display_mode": bool}) -> str`,
        by default escapes HTML
    :param label_renderer: Function to render labels, by default creates anchor

    """
    if label_normalizer is None:
        label_normalizer = lambda label: re.sub(r"\s+", "-", label)

    md.inline.ruler.before(
        "escape",
        "math_inline",
        math_inline_dollar(allow_space, allow_digits, double_inline),
    )
    md.block.ruler.before("fence", "math_block",
                          math_block_dollar(allow_labels, label_normalizer))

    # TODO the current render rules are really just for testing
    # would be good to allow "proper" math rendering,
    # e.g. https://github.com/roniemartinez/latex2mathml

    if renderer is None:
        _renderer = lambda content, _: escapeHtml(content)
    else:
        _renderer = renderer

    if label_renderer is None:
        _label_renderer = (
            lambda label:
            f'<a href="#{label}" class="mathlabel" title="Permalink to this equation">¶</a>'  # noqa: E501
        )
    else:
        _label_renderer = label_renderer

    def render_math_inline(self, tokens, idx, options, env) -> str:
        content = _renderer(
            str(tokens[idx].content).strip(), {"display_mode": False})
        return f'<span class="math inline">{content}</span>'

    def render_math_inline_double(self, tokens, idx, options, env) -> str:
        content = _renderer(
            str(tokens[idx].content).strip(), {"display_mode": True})
        return f'<div class="math inline">{content}</div>'

    def render_math_block(self, tokens, idx, options, env) -> str:
        content = _renderer(
            str(tokens[idx].content).strip(), {"display_mode": True})
        return f'<div class="math block">\n{content}\n</div>\n'

    def render_math_block_label(self, tokens, idx, options, env) -> str:
        content = _renderer(
            str(tokens[idx].content).strip(), {"display_mode": True})
        _id = tokens[idx].info
        label = _label_renderer(tokens[idx].info)
        return f'<div id="{_id}" class="math block">\n{label}\n{content}\n</div>\n'

    md.add_render_rule("math_inline", render_math_inline)
    md.add_render_rule("math_inline_double", render_math_inline_double)

    md.add_render_rule("math_block", render_math_block)
    md.add_render_rule("math_block_label", render_math_block_label)
 def render_autolink(self, token: SyntaxTreeNode) -> None:
     refuri = target = escapeHtml(token.attrGet("href")
                                  or "")  # type: ignore[arg-type]
     ref_node = nodes.reference(target, target, refuri=refuri)
     self.add_line_and_source_path(ref_node, token)
     self.current_node.append(ref_node)