16

好吧,这可能是一个愚蠢的问题,但我想知道是否有任何方法可以在 Jekyll 中生成标记来保留 Liquid-tag 的缩进。如果无法解决,世界就不会结束。我只是好奇,因为我喜欢我的代码看起来整洁,即使编译。:)

例如我有这两个:

base.html:

<body>
    <div id="page">
        {{content}}
    </div>
</body>

索引.md:

---
layout: base
---
<div id="recent_articles">
    {% for post in site.posts %}
    <div class="article_puff">
        <img src="/resources/images/fancyi.jpg" alt="" />
        <h2><a href="{{post.url}}">{{post.title}}</a></h2>
        <p>{{post.description}}</p>
        <a href="{{post.url}}" class="read_more">Read more</a>
    </div>
    {% endfor %}    
</div>

问题是导入的 {{content}}-tag 是在没有上面使用的缩进的情况下呈现的。

所以而不是

<body>
    <div id="page">
        <div id="recent_articles">  
            <div class="article_puff">
                <img src="/resources/images/fancyimage.jpg" alt="" />
                <h2><a href="/articles/2012/11/14/gettin-down-with-rwd.html">Gettin' down with responsive web design</a></h2>
                <p>Everyone's talking about it. Your client wants it. You need to code it.</p>
                <a href="/articles/2012/11/14/gettin-down-with-rwd.html" class="read_more">Read more</a>
            </div>
        </div>
    </div>
</body>

我明白了

<body>
    <div id="page">
        <div id="recent_articles">  
<div class="article_puff">
<img src="/resources/images/fancyimage.jpg" alt="" />
    <h2><a href="/articles/2012/11/14/gettin-down-with-rwd.html">Gettin' down with responsive web design</a></h2>
    <p>Everyone's talking about it. Your client wants it. You need to code it.</p>
    <a href="/articles/2012/11/14/gettin-down-with-rwd.html" class="read_more">Read more</a>
</div>
</div>
    </div>
</body>

似乎只有第一行正确缩进。其余的从行首开始......那么,多行液体模板导入?:)

4

2 回答 2

13

使用液体过滤器

我设法使用液体过滤器完成了这项工作。有几个注意事项:

  • 您的输入必须是干净的。我有一些弯引号和不可打印的字符,在一些文件中看起来像空格(来自 Word 的 copypasta 等),并且将“UTF-8 中的无效字节序列”视为 Jekyll 错误。

  • 它可能会破坏一些东西。我正在使用<i class="icon-file"></i>来自 twitter bootstrap 的图标。它将空标签替换为<i class="icon-file"/>引导程序不喜欢那样。此外,它搞砸了我内容中的 octopress {% codeblock %}。我并没有真正研究为什么。

  • 虽然这将清除液体变量的输出,例如{{ content }}它实际上并不能解决原始帖子中的问题,即在周围 html的上下文中缩进 html。这将提供格式良好的 html,但作为一个片段,不会相对于片段上方的标签缩进。如果您想在上下文中格式化所有内容,请使用 Rake 任务而不是过滤器。

-

require 'rubygems'
require 'json'
require 'nokogiri'
require 'nokogiri-pretty'

module Jekyll
  module PrettyPrintFilter
    def pretty_print(input)
      #seeing some ASCII-8 come in
      input = input.encode("UTF-8")

      #Parsing with nokogiri first cleans up some things the XSLT can't handle
      content = Nokogiri::HTML::DocumentFragment.parse input
      parsed_content = content.to_html

      #Unfortunately nokogiri-pretty can't use DocumentFragments...
      html = Nokogiri::HTML parsed_content
      pretty = html.human

      #...so now we need to remove the stuff it added to make valid HTML
      output = PrettyPrintFilter.strip_extra_html(pretty)
      output
    end

    def PrettyPrintFilter.strip_extra_html(html)
      #type declaration
      html = html.sub('<?xml version="1.0" encoding="ISO-8859-1"?>','')

      #second <html> tag
      first = true
      html = html.gsub('<html>') do |match|
        if first == true
          first = false
          next
        else
          ''
        end
      end

      #first </html> tag
      html = html.sub('</html>','')

      #second <head> tag
      first = true
      html = html.gsub('<head>') do |match|
        if first == true
          first = false
          next
        else
          ''
        end
      end

      #first </head> tag
      html = html.sub('</head>','')

      #second <body> tag
      first = true
      html = html.gsub('<body>') do |match|
        if first == true
          first = false
          next
        else
          ''
        end
      end

      #first </body> tag
      html = html.sub('</body>','')

      html
    end
  end
end

Liquid::Template.register_filter(Jekyll::PrettyPrintFilter)

使用 Rake 任务

在生成 jekyll 站点后,我在我的 rakefile 中使用一个任务来漂亮地打印输出。

require 'nokogiri'
require 'nokogiri-pretty'

desc "Pretty print HTML output from Jekyll"
task :pretty_print do
  #change public to _site or wherever your output goes
  html_files = File.join("**", "public", "**", "*.html")

  Dir.glob html_files do |html_file|
    puts "Cleaning #{html_file}"

    file = File.open(html_file)
    contents = file.read

    begin
      #we're gonna parse it as XML so we can apply an XSLT
      html = Nokogiri::XML(contents)

      #the human() method is from nokogiri-pretty. Just an XSL transform on the XML.
      pretty_html = html.human
    rescue Exception => msg
      puts "Failed to pretty print #{html_file}: #{msg}"
    end

    #Yep, we're overwriting the file. Potentially destructive.
    file = File.new(html_file,"w")
    file.write(pretty_html)

    file.close
  end
end
于 2013-02-23T05:18:13.020 回答
0

我们可以通过编写一个自定义的 Liquid 过滤器来整理 html,然后{{content | tidy }}包含 html 来实现这一点。

快速搜索表明,红宝石 tidy gem 可能无法维护,但 nokogiri 是要走的路。这当然意味着安装 nokogiri gem。

请参阅有关编写液体过滤器的建议Jekyll 示例过滤器

一个示例可能如下所示: 在 中_plugins,添加一个名为 tidy-html.rb 的脚本,其中包含:

require 'nokogiri'
module TextFilter
  def tidy(input)
  desired = Nokogiri::HTML::DocumentFragment.parse(input).to_html
  end
end
Liquid::Template.register_filter(TextFilter)

(未经测试)

于 2012-11-30T22:38:58.623 回答