add css stylesheet string generation functionality
This commit is contained in:
parent
a74fdd5ae6
commit
eadbe13ee1
|
@ -11,4 +11,9 @@
|
||||||
[hiccup "1.0.5"]]
|
[hiccup "1.0.5"]]
|
||||||
|
|
||||||
:profiles {:provided
|
:profiles {:provided
|
||||||
{:dependencies [[org.clojure/clojure "1.8.0"]]}})
|
{:dependencies [[org.clojure/clojure "1.8.0"]]}
|
||||||
|
|
||||||
|
:dev
|
||||||
|
{:dependencies [[pjstadig/humane-test-output "0.8.1"]]
|
||||||
|
:injections [(require 'pjstadig.humane-test-output)
|
||||||
|
(pjstadig.humane-test-output/activate!)]}})
|
||||||
|
|
53
src/clj_htmltopdf/css.clj
Normal file
53
src/clj_htmltopdf/css.clj
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
(ns clj-htmltopdf.css
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string])
|
||||||
|
(:import
|
||||||
|
[java.lang StringBuilder]))
|
||||||
|
|
||||||
|
; everything in this namespace solely exists because garden cannot be used
|
||||||
|
; to define suitable @page css that we will require.
|
||||||
|
; and it defines a bunch of its internal extension functionality as private.
|
||||||
|
; *sigh*
|
||||||
|
|
||||||
|
(defn css-rule-name-str
|
||||||
|
[names]
|
||||||
|
(let [names (map #(if (keyword? %) (name %) %) names)]
|
||||||
|
(string/join ", " names)))
|
||||||
|
|
||||||
|
(defn css-attr-str
|
||||||
|
[attr-name attr-value]
|
||||||
|
(let [attr-name (if (keyword? attr-name) (name attr-name) attr-name)
|
||||||
|
attr-value (str attr-value)]
|
||||||
|
(if (and (not (string/blank? attr-name)) (not (string/blank? attr-value)))
|
||||||
|
(str attr-name ": " attr-value ";"))))
|
||||||
|
|
||||||
|
(defn css-rule->str
|
||||||
|
[^StringBuilder sb rule & [level]]
|
||||||
|
(if (seq rule)
|
||||||
|
(let [level (or level 0)
|
||||||
|
indent (string/join (repeat level " "))
|
||||||
|
attr-indent (str indent " ")
|
||||||
|
names (take-while #(or (keyword? %) (string? %)) rule)
|
||||||
|
rule (drop (count names) rule)
|
||||||
|
attrs (first rule)
|
||||||
|
sub-rules (rest rule)]
|
||||||
|
(.append sb indent)
|
||||||
|
(.append sb (css-rule-name-str names))
|
||||||
|
(.append sb " {\n")
|
||||||
|
(doseq [[attr-name attr-value] attrs]
|
||||||
|
(when-let [attr-str (css-attr-str attr-name attr-value)]
|
||||||
|
(.append sb attr-indent)
|
||||||
|
(.append sb attr-str)
|
||||||
|
(.append sb \newline)))
|
||||||
|
(doseq [sub-rule sub-rules]
|
||||||
|
(css-rule->str sb sub-rule (inc level)))
|
||||||
|
(.append sb indent)
|
||||||
|
(.append sb "}\n")))
|
||||||
|
sb)
|
||||||
|
|
||||||
|
(defn css->str
|
||||||
|
[rules]
|
||||||
|
(let [sb (StringBuilder.)]
|
||||||
|
(doseq [rule rules]
|
||||||
|
(css-rule->str sb rule))
|
||||||
|
(.toString sb)))
|
107
test/clj_htmltopdf/test/css.clj
Normal file
107
test/clj_htmltopdf/test/css.clj
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
(ns clj-htmltopdf.test.css
|
||||||
|
(:use
|
||||||
|
clojure.test
|
||||||
|
clj-htmltopdf.css)
|
||||||
|
(:import
|
||||||
|
[java.lang StringBuilder]))
|
||||||
|
|
||||||
|
(deftest rule-name-parsing
|
||||||
|
(is (= ""
|
||||||
|
(css-rule-name-str nil)))
|
||||||
|
(is (= ""
|
||||||
|
(css-rule-name-str [])))
|
||||||
|
(is (= "p"
|
||||||
|
(css-rule-name-str ["p"])))
|
||||||
|
(is (= "p"
|
||||||
|
(css-rule-name-str [:p])))
|
||||||
|
(is (= "p, li"
|
||||||
|
(css-rule-name-str ["p" :li])))
|
||||||
|
(is (= "h1, h2, h3, h4, h5, h6"
|
||||||
|
(css-rule-name-str [:h1 :h2 :h3 :h4 :h5 :h6])))
|
||||||
|
(is (= "ul>li, ol>li"
|
||||||
|
(css-rule-name-str [:ul>li :ol>li])))
|
||||||
|
(is (= "ul>li, ol>li"
|
||||||
|
(css-rule-name-str ["ul>li" "ol>li"]))))
|
||||||
|
|
||||||
|
(deftest rule-attribute-parsing
|
||||||
|
(is (= "color: black;"
|
||||||
|
(css-attr-str :color "black")))
|
||||||
|
(is (= "color: #ff0000;"
|
||||||
|
(css-attr-str "color" "#ff0000")))
|
||||||
|
(is (= nil
|
||||||
|
(css-attr-str nil "foo")))
|
||||||
|
(is (= nil
|
||||||
|
(css-attr-str :color nil)))
|
||||||
|
(is (= nil
|
||||||
|
(css-attr-str "" "bar")))
|
||||||
|
(is (= nil
|
||||||
|
(css-attr-str :color "")))
|
||||||
|
(is (= nil
|
||||||
|
(css-attr-str nil nil))))
|
||||||
|
|
||||||
|
(deftest rule-parsing
|
||||||
|
(is (= ""
|
||||||
|
(str (css-rule->str (StringBuilder.) nil))))
|
||||||
|
(is (= ""
|
||||||
|
(str (css-rule->str (StringBuilder.) []))))
|
||||||
|
(is (= "p {\n}\n"
|
||||||
|
(str (css-rule->str (StringBuilder.) [:p]))))
|
||||||
|
(is (= "p {\n}\n"
|
||||||
|
(str (css-rule->str (StringBuilder.) [:p {}]))))
|
||||||
|
(is (= "p {\n font-weight: bold;\n}\n"
|
||||||
|
(str (css-rule->str (StringBuilder.) [:p {:font-weight "bold"}]))))
|
||||||
|
(is (= "p {\n font-weight: bold;\n color: #000;\n}\n"
|
||||||
|
(str (css-rule->str (StringBuilder.) [:p {:font-weight "bold" :color "#000"}]))))
|
||||||
|
(is (= "@page {\n size: 8.5in 11in;\n margin: 10%;\n @top-right {\n content: \"Page \" counter(page);\n }\n @top-left {\n content: \"Foobar\";\n border: solid red;\n }\n}\n"
|
||||||
|
(str (css-rule->str
|
||||||
|
(StringBuilder.)
|
||||||
|
["@page"
|
||||||
|
{:size "8.5in 11in" :margin "10%"}
|
||||||
|
["@top-right"
|
||||||
|
{:content "\"Page \" counter(page)"}]
|
||||||
|
["@top-left"
|
||||||
|
{:content "\"Foobar\""
|
||||||
|
:border "solid red"}]])))))
|
||||||
|
|
||||||
|
(deftest sheet-parsing
|
||||||
|
(is (= ""
|
||||||
|
(css->str nil)))
|
||||||
|
(is (= ""
|
||||||
|
(css->str [])))
|
||||||
|
(is (thrown?
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
(css->str [:body {:color "red"}])))
|
||||||
|
(is (= "body {\n}\n"
|
||||||
|
(css->str [[:body]])))
|
||||||
|
(is (= "body {\n}\n"
|
||||||
|
(css->str [[:body {}]])))
|
||||||
|
(is (= "body {\n}\np {\n font-size: 12pt;\n}\n"
|
||||||
|
(css->str
|
||||||
|
[[:body {}]
|
||||||
|
[:p {:font-size "12pt"}]])))
|
||||||
|
(is (thrown?
|
||||||
|
java.lang.IllegalArgumentException
|
||||||
|
(css->str
|
||||||
|
[[:body {}]
|
||||||
|
:p])))
|
||||||
|
(is (= "body {\n background-color: white;\n color: black;\n}\np {\n font-size: 12pt;\n}\n"
|
||||||
|
(css->str
|
||||||
|
[[:body
|
||||||
|
{:background-color "white"
|
||||||
|
:color "black"}]
|
||||||
|
[:p
|
||||||
|
{:font-size "12pt"}]])))
|
||||||
|
(is (= "body {\n background-color: white;\n color: black;\n}\n@page {\n size: 8.5in 11in;\n margin: 10%;\n @top-right {\n content: \"Page \" counter(page);\n }\n @top-left {\n content: \"Foobar\";\n border: solid red;\n }\n}\n"
|
||||||
|
(css->str
|
||||||
|
[[:body
|
||||||
|
{:background-color "white"
|
||||||
|
:color "black"}]
|
||||||
|
["@page"
|
||||||
|
{:size "8.5in 11in" :margin "10%"}
|
||||||
|
["@top-right"
|
||||||
|
{:content "\"Page \" counter(page)"}]
|
||||||
|
["@top-left"
|
||||||
|
{:content "\"Foobar\""
|
||||||
|
:border "solid red"}]]]))))
|
||||||
|
|
||||||
|
#_(run-tests)
|
Loading…
Reference in a new issue