                                                                              it
                                                                              '(error "no match, expecting ( or a-zA-Z0-9")))))))
 
+(defun zencoding-extract-filters (input)
+  "Extract filters from expression."
+  (zencoding-pif (zencoding-parse "\\([^\\|]+?\\)|" 2 "" it)
+                 (let ((filter-name (elt it 1))
+                       (more-filters (elt it 2)))
+                   (zencoding-pif (zencoding-extract-filters more-filters)
+                                  (cons filter-name it)
+                                  it))
+                 (zencoding-parse "\\([^\\|]+\\)" 1 "filter name" `(,(elt it 1)))))
+
+(defun zencoding-filter (input filters)
+  "Construct AST with specified filters."
+  (zencoding-pif (zencoding-subexpr input)
+                 (let ((result (car it))
+                       (rest (cdr it)))
+                   `((filter ,filters ,result) . ,rest))
+                 it))
+
+(defun zencoding-default-filter ()
+  "Default filter(s) to be used if none is specified."
+  (let* ((file-ext (car (zencoding-regex ".*\\(\\..*\\)"(buffer-file-name) 1)))
+         (defaults '(".html" ("html")
+                     ".htm"  ("html")
+                     ".haml" ("haml")
+                     ".clj"  ("hic")))
+         (default-else      '("html"))
+         (selected-default (member file-ext defaults)))
+    (if selected-default
+        (cadr selected-default)
+      default-else)))
+
 (defun zencoding-multiplier (input)
   (zencoding-por zencoding-pexpr zencoding-tag
                  (let ((multiplier expr))

    (if (first expr)
        (list (first expr) start end))))

(defun zencoding-prettify (markup indent)
  (save-match-data
    ;;(setq markup (replace-regexp-in-string "><" ">\n<" markup))
    (setq markup (replace-regexp-in-string "\n\n" "\n" markup))
    (setq markup (replace-regexp-in-string "^\n" "" markup)))
  (with-temp-buffer
    (indent-to indent)
    (insert "<i></i>")
    (insert "\n")
    (let ((here (point)))
      (insert markup)
      (sgml-mode)
      (indent-region here (point-max))
      (buffer-substring-no-properties here (point-max)))))

;;;###autoload
(defun zencoding-expand-line (arg)

;; Zen coding parsers

(defun zencoding-expr (input)
  "Parse a zen coding expression with optional filters."
  (zencoding-pif (zencoding-parse "\\(.*?\\)|" 2 "expr|filter" it)
                 (let ((input (elt it 1))
                       (filters (elt it 2)))
                   (zencoding-pif (zencoding-extract-filters filters)
                                  (zencoding-filter input it)
                                  it))
                 (zencoding-filter input (zencoding-default-filter))))

(defun zencoding-subexpr (input)
  "Parse a zen coding expression with no filter. This pretty much defines precedence."
  (zencoding-run zencoding-siblings
                 it
                 (zencoding-run zencoding-parent-child
