| 1 | ;;; org-jsinfo.el --- Support for org-info.js Javascript in Org HTML export |
| 2 | |
| 3 | ;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Author: Carsten Dominik <carsten at orgmode dot org> |
| 6 | ;; Keywords: outlines, hypermedia, calendar, wp |
| 7 | ;; Homepage: http://orgmode.org |
| 8 | ;; Version: 6.13a |
| 9 | ;; |
| 10 | ;; This file is part of GNU Emacs. |
| 11 | ;; |
| 12 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
| 13 | ;; it under the terms of the GNU General Public License as published by |
| 14 | ;; the Free Software Foundation, either version 3 of the License, or |
| 15 | ;; (at your option) any later version. |
| 16 | |
| 17 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | ;; GNU General Public License for more details. |
| 21 | |
| 22 | ;; You should have received a copy of the GNU General Public License |
| 23 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
| 24 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 25 | ;; |
| 26 | ;;; Commentary: |
| 27 | |
| 28 | ;; This file implements the support for Sebastian Rose's Javascript |
| 29 | ;; org-info.js to display an org-mode file exported to HTML in an |
| 30 | ;; Info-like way, or using folding similar to the outline structure |
| 31 | ;; org org-mode itself. |
| 32 | |
| 33 | ;; Documentation for using this module is in the Org manual. The script |
| 34 | ;; itself is documented by Sebastian Rose in a file distributed with |
| 35 | ;; the script. FIXME: Accurate pointers! |
| 36 | |
| 37 | ;; Org-mode loads this module by default - if this is not what you want, |
| 38 | ;; configure the variable `org-modules'. |
| 39 | |
| 40 | ;;; Code: |
| 41 | |
| 42 | (require 'org-exp) |
| 43 | |
| 44 | (add-to-list 'org-export-inbuffer-options-extra '("INFOJS_OPT" :infojs-opt)) |
| 45 | (add-hook 'org-export-options-filters 'org-infojs-handle-options) |
| 46 | |
| 47 | (defgroup org-infojs nil |
| 48 | "Options specific for using org-info.js in HTML export of Org-mode files." |
| 49 | :tag "Org Export HTML INFOJS" |
| 50 | :group 'org-export-html) |
| 51 | |
| 52 | (defcustom org-export-html-use-infojs 'when-configured |
| 53 | "Should Sebasian Rose's Java Script org-info.js be linked into HTML files? |
| 54 | This option can be nil or t to never or always use the script. It can |
| 55 | also be the symbol `when-configured', meaning that the script will be |
| 56 | linked into the export file if and only if there is a \"#+INFOJS_OPT:\" |
| 57 | line in the buffer. See also the variable `org-infojs-options'." |
| 58 | :group 'org-export-html |
| 59 | :group 'org-infojs |
| 60 | :type '(choice |
| 61 | (const :tag "Never" nil) |
| 62 | (const :tag "When configured in buffer" when-configured) |
| 63 | (const :tag "Always" t))) |
| 64 | |
| 65 | (defconst org-infojs-opts-table |
| 66 | '((path PATH "http://orgmode.org/org-info.js") |
| 67 | (view VIEW "info") |
| 68 | (toc TOC :table-of-contents) |
| 69 | (ftoc FIXED_TOC "0") |
| 70 | (tdepth TOC_DEPTH "max") |
| 71 | (sdepth SECTION_DEPTH "max") |
| 72 | (mouse MOUSE_HINT "underline") |
| 73 | (buttons VIEW_BUTTONS "0") |
| 74 | (ltoc LOCAL_TOC "1") |
| 75 | (up LINK_UP :link-up) |
| 76 | (home LINK_HOME :link-home)) |
| 77 | "JavaScript options, long form for script, default values.") |
| 78 | |
| 79 | (defvar org-infojs-options) |
| 80 | (when (and (boundp 'org-infojs-options) |
| 81 | (assq 'runs org-infojs-options)) |
| 82 | (setq org-infojs-options (delq (assq 'runs org-infojs-options) |
| 83 | org-infojs-options))) |
| 84 | |
| 85 | (defcustom org-infojs-options |
| 86 | (mapcar (lambda (x) (cons (car x) (nth 2 x))) |
| 87 | org-infojs-opts-table) |
| 88 | "Options settings for the INFOJS Javascript. |
| 89 | Each of the options must have an entry in `org-export-html/infojs-opts-table'. |
| 90 | The value can either be a string that will be passed to the script, or |
| 91 | a property. This property is then assumed to be a property that is defined |
| 92 | by the Export/Publishing setup of Org. |
| 93 | The `sdepth' and `tdepth' parameters can also be set to \"max\", which |
| 94 | means to use the maximum value consistent with other options." |
| 95 | :group 'org-infojs |
| 96 | :type |
| 97 | `(set :greedy t :inline t |
| 98 | ,@(mapcar |
| 99 | (lambda (x) |
| 100 | (list 'cons (list 'const (car x)) |
| 101 | '(choice |
| 102 | (symbol :tag "Publishing/Export property") |
| 103 | (string :tag "Value")))) |
| 104 | org-infojs-opts-table))) |
| 105 | |
| 106 | (defcustom org-infojs-template |
| 107 | "<script type=\"text/javascript\" src=\"%SCRIPT_PATH\"></script> |
| 108 | <script type=\"text/javascript\" > |
| 109 | /* <![CDATA[ */ |
| 110 | %MANAGER_OPTIONS |
| 111 | org_html_manager.setup(); // activate after the parameterd are set |
| 112 | /* ]]> */ |
| 113 | </script>" |
| 114 | "The template for the export style additions when org-info.js is used. |
| 115 | Option settings will replace the %MANAGER-OPTIONS cookie." |
| 116 | :group 'org-infojs |
| 117 | :type 'string) |
| 118 | |
| 119 | (defun org-infojs-handle-options (exp-plist) |
| 120 | "Analyze JavaScript options in INFO-PLIST and modify EXP-PLIST accordingly." |
| 121 | (if (or (not org-export-html-use-infojs) |
| 122 | (and (eq org-export-html-use-infojs 'when-configured) |
| 123 | (or (not (plist-get exp-plist :infojs-opt)) |
| 124 | (string-match "\\<view:nil\\>" |
| 125 | (plist-get exp-plist :infojs-opt))))) |
| 126 | ;; We do not want to use the script |
| 127 | exp-plist |
| 128 | ;; We do want to use the script, set it up |
| 129 | (let ((template org-infojs-template) |
| 130 | (ptoc (plist-get exp-plist :table-of-contents)) |
| 131 | (hlevels (plist-get exp-plist :headline-levels)) |
| 132 | tdepth sdepth p1 s p v a1 tmp e opt var val table default) |
| 133 | (setq sdepth hlevels |
| 134 | tdepth hlevels) |
| 135 | (if (integerp ptoc) (setq tdepth (min ptoc tdepth))) |
| 136 | (setq v (plist-get exp-plist :infojs-opt) |
| 137 | table org-infojs-opts-table) |
| 138 | (while (setq e (pop table)) |
| 139 | (setq opt (car e) var (nth 1 e) |
| 140 | default (cdr (assoc opt org-infojs-options))) |
| 141 | (and (symbolp default) (not (memq default '(t nil))) |
| 142 | (setq default (plist-get exp-plist default))) |
| 143 | (if (string-match (format " %s:\\(\\S-+\\)" opt) v) |
| 144 | (setq val (match-string 1 v)) |
| 145 | (setq val default)) |
| 146 | (cond |
| 147 | ((eq opt 'path) |
| 148 | (and (string-match "%SCRIPT_PATH" template) |
| 149 | (setq template (replace-match val t t template)))) |
| 150 | ((eq opt 'sdepth) |
| 151 | (if (integerp (read val)) |
| 152 | (setq sdepth (min (read val) hlevels)))) |
| 153 | ((eq opt 'tdepth) |
| 154 | (if (integerp (read val)) |
| 155 | (setq tdepth (min (read val) hlevels)))) |
| 156 | (t |
| 157 | (setq val |
| 158 | (cond |
| 159 | ((or (eq val t) (equal val "t")) "1") |
| 160 | ((or (eq val nil) (equal val "nil")) "0") |
| 161 | ((stringp val) val) |
| 162 | (t (format "%s" val)))) |
| 163 | (push (cons var val) s)))) |
| 164 | |
| 165 | ;; Now we set the depth of the *generated* TOC to SDEPTH, because the |
| 166 | ;; toc will actually determine the splitting. How much of the toc will |
| 167 | ;; actually be displayed is governed by the TDEPTH option. |
| 168 | (setq exp-plist (plist-put exp-plist :table-of-contents sdepth)) |
| 169 | |
| 170 | ;; The table of contents should ot show more sections then we generate |
| 171 | (setq tdepth (min tdepth sdepth)) |
| 172 | (push (cons "TOC_DEPTH" tdepth) s) |
| 173 | |
| 174 | (setq s (mapconcat |
| 175 | (lambda (x) (format "org_html_manager.set(\"%s\", \"%s\");" |
| 176 | (car x) (cdr x))) |
| 177 | s "\n")) |
| 178 | (when (and s (> (length s) 0)) |
| 179 | (and (string-match "%MANAGER_OPTIONS" template) |
| 180 | (setq s (replace-match s t t template)) |
| 181 | (setq exp-plist |
| 182 | (plist-put |
| 183 | exp-plist :style-extra |
| 184 | (concat (or (plist-get exp-plist :style-extra) "") "\n" s))))) |
| 185 | ;; This script absolutely needs the table of contents, to we change that |
| 186 | ;; setting |
| 187 | (if (not (plist-get exp-plist :table-of-contents)) |
| 188 | (setq exp-plist (plist-put exp-plist :table-of-contents t))) |
| 189 | ;; Return the modified property list |
| 190 | exp-plist))) |
| 191 | |
| 192 | (defun org-infojs-options-inbuffer-template () |
| 193 | (format "#+INFOJS_OPT: view:%s toc:%s ltoc:%s mouse:%s buttons:%s path:%s" |
| 194 | (if (eq t org-export-html-use-infojs) (cdr (assoc 'view org-infojs-options)) nil) |
| 195 | (let ((a (cdr (assoc 'toc org-infojs-options)))) |
| 196 | (cond ((memq a '(nil t)) a) |
| 197 | (t (plist-get (org-infile-export-plist) :table-of-contents)))) |
| 198 | (if (equal (cdr (assoc 'ltoc org-infojs-options)) "1") t nil) |
| 199 | (cdr (assoc 'mouse org-infojs-options)) |
| 200 | (cdr (assoc 'buttons org-infojs-options)) |
| 201 | (cdr (assoc 'path org-infojs-options)))) |
| 202 | |
| 203 | (provide 'org-infojs) |
| 204 | (provide 'org-jsinfo) |
| 205 | |
| 206 | ;; arch-tag: c71d1d85-3337-4817-a066-725e74ac9eac |
| 207 | |
| 208 | ;;; org-jsinfo.el ends here |