diff --git a/src/clj_htmltopdf/core.clj b/src/clj_htmltopdf/core.clj index 3c5cf89..5bc11da 100644 --- a/src/clj_htmltopdf/core.clj +++ b/src/clj_htmltopdf/core.clj @@ -1,9 +1,7 @@ (ns clj-htmltopdf.core (:require [clojure.java.io :as io] - [clojure.string :as string] [hiccup.page :as h] - [clj-htmltopdf.css :as css] [clj-htmltopdf.options :as o]) (:import [java.io OutputStream] @@ -11,11 +9,10 @@ [com.openhtmltopdf.pdfboxout PdfRendererBuilder] [com.openhtmltopdf.util XRLog] [org.jsoup Jsoup] - [org.jsoup.nodes Document Element] - [org.jsoup.parser Tag])) + [org.jsoup.nodes Document])) -(defn- read-html - [in] +(defn- read-html-string + ^String [in] (cond (string? in) in (sequential? in) (h/html5 {} in) @@ -23,35 +20,42 @@ (slurp r)))) (defn- ->output-stream - [out] + ^OutputStream [out] (if (instance? OutputStream out) out (io/output-stream out))) -(defn- set-jsoup-html-doc - [^PdfRendererBuilder builder jsoup-doc base-uri] - (let [doc (DOMBuilder/jsoup2DOM jsoup-doc)] - (.withW3cDocument builder doc base-uri))) +(defn configure-logging! + [options] + (if (:logging? options) + (do + (if-let [logger (:logger options)] + (XRLog/setLoggerImpl logger)) + (XRLog/setLoggingEnabled true)) + ; NOTE: a bug in how Open HTML to PDF's XRLog class initializes itself will always result + ; in an initial little bit of logging output regardless of when we set this to false. + (XRLog/setLoggingEnabled false))) + +(defn prepare-html + [in options] + (let [html (read-html-string in) + html-doc (Jsoup/parse html)] + (o/inject-options-into-html! html-doc options) + html-doc)) + +(defn write-pdf! + [^Document html-doc ^String base-uri out] + (let [builder (PdfRendererBuilder.) + os (->output-stream out)] + (.withW3cDocument builder (DOMBuilder/jsoup2DOM html-doc) base-uri) + (with-open [os os] + (.toStream builder os) + (.run builder) + os))) (defn ->pdf [in out & [options]] (let [options (merge o/default-options options) - builder (PdfRendererBuilder.) - html (read-html in) - html-doc (Jsoup/parse html) - html-doc (o/inject-options-into-html html-doc options) - output (->output-stream out)] - (if (:logging? options) - (let [logger (:logger options)] - (if logger (XRLog/setLoggerImpl logger)) - (XRLog/setLoggingEnabled true)) - (XRLog/setLoggingEnabled false)) - (set-jsoup-html-doc builder html-doc (o/->base-uri options)) - (with-open [os output] - (.toStream builder os) - (try - (.run builder) - os - (catch Exception ex - (throw (Exception. "Failed to convert to PDF." ex))))))) - + html-doc (prepare-html in options)] + (configure-logging! options) + (write-pdf! html-doc (o/->base-uri options) out))) diff --git a/src/clj_htmltopdf/options.clj b/src/clj_htmltopdf/options.clj index 65e71c6..e09b758 100644 --- a/src/clj_htmltopdf/options.clj +++ b/src/clj_htmltopdf/options.clj @@ -41,7 +41,7 @@ (reduce #(assoc %1 (first %2) (second %2)) {}))] [["@page" styles]])) -(defn append-page-options-style-tag +(defn append-page-options-style-tag! ^Element [^Element parent options] (let [styles (-> (:page options) (page-options->css) @@ -50,17 +50,17 @@ (.attr element "type" "text/css") (.text element styles))) -(defn append-base-css-link-tag +(defn append-base-css-link-tag! ^Element [^Element parent] (let [element (.appendElement parent "link")] (.attr element "type" "text/css") (.attr element "rel" "stylesheet") (.attr element "href" (str (io/resource "htmltopdf-base.css"))))) -(defn inject-options-into-html +(defn inject-options-into-html! [^Document doc options] (let [base-uri (->base-uri options) head-tag (-> doc (.select "head") (.first))] - (append-page-options-style-tag head-tag options) - (if (:include-base-css? options) (append-base-css-link-tag head-tag)) + (append-page-options-style-tag! head-tag options) + (if (:include-base-css? options) (append-base-css-link-tag! head-tag)) doc))