diff --git a/project.clj b/project.clj index b270587..1ab812a 100644 --- a/project.clj +++ b/project.clj @@ -52,6 +52,7 @@ [vega-embed "6.2.2"] [vega-lite "4.1.1"] [mermaid "8.4.6"] + [photoswipe "4.1.3"] [tablesort "5.2.0"]] :root "resources/public/vendor"} diff --git a/resources/config.edn b/resources/config.edn index c2c9161..4f9532d 100644 --- a/resources/config.edn +++ b/resources/config.edn @@ -34,7 +34,8 @@ :formatters {"vega" smeagol.formatting/process-vega "vis" smeagol.formatting/process-vega "mermaid" smeagol.extensions.mermaid/process-mermaid - "backticks" smeagol.formatting/process-backticks} + "backticks" smeagol.formatting/process-backticks + "pswp" smeagol.formatting/process-photoswipe} :log-level :info ;; the minimum logging level; one of ;; :trace :debug :info :warn :error :fatal :js-from :cloudflare ;; where to load JavaScript libraries diff --git a/resources/public/content/Example gallery.md b/resources/public/content/Example gallery.md new file mode 100644 index 0000000..8379206 --- /dev/null +++ b/resources/public/content/Example gallery.md @@ -0,0 +1,59 @@ +## The Gallery + +This page holds an example Photoswipe gallery. + +```pswp +{ + slides: [ + { src: 'content/uploads/g1.jpg', w: 2592, h:1944, + title: 'Frost on a gate, Laurieston' }, + { src: 'content/uploads/g2.jpg', w: 2560, h:1920, + title: 'Feathered crystals on snow surface, Taliesin' }, + { src: 'content/uploads/g3.jpg', w: 2560, h:1920, + title: 'Feathered snow on log, Taliesin' }, + { src: 'content/uploads/g4.jpg', w: 2560, h:1920, + title: 'Crystaline growth on seed head, Taliesin' }], + options: { + timeToIdle: 100 + }, + openImmediately: true +} + +``` + +## How this works + +The specification for this gallery is as follows: + +``` +{ + slides: [ + { src: 'content/uploads/g1.jpg', w: 2592, h:1944, + title: 'Frost on a gate, Laurieston' }, + { src: 'content/uploads/g2.jpg', w: 2560, h:1920, + title: 'Feathered crystals on snow surface, Taliesin' }, + { src: 'content/uploads/g3.jpg', w: 2560, h:1920, + title: 'Feathered snow on log, Taliesin' }, + { src: 'content/uploads/g4.jpg', w: 2560, h:1920, + title: 'Crystaline growth on seed head, Taliesin' }], + options: { + timeToIdle: 100 + }, + openImmediately: true +} + +``` + +The format of the specification is [JSON](https://www.json.org/json-en.html); there are (at present) three keys, as follows + +### slides + +Most be present. The value of `slides` is a list delimited by square brackets of slide objects. For more information, see the [authoritative documentation](https://photoswipe.com/documentation/getting-started.html) under the sub heading **'Creating an Array of Slide Objects'**. + +### options + +Optional. The value of `options` is a JSON object [as documented here](https://photoswipe.com/documentation/options.html). + +### openImmediately + +Optional. If the value of `openImmediately` is `true`, the gallery will open immediately, covering the whole page. If false, only a button with the label 'Open the gallery' will be shown. Selecting this button will cause the gallery to open. diff --git a/resources/public/content/Extensible Markup.md b/resources/public/content/Extensible Markup.md index aec9e82..3bc8301 100644 --- a/resources/public/content/Extensible Markup.md +++ b/resources/public/content/Extensible Markup.md @@ -66,6 +66,12 @@ Mermaid graph specifications can also be loaded from URLs. Here's another exampl data/classes.mermaid ``` +## Photoswipe galleries + +Not so much a formatter, this is an extension to allow you to embed image galleries in your markdown. To specify a gallery, use three backticks followed by `pswp`, followed on the following lines by a Photoswipe specification in [JSON](https://www.json.org/json-en.html) +followed by three backticks on a line by themselves. There is an [[Example gallery]] so that you can see how this works. + + ## Writing your own custom formatters A custom formatter is simply a Clojure function which takes a string and an integer as arguments and produces a string as output. The string is the text the user has typed into their markdown; the integer is simply a number you can use to keep track of which addition to the page this is, in order, for example, to fix up some JavaScript to render it. diff --git a/resources/public/html-includes/photoswipe-boilerplate.html b/resources/public/html-includes/photoswipe-boilerplate.html new file mode 100644 index 0000000..2dec488 --- /dev/null +++ b/resources/public/html-includes/photoswipe-boilerplate.html @@ -0,0 +1,65 @@ + + +
+ + +
+ + +
+
+
+
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + +
+
+
+
+
+
+
+
+ + + + + + + +
+
+
+ +
+ +
diff --git a/resources/public/vendor/README.md b/resources/public/vendor/README.md deleted file mode 100644 index c3ab41c..0000000 --- a/resources/public/vendor/README.md +++ /dev/null @@ -1 +0,0 @@ -This folder must exist in order that the Bower package manager can deploy JavaScript packages to it. diff --git a/resources/templates/wiki.html b/resources/templates/wiki.html index ffc9b1a..9413902 100644 --- a/resources/templates/wiki.html +++ b/resources/templates/wiki.html @@ -2,6 +2,10 @@ {% block extra-headers %} + {% script "https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js" %} + {% script "https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js" %} + {% style "vendor/node_modules/photoswipe/dist/photoswipe.css" %} + {% style "vendor/node_modules/photoswipe/dist/default-skin/default-skin.css" %} diff --git a/src/smeagol/extensions/vega.clj b/src/smeagol/extensions/vega.clj index 14cf285..1b9e2de 100644 --- a/src/smeagol/extensions/vega.clj +++ b/src/smeagol/extensions/vega.clj @@ -1,7 +1,9 @@ (ns ^{:doc "Format Semagol's extended markdown format." :author "Simon Brooke"} smeagol.extensions.vega - (:require [smeagol.extensions.utils :refer :all] + (:require [clojure.data.json :as json] + [clj-yaml.core :as yaml] + [smeagol.extensions.utils :refer :all] [taoensso.timbre :as log])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -60,6 +62,11 @@ ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defn yaml->json + "Rewrite this string, assumed to be in YAML format, as JSON." + [^String yaml-src] + (json/write-str (yaml/parse-string yaml-src))) + (defn process-vega "If this `src-resource-or-url` is a valid URL, it is assumed to point to a plain text file pointing to valid `vega-src`; otherwise, it is expected to @@ -68,7 +75,7 @@ Process this `vega-src` string, assumed to be in YAML format, into a specification of a Vega chart, and add the plumbing to render it." [^String src-resource-or-url ^Integer index] - (let [data (resource-url-or-data->data url-or-graph-spec) + (let [data (resource-url-or-data->data src-resource-or-url) vega-src (:data data)] (log/info "Retrieved vega-src from " (:from data) " `" ((:from data) data) "`") (str diff --git a/src/smeagol/formatting.clj b/src/smeagol/formatting.clj index eca5277..357f6aa 100644 --- a/src/smeagol/formatting.clj +++ b/src/smeagol/formatting.clj @@ -6,6 +6,7 @@ [cemerick.url :refer (url url-encode url-decode)] [clj-yaml.core :as yaml] [markdown.core :as md] + [noir.io :as io] ;; used by photoswipe, only [smeagol.configuration :refer [config]] [smeagol.extensions.mermaid :refer [process-mermaid]])) @@ -85,7 +86,27 @@ index ");\n//]]\n")) - +(defn process-photoswipe + "Process specification for a photoswipe gallery" + [^String spec ^Integer index] + (str + "
\n" + (slurp (str (io/resource-path) "html-includes/photoswipe-boilerplate.html")) + "
+ +

+ ")) (defn process-backticks