Compojure HTML Formatting

6

我相对于Clojure和HTML/Compojure是新手。我正在尝试使用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)))

该函数仅将HTML写入文件。(这里的args参数不相关,只是为了确保示例在我的程序中编译和运行。)《Clojure编程》指出调用html函数会产生格式化的HTML--多行缩进。但我得到的只有预期的文档类型,后面跟着所有HTML在一行上。HTML Tidy没有发现输出文件内容的任何问题。如果我在REPL中使用println,它也会作为单行输出。是否还需要其他东西以获得格式化输出?
5个回答

10
虽然Brian的答案指向了Firebug,让我开启所需的调试,但我太过于执着,无法放手。根据kwertii提供的指针,我在我的程序中包含了以下代码。
编辑:简化了代码一些。
(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)))

我将jtidy-r938.jar添加到我的项目中(使用enclojure插件的NetBeans),并将其导入。配置函数告诉解析器输出格式化、缩进的HTML并跳过警告。漂亮打印函数的返回值现在被很好地格式化,无论我是用Firebug还是简单的文本编辑器打开它。


10

出于性能和复杂性原因,Compojure中HTML输出的格式已被删除。如果您需要获取格式化输出,则可能需要编写自己的打印函数。

我通常将HTML输出为Compojure所需的格式,并使用Firebug在浏览器中实时查看它。无论实际上是否全部在一行上,Firebug都会以漂亮的格式显示它。这在大多数情况下已经足够好了。如果您需要将此HTML序列化为可读形式,可以将其保留为Clojure向量和S-表达式,然后以这种方式进行序列化。


谢谢你的另一个答案,Brian。我之前不熟悉Firebug,但是玩了几分钟后,它似乎给了我所需要的调试能力。我还发现了另一种有趣的方法,网址是http://www.erik-rasmussen.com/blog/2009/09/08/xml-renderer-in-clojure/。虽然我还没有尝试过,但它看起来比开发我的打印函数要容易得多(更快)。或者我可以使用早期版本的Compojure来进行格式化。 - clartaq

4
有大量的Java可用的HTML漂亮打印机,其中一个著名的是JTidy,它是HTML Tidy的Java移植版。您可以轻松地通过该库将Clojure的输出进行编程处理,并获得整齐缩进和格式化的HTML返回。
如果您愿意尝试,HTML Tidy也可以作为Unix命令行程序使用--您只需像其他shell程序一样将HTML输入到它中即可。

感谢指点,kwertii。我之前不知道这个,会尝试一下。 - clartaq

1
上述方法对我没有起作用。 我稍微改动了一下。 在project.clj中添加[jtidy“4aug2000r7-dev”]。
(: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)))

0
如果有人仍在关注这个查询,您需要使用hiccup库。它可以从与Clojure数据结构完全相同的格式化HTML。
因此,

(require '[hiccup.core :refer [html]])

(defn fake-write-html
  [dir args]
  (let [file (str dir *file-separator* *index-file*)
        my-html (html
                  [: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)))

会按照原帖作者的意图精确地工作。强烈推荐。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接