diff --git a/Readme.org b/Readme.org
index d518f7b..4457590 100644
--- a/Readme.org
+++ b/Readme.org
@@ -569,26 +569,16 @@ supported options. Check the head part of this document for an
example.
** Third-Party Plugins
Reveal.js is also extensible through third-party plugins. Org-reveal
-now includes a mechanism to load these as well, either for all org buffers
-by defining variable, or for local org buffer by setting option line.
-
-*** By Defining Variable
-Store the names and loading instructions for each plugin in the
-customizable variable ~org-reveal-external-plugins~. This variable is
-an associative list. The first element of each Assoc cell is a symbol
--- the name of the plugin -- and the second is the string of the code
-for enabling the plugin. The string can have ONE optional ~%s~, which
-will be replaced by `reveal-root`.
-
-So, this second element should have the form ~"{src:
-\"%srelative/path/toplugin/from/reveal/root.js\"}~. If you need the
-async or callback parameters, include those too. Ox-reveal will add
-the plugin to the dependencies parameter when Reveal is initialized.
-
-*** By Local Option Line
-Specify the plugin by option line ~#+REVEAL_EXTERNAL_PLUGINS: string
-of code~. Similar to the global plugin definition, the string of code
-can have one optional ~%s~ to be replaced by ~reveal-root~.
+provides a customizable variable ~org-reveal-external-plugins~ for
+defining available third-party plugins. This variable is an
+associative list. The first element of each Assoc cell is a symbol
+same as the name of the plugin and the second is a string specifying
+the location of the plugin script. The string can have ONE optional
+~%s~, which will be replaced by `reveal-root`. Code below is an
+example.
+#+begin_src lisp
+(setq org-reveal-external-plugins '((menu . "path/to/reveal.js-menu/menu.js"))
+#+end_src
** Highlight Source Code
diff --git a/ox-reveal.el b/ox-reveal.el
index 8059d9f..a9ffc8d 100644
--- a/ox-reveal.el
+++ b/ox-reveal.el
@@ -270,11 +270,10 @@ embedded into Reveal.initialize()."
:type 'string)
(defcustom org-reveal-plugins
- '(classList markdown zoom notes)
+ '(markdown zoom notes)
"Default builtin plugins"
:group 'org-export-reveal
:type '(set
- (const classList)
(const markdown)
(const highlight)
(const zoom)
@@ -668,6 +667,53 @@ using custom variable `org-reveal-root'."
(or (and buffer-plugins (listp buffer-plugins) buffer-plugins)
org-reveal-plugins)))
+(defun org-reveal--legacy-dependency (root-path plugins info)
+ (concat
+ "
+// Optional libraries used to extend on reveal.js
+dependencies: [
+"
+ ;; JS libraries
+ (let* ((builtins
+ (list
+ classList (format " { src: '%slib/js/classList.js', condition: function() { return !document.body.classList; } }" root-path)
+ markdown (format " { src: '%splugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+ { src: '%splugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }" root-path root-path)
+ highlight (format " { src: '%splugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }" root-path)
+ zoom (format " { src: '%splugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
+ notes (format " { src: '%splugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
+ search (format " { src: '%splugin/search/search.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
+ remotes (format " { src: '%splugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
+ ;; multiplex setup for reveal.js 3.x
+ multiplex (format " { src: '%s', async: true },\n%s"
+ (plist-get info :reveal-multiplex-socketio-url)
+ ; following ensures that either client.js or master.js is included depending on defva client-multiplex value state
+ (if (not client-multiplex)
+ (progn
+ (if (plist-get info :reveal-multiplex-secret)
+ (setq client-multiplex t))
+ (format " { src: '%splugin/multiplex/master.js', async: true }" root-path))
+ (format " { src: '%splugin/multiplex/client.js', async: true }" root-path)))))
+ (builtin-codes
+ (mapcar (lambda (p)
+ (eval (plist-get builtins p)))
+ plugins))
+ (external-plugins
+ (append
+ ;; Global setting
+ (cl-loop for (key . value) in org-reveal-external-plugins
+ collect (format value root-path ))
+ ;; Local settings
+ (let ((local-plugins (plist-get info :reveal-external-plugins)))
+ (and local-plugins
+ (list (format local-plugins root-path))))))
+
+ (all-plugins (if external-plugins (append external-plugins builtin-codes) builtin-codes))
+ (extra-codes (plist-get info :reveal-extra-js))
+ (total-codes
+ (if (string= "" extra-codes) all-plugins (append (list extra-codes) all-plugins))))
+ (mapconcat 'identity total-codes ",\n"))
+ "]\n"))
(defun org-reveal-scripts (info)
"Return the necessary scripts for initializing reveal.js using
custom variable `org-reveal-root'."
@@ -677,8 +723,9 @@ custom variable `org-reveal-root'."
;; Local files
(local-root-path (org-reveal--file-url-to-path root-path))
(local-reveal-js (org-reveal--choose-path local-root-path version "dist/reveal.js" "js/reveal.js"))
- (reveal-4-plugin (if (eq 4 (org-reveal--get-reveal-js-version info))
- (org-reveal-plugin-scripts-4 info)
+ (plugins (org-reveal--get-plugins info))
+ (reveal-4-plugin (if (eq 4 version)
+ (org-reveal-plugin-scripts-4 plugins info)
(cons nil nil)))
(in-single-file (plist-get info :reveal-single-file)))
(concat
@@ -701,140 +748,108 @@ custom variable `org-reveal-root'."
"\n"))
;; plugin headings
(if-format "%s\n" (car reveal-4-plugin))
- "
-
"
- ;; JS libraries
- (let* ((builtins
- '(classList (format " { src: '%slib/js/classList.js', condition: function() { return !document.body.classList; } }" root-path)
- markdown (format " { src: '%splugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
- { src: '%splugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }" root-path root-path)
- highlight (format " { src: '%splugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }" root-path)
- zoom (format " { src: '%splugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
- notes (format " { src: '%splugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
- search (format " { src: '%splugin/search/search.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
- remotes (format " { src: '%splugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }" root-path)
- ;; multiplex setup for reveal.js 3.x
- multiplex (format " { src: '%s', async: true },\n%s"
- (plist-get info :reveal-multiplex-socketio-url)
- ; following ensures that either client.js or master.js is included depending on defva client-multiplex value state
- (if (not client-multiplex)
- (progn
- (if (plist-get info :reveal-multiplex-secret)
- (setq client-multiplex t))
- (format " { src: '%splugin/multiplex/master.js', async: true }" root-path))
- (format " { src: '%splugin/multiplex/client.js', async: true }" root-path)))))
- (builtin-codes
- (let ((plugins (org-reveal--get-plugins info)))
- (if (eq version 4)
- ;; For reveal.js 4.x, skip the builtin plug-in
- ;; codes except multiplex as all other plug-ins
- ;; in 4.x are specified by separate \n")))
-
-(defun org-reveal-plugin-scripts-4 (info)
+(defun org-reveal-plugin-scripts-4 (plugins info)
"Return scripts for initializing reveal.js 4.x builtin scripts"
- (let ((plugins (org-reveal--get-plugins info)))
- (if (not (null plugins))
- ;; Generate plugin scripts
- (let* ((available-plugins
- '(highlight ("RevealHighlight" . "highlight/highlight.js")
- markdown ("RevealMarkdown" . "markdown/markdown.js")
- search ("RevealSearch" . "search/search.js")
- notes ("RevealNotes" . "notes/notes.js")
- math ("RevealMath" . "math/math.js")
- zoom ("RevealZoom" . "zoom/zoom.js")))
- (plugin-info (seq-filter 'identity
- (seq-map (lambda (p)
- (plist-get available-plugins p))
- plugins))))
- (if (not (null plugin-info))
- (cons
- ;; Plugin initialization script
- (let ((root-path (file-name-as-directory (plist-get info :reveal-root))))
- (mapconcat
- (lambda (p)
- (format "\n" root-path (cdr p)))
- plugin-info
- ""))
- ;; Reveal initialization for plugins
- (format "plugins: [%s]"
- (mapconcat #'car plugin-info ",")))
- ;; No available plugin info found. Perhaps wrong plugin
- ;; names are given
- (cons nil nil)))
- ;; No plugins, return empty string
- (cons nil nil))))
+ (if (not (null plugins))
+ ;; Generate plugin scripts
+ (let* ((plugins (mapcar
+ (lambda (p)
+ ;; Convert legacy
+ ;; plugin names into
+ ;; reveal.js 4.0 ones
+ (cond
+ ((eq p 'highlight) 'RevealHighlight)
+ ((eq p 'markdown) 'RevealMarkdown)
+ ((eq p 'search) 'RevealSearch)
+ ((eq p 'notes) 'RevealNotes)
+ ((eq p 'math) 'RevealMath)
+ ((eq p 'zoom) 'RevealZoom)
+ (t p)))
+ plugins))
+ (available-plugins
+ (append '((RevealHighlight . "%splugin/highlight/highlight.js")
+ (RevealMarkdown . "%splugin/markdown/markdown.js")
+ (RevealSearch . "%splugin/search/search.js")
+ (RevealNotes . "%splugin/notes/notes.js")
+ (RevealMath . "%splugin/math/math.js")
+ (RevealZoom . "%splugin/zoom/zoom.js"))
+ org-reveal-external-plugins))
+ (plugin-js (seq-filter 'identity ;; Filter out nil
+ (mapcar (lambda (p)
+ (cdr (assoc p available-plugins)))
+ plugins))))
+ (if (not (null plugin-js))
+ (cons
+ ;; Plugin initialization script
+ (let ((root-path (file-name-as-directory (plist-get info :reveal-root))))
+ (mapconcat
+ (lambda (p)
+ (format "\n"
+ (format p root-path)))
+ plugin-js
+ ""))
+ ;; Reveal initialization for plugins
+ (format "plugins: [%s]"
+ (mapconcat 'symbol-name plugins ", ")))
+ ;; No available plugin info found. Perhaps wrong plugin
+ ;; names are given
+ (cons nil nil)))
+ ;; No plugins, return empty string
+ (cons nil nil)))
(defun org-reveal-toc (depth info)
"Build a slide of table of contents."
(let ((toc (org-html-toc depth info)))