53

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>
bahrep
  • 29,961
  • 12
  • 103
  • 150
sunnyrjuneja
  • 6,033
  • 2
  • 32
  • 51

7 Answers7

85

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!

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
Cristian
  • 1,338
  • 1
  • 9
  • 12
  • 4
    Thank you fine sir, this is the cleanest solution proposed. – Art Oct 10 '14 at 07:17
  • 5
    Becareful not having 4 spaces when indenting your HTML code, otherwise you will get `
    `, see https://github.com/gettalong/kramdown/issues/213
    – tanguy_k Feb 03 '15 at 23:47
  • 3
    @PerLundberg I struggled to get this work too. Fiddled with everything!!! Finally I found this: http://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. – Kobold Apr 01 '16 at 10:27
  • Works with jekyll 3.0 for me – Lucas Apr 29 '16 at 21:03
  • Does not work in default.html with the minimal GitHub setup. – SeanFromIT Jul 07 '18 at 22:02
  • This method mostly worked, except that for some strange reason, it kept adding random `` 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://stackoverflow.com/a/38819797/85309 – Topher Fangio Aug 02 '18 at 18:23
  • Considering that you have to use .md files, how is this different than without the surrounding `
    ` tag? Edit: nevermind, I get it--you can render markdown deep within HTML tags where it would normally be ignored by Kramdown.
    – Matt Thomas Oct 27 '20 at 13:13
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.

MisterMetaphor
  • 5,900
  • 3
  • 24
  • 31
  • 1
    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! – Peter Ehrlich Jan 21 '14 at 21:30
  • 2
    Note also that `Document.new(content, input: 'GFM)` will enable github-flavored markdown for you. – Peter Ehrlich Jan 21 '14 at 21:48
  • @PeterEhrlich: Jekyll uses Kramdown as the default: https://github.com/jekyll/jekyll/blob/master/lib/jekyll/configuration.rb#L37. But yes, it would be nicer to be able to delegate the call to *whatever-markdown-processor-is-used-in-the-current-config* somehow. – Per Lundberg Nov 14 '15 at 15:18
  • Could you please detail what to do with the block of code you've got at the start of this answer? – detly Feb 21 '16 at 03:11
  • 1
    @detly, I've updated the answer with short installation instruction. – MisterMetaphor Feb 21 '16 at 03:15
  • Does not work with: {% markdown %} * TOC {:toc} {% endmarkdown %} – Natalie Perret Feb 04 '18 at 07:37
  • 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. – watzon Aug 25 '19 at 21:23
14

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>
Frank N
  • 9,625
  • 4
  • 80
  • 110
  • Should `markdown="1"` work on other elements, such as `display` or does it only work in a `div`? – dlu Jun 04 '18 at 01:45
  • I am unaware of a display element :P, but it should work on `
    `, `
    – Frank N Jun 04 '18 at 07:01
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

J W
  • 2,801
  • 2
  • 18
  • 22
7

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.

Josh_Thompson
  • 91
  • 3
  • 12
  • You made my day ^^ – Despertaweb Aug 23 '20 at 20:44
  • @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. – functional_overflow Aug 09 '22 at 06:48
4

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>
J.T.
  • 864
  • 9
  • 17
2

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

bahrep
  • 29,961
  • 12
  • 103
  • 150
Traveling Tech Guy
  • 27,194
  • 23
  • 111
  • 159
  • 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. – sunnyrjuneja Apr 10 '13 at 05:28
  • 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 forever – Ky - Dec 21 '20 at 06:11