A Weird Imagination

Markdown code blocks in footnotes

Posted in

The problem#

In a recent post, I wanted to include a large code block of a log. In order to not make the reader scroll past that long block, I put it in a footnote. But triple-backtick (```) syntax for code blocks doesn't work in Python Markdown footnotes:

[^1]: Broken footnote, do not use:
    ```py
    print("Hello World!")
    ```

outputs the code block before the footnote, not inside it.

The solution#

For code blocks in footnotes, indent the code lines (and use ::: on the first line to specify the highlighting mode if desired). For example, the Markdown for the footnote in that post starts as follows:

[^full-journalctl-log]:
    The full log:

        :::text
        Aug 09 02:43:20 host systemd[1]: Starting unifi.service - unifi...
        Aug 09 02:43:20 host unifi-network-service-helper[2203]: grep: /var/lib/unifi/system.properties: Permission denied

The details#

Markdown code block syntaxes#

Python Markdown supports multiple ways to write code blocks: Markdown intended code blocks and fenced code blocks which can be guarded by backticks (```) or tildes (~~~). I normally use the backticks form.

The body of footnotes also uses indents, so I tried various combinations of those code block forms with indents before figuring out that two levels of indents results in a code block inside a footnote.

Nested blocks unsupported#

I wondered if this limitation was documented (or if I was just confused about the proper syntax), so I searched the GitHub issues for Python Markdown and found issue #53 "Support fenced code block within lists and blockquotes" (via issue #73 "Codehilite doesn't work inside of footnotes"). In that thread, there's a comment stating the issue is that the parser does not support "blocks" nested inside other blocks, which means fenced code blocks cannot appear inside a list or a footnote.

Markdown inconsistency#

Since this blog uses Pelican which uses Python Markdown to process Markdown, that's the implementation I actually care about. But Babelmark 3 can be used to compare different Markdown implementations. For instance, this example shows that some Markdown implementations do in fact handle fenced code blocks in footnotes as I expected. I found that indirectly through an OSnews article on issues with Markdown posted while I was composing this post.

Fixing styles#

In the theme I use, the code block in the footnote was getting styled weirdly. The first line was intended a couple spaces and each line had a border in addition to the border around the entire code block. After some inspection using my browser's web developer tools, I noticed that the code blocks had a <code> tag nested inside a <pre> tag and the CSS rule in the theme for the <pre> tag also applied to <code> tags inside <li> tags (and footnotes were defined as <li> tags). Which meant that the border rules were being applied twice to code blocks inside footnotes.

In the interest of making the minimal change to the CSS, since I did not write the original style, so I'm not sure why things are the way they are, I noticed that the <li> tags defining footnotes had an id starting fn:, so I excluded <li> tags which such ids from the CSS rule by changing the relevant li to :not([id^="fn:"]).

I did confirm that inline code in footnotes still looks right with that change.12


  1. This footnote has inline code

  2. This footnote has a code block:

    print("Hello World!")
    print("Goodbye World!")
    

Comments

Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.

There are no comments yet.