Ответ 1
Использование жидкостного фильтра
Мне удалось выполнить эту работу с использованием жидкостного фильтра. Есть несколько предостережений:
-
Ваш вход должен быть чистым. У меня были кудрявые цитаты и непечатаемые символы, которые выглядели как пробелы в нескольких файлах (copypasta из Word или некоторые из них) и видели ошибку "Недопустимая последовательность байтов в UTF-8" как ошибка Jekyll.
-
Это может сломать некоторые вещи. Я использовал значки
<i class="icon-file"></i>
из бутстрапа twitter. Он заменил пустой тег на<i class="icon-file"/>
, и bootstrap не понравилось. Кроме того, он крепит октопресс{% 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
Я использую задачу в своем файле rakefile, чтобы печатать выходные данные после создания сайта jekyll.
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