clojuredocumentss-expression

How to represent a simple document as an s-exp?


I'm trying to understand how to express a simple document in an s-expression. Here's what I mean. Let's say I have this simple html structure:

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

Also let's assume that I'm okay with losing the original tag provenance and just want to preserve the structure. How could this be expressed with an sexp? My initial try (using clojure) looks like this, but I'm not sure that it is correct:

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

Solution

  • I would recommend using Hiccup's syntax for cases like this:

    (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
    

    If you don't need to convert back to an HTML string, then obviously you don't need the Hiccup dependency; I simply put it here to demonstrate that each of those three vectors is valid Hiccup.

    Since this syntax uses vectors instead of lists, you don't need to quote things or use the list function directly, which gives you a couple of advantages:

    And if you want to come up with your own tags to use instead of the existing HTML tags, there's nothing stopping you from doing that within Hiccup's syntax as well.