Как представить простой документ в виде s-exp?

Я пытаюсь понять, как выразить простой документ в 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." ()))))

2 ответа

Решение

Я бы рекомендовал использовать синтаксис 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; Я просто изложил это здесь, чтобы продемонстрировать, что каждый из этих трех векторов является действительным Иккингом.

Поскольку этот синтаксис использует векторы вместо списков, вам не нужно заключать в кавычки или использовать list функция, которая дает вам пару преимуществ:

  • Если вы заключаете в кавычки, вы не можете вызывать функции для создания внутренних форм в "Hiccup literal"
  • Если вам нужно позвонить list функция для каждой формы, это становится тесно и трудно читать

И если вы хотите придумать собственные теги для использования вместо существующих тегов HTML, ничто не мешает вам делать это и в синтаксисе Hiccup.

S-выражения являются деревьями, и поэтому приведенный ниже пример может быть представлением html-документа:

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

Атрибуты могут быть реализованы каждым элементом, имеющим первый элемент с тегом attributes:

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

Это не красиво, поскольку атрибуты фактически представляют один уровень данных значения ключа для каждого тега, который должен быть структурой. Я думаю, что в какой-то момент W3C действительно предложил что-то подобное, но это делает документ намного более сложным.

Другие вопросы по тегам