在Jekyll / Ruby中缩进生成的标记 [英] Indenting generated markup in Jekyll/Ruby

查看:95
本文介绍了在Jekyll / Ruby中缩进生成的标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如我有以下两种:

base.html:

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

index.md:

  --- 
layout:base
---
< div id =recent_articles>
{%for site.posts%中的帖子}
< div class =article_puff>
< img src =/ resources / images / fancyi.jpgalt =/>
< h2>< a href ={{post.url}}> {{post.title}}< / a>< / h2>
< p> {{post.description}}< / p>
< a href ={{post.url}}class =read_more>阅读更多内容< / a>
< / div>
{%endfor%}
< / div>

问题在于,导入的{{content}} - 标记在没有上面使用的indendation的情况下呈现。 / p>

因此,而不是

 < body> 
< div id =page>
< div id =recent_articles>
< div class =article_puff>
< img src =/ resources / images / fancyimage.jpgalt =/>
< h2>< a href =/ articles / 2012/11/14 / gettin-down-with-rwd.html>使用响应式网页设计开始下载< / a>< / h2> ;
< p>大家都在谈论它。你的客户想要它。您需要编码。< / p>
< a href =/ articles / 2012/11/14 / gettin-down-with-rwd.htmlclass =read_more>阅读更多内容< / a>
< / div>
< / div>
< / div>
< / body>

我得到

 <身体GT; 
< div id =page>
< div id =recent_articles>
< div class =article_puff>
< img src =/ resources / images / fancyimage.jpgalt =/>
< h2>< a href =/ articles / 2012/11/14 / gettin-down-with-rwd.html>使用响应式网页设计开始下载< / a>< / h2> ;
< p>大家都在谈论它。你的客户想要它。您需要编码。< / p>
< a href =/ articles / 2012/11/14 / gettin-down-with-rwd.htmlclass =read_more>阅读更多内容< / a>
< / div>
< / div>
< / div>
< / body>

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

解决方案

使用液体过滤器

我设法使用液体过滤器来完成这项工作。有几点需要注意:


  • 您的输入必须清晰。我在一些文件(Word或其他文件的副本)中看到了一些卷曲的引号和不可打印的字符,看起来像是空白的,并且看到UTF-8中的无效字节序列为Jekyll错误。


  • 它可能会破坏一些东西。我使用的是twitter bootstrap中的< i class =icon-file>< / i> 图标。它用< i class =icon-file/> 替换了空标记,bootstrap不喜欢那样。此外,它还会在我的内容中加入八进制数 {%codeblock%} s。我没有真正考虑过为什么。

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

      require'rubygems'
    需要'json'
    需要'nokogiri'
    需要'nokogiri-pretty'

    模块Jekyll
    模块PrettyPrintFilter
    def pretty_print(输入)
    #一些ASCII-8进来
    input = input.encode(UTF- 8)

    #使用nokogiri首先清理XSLT无法处理的某些内容
    content = Nokogiri :: HTML :: DocumentFragment.parse输入
    parsed_content = content。 to_html

    #不幸的是nokogiri-pretty不能使用DocumentFragments ...
    html = Nokogiri :: HTML parsed_content
    漂亮= html.human

    #...所以现在我们需要删除它添加的东西来生成有效的HTML
    output = PrettyPrintFilter.strip_extra_html(漂亮)
    输出
    结束

    def PrettyPrint Filter.strip_extra_html(html)
    #type声明
    html = html.sub('<?xml version =1.0encoding =ISO-8859-1?>','')

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

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

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

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

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

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

    html
    结束
    结束
    结束

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

    使用Rake任务



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

     需要'nokogiri'
    需要'nokogiri-pretty'

    descPretty print来自Jekyll的HTML输出
    任务:pretty_print做
    #将public变为_site或者输出到任何地方
    html_files = File.join(**,public,** ,* .html)

    Dir.glob html_files do | html_file |
    putsCleaning#{html_file}

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

    egin
    #我们将它解析为XML,以便我们可以应用XSLT
    html = Nokogiri :: XML(内容)

    #human()方法来自nokogiri-pretty。只需对XML进行XSL转换。
    pretty_html = html.human
    rescue Exception => msg
    puts无法完美打印#{html_file}:#{msg}
    end

    #Yep,我们覆盖文件。潜在的破坏性。
    file = File.new(html_file,w)
    file.write(pretty_html)

    file.close
    end
    end


    Well this is probably kind of a silly question but I'm wondering if there's any way to have the generated markup in Jekyll to preserve the indentation of the Liquid-tag. World doesn't end if it isn't solvable. I'm just curious since I like my code to look tidy, even if compiled. :)

    For example I have these two:

    base.html:

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

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

    Problem is that the imported {{content}}-tag is rendered without the indendation used above.

    So instead of

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

    I get

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

    Seems like only the first line is indented correctly. The rest starts at the beginning of the line... So, multiline liquid-templating import? :)

    解决方案

    Using a Liquid Filter

    I managed to make this work using a liquid filter. There are a few caveats:

    • Your input must be clean. I had some curly quotes and non-printable chars that looked like whitespace in a few files (copypasta from Word or some such) and was seeing "Invalid byte sequence in UTF-8" as a Jekyll error.

    • It could break some things. I was using <i class="icon-file"></i> icons from twitter bootstrap. It replaced the empty tag with <i class="icon-file"/> and bootstrap did not like that. Additionally, it screws up the octopress {% codeblock %}s in my content. I didn't really look into why.

    • While this will clean the output of a liquid variable such as {{ content }} it does not actually solve the problem in the original post, which is to indent the html in context of the surrounding html. This will provide well formatted html, but as a fragment that will not be indented relative to tags above the fragment. If you want to format everything in context, use the Rake task instead of the filter.

    -

    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)
    

    Using a Rake task

    I use a task in my rakefile to pretty print the output after the jekyll site has been generated.

    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
    

    这篇关于在Jekyll / Ruby中缩进生成的标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆