HTML inside Kramdown table cells

Updated by Michael Rose 2 min read

The question of how to write a list inside of a table cell with Kramdown recently came up in a thread on Jekyll Talk — prompting me to look for a solution.

Unfortunately something like this doesn’t work:

| Fruit         | Price         | Advantages         |
| ------------- | ------------- | ------------------ |
| Bananas       | $1.34         | - built-in wrapper |
|               |               | - bright color     |
| Oranges       | $2.10         | - cures scurvy     |
|               |               | - tasty            |

Kramdown treats each new line as a row and doesn’t render the bullet lists properly in the Banana and Oranges rows.

Throwing HTML at the problem doesn’t quite work either.

| Fruit         | Price         | Advantages         |
| ------------- | ------------- | ------------------ |
| Bananas       | $1.34         | <ul><li>built-in wrapper</li><li>bright color</li></ul> |
| Oranges       | $2.10         | <ul><li>cures scurvy</li><li>tasty</li></ul> |

Instead of rendering the HTML, it is escaped and outputted as a single line of text.

What is needed is a way of telling Kramdown to leave the HTML alone and output as is. Thankfully there is such a way using the nomarkdown extension.

Simply wrap the HTML with {::nomarkdown} ... {:/} like so:

| Fruit         | Price         | Advantages         |
| ------------- | ------------- | ------------------ |
| Bananas       | $1.34         | {::nomarkdown}<ul><li>built-in wrapper</li><li>bright color</li></ul>{:/}|
| Oranges       | $2.10         | {::nomarkdown}<ul><li>cures scurvy</li><li>tasty</li></ul>{:/} |

And the table will output as expected1.

Fruit Price Advantages
Bananas $1.34
  • built-in wrapper
  • bright color
Oranges $2.10
  • cures scurvy
  • tasty

While not as readable as a pure Markdown solution, it gets the job done.

From what I understand Pandoc and RedCarpet have better support for this sort of thing if you want to use their flavor of Markdown.

Since Kramdown is the default renderer used by Jekyll I think I’ll just suck it up and stick with this workaround for now.

  1. Be sure to keep all of your HTML on a single line for this to work properly.


Willy McAllister on

I have the opposite challenge … getting kramdown to process text inside a <details> tag. I would prefer not to drop into html when writing <details>. The solution I’ve come across is

This plugin works great, but it is not supported by github pages, so I have to transfer my whole _site to github. Have you come across a kramdown extension that says “hey kramdown, process me!”

Michael Rose on

message: “Have you looked at the markdownify filter? I use it to do something similar to place Markdown text inside of a figcaption element.

There’s several ways to handle this without the need of a plugin. You could do something like this with a Liquid capture:

{% capture your_md %}Here is some Markdown you'd like to **capture**.{% endcapture %}

Then inject the captured variable into whatever you want and add the Markdownify filter so Kramdown processes it like so:

  {{ your_md | markdownify }}

Which would give you the following HTML output:

  <p>Here is some Markdown you'd like to <strong>capture</strong>.</p>

If you don’t want to bother with all the captures you could build your own Jekyll include that you could pass text through as a parameter to be Markdownified.

Willy McAllister on

Captures work nicely! I added a summary, and removed the spurious <p> tags so the summary lines up with the open icon.

{% capture summary %}Here is my Markdown *summary*{% endcapture %} {% capture
details %}Here is my Markdown **captured**.{% endcapture %}

    >{{ summary | markdownify | remove: '
    <p>' | remove: '</p>
    ' }}</summary
  {{ details | markdownify }}