diff --git a/Readme.org b/Readme.org index 3ea3230..125579a 100644 --- a/Readme.org +++ b/Readme.org @@ -591,6 +591,9 @@ plugin specifications of the same format as in ,#+REVEAL_EXTERNAL_PLUGINS: (plugin3 "ex/plugin3-1.js" "ex/plugin3-2.js") #+end_src +At most one ~%s~ can be inserted into each plugin string, which will +be replaced by Reveal.js root path. + ** Highlight Source Code There are two ways to highlight source code. @@ -900,8 +903,9 @@ To disable the automatic TOC, add =toc:nil= to =#+OPTIONS= ** Custom JS To pass custom JS code to ~Reveal.initialize~, state the code by - ~#+REVEAL_EXTRA_INITIAL_JS~ (multiple statements are concatenated) or by - custom variable ~org-reveal-extra-initial-js~. + ~#+REVEAL_EXTRA_INITIAL_JS~ (multiple statements are concatenated) + or by custom variable ~org-reveal-extra-initial-js~. The first + appearance of ~%s~ in the script will be replaced by Reveal.js root path. If you want to add extra code outside of the ~Reveal.initialize~ block, then ~#+REVEAL_EXTRA_SCRIPT~ can be used. The code will be diff --git a/ox-reveal.el b/ox-reveal.el index 776a17e..045df68 100644 --- a/ox-reveal.el +++ b/ox-reveal.el @@ -616,10 +616,12 @@ holding contextual information." (concat root-path file-path-0) (concat root-path file-path-1))) +(defun org-reveal-root-path (info) + (file-name-as-directory (plist-get info :reveal-root))) (defun org-reveal-stylesheets (info) "Return the HTML contents for declaring reveal stylesheets using custom variable `org-reveal-root'." - (let* ((root-path (file-name-as-directory (plist-get info :reveal-root))) + (let* ((root-path (org-reveal-root-path info)) (version (org-reveal--get-reveal-js-version info)) (reveal-css (org-reveal--choose-path root-path version "dist/reveal.css" "css/reveal.css")) (theme (plist-get info :reveal-theme)) @@ -714,11 +716,11 @@ dependencies: [ (append ;; Global setting (cl-loop for (key . value) in org-reveal-external-plugins - collect (format value root-path )) + collect (org-reveal--replace-first-%s value root-path )) ;; Local settings (let ((local-plugins (plist-get info :reveal-external-plugins))) (and local-plugins - (list (format local-plugins root-path)))))) + (list (org-reveal--replace-first-%s local-plugins root-path)))))) (all-plugins (if external-plugins (append external-plugins builtin-codes) builtin-codes)) (extra-codes (plist-get info :reveal-extra-js)) @@ -729,7 +731,7 @@ dependencies: [ (defun org-reveal-scripts (info) "Return the necessary scripts for initializing reveal.js using custom variable `org-reveal-root'." - (let* ((root-path (file-name-as-directory (plist-get info :reveal-root))) + (let* ((root-path (org-reveal-root-path info)) (version (org-reveal--get-reveal-js-version info)) (reveal-js (org-reveal--choose-path root-path version "dist/reveal.js" "js/reveal.js")) ;; Local files @@ -806,7 +808,7 @@ Reveal.initialize({ (list reveal-4-plugin-statement init-options multiplex-statement - (format extra-initial-js-statement root-path) + (org-reveal--replace-first-%s extra-initial-js-statement root-path) legacy-dependency-statement)) ",\n") ;; Extra initialization scripts @@ -822,6 +824,40 @@ Reveal.initialize({ (and obj (cons obj (org-reveal--read-sexps-from-string (substring s remain-index))))))))) +(defun org-reveal--search-first-%s-or-%% (s start) + "Search the first appearance of '%s' or '%%' in fmt from + start. Return the location (of the '%') if found, nil + otherwise" + (when (< start (length s)) + (if (eq (aref s start) ?%) + (let ((next (1+ start))) + (when (< next (length s)) + ;; Only when % is not the last character + (let ((next-c (aref s next))) + (if (or (eq next-c ?s) (eq next-c ?%)) + ;; ^ Found the first %s or %%. Return the index + start + ;; Not a %s or %%. Keep searching + (org-reveal--search-first-%s-or-%% s (1+ next)))))) + ;; Not a %. Keep search + (org-reveal--search-first-%s-or-%% s (1+ start))))) + +(defun org-reveal--replace-first-%s (fmt str) + (let ((idx (org-reveal--search-first-%s-or-%% fmt 0))) + (if idx + (concat + ;; Pre + (substring fmt 0 idx) + ;; To be replaced + (if (eq ?% (aref fmt (1+ idx))) + "%" ;; %% -> % + str ;; %s -> str + ) + ;; Post + (substring fmt (+ 2 idx) nil)) + ;; nil, no %s or %% found + fmt))) + (defun org-reveal-plugin-scripts-4 (plugins info) "Return scripts for initializing reveal.js 4.x builtin scripts" ;; Return a tuple (represented as a list), the first value is a list of script @@ -863,7 +899,7 @@ Reveal.initialize({ (if (not (null plugin-js)) (cons ;; First value of the tuple, a list of scripts HTML tags - (let ((root-path (file-name-as-directory (plist-get info :reveal-root)))) + (let ((root-path (org-reveal-root-path info))) (mapconcat (lambda (p) ;; when it is a list, create a script tag for every entry @@ -871,12 +907,12 @@ Reveal.initialize({ ((listp p) (mapconcat (lambda (pi) (format "\n" - (format pi root-path))) + (org-reveal--replace-first-%s pi root-path))) p "")) ;; when it is a single string, create a single script tag (t (format "\n" - (format p root-path))))) + (org-reveal--replace-first-%s p root-path))))) plugin-js "")) ;; Second value of the tuple, a list of Reveal plugin