From 5962f7d246e225ccfc13c969bc6456cb72d88c44 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Tue, 13 Sep 2016 22:31:59 +0200 Subject: [PATCH 01/10] feat(asciidoctor): basic asciidoc plugin The asciidoc plugin uses AsciidoctorJ from the Asciidoctor project to bring Asciidoc rendering to Perun. ROOM FOR IMPROVEMENT AsciidoctorJ has plenty of extension options, like including other Asciidoctor libraries (like 'asciidoctor-diagram') and including gems. Also attributes can be set, determining how the HTML is rendered. These Asciidoctor features make it flexible and powerful but these features need to be enabled still. Another potential improvement is the linking of Asciidoc containers (JRuby containers) to pods to prevent initialization. This will require further changes in the perun.clj file related to the pod dispatch. This ticket is related to issue 49 on GitHub: https://github.com/hashobject/perun/issues/49 --- build.boot | 3 +- src/io/perun.clj | 40 ++++++++++++++++++++++++++ src/io/perun/contrib/asciidoctor.clj | 43 ++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/io/perun/contrib/asciidoctor.clj diff --git a/build.boot b/build.boot index 87c569fb..6625c82a 100644 --- a/build.boot +++ b/build.boot @@ -11,7 +11,8 @@ [gravatar "1.1.1" :scope "test"] [clj-time "0.12.0" :scope "test"] [mvxcvi/puget "1.0.0" :scope "test"] - [com.novemberain/pantomime "2.8.0" :scope "test"]]) + [com.novemberain/pantomime "2.8.0" :scope "test"] + [org.asciidoctor/asciidoctorj "1.5.4" :scope "test"]]) (require '[adzerk.bootlaces :refer :all]) diff --git a/src/io/perun.clj b/src/io/perun.clj index b6d29c67..fa3395de 100644 --- a/src/io/perun.clj +++ b/src/io/perun.clj @@ -142,6 +142,46 @@ (reset! prev-meta final-metadata) (perun/set-meta fileset final-metadata))))) +(def ^:private asciidoctor-deps + '[[org.asciidoctor/asciidoctorj "1.5.4"] + [circleci/clj-yaml "0.5.5"]]) + +(deftask asciidoctor + "Parse asciidoc files + + This task will look for files ending with `adoc` (preferred), `ad`, `asc`, + `adoc` or `asciidoc` and add a `:content` key to their metadata containing + the HTML resulting from processing asciidoc file's content" + [o options OPTS edn "options to be passed to the asciidoctor parser"] + (let [pod (create-pod asciidoctor-deps) + prev-meta (atom {}) + prev-fs (atom nil)] + (boot/with-pre-wrap fileset + (let [ad-files (->> fileset + (boot/fileset-diff @prev-fs) + boot/user-files + (boot/by-ext ["ad" "asc" "adoc" "asciidoc"]) + add-filedata) + ; process all removed asciidoc files + removed? (->> fileset + (boot/fileset-removed @prev-fs) + boot/user-files + (boot/by-ext ["ad" "asc" "adoc" "asciidoc"]) + (map #(boot/tmp-path %)) + set) + updated-files (pod/with-call-in @pod + (io.perun.contrib.asciidoctor/parse-asciidoc ~ad-files ~options)) + initial-metadata (perun/merge-meta* (perun/get-meta fileset) @prev-meta) + ; Pure merge instead of `merge-with merge` (meta-meta). + ; This is because updated metadata should replace previous metadata to + ; correctly handle cases where a metadata key is removed from post metadata. + final-metadata (vals (merge (perun/key-meta initial-metadata) (perun/key-meta updated-files))) + final-metadata (remove #(-> % :path removed?) final-metadata)] + (reset! prev-fs fileset) + (reset! prev-meta final-metadata) + (perun/set-meta fileset final-metadata))))) +;; TODO perhaps reuse the Asciidoctor container inside a pod, to prevent repeatedly re-initializing the JRuby container. + (deftask global-metadata "Read global metadata from `perun.base.edn` or configured file. diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj new file mode 100644 index 00000000..4c942f5d --- /dev/null +++ b/src/io/perun/contrib/asciidoctor.clj @@ -0,0 +1,43 @@ +(ns io.perun.contrib.asciidoctor + "AsciidoctorJ based converter from Asciidoc to HTML" + (:require [io.perun.core :as perun] + [clojure.java.io :as io] + [clojure.string :as str] + [clj-yaml.core :as yml] + [io.perun.markdown :as md]) + (:import [org.asciidoctor Asciidoctor Asciidoctor$Factory] + org.asciidoctor.internal.JRubyAsciidoctor)) + +(def adoc-container-defaults {:gempath "" + :libraries '("asciidoctor-diagram")}) +;; TODO integrate all options and defaults into a single map, and expose to the perun.clj file + +(defn new-adoc-container [& {:keys [gempath libraries]}] + (let [defaults adoc-container-defaults + gempath (or gempath (:gempath defaults)) + libraries (or libraries (:libraries defaults))] + ; (AsciidoctorContainer. (Asciidoctor$Factory/create) gempath libraries))) + (Asciidoctor$Factory/create gempath))) +;; TODO add desired libraries + +(defn parse-file-metadata [file-content] + (md/parse-file-metadata file-content)) +;; TODO include asciidoctor based metadata including attributes + +(defn asciidoc-to-html [file-content options] + (let [container (new-adoc-container) + opts {"backend" "html5"}] + (.convert container file-content opts))) +;; TODO incorporate options into container creation + +(defn process-file [file options] + (perun/report-debug "asciidoctor" "processing asciidoc" (:filename file)) + (let [file-content (-> file :full-path io/file slurp) + ad-metadata (parse-file-metadata file-content) + html (asciidoc-to-html file-content options)] + (merge ad-metadata {:content html} file))) + +(defn parse-asciidoc [asciidoc-files options] + (let [updated-files (doall (map #(process-file % options) asciidoc-files))] + (perun/report-info "asciidoctor" "parsed %s asciidoc files" (count asciidoc-files)) + updated-files)) From 88ee873c59446c9dd7ef0ec722e60def41a10017 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Thu, 15 Sep 2016 21:02:53 +0200 Subject: [PATCH 02/10] refactor(asciidoctor): refactor and tests --- src/io/perun.clj | 18 ++++-- src/io/perun/contrib/asciidoctor.clj | 65 +++++++++++++------ test/io/perun/contrib/asciidoctor_test.clj | 72 ++++++++++++++++++++++ 3 files changed, 132 insertions(+), 23 deletions(-) create mode 100644 test/io/perun/contrib/asciidoctor_test.clj diff --git a/src/io/perun.clj b/src/io/perun.clj index fa3395de..901586b9 100644 --- a/src/io/perun.clj +++ b/src/io/perun.clj @@ -146,14 +146,22 @@ '[[org.asciidoctor/asciidoctorj "1.5.4"] [circleci/clj-yaml "0.5.5"]]) +(def ^:private +asciidoctor-defaults+ + {:gempath "" + :libraries '("asciidoctor-diagram") + :attributes {:generator "perun"}}) + (deftask asciidoctor "Parse asciidoc files - This task will look for files ending with `adoc` (preferred), `ad`, `asc`, - `adoc` or `asciidoc` and add a `:content` key to their metadata containing - the HTML resulting from processing asciidoc file's content" + This task will look for files ending with `adoc` (preferred), + `ad`, `asc`, `adoc` or `asciidoc` and add a `:content` key to + their metadata containing the HTML resulting from processing + asciidoc file's content" [o options OPTS edn "options to be passed to the asciidoctor parser"] - (let [pod (create-pod asciidoctor-deps) + + (let [options (merge +images-resize-defaults+ *opts*) + pod (create-pod asciidoctor-deps) prev-meta (atom {}) prev-fs (atom nil)] (boot/with-pre-wrap fileset @@ -170,7 +178,7 @@ (map #(boot/tmp-path %)) set) updated-files (pod/with-call-in @pod - (io.perun.contrib.asciidoctor/parse-asciidoc ~ad-files ~options)) + (io.perun.contrib.asciidoctor/parse-asciidoc ~ad-files ~(merge +asciidoctor-defaults+ options))) initial-metadata (perun/merge-meta* (perun/get-meta fileset) @prev-meta) ; Pure merge instead of `merge-with merge` (meta-meta). ; This is because updated metadata should replace previous metadata to diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index 4c942f5d..00605cf4 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -5,39 +5,68 @@ [clojure.string :as str] [clj-yaml.core :as yml] [io.perun.markdown :as md]) - (:import [org.asciidoctor Asciidoctor Asciidoctor$Factory] - org.asciidoctor.internal.JRubyAsciidoctor)) + (:import [org.asciidoctor Asciidoctor Asciidoctor$Factory])) + +(defn keywords->names + "Converts a map with keywords to a map with named keys. Only handles the top + level of any nesting structure." + [m] + (reduce-kv #(assoc %1 (name %2) %3) {} m)) + +(defn normalize-options + "Takes the options for the Asciidoctor parser and puts the in the format + appropriate for handling by the downstream functions. Mostly to better suit + the parsing by the AsciidoctorJ library." + [clj-opts] + (let [atr (-> (:attributes clj-opts) + (keywords->names) + (java.util.HashMap.)) + opts (assoc clj-opts :attributes atr)] + (keywords->names opts))) -(def adoc-container-defaults {:gempath "" - :libraries '("asciidoctor-diagram")}) ;; TODO integrate all options and defaults into a single map, and expose to the perun.clj file -(defn new-adoc-container [& {:keys [gempath libraries]}] - (let [defaults adoc-container-defaults - gempath (or gempath (:gempath defaults)) - libraries (or libraries (:libraries defaults))] +(defn new-adoc-container + "Creates a new AsciidoctorJ (JRuby) container, based on the normalized options + provided." + [n-opts] + (let [libraries (get n-opts "libraries")] ; (AsciidoctorContainer. (Asciidoctor$Factory/create) gempath libraries))) - (Asciidoctor$Factory/create gempath))) + (Asciidoctor$Factory/create (str (get n-opts "gempath"))))) ;; TODO add desired libraries -(defn parse-file-metadata [file-content] +(defn parse-file-metadata + "Read the file-content and derive relevant metadata for use in other Perun + tasks." + [file-content] (md/parse-file-metadata file-content)) ;; TODO include asciidoctor based metadata including attributes -(defn asciidoc-to-html [file-content options] - (let [container (new-adoc-container) - opts {"backend" "html5"}] - (.convert container file-content opts))) +(defn asciidoc-to-html + "Converts a given string of asciidoc into HTML. The normalized options that + can be provided, influence the behavior of the conversion." + [file-content n-opts] + (let [container (new-adoc-container n-opts) + options (-> (select-keys ["header_footer" "attributes"] n-opts) + (assoc "backend" "html5"))] + (.convert container (md/remove-metadata file-content) options))) ;; TODO incorporate options into container creation -(defn process-file [file options] +(defn process-file + "Parses the content of a single file and associates the available metadata to + the resulting html string. The HTML conversion is dispatched." + [file options] (perun/report-debug "asciidoctor" "processing asciidoc" (:filename file)) (let [file-content (-> file :full-path io/file slurp) - ad-metadata (parse-file-metadata file-content) - html (asciidoc-to-html file-content options)] + ad-metadata (parse-file-metadata file-content) + n-opts (normalize-options options) + html (asciidoc-to-html file-content n-opts)] (merge ad-metadata {:content html} file))) -(defn parse-asciidoc [asciidoc-files options] +(defn parse-asciidoc + "Responsible for parsing all provided asciidoc files. The actual parsing is + dispatched." + [asciidoc-files options] (let [updated-files (doall (map #(process-file % options) asciidoc-files))] (perun/report-info "asciidoctor" "parsed %s asciidoc files" (count asciidoc-files)) updated-files)) diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj new file mode 100644 index 00000000..339af5b1 --- /dev/null +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -0,0 +1,72 @@ +(ns io.perun.contrib.asciidoctor-test + (:require [clojure.test :refer :all] + [io.perun.contrib.asciidoctor :refer :all])) + +(def sample-adoc " +--- +draft: +name: in my own image +--- += In my own image: Perun +:author: Zeus zeus@thunderdome.olympus +:revdate: 02-08-907 +:toc: + +I Zeus would like to describe how the god Perun relates to my image. + +[quote, Perun, Having struck Veles] +\"Well, there is your place, remain there!\" + +.No power more godlike then the Clojure power of Perun +[source, clojure] +---- +(deftask build + \"Build blog.\" + [] + (comp (asciidoctor) + (render :renderer renderer))) +---- +") + +(def expected-html "
+

I Zeus would like to describe how the god Perun relates to my image.

+
+
+
+\"Well, there is your place, remain there!\" +
+
+— Perun
+Having struck Veles +
+
+
+
No power more godlike then the Clojure power of Perun
+
+
(deftask build
+  \"Build blog.\"
+  []
+  (comp (asciidoctor)
+        (render :renderer renderer)))
+
+
") + +(def expected-meta + {:draft nil + :name "in my own image" + :original true}) + +(def +asciidoctor-defaults+ + {:gempath "" + :libraries '("asciidoctor-diagram") + :attributes {:generator "perun"}}) + +(deftest test-asciidoc-to-html + "Test the `asciidoc-to-html` function on its actual conversion." + (let [rendered (asciidoc-to-html sample-adoc (normalize-options +asciidoctor-defaults+))] + (is (= expected-html rendered)))) + +(deftest test-parse-file-metadata + "Test the metadata extraction by `parse-file-metadata`." + (let [metadata (parse-file-metadata sample-adoc)] + (is (= expected-meta metadata)))) From a70ab689ca9620ae8c4106ee8f1ae984be81ad9d Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Thu, 15 Sep 2016 22:54:28 +0200 Subject: [PATCH 03/10] feat(asciidoctor): image rendering working --- src/io/perun.clj | 7 ++++--- src/io/perun/contrib/asciidoctor.clj | 20 ++++++++++---------- test/io/perun/contrib/asciidoctor_test.clj | 22 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/io/perun.clj b/src/io/perun.clj index 901586b9..1b0580af 100644 --- a/src/io/perun.clj +++ b/src/io/perun.clj @@ -147,9 +147,10 @@ [circleci/clj-yaml "0.5.5"]]) (def ^:private +asciidoctor-defaults+ - {:gempath "" - :libraries '("asciidoctor-diagram") - :attributes {:generator "perun"}}) + {:gempath "" + :libraries ["asciidoctor-diagram"] + :header_footer false + :attributes {:generator "perun"}}) (deftask asciidoctor "Parse asciidoc files diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index 00605cf4..4de84a46 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -1,5 +1,5 @@ (ns io.perun.contrib.asciidoctor - "AsciidoctorJ based converter from Asciidoc to HTML" + "AsciidoctorJ based converter from Asciidoc to HTML." (:require [io.perun.core :as perun] [clojure.java.io :as io] [clojure.string :as str] @@ -24,16 +24,12 @@ opts (assoc clj-opts :attributes atr)] (keywords->names opts))) -;; TODO integrate all options and defaults into a single map, and expose to the perun.clj file - (defn new-adoc-container "Creates a new AsciidoctorJ (JRuby) container, based on the normalized options provided." [n-opts] - (let [libraries (get n-opts "libraries")] - ; (AsciidoctorContainer. (Asciidoctor$Factory/create) gempath libraries))) - (Asciidoctor$Factory/create (str (get n-opts "gempath"))))) -;; TODO add desired libraries + (let [acont (Asciidoctor$Factory/create (str (get n-opts "gempath")))] + (doto acont (.requireLibraries (into '() (get n-opts "libraries")))))) (defn parse-file-metadata "Read the file-content and derive relevant metadata for use in other Perun @@ -50,7 +46,6 @@ options (-> (select-keys ["header_footer" "attributes"] n-opts) (assoc "backend" "html5"))] (.convert container (md/remove-metadata file-content) options))) -;; TODO incorporate options into container creation (defn process-file "Parses the content of a single file and associates the available metadata to @@ -64,8 +59,13 @@ (merge ad-metadata {:content html} file))) (defn parse-asciidoc - "Responsible for parsing all provided asciidoc files. The actual parsing is - dispatched." + "The main function of `io.perun.contrib.asciidoctor`. Responsible for parsing + all provided asciidoc files. The actual parsing is dispatched. It accepts a + boot fileset and a map of options. + + The map of options typically includes an array of libraries and an array of attributes: {:libraries [] :attributes {}}. Libraries are loaded from the AsciidoctorJ project, and can be loaded specifically (\"asciidoctor-diagram/ditaa\") or more broadly (\"asciidoctor-diagram\"). Attributes can be set freely, although a large set + has been predefined in the Asciidoctor project to configure rendering options + or set meta-data." [asciidoc-files options] (let [updated-files (doall (map #(process-file % options) asciidoc-files))] (perun/report-info "asciidoctor" "parsed %s asciidoc files" (count asciidoc-files)) diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj index 339af5b1..7efcea94 100644 --- a/test/io/perun/contrib/asciidoctor_test.clj +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -56,9 +56,24 @@ I Zeus would like to describe how the god Perun relates to my image. :name "in my own image" :original true}) +(def diagram-sample " += The way Perun does + +[plantuml, lighting-direction] +.... +Branch --|> Velves +.... +") + +(def expected-diagram-html "
+
+\"lighting +
+
") + (def +asciidoctor-defaults+ {:gempath "" - :libraries '("asciidoctor-diagram") + :libraries ["asciidoctor-diagram"] :attributes {:generator "perun"}}) (deftest test-asciidoc-to-html @@ -70,3 +85,8 @@ I Zeus would like to describe how the god Perun relates to my image. "Test the metadata extraction by `parse-file-metadata`." (let [metadata (parse-file-metadata sample-adoc)] (is (= expected-meta metadata)))) + +(deftest convert-with-asciidoctor-diagram + "Test the handling by the `asciidoctor-diagram` library for built-in images" + (let [rendered (asciidoc-to-html diagram-sample (normalize-options +asciidoctor-defaults+))] + (is (= expected-diagram-html rendered)))) From 3ff6381038253e680c34fa1d78161980783b6c00 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Fri, 16 Sep 2016 10:39:08 +0200 Subject: [PATCH 04/10] feat(asciidoctor): metadata handling --- src/io/perun/contrib/asciidoctor.clj | 41 +++++++++---- test/io/perun/contrib/asciidoctor_test.clj | 70 +++++++++++++++++++--- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index 4de84a46..ef97aad7 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -9,10 +9,16 @@ (defn keywords->names "Converts a map with keywords to a map with named keys. Only handles the top - level of any nesting structure." + level of any nested structure." [m] (reduce-kv #(assoc %1 (name %2) %3) {} m)) +(defn names->keywords + "Converts a map with named keys to a map with keywords. Only handles the top + level of any nested structure." + [m] + (reduce-kv #(assoc %1 (keyword %2) %3) {} m)) + (defn normalize-options "Takes the options for the Asciidoctor parser and puts the in the format appropriate for handling by the downstream functions. Mostly to better suit @@ -33,17 +39,27 @@ (defn parse-file-metadata "Read the file-content and derive relevant metadata for use in other Perun - tasks." - [file-content] - (md/parse-file-metadata file-content)) -;; TODO include asciidoctor based metadata including attributes + tasks. The document is read in its entirety (.readDocumentStructure instead + of .readDocumentHeader) to have the results of the options reflected into the + resulting metadata. As the document is rendered again, the time-based + attributes will vary from the asciidoc-to-html convertion (doctime, + docdatetime, localdate, localdatetime, localtime)." + [container file-content n-opts] + (let [frontmatter (md/parse-file-metadata file-content) + attributes (->> (.readDocumentStructure container file-content n-opts) + (.getHeader) + (.getAttributes) + (into {}) + (names->keywords))] + (merge frontmatter attributes))) +;; TODO align attribute keywords with perun keywords +;; TODO perhaps use dedicated functions for getting the title and author info (defn asciidoc-to-html "Converts a given string of asciidoc into HTML. The normalized options that can be provided, influence the behavior of the conversion." - [file-content n-opts] - (let [container (new-adoc-container n-opts) - options (-> (select-keys ["header_footer" "attributes"] n-opts) + [container file-content n-opts] + (let [options (-> (select-keys ["header_footer" "attributes"] n-opts) (assoc "backend" "html5"))] (.convert container (md/remove-metadata file-content) options))) @@ -52,10 +68,11 @@ the resulting html string. The HTML conversion is dispatched." [file options] (perun/report-debug "asciidoctor" "processing asciidoc" (:filename file)) - (let [file-content (-> file :full-path io/file slurp) - ad-metadata (parse-file-metadata file-content) - n-opts (normalize-options options) - html (asciidoc-to-html file-content n-opts)] + (let [n-opts (normalize-options options) + container (new-adoc-container n-opts) + file-content (-> file :full-path io/file slurp) + ad-metadata (parse-file-metadata container file-content n-opts) + html (asciidoc-to-html container file-content n-opts)] (merge ad-metadata {:content html} file))) (defn parse-asciidoc diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj index 7efcea94..3ebab067 100644 --- a/test/io/perun/contrib/asciidoctor_test.clj +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -1,5 +1,6 @@ (ns io.perun.contrib.asciidoctor-test (:require [clojure.test :refer :all] + [clojure.set :as s] [io.perun.contrib.asciidoctor :refer :all])) (def sample-adoc " @@ -52,9 +53,60 @@ I Zeus would like to describe how the god Perun relates to my image. ") (def expected-meta - {:draft nil - :name "in my own image" - :original true}) + {:appendix-caption "Appendix", + :asciidoctor "", + :asciidoctor-version "1.5.4", + :attribute-missing "skip", + :attribute-undefined "drop-line", + :backend "html5", + :backend-html5 "", + :backend-html5-doctype-article "", + :basebackend "html", + :basebackend-html "", + :basebackend-html-doctype-article "", + :caution-caption "Caution", + :docdate "2016-09-16", + ; :docdatetime "2016-09-16 08:31:58 CEST", + :docdir "", + ; :doctime "08:31:58 CEST", + :doctype "article", + :doctype-article "", + :embedded "", + :example-caption "Example", + :figure-caption "Figure", + :filetype "html", + :filetype-html "", + :generator "perun", + :htmlsyntax "html", + :iconfont-remote "", + :iconsdir "./images/icons", + :important-caption "Important", + :last-update-label "Last updated", + :linkcss "", + ; :localdate "2016-09-16", + ; :localdatetime "2016-09-16 08:31:58 CEST", + ; :localtime "08:31:58 CEST", + :manname-title "NAME", + :max-include-depth 64, + :note-caption "Note", + :notitle "", + :outfilesuffix ".html", + :prewrap "", + :safe-mode-level 20, + :safe-mode-name "secure", + :safe-mode-secure "", + :sectids "", + :stylesdir ".", + :stylesheet "", + :table-caption "Table", + :tip-caption "Tip", + :toc-placement "auto", + :toc-title "Table of Contents", + :untitled-label "Untitled", + :user-home ".", + :version-label "Version", + :warning-caption "Warning", + :webfonts ""}) (def diagram-sample " = The way Perun does @@ -76,17 +128,21 @@ Branch --|> Velves :libraries ["asciidoctor-diagram"] :attributes {:generator "perun"}}) +(def n-opts (normalize-options +asciidoctor-defaults+)) + +(def container (new-adoc-container n-opts)) + (deftest test-asciidoc-to-html "Test the `asciidoc-to-html` function on its actual conversion." - (let [rendered (asciidoc-to-html sample-adoc (normalize-options +asciidoctor-defaults+))] + (let [rendered (asciidoc-to-html container sample-adoc n-opts)] (is (= expected-html rendered)))) (deftest test-parse-file-metadata "Test the metadata extraction by `parse-file-metadata`." - (let [metadata (parse-file-metadata sample-adoc)] - (is (= expected-meta metadata)))) + (let [metadata (parse-file-metadata container sample-adoc n-opts)] + (is (s/subset? (into #{} expected-meta) (into #{} metadata))))) (deftest convert-with-asciidoctor-diagram "Test the handling by the `asciidoctor-diagram` library for built-in images" - (let [rendered (asciidoc-to-html diagram-sample (normalize-options +asciidoctor-defaults+))] + (let [rendered (asciidoc-to-html container diagram-sample n-opts)] (is (= expected-diagram-html rendered)))) From 4f5914ee030a550e13665608c236bf1aa4ef4932 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Sat, 17 Sep 2016 08:51:37 +0200 Subject: [PATCH 05/10] chore(asciidoctor) metadata tests improved --- test/io/perun/contrib/asciidoctor_test.clj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj index 3ebab067..24eccc13 100644 --- a/test/io/perun/contrib/asciidoctor_test.clj +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -65,12 +65,13 @@ I Zeus would like to describe how the god Perun relates to my image. :basebackend-html "", :basebackend-html-doctype-article "", :caution-caption "Caution", - :docdate "2016-09-16", + ; :docdate "2016-09-16", ; :docdatetime "2016-09-16 08:31:58 CEST", :docdir "", ; :doctime "08:31:58 CEST", :doctype "article", :doctype-article "", + :draft nil, ;; from frontmatter :embedded "", :example-caption "Example", :figure-caption "Figure", @@ -88,8 +89,10 @@ I Zeus would like to describe how the god Perun relates to my image. ; :localtime "08:31:58 CEST", :manname-title "NAME", :max-include-depth 64, + :name "in my own image" ;; from frontmatter :note-caption "Note", :notitle "", + :original true, ;; from frontmatter :outfilesuffix ".html", :prewrap "", :safe-mode-level 20, From 05fa760d133780ee526df5483316c6602245c0bf Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Sat, 17 Sep 2016 09:08:15 +0200 Subject: [PATCH 06/10] feat(asciidoctor): containers now per fileset --- src/io/perun/contrib/asciidoctor.clj | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index ef97aad7..7fd5a0a0 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -66,11 +66,9 @@ (defn process-file "Parses the content of a single file and associates the available metadata to the resulting html string. The HTML conversion is dispatched." - [file options] + [container file n-opts] (perun/report-debug "asciidoctor" "processing asciidoc" (:filename file)) - (let [n-opts (normalize-options options) - container (new-adoc-container n-opts) - file-content (-> file :full-path io/file slurp) + (let [file-content (-> file :full-path io/file slurp) ad-metadata (parse-file-metadata container file-content n-opts) html (asciidoc-to-html container file-content n-opts)] (merge ad-metadata {:content html} file))) @@ -80,10 +78,22 @@ all provided asciidoc files. The actual parsing is dispatched. It accepts a boot fileset and a map of options. - The map of options typically includes an array of libraries and an array of attributes: {:libraries [] :attributes {}}. Libraries are loaded from the AsciidoctorJ project, and can be loaded specifically (\"asciidoctor-diagram/ditaa\") or more broadly (\"asciidoctor-diagram\"). Attributes can be set freely, although a large set - has been predefined in the Asciidoctor project to configure rendering options - or set meta-data." + The map of options typically includes an array of libraries and an array of + attributes: {:libraries [] :attributes {}}. Libraries are loaded from the + AsciidoctorJ project, and can be loaded specifically + (\"asciidoctor-diagram/ditaa\") or more broadly (\"asciidoctor-diagram\"). + Attributes can be set freely, although a large set has been predefined in the + Asciidoctor project to configure rendering options or set meta-data. + + This will create a new AsciidoctorJ (JRuby) container for parsing the given + set of files. All the downstream operations on the files will use this + container, preventing concurrent parsing. But the container creation and + computing overhead is such that having a couple of AsciidoctorJ containers + only makes sense for large or complex jobs, taking minutes rather than + seconds." [asciidoc-files options] - (let [updated-files (doall (map #(process-file % options) asciidoc-files))] + (let [n-opts (normalize-options options) + container (new-adoc-container n-opts) + updated-files (doall (map #(process-file container % n-opts ) asciidoc-files))] (perun/report-info "asciidoctor" "parsed %s asciidoc files" (count asciidoc-files)) updated-files)) From e96f6b9ac4ac252beae7f084be2ebf4eaf4b1f20 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Sat, 17 Sep 2016 09:26:21 +0200 Subject: [PATCH 07/10] chore(asciidoctor): copyright notice --- src/io/perun/contrib/asciidoctor.clj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index 7fd5a0a0..323be07e 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -1,3 +1,12 @@ +; Copyright (c) 2016 Nico Rikken nico@nicorikken.eu +; All rights reserved. +; The use and distribution terms for this software are covered by the +; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +; which can be found in the file LICENSE at the root of this distribution. +; By using this software in any fashion, you are agreeing to be bound by +; the terms of this license. +; You must not remove this notice, or any other, from this software. + (ns io.perun.contrib.asciidoctor "AsciidoctorJ based converter from Asciidoc to HTML." (:require [io.perun.core :as perun] From 0d29ba6cbefa73ca56f070243eb72ac6349bfb66 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Sun, 18 Sep 2016 10:04:03 +0200 Subject: [PATCH 08/10] feat(asciidoctor): metadata according to spec --- src/io/perun.clj | 10 ++++--- src/io/perun/contrib/asciidoctor.clj | 22 +++++++++----- test/io/perun/contrib/asciidoctor_test.clj | 35 +++++++++++++++------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/io/perun.clj b/src/io/perun.clj index 1b0580af..068ca2af 100644 --- a/src/io/perun.clj +++ b/src/io/perun.clj @@ -147,10 +147,12 @@ [circleci/clj-yaml "0.5.5"]]) (def ^:private +asciidoctor-defaults+ - {:gempath "" - :libraries ["asciidoctor-diagram"] - :header_footer false - :attributes {:generator "perun"}}) + {:gempath "" ; no given gempath + :libraries ["asciidoctor-diagram"] ; asciidoctor-diagram incl. + :header_footer false ; no full HTML doc + :attributes {:generator "perun" ; context to document + :backend "html5" ; for HTML5 output + :skip-front-matter ""}}) ; skip YAML frontmatter (deftask asciidoctor "Parse asciidoc files diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index 323be07e..4f388e90 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -46,6 +46,16 @@ (let [acont (Asciidoctor$Factory/create (str (get n-opts "gempath")))] (doto acont (.requireLibraries (into '() (get n-opts "libraries")))))) +(defn perunize-meta + [meta] + "Add duplicate entries for the metadata keys gathered from the AsciidoctorJ + parsing using keys that adhere to the Perun specification of keys. The native + AsciidoctorJ keys are still available for reference and debugging." + (merge meta {:author-email (:email meta) + :name (:doctitle meta) + :date-build (:localdate meta) + :date-modified (:docdate meta)})) + (defn parse-file-metadata "Read the file-content and derive relevant metadata for use in other Perun tasks. The document is read in its entirety (.readDocumentStructure instead @@ -55,22 +65,20 @@ docdatetime, localdate, localdatetime, localtime)." [container file-content n-opts] (let [frontmatter (md/parse-file-metadata file-content) - attributes (->> (.readDocumentStructure container file-content n-opts) + attributes (->> (.readDocumentStructure container (md/remove-metadata file-content) n-opts) (.getHeader) (.getAttributes) (into {}) (names->keywords))] - (merge frontmatter attributes))) -;; TODO align attribute keywords with perun keywords -;; TODO perhaps use dedicated functions for getting the title and author info + (merge frontmatter (perunize-meta attributes)))) +;; TODO make sure remove-metadata is compatible with Asciidoctor block syntax's (defn asciidoc-to-html "Converts a given string of asciidoc into HTML. The normalized options that can be provided, influence the behavior of the conversion." [container file-content n-opts] - (let [options (-> (select-keys ["header_footer" "attributes"] n-opts) - (assoc "backend" "html5"))] - (.convert container (md/remove-metadata file-content) options))) + (.convert container (md/remove-metadata file-content) n-opts)) +;; TODO get 'skip-front-matter' attribute working to avoid the md/remove-metadata call (defn process-file "Parses the content of a single file and associates the available metadata to diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj index 24eccc13..95699fb8 100644 --- a/test/io/perun/contrib/asciidoctor_test.clj +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -1,7 +1,8 @@ (ns io.perun.contrib.asciidoctor-test (:require [clojure.test :refer :all] [clojure.set :as s] - [io.perun.contrib.asciidoctor :refer :all])) + [io.perun.contrib.asciidoctor :refer :all] + [io.perun])) (def sample-adoc " --- @@ -9,9 +10,11 @@ draft: name: in my own image --- = In my own image: Perun -:author: Zeus zeus@thunderdome.olympus +:author: Zeus +:email: zeus@thunderdome.olympus :revdate: 02-08-907 :toc: +:description: Some posts are close to your heart... I Zeus would like to describe how the god Perun relates to my image. @@ -58,6 +61,11 @@ I Zeus would like to describe how the god Perun relates to my image. :asciidoctor-version "1.5.4", :attribute-missing "skip", :attribute-undefined "drop-line", + :author "Zeus", + :author-email "zeus@thunderdome.olympus", + :authorcount 1, + :authorinitials "Z", + :authors "Zeus", :backend "html5", :backend-html5 "", :backend-html5-doctype-article "", @@ -65,18 +73,24 @@ I Zeus would like to describe how the god Perun relates to my image. :basebackend-html "", :basebackend-html-doctype-article "", :caution-caption "Caution", + ; :date-build "2016-09-16", + ; :date-modified "2016-09-16" + :description "Some posts are close to your heart..." ; :docdate "2016-09-16", ; :docdatetime "2016-09-16 08:31:58 CEST", :docdir "", ; :doctime "08:31:58 CEST", + :doctitle "In my own image: Perun" :doctype "article", :doctype-article "", :draft nil, ;; from frontmatter + :email "zeus@thunderdome.olympus" :embedded "", :example-caption "Example", :figure-caption "Figure", :filetype "html", :filetype-html "", + :firstname "Zeus" :generator "perun", :htmlsyntax "html", :iconfont-remote "", @@ -89,20 +103,23 @@ I Zeus would like to describe how the god Perun relates to my image. ; :localtime "08:31:58 CEST", :manname-title "NAME", :max-include-depth 64, - :name "in my own image" ;; from frontmatter + :name "In my own image: Perun" ;; frontmatter overwritten by doc :note-caption "Note", :notitle "", :original true, ;; from frontmatter :outfilesuffix ".html", :prewrap "", + :revdate "02-08-907" :safe-mode-level 20, :safe-mode-name "secure", :safe-mode-secure "", + :skip-front-matter "" :sectids "", :stylesdir ".", :stylesheet "", :table-caption "Table", :tip-caption "Tip", + :toc "" :toc-placement "auto", :toc-title "Table of Contents", :untitled-label "Untitled", @@ -114,7 +131,7 @@ I Zeus would like to describe how the god Perun relates to my image. (def diagram-sample " = The way Perun does -[plantuml, lighting-direction] +[plantuml, lightning-direction] .... Branch --|> Velves .... @@ -122,16 +139,12 @@ Branch --|> Velves (def expected-diagram-html "
-\"lighting +\"lightning
") -(def +asciidoctor-defaults+ - {:gempath "" - :libraries ["asciidoctor-diagram"] - :attributes {:generator "perun"}}) - -(def n-opts (normalize-options +asciidoctor-defaults+)) +(def n-opts (normalize-options @#'io.perun/+asciidoctor-defaults+)) +; deref the private defintion var to circument the private-ness (def container (new-adoc-container n-opts)) From f04d8faffe24889b320d52a6d08a9a56116edba7 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Sun, 18 Sep 2016 22:03:17 +0200 Subject: [PATCH 09/10] feat(asciidoctor): header by default --- src/io/perun.clj | 7 ++++--- test/io/perun/contrib/asciidoctor_test.clj | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/io/perun.clj b/src/io/perun.clj index 068ca2af..a12358f3 100644 --- a/src/io/perun.clj +++ b/src/io/perun.clj @@ -152,7 +152,8 @@ :header_footer false ; no full HTML doc :attributes {:generator "perun" ; context to document :backend "html5" ; for HTML5 output - :skip-front-matter ""}}) ; skip YAML frontmatter + :skip-front-matter "" ; skip YAML frontmatter + :showtitle ""}}) (deftask asciidoctor "Parse asciidoc files @@ -163,7 +164,7 @@ asciidoc file's content" [o options OPTS edn "options to be passed to the asciidoctor parser"] - (let [options (merge +images-resize-defaults+ *opts*) + (let [options (merge +asciidoctor-defaults+ *opts*) pod (create-pod asciidoctor-deps) prev-meta (atom {}) prev-fs (atom nil)] @@ -191,7 +192,7 @@ (reset! prev-fs fileset) (reset! prev-meta final-metadata) (perun/set-meta fileset final-metadata))))) -;; TODO perhaps reuse the Asciidoctor container inside a pod, to prevent repeatedly re-initializing the JRuby container. +;; TODO Support task option syntax (deftask global-metadata "Read global metadata from `perun.base.edn` or configured file. diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj index 95699fb8..5369394d 100644 --- a/test/io/perun/contrib/asciidoctor_test.clj +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -32,7 +32,8 @@ I Zeus would like to describe how the god Perun relates to my image. ---- ") -(def expected-html "
+(def expected-html "

In my own image: Perun

+

I Zeus would like to describe how the god Perun relates to my image.

@@ -137,7 +138,8 @@ Branch --|> Velves .... ") -(def expected-diagram-html "
+(def expected-diagram-html "

The way Perun does

+
\"lightning
From fbea53beb44e3f995aefec71c3dd06e720399f81 Mon Sep 17 00:00:00 2001 From: Nico Rikken Date: Wed, 21 Sep 2016 22:37:09 +0200 Subject: [PATCH 10/10] feat(asciidoctor): better yaml frontmatter handling --- src/io/perun.clj | 3 +- src/io/perun/contrib/asciidoctor.clj | 70 +++++++++++++++++----- test/io/perun/contrib/asciidoctor_test.clj | 27 +++++++-- 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/src/io/perun.clj b/src/io/perun.clj index a12358f3..23edc5ec 100644 --- a/src/io/perun.clj +++ b/src/io/perun.clj @@ -153,7 +153,8 @@ :attributes {:generator "perun" ; context to document :backend "html5" ; for HTML5 output :skip-front-matter "" ; skip YAML frontmatter - :showtitle ""}}) + :showtitle "" ; include

from header + :imagesdir "."}}) ; image dir relative to adoc file (deftask asciidoctor "Parse asciidoc files diff --git a/src/io/perun/contrib/asciidoctor.clj b/src/io/perun/contrib/asciidoctor.clj index 4f388e90..24598919 100644 --- a/src/io/perun/contrib/asciidoctor.clj +++ b/src/io/perun/contrib/asciidoctor.clj @@ -12,7 +12,7 @@ (:require [io.perun.core :as perun] [clojure.java.io :as io] [clojure.string :as str] - [clj-yaml.core :as yml] + [clj-yaml.core :as yaml] [io.perun.markdown :as md]) (:import [org.asciidoctor Asciidoctor Asciidoctor$Factory])) @@ -39,6 +39,44 @@ opts (assoc clj-opts :attributes atr)] (keywords->names opts))) +(defn base-dir + "Derive the `base_dir` from the meta-data, as a basis for links and inclusions + but also for image generation. The regex will filter out the last part of the + file path, after the last slash (`/`) to get back the base_dir." + [full-path] + (get (re-matches #"(.*\/)[^\/]+" full-path) 1)) + +(defn extract-meta + "Extract the above YAML metadata (front-matter) from the head of the file. + It returns a map with the `:meta` and the `:asciidoc` content. The `:meta` + key contains a map of the metadata, or a `nil` if the extraction or parsing + failed. The `:asciidoc` key contains a string of the remaining Asciidoc + content. + + This function prevents the need to rely on the `skip-front-matter` option in + the AsciidoctorJ conversion process." + [content] + (let [first-line (first (drop-while str/blank? (str/split-lines content))) + start? (= "---" first-line) + splitted (str/split content #"---\n" 3) + finish? (> (count splitted) 2)] + (if (and start? finish?) + ;; metadata was found, try to parse it + (let [;metadata-str (nth splitted 1) + ;adoc-content (nth splitted 2)] + metadata-str (get splitted 1) + adoc-content (get splitted 2)] + (if-let [parsed-yaml (md/normal-colls (yaml/parse-string metadata-str))] + ;; yaml parsing succeeded, return the map + {:meta (assoc parsed-yaml :original true) + :asciidoc adoc-content} + ;; yaml parsing failed, return only the adoc-content + {:meta nil + :asciidoc adoc-content})) + ;; no metadata found, return the original content + {:meta nil + :asciidoc content}))) + (defn new-adoc-container "Creates a new AsciidoctorJ (JRuby) container, based on the normalized options provided." @@ -57,38 +95,42 @@ :date-modified (:docdate meta)})) (defn parse-file-metadata - "Read the file-content and derive relevant metadata for use in other Perun + "Read the asciidoc content and derive relevant metadata for use in other Perun tasks. The document is read in its entirety (.readDocumentStructure instead of .readDocumentHeader) to have the results of the options reflected into the resulting metadata. As the document is rendered again, the time-based attributes will vary from the asciidoc-to-html convertion (doctime, docdatetime, localdate, localdatetime, localtime)." - [container file-content n-opts] - (let [frontmatter (md/parse-file-metadata file-content) - attributes (->> (.readDocumentStructure container (md/remove-metadata file-content) n-opts) + [container adoc-content frontmatter n-opts] + (let [attributes (->> (.readDocumentStructure container adoc-content n-opts) (.getHeader) (.getAttributes) (into {}) (names->keywords))] (merge frontmatter (perunize-meta attributes)))) -;; TODO make sure remove-metadata is compatible with Asciidoctor block syntax's (defn asciidoc-to-html "Converts a given string of asciidoc into HTML. The normalized options that can be provided, influence the behavior of the conversion." - [container file-content n-opts] - (.convert container (md/remove-metadata file-content) n-opts)) -;; TODO get 'skip-front-matter' attribute working to avoid the md/remove-metadata call + [container adoc-content n-opts] + (.convert container adoc-content n-opts)) (defn process-file "Parses the content of a single file and associates the available metadata to the resulting html string. The HTML conversion is dispatched." - [container file n-opts] + [container file options] (perun/report-debug "asciidoctor" "processing asciidoc" (:filename file)) - (let [file-content (-> file :full-path io/file slurp) - ad-metadata (parse-file-metadata container file-content n-opts) - html (asciidoc-to-html container file-content n-opts)] + (let [basedir {:base_dir (base-dir (:full-path file))} + opts (merge-with options {:attributes {:base_dir (base-dir (:full-path file))}}) + n-opts (normalize-options opts) + file-content (-> file :full-path io/file slurp) + extraction (extract-meta file-content) + adoc-content (:asciidoc extraction) + frontmatter (:meta extraction) + ad-metadata (parse-file-metadata container adoc-content frontmatter n-opts) + html (asciidoc-to-html container adoc-content n-opts)] (merge ad-metadata {:content html} file))) +;; TODO get 'skip-front-matter' attribute working to avoid the extract-meta call (defn parse-asciidoc "The main function of `io.perun.contrib.asciidoctor`. Responsible for parsing @@ -111,6 +153,6 @@ [asciidoc-files options] (let [n-opts (normalize-options options) container (new-adoc-container n-opts) - updated-files (doall (map #(process-file container % n-opts ) asciidoc-files))] + updated-files (doall (map #(process-file container % options ) asciidoc-files))] (perun/report-info "asciidoctor" "parsed %s asciidoc files" (count asciidoc-files)) updated-files)) diff --git a/test/io/perun/contrib/asciidoctor_test.clj b/test/io/perun/contrib/asciidoctor_test.clj index 5369394d..1b4c8058 100644 --- a/test/io/perun/contrib/asciidoctor_test.clj +++ b/test/io/perun/contrib/asciidoctor_test.clj @@ -95,7 +95,8 @@ I Zeus would like to describe how the god Perun relates to my image. :generator "perun", :htmlsyntax "html", :iconfont-remote "", - :iconsdir "./images/icons", + :iconsdir "./icons", + :imagesdir "." :important-caption "Important", :last-update-label "Last updated", :linkcss "", @@ -114,6 +115,7 @@ I Zeus would like to describe how the god Perun relates to my image. :safe-mode-level 20, :safe-mode-name "secure", :safe-mode-secure "", + :showtitle "", :skip-front-matter "" :sectids "", :stylesdir ".", @@ -141,26 +143,41 @@ Branch --|> Velves (def expected-diagram-html "

The way Perun does

-\"lightning +\"lightning
") +(def expected-extraction + {:meta + {:draft nil + :name "in my own image" + :original true}, + :asciidoc + "= In my own image: Perun\n:author: Zeus\n:email: zeus@thunderdome.olympus\n:revdate: 02-08-907\n:toc:\n:description: Some posts are close to your heart...\n\nI Zeus would like to describe how the god Perun relates to my image.\n\n[quote, Perun, Having struck Veles]\n\"Well, there is your place, remain there!\"\n\n.No power more godlike then the Clojure power of Perun\n[source, clojure]\n----\n(deftask build\n \"Build blog.\"\n []\n (comp (asciidoctor)\n (render :renderer renderer)))\n----\n"}) + (def n-opts (normalize-options @#'io.perun/+asciidoctor-defaults+)) ; deref the private defintion var to circument the private-ness (def container (new-adoc-container n-opts)) +(deftest test-extract-meta + (let [extraction (extract-meta sample-adoc)] + (is (= expected-extraction extraction)))) + (deftest test-asciidoc-to-html "Test the `asciidoc-to-html` function on its actual conversion." - (let [rendered (asciidoc-to-html container sample-adoc n-opts)] + (let [rendered (asciidoc-to-html container (:asciidoc (extract-meta sample-adoc)) n-opts)] (is (= expected-html rendered)))) (deftest test-parse-file-metadata "Test the metadata extraction by `parse-file-metadata`." - (let [metadata (parse-file-metadata container sample-adoc n-opts)] + (let [extraction (extract-meta sample-adoc) + adoc-content (:asciidoc extraction) + frontmatter (:meta extraction) + metadata (parse-file-metadata container adoc-content frontmatter n-opts)] (is (s/subset? (into #{} expected-meta) (into #{} metadata))))) (deftest convert-with-asciidoctor-diagram "Test the handling by the `asciidoctor-diagram` library for built-in images" - (let [rendered (asciidoc-to-html container diagram-sample n-opts)] + (let [rendered (asciidoc-to-html container (:asciidoc (extract-meta diagram-sample)) n-opts)] (is (= expected-diagram-html rendered))))