Python-Markdown / markdown

A Python implementation of John Gruber’s Markdown with Extension support.
https://python-markdown.github.io/
BSD 3-Clause "New" or "Revised" License
3.79k stars 863 forks source link

Pass code block's language to the specified Pygments formatter in CodeHilite #1258

Closed ccwang002 closed 2 years ago

ccwang002 commented 2 years ago

As per the discussions in PR #1255, I add a new option lang_str that passes the language of a code block to the specified Pygments formatter. lang_str has the value of {lang_prefix}{lang}, so it respects the existing language prefix option.

While lang_str has no effect the builtin Pygments formatters, users can leverage this information in their custom formatter to annotate the generated output.

An example I added to the documentation annotates the language as a class of the <code> tag. I copied it below:

from pygments.formatters import HtmlFormatter

class CustomHtmlFormatter(HtmlFormatter):
    def __init__(self, lang_str='', **options):
        super().__init__(**options)
        # lang_str has the value {lang_prefix}{lang} 
        # specified by the CodeHilite's options
        self.lang_str = lang_str

    def _wrap_code(self, source):
        yield 0, f'<code class="{self.lang_str}">'
        yield from source
        yield 0, '</code>'

some_text = '''\
    :::python
    print('hellow world')
'''

markdown.markdown(
    some_text,
    extensions=['markdown.extensions.codehilite'],
    extension_configs={'markdown.extensions.codehilite': {
        'pygments_formatter': CustomHtmlFormatter
    }}
)

The formatter above will output the following HTML structure for the code block:

<div class="codehilite">
    <pre>
        <code class="language-python">
        ...
        </code>
    </pre>
</div>
waylan commented 2 years ago

I made a few tweaks to adjust some awkward wording. Also, I altered the example to use the extension class directly rather than using the string name. While both ways are supported, we recommend users use the Python objects. Therefore, our documentation should reflect that.

Otherwise, this looks good to me.

ccwang002 commented 2 years ago

Nice. Thanks for the feedback and review 👍