Неверное отображение уценки при добавлении блока кода в список

Я использую фрагменты и kramdown в моем блоге Джекила.

Я пытался добавить блок кода в список уценки, но отображал некорректно.

1. first

2. second

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

3. third

2015-10-29 6 39 28

сгенерированный 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>

но если я напишу так, это не проблема.

1. first

2. second

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

3. third

2015-10-29 6 41 37

Это осколки или проблема Крамдауна? Надеюсь, кто-нибудь может мне помочь, спасибо заранее!

3 ответа

Решение

Проблема не в жидкости или крамдауне, а в том, как они работают вместе. Jekyll, кажется, сначала обрабатывает файлы с помощью Liquid, а затем передает результат в kramdown для анализа как уценки.

Это означает, что kramdown видит что-то вроде этого:

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 не сохраняет отступ в разделе кода, поэтому при обработке как уценке он закрывает список, а третий элемент отображается как новый список.

Для того, чтобы использовать highlight Жидкая метка, которую необходимо указать, чтобы результат обработки жидкости был соответствующим отступом. Я не знаю, возможно ли это с простым Jekyll, но вы могли бы сделать это довольно просто с помощью плагина (так что это не будет работать, если вы используете страницы Github).

Создайте файл с именем что-то вроде _plugins/indent_filter.rb с этим содержанием:

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

Liquid::Template.register_filter(IndentFilter)

Теперь вы можете использовать это так:

1. first

2. second

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

3. third

Обратите внимание, что вам нужно использовать capture сначала для того, чтобы использовать indent фильтр (возможно, вы могли бы создать собственный тег для использования вместо highlight Если вы предпочитаете). Также обратите внимание, что теги Liquid вообще не имеют отступов, что обрабатывается фильтром.

Результат этого после обработки жидкости, но до уценки выглядит примерно так:

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 

Теперь блок кода имеет правильные отступы, поэтому уценка видит его как содержимое второго элемента списка. Поскольку это уже HTML, kramdown не пытается обрабатывать его дальше, но и не закрывает список. Результат после обработки уценки:

<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>

Джекилл highlight тег обрезает содержимое. Так как пробелы перед вашим end Заявление находится в середине текста, оно не будет обрезано.

Разблокируйте весь блок кода, и он должен отображаться правильно.

1. first

2. second

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

3. third

Я немного изменил ответ @matt.

Мы можем использовать \t в файле rb вместо 4 пробелов.

Благодаря этим изменениям мы также можем использовать отступ для элементов списка 1-го уровня и 2-го уровня.

Найдите файл rb ниже

      module IndentFilter
  def indent1(input)
    input.gsub(/\n/, "\n\t")
  end
  def indent2(input)
    input.gsub(/\n/, "\n\t\t")
  end
end

Liquid::Template.register_filter(IndentFilter)
Другие вопросы по тегам