How to use Pygments in Pelican with Markdown?
Question: TLDR: I am trying to do CSS line numbering in pelican, while writing in
markdown. Pygments is used indirectly and you can't pass options to it, so I
can't separate the lines and there is no CSS selector for "new line".

Using Markdown in Pelican, I can generate code blocks using the CodeHilite
extension. Pelican doesn't support using pygments directly if you are using
Markdown...only RST(and ... no to converting everything to RST).

So, what I have tried:

    
    
    MD_EXTENSIONS = [
    'codehilite(css_class=highlight,linenums=False,guess_lang=True,use_pygments=True)',
    'extra']
    

And:

    
    
    :::python
    <div class="line">import __main__ as main</div>
    

And:

    
    
    PYGMENTS_RST_OPTIONS = {'classprefix': 'pgcss', 'linenos': 'table'}
    

Can I get line numbers to show up? Yes. Can I get them to continue to the next
code block? No. And that is why I want to use CSS line numbering...its way
easier to control when the numbering starts and stops.

Any help would be greatly appreciated, I've been messing with this for a few
hours.


Answer: The only way I'm aware of is to fork the CodeHilite Extension (and I'm the
developer). First you will need to make a copy of the existing extension (this
[file](https://github.com/waylan/Python-
Markdown/blob/master/markdown/extensions/codehilite.py)), make changes to the
code necessary to effect your desired result, and save the file to your
PYTHONPATH (probably in the "sitepackages" directory, the exact location of
which depends on which system you are on and how Python was installed). Note
that you will want to create a unique name for your file so as not to conflict
with any other Python packages.

Once you have done that, you need to tell Pelican about it. As Pelican's
config file is just Python, import your new extension (use the name of your
file without the file extension: `yourmodule.py` => `yourmodule`) and include
it in the list of extensions.

    
    
    from yourmodule import CodeHiliteExtension
    MD_EXTENSIONS = [
    CodeHiliteExtension(css_class='highlight', linenums=False),
    'extra']
    

Note that the call to `CodeHiliteExtension` is not a string but actually
calling the class and passing in the appropriate arguments, which you can
adjust as appropriate.

And that should be it. If you would like to set up a easier way to deploy your
extension (or distribute it for others to use), you might want to consider
creating a `setup.py` file, which is beyond the scope of this question. See
this [tutorial](https://github.com/waylan/Python-
Markdown/wiki/Tutorial:-Writing-Extensions-for-Python-Markdown) for help
specific to Markdown extensions.

If you would like specific help with the changes you need to make to the code
within the extension, that depends on what you want to accomplish. To get
started, the arguments are passing to Pygments on line 117. The simplest
approach would be to hardcode your desired options there.

* * *

Be ware that if you are trying to replicate the behavior in reStructuredText,
you will likely be disappointed. Docutils wraps Pygments with some of its own
processing. In fact, a few of the options never get passed to Pygments but are
handled by the reStructeredText parser itself. If I recall correctly, CSS line
numbering is one such feature. In fact, Pygments does not offer that as an
option.

That being the case, you would need to modify your fork of the CodeHilite
Extension by having Pygments return non-numbered code, then applying the
necessary hooks yourself before the extension returns the highlighted code
block. To do so, you would likely need to split on line breaks and then loop
through the lines wrapping each line appropriately. Finally, join the newly
wrapped lines and return.

* * *

I suspect the following (untested) changes will get you started:

    
    
    diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py
    index 0657c37..fbd127d 100644
    --- a/markdown/extensions/codehilite.py
    +++ b/markdown/extensions/codehilite.py
    @@ -115,12 +115,18 @@ class CodeHilite(object):
                     except ValueError:
                         lexer = get_lexer_by_name('text')
                 formatter = get_formatter_by_name('html',
    -                                              linenos=self.linenums,
    +                                              linenos=self.linenums if self.linenumes != 'css' else False,
                                                   cssclass=self.css_class,
                                                   style=self.style,
                                                   noclasses=self.noclasses,
                                                   hl_lines=self.hl_lines)
    -            return highlight(self.src, lexer, formatter)
    +            result = highlight(self.src, lexer, formatter)
    +            if self.linenums == 'css':
    +                lines = result.split('\n')
    +                for i, line in enumerate(lines):
    +                    lines[i] = '<div class="line">%s</div>' % line
    +                result = '\n'.join(lines)
    +            return result
             else:
                 # just escape and build markup usable by JS highlighting libs
                 txt = self.src.replace('&', '&amp;')
    

* * *

You may have better success in attaining what you want by disabling Pygments
and using a JavaScript library to do the highlighting. That depends on which
JavaScript Library you choose and what features it has.

