Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Marko Mikulicic
committed
Mar 29, 2010
1 parent
d123c1b
commit 40762c2
Showing
1 changed file
with
34 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,58 @@ | ||
(ns haml-macro.core | ||
(:use [eu.dnetlib.clojure clarsec monad])) | ||
|
||
(declare tag) | ||
|
||
(defn not-nil? [p] (not (nil? p))) | ||
|
||
(def newlinep (one-of "\n")) | ||
(def sspace (one-of " ")) | ||
|
||
(defn prefixed [ch p] | ||
(>> (is-char ch) p)) | ||
|
||
(defn repeated [n p] | ||
(if (<= n 0) | ||
(result []) | ||
(m-sequence (repeat n p)))) | ||
|
||
(defn indented [level p] (let-bind [_ newlinep | ||
_ (repeated level sspace)] | ||
p)) | ||
|
||
(def anyChar (not-char \newline)) | ||
|
||
(def text (>>== (many anyChar) #(vector :text (apply str %)))) | ||
|
||
(defn statement [l] (delay (either (tag l) text))) | ||
|
||
(def tagPrefix (one-of "%#.")) | ||
(def tagChar (either letter digit (one-of "-_") tagPrefix)) | ||
(def tagName (let-bind [prefix tagPrefix | ||
rest (many1 tagChar)] | ||
(let [autoTag (if (not= \% prefix) "%div")] | ||
(result (keyword (apply str autoTag prefix rest)))))) | ||
(let [autoTag (if (not= \% prefix) "div")] | ||
(result (keyword (apply str autoTag (if (not= \% prefix) prefix) rest)))))) | ||
|
||
(def tag (let-bind [t tagName | ||
b (optional (>> space text))] | ||
(result [:tag t (second b)]))) | ||
(defn make-compojure-tag [t inline body] | ||
(apply vector (filter not-nil? (apply vector t (second inline) body)))) | ||
|
||
(def text (>>== (many anyChar) #(vector :text (apply str %)))) | ||
(defn tag [l] | ||
(let [nl (+ 2 l)] | ||
(let-bind [t tagName | ||
inline (optional (>> sspace text)) | ||
body (optional (many1 (indented nl (tag nl))))] | ||
(result (make-compojure-tag t inline body))))) | ||
|
||
(def statement (either tag text)) | ||
|
||
(def statements (followedBy (sepBy1 statement newlinep) (optional newlinep))) | ||
(defn statements [l] (followedBy (sepBy1 (statement l) newlinep) (optional newlinep))) | ||
|
||
(def body statements) | ||
(def body (statements 0)) | ||
|
||
(def source | ||
(followedBy body (lexeme eof))) | ||
|
||
(defn haml [strn] | ||
(defn haml-str [strn] | ||
(:value (parse source strn))) | ||
|
||
(defn haml-file [file] | ||
(haml-str (slurp file))) |