Skip to content

markdown_pycon ¤

Markdown PyCon package.

Markdown extension to parse pycon code blocks without indentation or fences.

Classes:

Functions:

Highlighter ¤

Highlighter(md: Markdown)

Bases: Highlight

Code highlighter that tries to match the Markdown configuration.

Picking up the global config and defaults works only if you use the codehilite or pymdownx.highlight (recommended) Markdown extension.

  • If you use pymdownx.highlight, highlighting settings are picked up from it, and the default CSS class is .highlight. This also means the default of guess_lang: false.

  • Otherwise, if you use the codehilite extension, settings are picked up from it, and the default CSS class is .codehilite. Also consider setting guess_lang: false.

  • If neither are added to markdown_extensions, highlighting is enabled anyway. This is for backwards compatibility. If you really want to disable highlighting even in mkdocstrings, add one of these extensions anyway and set use_pygments: false.

The underlying implementation is pymdownx.highlight regardless.

Parameters:

  • md ¤

    (Markdown) –

    The Markdown instance to read configs from.

Methods:

Source code in src/markdown_pycon/_internal/extension.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def __init__(self, md: Markdown):
    """Configure to match a `markdown.Markdown` instance.

    Arguments:
        md: The Markdown instance to read configs from.
    """
    config: dict[str, Any] = {}
    self._highlighter: str | None = None
    for ext in md.registeredExtensions:
        if isinstance(ext, HighlightExtension) and (ext.enabled or not config):
            self._highlighter = "highlight"
            config = ext.getConfigs()
            break  # This one takes priority, no need to continue looking
        if isinstance(ext, CodeHiliteExtension) and not config:
            self._highlighter = "codehilite"
            config = ext.getConfigs()
            config["language_prefix"] = config["lang_prefix"]
    self._css_class = config.pop("css_class", "highlight")
    super().__init__(**{name: opt for name, opt in config.items() if name in self._highlight_config_keys})

highlight ¤

highlight(
    src: str,
    language: str | None = None,
    *,
    dedent: bool = True,
    linenums: bool | None = None,
    **kwargs: Any,
) -> str

Highlight a code-snippet.

Parameters:

  • src ¤

    (str) –

    The code to highlight.

  • language ¤

    (str | None, default: None ) –

    Explicitly tell what language to use for highlighting.

  • dedent ¤

    (bool, default: True ) –

    Whether to dedent the code before highlighting it or not.

  • linenums ¤

    (bool | None, default: None ) –

    Whether to add line numbers in the result.

  • **kwargs ¤

    (Any, default: {} ) –

    Pass on to pymdownx.highlight.Highlight.highlight.

Returns:

  • str –

    The highlighted code as HTML text, marked safe (not escaped for HTML).

Source code in src/markdown_pycon/_internal/extension.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def highlight(  # ty:ignore[invalid-method-override]
    self,
    src: str,
    language: str | None = None,
    *,
    dedent: bool = True,
    linenums: bool | None = None,
    **kwargs: Any,
) -> str:
    """Highlight a code-snippet.

    Arguments:
        src: The code to highlight.
        language: Explicitly tell what language to use for highlighting.
        dedent: Whether to dedent the code before highlighting it or not.
        linenums: Whether to add line numbers in the result.
        **kwargs: Pass on to `pymdownx.highlight.Highlight.highlight`.

    Returns:
        The highlighted code as HTML text, marked safe (not escaped for HTML).
    """
    if isinstance(src, Markup):
        src = src.unescape()
    if dedent:
        src = textwrap.dedent(src)

    kwargs.setdefault("css_class", self._css_class)
    old_linenums = self.linenums  # type: ignore[has-type]
    if linenums is not None:
        self.linenums = linenums
    try:
        result = super().highlight(src, language, **kwargs)
    finally:
        self.linenums = old_linenums

    return Markup(result)  # noqa: S704

PyConBlockProcessor ¤

Bases: BlockProcessor

Our block processor.

Methods:

  • run –

    Handle the block. Highlight as pycon code block.

  • test –

    Test whether we should process this block.

run ¤

run(parent: Element, blocks: list[str]) -> bool | None

Handle the block. Highlight as pycon code block.

Source code in src/markdown_pycon/_internal/extension.py
147
148
149
150
151
152
153
154
155
156
def run(self, parent: Element, blocks: list[str]) -> bool | None:
    """Handle the block. Highlight as `pycon` code block."""
    block = blocks.pop(0)
    block = _RE_DOCTEST_FLAGS.sub("", block)
    block = _RE_DOCTEST_BLANKLINE.sub("", block)
    highlighted = Highlighter(self.parser.md).highlight(block, "pycon")
    el = Element("p")
    el.text = self.parser.md.htmlStash.store(highlighted)
    parent.append(el)
    return None

test ¤

test(parent: Element, block: str) -> bool

Test whether we should process this block.

Source code in src/markdown_pycon/_internal/extension.py
143
144
145
def test(self, parent: Element, block: str) -> bool:  # noqa: ARG002
    """Test whether we should process this block."""
    return block.startswith(">>>")

PyConExtension ¤

Bases: Extension

Our Markdown extension.

Methods:

extendMarkdown ¤

extendMarkdown(md: Markdown) -> None

Register the block processor.

Add an instance of our PyConBlockProcessor to the Markdown parser.

Parameters:

  • md ¤

    (Markdown) –

    A Markdown instance.

Source code in src/markdown_pycon/_internal/extension.py
162
163
164
165
166
167
168
169
170
def extendMarkdown(self, md: Markdown) -> None:  # noqa: N802 (casing: parent method's name)
    """Register the block processor.

    Add an instance of our [`PyConBlockProcessor`][markdown_pycon.PyConBlockProcessor] to the Markdown parser.

    Parameters:
        md: A Markdown instance.
    """
    md.parser.blockprocessors.register(PyConBlockProcessor(md.parser), "pycon", priority=30)

makeExtension ¤

makeExtension(*args: Any, **kwargs: Any) -> PyConExtension

Return extension.

Source code in src/markdown_pycon/_internal/extension.py
173
174
175
def makeExtension(*args: Any, **kwargs: Any) -> PyConExtension:  # noqa: N802
    """Return extension."""
    return PyConExtension(*args, **kwargs)