2009-12-17 13 views
5

Sono relativamente nuovo a Clojure e a una vergine HTML/Compojure completa. Sto cercando di utilizzare Compojure per creare pagine statiche di HTML utilizzando una funzione simile a questo:Formattazione Compojure HTML

(defn fake-write-html 
    [dir args] 
    (let [file (str dir *file-separator* *index-file*) 
     my-html (html 
        (doctype :html4) 
        [:html 
        [:head 
        [:title "Docs and Dirs:"]] 
        [:body 
        [:div 
        [:h2 "A nice title"]] 
        [:div 
        [:ul 
         [:li "One"] 
         [:li "Two"]]]]])] 
    (clojure.contrib.duck-streams/spit file my-html))) 

La funzione solo scrive HTML in un file. (L'argomento args è irrilevante in questa sede solo lì per assicurare l'esempio compilato ed eseguito nel mio programma..)

"Programmazione Clojure" ha indicato che la chiamata alla funzione html produrrebbe in formato HTML - linee multiple con rientro. Tutto quello che ottengo è il tipo di documento previsto, seguito da tutto il codice HTML su una singola riga. HTML Tidy non rileva alcun problema con il contenuto del file di output. Viene visualizzato come una riga singola se I println anche al REPL.

C'è qualcos'altro necessario per ottenere l'output formattato?

risposta

9

La formattazione dell'output HTML in Compojure era removed for performance and complexity reasons. Per ottenere un output formattato probabilmente dovrai scrivere la tua funzione di stampa.

Generalmente emetto il codice HTML come indicato da Compojure e utilizzo Firebug per visualizzarlo dal vivo nel mio browser. Firebug lo mostrerà ben formattato, indipendentemente dal fatto che sia davvero tutto su una riga o meno. Questo funziona abbastanza bene la maggior parte del tempo. Se hai bisogno di serializzare questo codice HTML in una forma leggibile, puoi mantenerlo come vettori Clojure e sexp e serializzarlo in questo modo.

+0

Grazie per un'altra risposta Brian. Non avevo familiarità con Firebug, ma dopo aver giocato per qualche minuto, sembra darmi l'abilità di debug che stavo cercando. Ho anche trovato un altro approccio interessante su http://www.erik-rasmussen.com/blog/2009/09/08/xml-renderer-in-clojure/. Non ho ancora provato, ma sembra molto più facile (più veloce) di sviluppare la mia funzione di stampante. O potrei semplicemente prendere una versione precedente di Compojure che ha fatto la formattazione. – clartaq

4

Ci sono tonnellate di HTML pretty printers available for Java, in particolare JTidy, una porta Java di HTML Tidy. È possibile alimentare facilmente l'output di Clojure attraverso questa libreria in modo programmatico e ottenere back HTML con rientri precisi e formattati.

HTML Tidy è anche disponibile come programma da riga di comando per Unix se ti interessa percorrere questa strada: puoi semplicemente passare l'HTML attraverso di esso come qualsiasi altro programma di shell.

+0

Grazie per il puntatore, kwertii. Non ne ero a conoscenza e farò un tentativo. – clartaq

8

Anche se la risposta di Brian mi ha indirizzato a Firebug, consentendo il debug che volevo, ero ossessivo-compulsivo di lasciarlo da solo. Seguendo il puntatore di kwertii su JTidy, ho incluso il seguente codice nel mio programma.

Edit: semplificato il codice di un po '

(ns net.dneclark.someprogram 
    (:gen-class) 
    ... 
    (:import (org.w3c.tidy Tidy)) 
    ) 

    ... 

(defn configure-pretty-printer 
    "Configure the pretty-printer (an instance of a JTidy Tidy class) to 
generate output the way we want -- formatted and without sending warnings. 
Return the configured pretty-printer." 
    [] 
    (doto (new Tidy) 
    (.setSmartIndent true) 
    (.setTrimEmptyElements true) 
    (.setShowWarnings false) 
    (.setQuiet true))) 

(defn pretty-print-html 
    "Pretty-print the html and return it as a string." 
    [html] 
    (let [swrtr (new StringWriter)] 
    (.parse (configure-pretty-printer) (new StringReader (str html)) swrtr) 
    (str swrtr))) 

ho aggiunto il jtidy-r938.jar al mio progetto (NetBeans utilizzando il plugin enclojure) e importato. La funzione di configurazione dice al parser di emettere il codice HTML formattato e rientrato e saltare gli avvertimenti. Il valore restituito dalla funzione pretty-printer ora è ben formattato sia che lo apro con Firebug o un semplice editor di testo.

1

Quanto sopra non ha funzionato per me. L'ho cambiato un po '.

aggiungere questo [jtidy "4aug2000r7-dev"] per project.clj

(:use clojure.core) 
(:import (org.w3c.tidy Tidy)) 
(:import (java.io ByteArrayInputStream ByteArrayOutputStream))) 



(defn configure-pretty-printer 
"Configure the pretty-printer (an instance of a JTidy Tidy class) to 
generate output the way we want -- formatted and without sending warnings. 
Return the configured pretty-printer." 
[] 
(doto (new Tidy) 
(.setSmartIndent true) 
;(.setTrimEmptyElements true) 
(.setShowWarnings false) 
(.setQuiet true))) 

(defn pretty-print-html 
    "Pretty-print the html and return it as a string." 
[html] 
(let [swrtr (ByteArrayOutputStream.)] 
    (.parse (configure-pretty-printer) (ByteArrayInputStream. (.getBytes (str html))) swrtr) 
(str swrtr)))