markdown display incorrect when add code block in

2019-08-10 20:11发布

I am using pygments and kramdown in my jekyll blog.

I tried to add code block to markdown list, but display incorrect.

1. first

2. second

    {% highlight ruby %}
    def foo
      puts 'foo'
    end
    {% endhighlight %}

3. third

2015-10-29 6 39 28

generated html:

<ol>
  <li>
    <p>first</p>
  </li>
  <li>
    <p>second</p>
  </li>
</ol>

<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span>
  <span class="nb">puts</span> <span class="s1">&#39;foo&#39;</span>
<span class="k">end</span></code></pre></div>

<ol>
  <li>third</li>
</ol>

but if I write like this, it is no problem.

1. first

2. second

    ```
    def foo
      puts 'foo'
    end
    ```

3. third

2015-10-29 6 41 37

Is this pygments or kramdown problem? Hope someone can help me, thanks in advanced!

2条回答
smile是对你的礼貌
2楼-- · 2019-08-10 20:53

The Jekyll highlight tag is trimming the content. Since the spaces before your end statement are in the middle of the text, it won't get trimmed.

Unindent the whole block of code and it should render correctly.

1. first

2. second

    {% highlight ruby %}
def foo
  puts 'foo'
end
    {% endhighlight %}

3. third
查看更多
3楼-- · 2019-08-10 21:02

The problem is not with Liquid or kramdown individually, but how they operate together. Jekyll seems to be processing the files with Liquid first, followed by passing the result to kramdown to be parsed as markdown.

This means that kramdown is seeing something like this:

1. first

2. second


<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby">    <span class="k">def</span> <span class="nf">foo</span>
      <span class="nb">puts</span> <span class="s1">'foo'</span>
    <span class="k">end</span>
    </code></pre></figure>


3. third

Liquid isn’t keeping the indentation of the code section, and so when processed as markdown it is causing the list to close and the third item to be seen as a new list.

In order to use the highlight Liquid tag here you need to ensure the result of Liquid processing is the appropriately indented markdown. I don’t know if this is possible with plain Jekyll, but you could do this fairly simply with a plugin (so this won’t work if you are using Github pages).

Create a file named something like _plugins/indent_filter.rb with these contents:

module IndentFilter
  def indent(input)
    input.gsub(/\n/, "\n    ")
  end
end

Liquid::Template.register_filter(IndentFilter)

Now you can use it like this:

1. first

2. second

{% capture the_code %}
{% highlight ruby %}
def foo
  puts 'foo'
end
{% endhighlight %}
{% endcapture %}
{{ the_code | indent }}

3. third

Note that you need to use capture first in order to use the indent filter (you could probably create a custom tag to use instead of highlight if you prefer). Also note that the Liquid tags aren’t indented at all, that is handled by the filter.

The result of this after Liquid processing but before markdown is something like this:

1. first

2. second

    <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span>
      <span class="nb">puts</span> <span class="s1">'foo'</span>
    <span class="k">end</span></code></pre></figure>

3. third 

Now the code block is correctly indented so that markdown sees it as the content of the second list item. Since it is already HTML kramdown doesn’t try to process it further, but also it doesn’t cause the list to be closed. The result after markdown processing is:

<ol>
  <li>
    <p>first</p>
  </li>
  <li>
    <p>second</p>

    <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span>
   <span class="nb">puts</span> <span class="s1">'foo'</span>
 <span class="k">end</span></code></pre></figure>
  </li>
  <li>
    <p>third</p>
  </li>
</ol>
查看更多
登录 后发表回答