mirror of
https://github.com/journeyman-cc/smeagol.git
synced 2026-04-12 18:05:06 +00:00
Updated JS dependencies; fixed the problem with pluggable extensions.
This commit is contained in:
parent
9f66ccf6ab
commit
96fa9c7033
7 changed files with 55 additions and 44 deletions
14
project.clj
14
project.clj
|
|
@ -54,15 +54,15 @@
|
||||||
[lein-npm "0.6.2"]
|
[lein-npm "0.6.2"]
|
||||||
[lein-ring "0.12.5" :exclusions [org.clojure/clojure]]]
|
[lein-ring "0.12.5" :exclusions [org.clojure/clojure]]]
|
||||||
|
|
||||||
:npm {:dependencies [[simplemde "1.11.2"]
|
:npm {:dependencies [[geocsv-js "simon-brooke/geocsv-js#3a34ba7"]
|
||||||
[vega "5.9.0"]
|
[mermaid "8.13.8"]
|
||||||
[vega-embed "6.2.2"]
|
|
||||||
[vega-lite "4.1.1"]
|
|
||||||
[mermaid "8.4.6"]
|
|
||||||
[photoswipe "4.1.3"]
|
[photoswipe "4.1.3"]
|
||||||
|
[simplemde "1.11.2"]
|
||||||
[showdown "1.9.1"]
|
[showdown "1.9.1"]
|
||||||
[tablesort "5.2.0"]
|
[tablesort "5.3.0"]
|
||||||
[geocsv-js "simon-brooke/geocsv-js#3a34ba7"]]
|
[vega "5.21.0"]
|
||||||
|
[vega-embed "6.20.5"]
|
||||||
|
[vega-lite "5.2.0"]]
|
||||||
:root "resources/public/vendor"}
|
:root "resources/public/vendor"}
|
||||||
|
|
||||||
:docker {:image-name "simonbrooke/smeagol"
|
:docker {:image-name "simonbrooke/smeagol"
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,9 @@ followed by three backticks on a line by themselves. There is an [[Example galle
|
||||||
|
|
||||||
## Writing your own custom formatters
|
## 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.
|
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 argument 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.
|
||||||
|
|
||||||
|
The string returned should just be the necessary HTML text to add to the page to invoke the formatter.
|
||||||
|
|
||||||
For example, here's the formatter which handles the Vega charts:
|
For example, here's the formatter which handles the Vega charts:
|
||||||
|
|
||||||
|
|
@ -166,6 +168,10 @@ For example, here's the formatter which handles the Vega charts:
|
||||||
index
|
index
|
||||||
");\n//]]\n</script>"))
|
");\n//]]\n</script>"))
|
||||||
|
|
||||||
|
In order to allow pluggable extensions -- that is, extensions which are not compiled as part of Smeagol but are added as additional classes on the classpath at run time -- every extension function must be written in a namespace which has the `(:gen-class)` directive.
|
||||||
|
|
||||||
|
In principal it should be possible to write extensions in Java, or in other languages which compile for the JVM, but this has not yet been demonstrated.
|
||||||
|
|
||||||
### Configuring Smeagol to use your formatter
|
### Configuring Smeagol to use your formatter
|
||||||
|
|
||||||
To add your own formatter, compile it into a jar file which is on the classpath - it does *not* have to be part of the Smeagol project directly - and then edit the value of the key `:formatters` in the file `config.edn`; whose standard definition is:
|
To add your own formatter, compile it into a jar file which is on the classpath - it does *not* have to be part of the Smeagol project directly - and then edit the value of the key `:formatters` in the file `config.edn`; whose standard definition is:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
smeagol.extensions.geocsv
|
smeagol.extensions.geocsv
|
||||||
(:require [smeagol.configuration :refer [config]]
|
(:require [smeagol.configuration :refer [config]]
|
||||||
[smeagol.extensions.utils :refer [resource-url-or-data->data]]
|
[smeagol.extensions.utils :refer [resource-url-or-data->data]]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;
|
;;;;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
smeagol.extensions.mermaid
|
smeagol.extensions.mermaid
|
||||||
(:require [smeagol.extensions.utils :refer [resource-url-or-data->data]]
|
(:require [smeagol.extensions.utils :refer [resource-url-or-data->data]]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;
|
;;;;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
(ns ^{:doc "Photoswipe gallery formatter for Semagol's extendsible markdown
|
(ns ^{:doc "Photoswipe gallery formatter for Semagol's extendsible markdown
|
||||||
format."
|
format."
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
smeagol.extensions.photoswipe
|
smeagol.extensions.photoswipe
|
||||||
(:require [clojure.data.json :as json]
|
(:require [clojure.data.json :as json]
|
||||||
[clojure.java.io :as cio]
|
[clojure.java.io :as cio]
|
||||||
[clojure.string :as cs]
|
[clojure.string :as cs]
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
[smeagol.configuration :refer [config]]
|
[smeagol.configuration :refer [config]]
|
||||||
[smeagol.extensions.utils :refer [resource-url-or-data->data uploaded?]]
|
[smeagol.extensions.utils :refer [resource-url-or-data->data uploaded?]]
|
||||||
[smeagol.util :refer [content-dir upload-dir]]
|
[smeagol.util :refer [content-dir upload-dir]]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;
|
;;;;
|
||||||
|
|
@ -68,11 +69,11 @@
|
||||||
"Simplify a parse-`tree` created by `simple-grammar`, q.v."
|
"Simplify a parse-`tree` created by `simple-grammar`, q.v."
|
||||||
[tree]
|
[tree]
|
||||||
(when
|
(when
|
||||||
(coll? tree)
|
(coll? tree)
|
||||||
(case (first tree)
|
(case (first tree)
|
||||||
:SLIDES (cons
|
:SLIDES (cons
|
||||||
(simplify (first (rest tree)))
|
(simplify (first (rest tree)))
|
||||||
(first (simplify (rest (rest tree)))))
|
(first (simplify (rest (rest tree)))))
|
||||||
:SLIDE (remove empty? (map simplify (rest tree)))
|
:SLIDE (remove empty? (map simplify (rest tree)))
|
||||||
:title tree
|
:title tree
|
||||||
:src tree
|
:src tree
|
||||||
|
|
@ -90,12 +91,12 @@
|
||||||
dimensions (try
|
dimensions (try
|
||||||
(when (uploaded? url)
|
(when (uploaded? url)
|
||||||
(dimensions
|
(dimensions
|
||||||
(buffered-image
|
(buffered-image
|
||||||
(cio/file upload-dir (fs/base-name url)))))
|
(cio/file upload-dir (fs/base-name url)))))
|
||||||
(catch Exception x
|
(catch Exception x
|
||||||
(log/error
|
(log/error
|
||||||
"Failed to fetch dimensions of image "
|
"Failed to fetch dimensions of image "
|
||||||
url (.getMessage x))
|
url (.getMessage x))
|
||||||
nil))]
|
nil))]
|
||||||
(if dimensions
|
(if dimensions
|
||||||
(assoc slide :w (first dimensions) :h (nth dimensions 1))
|
(assoc slide :w (first dimensions) :h (nth dimensions 1))
|
||||||
|
|
@ -105,14 +106,14 @@
|
||||||
(defn find-thumb
|
(defn find-thumb
|
||||||
[url thumbsize]
|
[url thumbsize]
|
||||||
(when
|
(when
|
||||||
(and
|
(and
|
||||||
(uploaded? url)
|
(uploaded? url)
|
||||||
thumbsize)
|
thumbsize)
|
||||||
(let [p (str (cio/file "uploads" (name thumbsize) (fs/base-name url)))
|
(let [p (str (cio/file "uploads" (name thumbsize) (fs/base-name url)))
|
||||||
p' (cio/file content-dir p)
|
p' (cio/file content-dir p)
|
||||||
r (str (cio/file "content" p))]
|
r (str (cio/file "content" p))]
|
||||||
(if
|
(if
|
||||||
(and (fs/exists? p') (fs/readable? p'))
|
(and (fs/exists? p') (fs/readable? p'))
|
||||||
r
|
r
|
||||||
(do
|
(do
|
||||||
(log/warn "Failed to find" thumbsize "thumbnail for" url "at" p')
|
(log/warn "Failed to find" thumbsize "thumbnail for" url "at" p')
|
||||||
|
|
@ -132,15 +133,15 @@
|
||||||
(let [s' (zipmap (map first slide) (map #(nth % 1) slide))
|
(let [s' (zipmap (map first slide) (map #(nth % 1) slide))
|
||||||
thumbsizes (:thumbnails config)
|
thumbsizes (:thumbnails config)
|
||||||
thumbsize (first
|
thumbsize (first
|
||||||
(sort
|
(sort
|
||||||
#(> (%1 thumbsizes) (%2 thumbsizes))
|
#(> (%1 thumbsizes) (%2 thumbsizes))
|
||||||
(keys thumbsizes)))
|
(keys thumbsizes)))
|
||||||
url (:src s')
|
url (:src s')
|
||||||
thumb (find-thumb url thumbsize)]
|
thumb (find-thumb url thumbsize)]
|
||||||
(slide-merge-dimensions
|
(slide-merge-dimensions
|
||||||
(if thumb
|
(if thumb
|
||||||
(assoc s' :msrc thumb)
|
(assoc s' :msrc thumb)
|
||||||
s'))))
|
s'))))
|
||||||
|
|
||||||
|
|
||||||
(def process-simple-photoswipe
|
(def process-simple-photoswipe
|
||||||
|
|
@ -148,15 +149,15 @@
|
||||||
a sequence of MarkDown image links. This is REALLY expensive to do, we don't
|
a sequence of MarkDown image links. This is REALLY expensive to do, we don't
|
||||||
want to do it often. Hence memoised."
|
want to do it often. Hence memoised."
|
||||||
(memoize
|
(memoize
|
||||||
(fn
|
(fn
|
||||||
[^String spec ^Integer index]
|
[^String spec ^Integer index]
|
||||||
(process-full-photoswipe
|
(process-full-photoswipe
|
||||||
(json/write-str
|
(json/write-str
|
||||||
{:slides (map
|
{:slides (map
|
||||||
process-simple-slide
|
process-simple-slide
|
||||||
(simplify (simple-grammar spec)))
|
(simplify (simple-grammar spec)))
|
||||||
:options { :timeToIdle 100 }
|
:options {:timeToIdle 100}
|
||||||
:openImmediately true}) index))))
|
:openImmediately true}) index))))
|
||||||
|
|
||||||
|
|
||||||
(defn process-photoswipe
|
(defn process-photoswipe
|
||||||
|
|
@ -165,7 +166,7 @@
|
||||||
[^String url-or-pswp-spec ^Integer index]
|
[^String url-or-pswp-spec ^Integer index]
|
||||||
(let [data (resource-url-or-data->data url-or-pswp-spec)
|
(let [data (resource-url-or-data->data url-or-pswp-spec)
|
||||||
spec (cs/trim (:data data))]
|
spec (cs/trim (:data data))]
|
||||||
(if
|
(if
|
||||||
(cs/starts-with? spec "![")
|
(cs/starts-with? spec "![")
|
||||||
(process-simple-photoswipe spec index)
|
(process-simple-photoswipe spec index)
|
||||||
(process-full-photoswipe spec index))))
|
(process-full-photoswipe spec index))))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
(ns ^{:doc "Very simple extension for testing the extension processing flow."
|
(ns ^{:doc "Very simple extension for testing the extension processing flow."
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
smeagol.extensions.test)
|
smeagol.extensions.test
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
|
|
||||||
(def process-test-return-value "<!-- The test extension has run and this is its output -->")
|
(def process-test-return-value "<!-- The test extension has run and this is its output -->")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
smeagol.extensions.vega
|
smeagol.extensions.vega
|
||||||
(:require [smeagol.extensions.utils :refer [resource-url-or-data->data yaml->json]]
|
(:require [smeagol.extensions.utils :refer [resource-url-or-data->data yaml->json]]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;
|
;;;;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue