-
Notifications
You must be signed in to change notification settings - Fork 26
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
Showing
8 changed files
with
298 additions
and
18 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
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
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
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 |
---|---|---|
@@ -0,0 +1,36 @@ | ||
(ns puget.color | ||
"This namespace defines multimethods to add color markup to text.") | ||
|
||
;; ## Coloring Multimethods | ||
|
||
(defn dispatch | ||
"Dispatches to coloring multimethods. Element should be a key from | ||
the color-scheme map." | ||
[element text options] | ||
(and (:print-color options) (:color-markup options))) | ||
|
||
|
||
(defmulti document | ||
"Constructs a pretty print document, which may be colored if | ||
`:print-color` is true." | ||
#'dispatch) | ||
|
||
|
||
(defmulti text | ||
"Produces text colored according to the active color scheme. This is mostly | ||
useful to clients which want to produce output which matches data printed by | ||
Puget, but which is not directly printed by the library. Note that this | ||
function still obeys the `:print-color` option." | ||
#'dispatch) | ||
|
||
|
||
;; ## No markup when colorless | ||
|
||
(defmethod document false | ||
[element text options] | ||
text) | ||
|
||
|
||
(defmethod text false | ||
[element text options] | ||
text) |
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 |
---|---|---|
@@ -0,0 +1,103 @@ | ||
(ns puget.html | ||
"This namespace defines methods for the :html-inline | ||
and :html-classes :color-markup options." | ||
(:require | ||
[clojure.string :as str] | ||
[puget.color :as color])) | ||
|
||
(def style-attribute | ||
"Map from keywords usable in a color-scheme value to vectors | ||
representing css style attributes" | ||
{:none nil | ||
:bold [:font-weight "bold"] | ||
:underline [:text-decoration "underline"] | ||
:blink [:text-decoration "blink"] | ||
:reverse nil | ||
:hidden [:visibility "hidden"] | ||
:strike [:text-decoration "line-through"] | ||
:black [:color "black"] | ||
:red [:color "red"] | ||
:green [:color "green"] | ||
:yellow [:color "yellow"] | ||
:blue [:color "blue"] | ||
:magenta [:color "magenta"] | ||
:cyan [:color "cyan"] | ||
:white [:color "white"] | ||
:fg-256 nil | ||
:fg-reset nil | ||
:bg-black [:background-color "black"] | ||
:bg-red [:background-color "red"] | ||
:bg-green [:background-color "green"] | ||
:bg-yellow [:background-color "yellow"] | ||
:bg-blue [:background-color "blue"] | ||
:bg-magenta [:background-color "magenta"] | ||
:bg-cyan [:background-color "cyan"] | ||
:bg-white [:background-color "white"] | ||
:bg-256 nil | ||
:bg-reset nil}) | ||
|
||
|
||
(defn style | ||
"Returns a formatted style attribute for a span given a seq of | ||
keywords usable in a :color-scheme value" | ||
[codes] | ||
(let [attributes (filter identity (map style-attribute codes))] | ||
(str "style=\"" | ||
(str/join ";" (map (fn [[k v]] (str (name k) ":" v)) attributes)) | ||
"\""))) | ||
|
||
|
||
(defn escape-html-text | ||
"Escapes special characters into html entities" | ||
[text] | ||
(.. ^String text | ||
(replace "&" "&") | ||
(replace "<" "<") | ||
(replace ">" ">") | ||
(replace "\"" """))) | ||
|
||
|
||
(defn escape-html-document | ||
"Escapes special characters into fipp :span/:escaped nodes" | ||
[text] | ||
(let [escaped-text (escape-html-text text) | ||
spans (.split escaped-text "(?=&)")] | ||
(reduce (fn [acc span] | ||
(case (first span) | ||
nil acc | ||
\& (let [[escaped span] (.split span "(?<=;)" 2) | ||
acc (conj acc [:escaped escaped])] | ||
(if (seq span) | ||
(conj acc span) | ||
acc)) | ||
(conj acc span))) | ||
[:span] | ||
spans))) | ||
|
||
|
||
(defmethod color/document :html-inline | ||
[element text options] | ||
(if-let [codes (-> options :color-scheme (get element) seq)] | ||
[:span [:pass "<span " (style codes) ">"] | ||
(escape-html-document text) | ||
[:pass "</span>"]] | ||
(escape-html-document text))) | ||
|
||
|
||
(defmethod color/text :html-inline | ||
[element text options] | ||
(if-let [codes (-> options :color-scheme (get element) seq)] | ||
(str "<span " (style codes) ">" (escape-html-text text) "</span>") | ||
(escape-html-text text))) | ||
|
||
|
||
(defmethod color/document :html-classes | ||
[element text options] | ||
[:span [:pass "<span class=\"" (name element) "\">"] | ||
(escape-html-document text) | ||
[:pass "</span>"]]) | ||
|
||
|
||
(defmethod color/text :html-classes | ||
[element text options] | ||
(str "<span class=\"" (name element) "\">" (escape-html-text text) "</span>")) |
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
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 |
---|---|---|
@@ -0,0 +1,106 @@ | ||
(ns puget.html-test | ||
(:require | ||
[clojure.test :refer :all] | ||
(puget | ||
[html :as html] | ||
[printer :as printer]))) | ||
|
||
|
||
(def test-color-scheme | ||
{:delimiter [:green] | ||
:tag [:bold :white] | ||
:nil [:black] | ||
:boolean [:cyan] | ||
:number [:red] | ||
:string [:magenta :underline] | ||
:character [:yello] | ||
:keyword [:cyan] | ||
:symbol nil | ||
:function-symbol [:bold :blue] | ||
:class-delimiter [:blue] | ||
:class-name [:bold :blue]}) | ||
|
||
|
||
(def inline-color | ||
{:print-color true | ||
:color-markup :html-inline}) | ||
|
||
|
||
(def classes-color | ||
{:print-color true | ||
:color-markup :html-classes}) | ||
|
||
|
||
(deftest style-test | ||
(is (= "style=\"font-weight:bold;text-decoration:underline;color:red\"" | ||
(html/style [:bold :underline :red])))) | ||
|
||
|
||
(deftest html-test | ||
(let [test-data {:a 1 :b 2 "c" 3.0 'd [1 2 3] \e #inst "2001"} | ||
inline-ref | ||
(str | ||
"<span style=\"color:green\">{</span>" | ||
"<span style=\"\">\\e</span> " | ||
"<span style=\"font-weight:bold;color:white\">#inst</span> " | ||
"<span style=\"color:magenta;text-decoration:underline\">" | ||
""2001-01-01T00:00:00.000-00:00"</span>, " | ||
"<span style=\"color:magenta;text-decoration:underline\">"c"</span> " | ||
"<span style=\"color:red\">3.0</span>, " | ||
"<span style=\"color:cyan\">:a</span> " | ||
"<span style=\"color:red\">1</span>, " | ||
"<span style=\"color:cyan\">:b</span> " | ||
"<span style=\"color:red\">2</span>, d " | ||
"<span style=\"color:green\">[</span>" | ||
"<span style=\"color:red\">1</span> " | ||
"<span style=\"color:red\">2</span> " | ||
"<span style=\"color:red\">3</span>" | ||
"<span style=\"color:green\">]</span>" | ||
"<span style=\"color:green\">}</span>") | ||
classes-ref | ||
(str | ||
"<span class=\"delimiter\">{</span>" | ||
"<span class=\"character\">\\e</span> " | ||
"<span class=\"tag\">#inst</span> " | ||
"<span class=\"string\">"2001-01-01T00:00:00.000-00:00"</span>, " | ||
"<span class=\"string\">"c"</span> " | ||
"<span class=\"number\">3.0</span>, " | ||
"<span class=\"keyword\">:a</span> " | ||
"<span class=\"number\">1</span>, " | ||
"<span class=\"keyword\">:b</span> " | ||
"<span class=\"number\">2</span>, " | ||
"<span class=\"symbol\">d</span> " | ||
"<span class=\"delimiter\">[</span>" | ||
"<span class=\"number\">1</span> " | ||
"<span class=\"number\">2</span> " | ||
"<span class=\"number\">3</span>" | ||
"<span class=\"delimiter\">]</span>" | ||
"<span class=\"delimiter\">}</span>")] | ||
(is (= inline-ref | ||
(printer/cprint-str test-data {:color-markup :html-inline | ||
:color-scheme test-color-scheme}))) | ||
(is (= classes-ref | ||
(printer/cprint-str test-data {:color-markup :html-classes})))) | ||
(testing "color-text" | ||
(testing "no color markup" | ||
(is (= ":inline>" | ||
(printer/color-text :keyword ":inline>"))) | ||
(is (= ":classes<" | ||
(printer/color-text :keyword ":classes<")))) | ||
(testing "unrecognized element html color markup" | ||
(is (= "in<line" | ||
(printer/with-options inline-color | ||
(printer/color-text :bogus "in<line")))) | ||
(is (= "<span class=\"bogus\">"classes</span>" | ||
(printer/with-options classes-color | ||
(printer/color-text :bogus "\"classes"))))) | ||
(testing "happy path html color markup" | ||
(is (= (str "<span style=\"font-weight:bold;color:yellow\">" | ||
":in&line</span>") | ||
(printer/with-options inline-color | ||
(printer/color-text :keyword ":in&line")))) | ||
(is (= "<span class=\"keyword\">:classes<></span>" | ||
(printer/with-options classes-color | ||
(printer/color-text :keyword ":classes<>"))))) | ||
(testing "escaping empty content" | ||
(is (= [:span] (html/escape-html-document "")))))) |
Oops, something went wrong.