1

我试图了解如何在 s 表达式中表达一个简单的文档。这就是我的意思。假设我有这个简单的 html 结构:

<h1>Document Title</h1>
<p>Paragraph with some text.</p>
<p>Paragraph with some <strong>bold</strong> text.</p>

还让我们假设我可以丢失原始标签出处并且只想保留结构。这怎么能用sexp来表达呢?我最初的尝试(使用 clojure)看起来像这样,但我不确定它是否正确:

(def sexp-doc '("Document Title"
                ("" ())
                ("This is a paragraph with some text." ())
                ("" ())
                ("This is a paragraph with" ("bold" ()) ("text." ()))))
4

2 回答 2

3

对于这样的情况,我建议使用Hiccup 的语法

(require '[clojure.string :as str]
         '[hiccup.core :as hiccup])

(def document
  [[:h1 "Document Title"]
   [:p "Paragraph with some text."]
   [:p "Paragraph with some " [:strong "bold"] " text."]])

(println (str/join "\n" (map #(hiccup/html %) document)))
;; <h1>Document Title</h1>
;; <p>Paragraph with some text.</p>
;; <p>Paragraph with some <strong>bold</strong> text.</p>
;;=> nil

如果您不需要转换回 HTML 字符串,那么显然您不需要 Hiccup 依赖项;我只是把它放在这里是为了证明这三个向量中的每一个都是有效的 Hiccup。

由于此语法使用向量而不是列表,因此您无需引用或list直接使用函数,这给您带来了几个优点:

  • 如果你引用东西,你不能在“打嗝文字”中调用函数来构造内部形式
  • 如果您必须list为每个表单调用该函数,它会变得拥挤且难以阅读

如果您想使用自己的标签来代替现有的 HTML 标签,那么在 Hiccup 的语法中也没有什么能阻止您这样做。

于 2017-02-14T17:00:27.397 回答
1

S 表达式是树,因此下面的示例可以是 html 文档的表示:

'(html (head (title "some title") (meta "some meta"))
       (body (h1 "Hello, World!") (p "This is the" (strong "body") "text"))

属性可以由具有第一个元素的每个元素实现 tag attributes

'(p (attributes 
     (attribute (name "style") 
                (value "margin: 10px;"))
     (attribute (name "title") 
                (value "Ingress"))) 
    "Once upon a time ....)

这并不漂亮,因为属性实际上代表了每个需要结构的标签的一级键值数据。我认为 W3C 曾一度提出过类似的建议,但它使文档更加复杂。

于 2017-02-14T09:51:11.433 回答