在Jekyll / Ruby中缩进生成的标记 [英] Indenting generated markup in Jekyll/Ruby
问题描述
例如我有以下两种:
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屋!