Indentation of HTML S-expressions

I’m using cl-who to generate HTML pages using simple S-expressions:

The only problem I had was the way these expressions are indented in Emacs. For example, a simple table will be indented as follows:

(:table :id "layout"
        (:tr
         (:td :class "id"
              (:div :class "box"
                    "Content"))))

This is quite annoying for large pages where the content of the page is quickly far too much indented.

Fortunately, with the slime-cl-indent module provided with Slime, it’s possible to customize indentation rules.

I use this small function to modify indentation rules:

(defun nm-cl-indent (symbol indent)
  "Set the indentation of SYMBOL to INDENT."
  (put symbol 'common-lisp-indent-function
       (if (symbolp indent)
           (get indent 'common-lisp-indent-function)
         indent)))

Then I change the indentation rules for all HTML elements:

(defvar *nm-cl-html-symbols*
  (list :a :abbr :acronym :address :applet :area :article :aside :audio :b
        :base :basefont :bdi :bdo :big :blockquote :body :br :button :canvas
        :caption :center :cite :code :col :colgroup :command :datalist :dd
        :del :details :dfn :dir :div :dl :dt :em :embed :fieldset :figcaption
        :figure :font :footer :form :frame :frameset :h1 :h2 :h3 :h4 :h5 :h6
        :head :header :hgroup :hr :html :i :iframe :img :input :ins :keygen
        :kbd :label :legend :li :link :map :mark :menu :meta :meter :nav
        :noframes :noscript :object :ol :optgroup :option :output :p :param
        :pre :progress :q :rp :rt :ruby :s :samp :script :section :select
        :small :source :span :strike :strong :style :sub :summary :sup :table
        :tbody :td :textarea :tfoot :th :thead :time :title :tr :track :tt :u
        :ul :var :video :wbr))

(dolist (symbol *nm-cl-html-symbols*)
  (nm-cl-indent symbol '(&body)))

HTML S-expressions are now more compact:

(:table :id "layout"
  (:tr
    (:td :class "id"
      (:div :class "box"
        "Content"))))