2012-11-30 7 views
12

Beh, probabilmente è una specie di domanda sciocca, ma mi chiedo se c'è un modo per avere il markup generato in Jekyll per preservare il rientro del Liquid-tag. Il mondo non finisce se non è risolvibile. Sono solo curioso dal momento che mi piace che il mio codice sia in ordine, anche se compilato. :)Indentazione del markup generato in Jekyll/Ruby

Per esempio io ho questi due:

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> 

Il problema è che la {{content}} importata - il tag è reso senza la correzione usata sopra.

Così, invece di

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

ottengo

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

Sembra come solo la prima riga è rientrato correttamente. Il resto inizia all'inizio della linea ... Quindi, l'importazione multilinea di templature liquide? :)

+0

Qualcuno ha mai trovare una soluzione che produce direttamente il markup correttamente rientrato? – mb21

risposta

13

Utilizzando un filtro liquido

Sono riuscito a fare questo lavoro usando un filtro liquido. Ci sono alcuni avvertimenti:

  • L'input deve essere pulito. Avevo alcune virgolette ricurve e caratteri non stampabili che sembravano spazi bianchi in alcuni file (copypasta da Word o alcuni di questi) e vedevo "Sequenza di byte non valida in UTF-8" come un errore di Jekyll.

  • Potrebbe rompere alcune cose. Stavo usando le icone <i class="icon-file"></i> dal bootstrap di Twitter. Ha sostituito il tag vuoto con <i class="icon-file"/> e il bootstrap non gli piaceva. Inoltre, rimuove il octopress {% codeblock %} s nel mio contenuto. Non ho davvero cercato perché.

  • Mentre questo pulirà l'uscita di una variabile liquido come {{ content }} realtà non risolve il problema nel post originale, che è quello di rientrare la html nel contesto del html circostante. Ciò fornirà un html ben formattato, ma come un frammento che non sarà indentato rispetto ai tag sopra il frammento.Se si desidera formattare tutto nel contesto, utilizzare l'attività Rake anziché il filtro.

-

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) 

Utilizzando un compito Rake

Io uso un compito nel mio rakefile per stampare abbastanza l'uscita dopo che il sito Jekyll è stato generato.

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

c'è un modo per indentare solo il contenuto dell'elemento 'body' ma lasciando extra nuove per la leggibilità? – fcalderan

+0

È possibile eseguire esplicitamente la trasformazione XSL come descritto qui: http://stackoverflow.com/questions/1898829/how-do-i-pretty-print-html-with-nokogiri e quindi personalizzare l'XSLT in base alle proprie esigenze. – bwest

0

Possiamo ottenere questo risultato scrivendo un filtro Liquid personalizzato per riordinare l'html e quindi fare {{content | tidy }} per includere l'html.

Una ricerca rapida suggests che la gemma ordinata di rubino non può essere mantenuta ma che nokogiri è la strada da percorrere. Questo ovviamente significherebbe installare la gemma di nokogiri.

Vedere advice on writing liquid filters e Jekyll example filters.

Un esempio potrebbe essere simile a questo: in _plugins, aggiungere uno script chiamato ordinata-html.rb contenente:

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

(testato)

+0

Ho appena provato questo approccio, ma il testo non è ancora presente – fcalderan