DEV Community 👩‍💻👨‍💻

Simon Hanukaev
Simon Hanukaev

Posted on

The Tale of Markdownify

While I was playing around with Hugo and Jekyll, I found out that their markdownify filter is somewhat confusing.

To describe the problem, first I want to show you how Jekyll's markdownify filter works.

Assume you have defined my_text parameter, for example inside _config.yml file:

my_text: consectetur **adipiscing** [elit](https://www.example.com)
Enter fullscreen mode Exit fullscreen mode

As you can see, this variable is a string in a markdown format. Now, let's try to use that variable inside a template file.

<div>Lorem ipsum dolor sit amet, {{ site.my_text | markdownify }}</div>
Enter fullscreen mode Exit fullscreen mode

Now, if you try to generate an HTML from this template using Jekyll, you will get something like this:

<div>Lorem ipsum dolor sit amet,
  <p>consectetur <strong>adipiscing</strong>
    <a href="https://www.example.com">elit</a>
  </p>
</div>
Enter fullscreen mode Exit fullscreen mode

Although this is probably not what we wanted, because the content of our variable is wrapped with <p> tag. It is totally predictable behaviour because markdown always wraps its content with block elements.

But in Hugo, the behaviour is less predictable:

<div>Lorem ipsum dolor sit amet, {{ .Site.Params.my_text | markdownify }}</div>
Enter fullscreen mode Exit fullscreen mode

Results in:

<div>Lorem ipsum dolor sit amet, consectetur <strong>adipiscing</strong>
  <a href="https://www.example.com">elit</a>
</div>
Enter fullscreen mode Exit fullscreen mode

This is actually what we wanted, but wait. What if our variable had two paragraphs?

params:
  my_text: |-
    first paragraph

    second paragraph
Enter fullscreen mode Exit fullscreen mode

Now we get this:

<div>Lorem ipsum dolor sit amet,
  <p>first paragraph</p>
  <p>second paragraph</p>
</div>
Enter fullscreen mode Exit fullscreen mode

Wait... but I thought Hugo was stripping these <p> tags. Well, not if you have more than one paragraph.

But what if I really wanted to wrap a paragraph with <p>? According to this thread, you should use blocks filter. But in my opinion, it is better to have some kind of inline parameter to strip out <p> tags rather than stripping them by default and making markdownify filter to behave incorrectly. Even if that means that we won't always get what we want. Standards are above us all :)

And what about Jekyll? Well, although there were some attempts (see this issue and this pull request) to provide an inline parameter to the markdownify filter, they didn't succeed. And I didn't find any nice way to markdownify that variable without making it being wrapped with <p> tag. The only solution I found is just to set the variable to raw HTML and use it without markdownify.

I think the real problem here is that markdown syntax does not define any standard way to create inline content, that wouldn't be wrapped with a block level elements such as <p>. But if we had something like:

This will be wrapped placed inside paragraph

!!!But this **will not**!!!
Enter fullscreen mode Exit fullscreen mode

That would produce:

<p>This will be wrapped with paragraph</p>

But this <strong>will not</strong>

Enter fullscreen mode Exit fullscreen mode

Then it would make our lives much better.

Live long and prosper 🖖

Top comments (2)

Collapse
andy profile image
Andy Zhao (he/him)

Hmm interesting! I've run into similar issues dealing with Markdown parsing where there's an additional <p> tag, and while it doesn't throw a wrench that destroys the system, it is a bit unexpected. Good to know it happens with other Markdown parsing.

Also, TIL you can use variables with Jekyll and Hugo.

Collapse
paul_melero profile image
Paul Melero • Edited on

Interesting. They do not specify a way of doing this in the Github spec neither, AFAIK. github.github.com/gfm

🌚 Life is too short to browse without dark mode