Embedding Markdown in Jekyll HTML
Asked Answered
D

7

54

I'm trying to nest markdown in an HTML file while using Jekyll. Is there a way to achieve something like the following?

# index.html

---
layout: default
---


<p>[Stack Overflow](http://www.stackoverflow.com)</p>

Note: I'm aware that I could do this instead.

# index.html

---
layout: default
---


<p><a href="http://www.stackoverflow.com">Stack Overflow</a></p>
Daugava answered 10/4, 2013 at 5:14 Comment(0)
H
27

Here's how you can define a markdown block with a Jekyll plugin:

module Jekyll
  class MarkdownBlock < Liquid::Block
    def initialize(tag_name, text, tokens)
      super
    end
    require "kramdown"
    def render(context)
      content = super
      "#{Kramdown::Document.new(content).to_html}"
    end
  end
end
Liquid::Template.register_tag('markdown', Jekyll::MarkdownBlock)

(To install this snippet as a plugin, put it in a *.rb file under _plugins directory of your source site root)

Then, use it like this:

{% markdown %}
[Stack Overflow](http://www.stackoverflow.com)
{% endmarkdown %}

EDIT: See @Cristian's answer for a better solution! If you're using Kramdown (which is likely the case since you are using Jekyll), you can use it's feature to render markdown inside div's with a markdown="1" attribute.

Helli answered 30/8, 2013 at 9:35 Comment(7)
note that I had to gem install kramdown for this. It seems a little hacky not to use whatever Jekyll uses built-in for markdown parsing, but it does work!Budweis
Note also that Document.new(content, input: 'GFM) will enable github-flavored markdown for you.Budweis
@PeterEhrlich: Jekyll uses Kramdown as the default: github.com/jekyll/jekyll/blob/master/lib/jekyll/…. But yes, it would be nicer to be able to delegate the call to whatever-markdown-processor-is-used-in-the-current-config somehow.Heflin
Could you please detail what to do with the block of code you've got at the start of this answer?Padang
@detly, I've updated the answer with short installation instruction.Helli
Does not work with: {% markdown %} * TOC {:toc} {% endmarkdown %}Chicle
If you change super to super.strip inside of the render method it will allow you to indent your code. Otherwise the block can't be indented.Enjoyable
S
89

If you are using Kramdown, based on their doc you can do this:

<div markdown="1">
   My text with **markdown** syntax
</div>

And this way, the text within the div is rendered as markdown.

Make sure to use the .md or .markdown extension for the file, as .html files aren't sent to Kramdown for processing!

Stroller answered 30/4, 2014 at 9:15 Comment(7)
Thank you fine sir, this is the cleanest solution proposed.Unattended
Becareful not having 4 spaces when indenting your HTML code, otherwise you will get <pre>, see github.com/gettalong/kramdown/issues/213Ptyalism
@PerLundberg I struggled to get this work too. Fiddled with everything!!! Finally I found this: ricostacruz.com/til/markdown-in-jekyll.html Long story short, rename index.html to index.md. Took me waaay too long to figure it out.Rojo
Works with jekyll 3.0 for meQuash
Does not work in default.html with the minimal GitHub setup.Whiny
This method mostly worked, except that for some strange reason, it kept adding random </div> tags to my code, and sometimes, it would not finish the code, so everything else in the file got treated as code as well. Eventually, I found the following solution using capture to capture the code at the top of the file and inject it into the {% highlight %} tags later in the page: https://mcmap.net/q/339680/-how-to-remove-unnecessary-indent-and-break-line-in-highlight-jekyllSpiceberry
Considering that you have to use .md files, how is this different than without the surrounding <div> tag? Edit: nevermind, I get it--you can render markdown deep within HTML tags where it would normally be ignored by Kramdown.Csch
H
27

Here's how you can define a markdown block with a Jekyll plugin:

module Jekyll
  class MarkdownBlock < Liquid::Block
    def initialize(tag_name, text, tokens)
      super
    end
    require "kramdown"
    def render(context)
      content = super
      "#{Kramdown::Document.new(content).to_html}"
    end
  end
end
Liquid::Template.register_tag('markdown', Jekyll::MarkdownBlock)

(To install this snippet as a plugin, put it in a *.rb file under _plugins directory of your source site root)

Then, use it like this:

{% markdown %}
[Stack Overflow](http://www.stackoverflow.com)
{% endmarkdown %}

EDIT: See @Cristian's answer for a better solution! If you're using Kramdown (which is likely the case since you are using Jekyll), you can use it's feature to render markdown inside div's with a markdown="1" attribute.

Helli answered 30/8, 2013 at 9:35 Comment(7)
note that I had to gem install kramdown for this. It seems a little hacky not to use whatever Jekyll uses built-in for markdown parsing, but it does work!Budweis
Note also that Document.new(content, input: 'GFM) will enable github-flavored markdown for you.Budweis
@PeterEhrlich: Jekyll uses Kramdown as the default: github.com/jekyll/jekyll/blob/master/lib/jekyll/…. But yes, it would be nicer to be able to delegate the call to whatever-markdown-processor-is-used-in-the-current-config somehow.Heflin
Could you please detail what to do with the block of code you've got at the start of this answer?Padang
@detly, I've updated the answer with short installation instruction.Helli
Does not work with: {% markdown %} * TOC {:toc} {% endmarkdown %}Chicle
If you change super to super.strip inside of the render method it will allow you to indent your code. Otherwise the block can't be indented.Enjoyable
B
15

As of current Jekyll 3.6.2 life can be a lot simpler with the following two options:

enter image description here

<div>
{{ "## Yes, this renders as markdown" | markdownify }}
</div>

note the markdown-attribute:

<div markdown="1">
## some markdown
inside some html. `snippet` _italic_ **bold**
</div>
Buzzer answered 22/11, 2017 at 10:26 Comment(2)
Should markdown="1" work on other elements, such as display or does it only work in a div?Sapid
I am unaware of a display element :P, but it should work on <section>, <nav>, <main> all the same…Buzzer
W
9

@sunny-juneja, check out the Liquid Extension Filter called markdownify:

https://github.com/mojombo/jekyll/wiki/liquid-extensions#markdownify

Use it like this:

<p>{{ '[Stack Overflow](http://www.stackoverflow.com)' | markdownify }}</p>

Put single or double quotes around your string inside of the Output tag.

Works for me on Jekyll 1.0.0beta3

Wanton answered 11/4, 2013 at 3:17 Comment(2)
This works for variables, but not if you want to import a separate markdown file or put markdown directly inside an HTML block. @MisterMetaphor's answer below to create a plugin solves that issue.Molt
I don't think this will work. The output content will be <p><p><p><a href="http://www.stackoverflow.com">Stack Overflow</a></p>.Sheasheaf
S
8

I just recently spent way too many hours trying to do something similar. @J.T.'s 2nd bullet point, referencing markdownify, is what ultimately got me moving in the right direction.

I had in my _layouts directory a few different layouts. One of them, I wanted to add a bit of an "index" before the page content. The index was working perfectly as a partial, if I called it directly from a page or post, but not when trying to add it to a layout.

Here's what I had:

---
layout: default
---

<div class="table-of-contents">
  
  {% include series_index.md %}
  
  {{ content }}
</div>

But it wouldn't work. Instead of rendering HTML on the page, the include was spitting out the markdown, which was then being added to the page as an ugly block of markdown, instead of rendering the markdown as HTML.

So, I tried tacking | markdownify to the include statement, like so:

  {% include jekyll-bug-fix-index.md | markdownify %}

and that didn't work.

The solution, using a variable, a capture "block", and markdownify

So, I captured the markdown, saved to a variable, and then rendered the variable with the liquid markdownify tag:

  {% capture index %}
  {% include series_index.md %}
  {% endcapture %}
  
  {{ index | markdownify }}

And this works! The Markdown is rendered as HTML on my pages, and all is right in the world.

I have no doubt this is unconventional, and I hope to someday learn a better solution, but it's 100% good enough for me, and I wanted to share so others might benefit from this.

Stopping answered 30/7, 2020 at 14:51 Comment(2)
You made my day ^^Silk
@Josh_Thompson: Thank you! I came closest with the help of your answer. But parts of my markdown(mainly links) are still not rendered properly. I use markdown instead of HTML for content with many links and I have been struggling to include that using jekyll.Servomotor
M
5

To convert the markdown-formatted string to HTML in a Jekyll page, there are THREE WAYS can be selected as below:


1. Kramdown:

If you are using Kramdown, based on their doc you can do this:

<div markdown="1">
## Some Markdown Title
Let's have a look. `snippet` _italic_ **bold**
</div>

The markdown attribute:

  • If an HTML tag has an attribute markdown="0", then the tag is parsed as raw HTML block.
  • If an HTML tag has an attribute markdown="1", then the default mechanism for parsing syntax in this tag is used.
  • If an HTML tag has an attribute markdown="block", then the content of the tag is parsed as block level elements.
  • If an HTML tag has an attribute markdown="span", then the content of the tag is parsed as span level elements.

Requirments:

  • The markdown content need to be within the DIV tag.
  • Make sure to use the .md or .markdown extension for the file as .html files aren't sent to Kramdown for processing)

2. Liquid Extension Filter

There is a liquid extension filter called markdownify, it also can help you convert a Markdown-formatted string into HTML.

<div>
{{ "Renders as markdown. `snippet` _italic_ **bold**" | markdownify }}
</div>

3. Jekyll plugin:

jekyll-spaceship - 🚀 A Jekyll plugin to provide powerful supports for table, mathjax, mermaid, plantuml, emoji, youtube, vimeo, dailymotion, etc.

https://github.com/jeffreytse/jekyll-spaceship

With this plugin, it's easy to write markdown inside HTML:

<script type="text/markdown">
# Hybrid HTML with Markdown is a not bad choice ^\_^

##2. Table Usage

| :        Fruits \|\| Food       : |||
| :--------- | :-------- | :--------  |
| Apple      | :  Apple :| Apple      \
| Banana     |   Banana  | Banana     \
| Orange     |   Orange  | Orange     |
| :   Rowspan is 4    : || How's it?  |
|^^    A. Peach         ||   1. Fine :|
|^^    B. Orange        ||^^ 2. Bad   |
|^^    C. Banana        ||  It's OK!  |

## PlantUML Usage

@startuml
Bob -> Alice : hello
@enduml

## Video Usage

![](https://www.youtube.com/watch?v=Ptk_1Dc2iPY)
</script>
Molybdenum answered 1/5, 2020 at 15:32 Comment(0)
B
2

Take a look at Paul Irish's Gist for a JS code that can interpret sections of your page from Markdown to HTML.

Beltz answered 10/4, 2013 at 5:24 Comment(2)
This is really cool. I was hoping for a jekyll specific solution but I'll mark you as an answer if no one provides one.Daugava
If this gist ever goes away, this answer won't be useful to future visitors. Placing the content in this answer while still providing a link to the original will keep this answer useful foreverIila

© 2022 - 2024 — McMap. All rights reserved.