ox-html: Fix stack overflow in regexp matching
[org-mode.git] / lisp / ox-jsinfo.el
blob34f24eac9641306f251bb0af25e09e2d39ed7c4a
1 ;;; ox-jsinfo.el --- Org HTML Export Extension for org-info.js
3 ;; Copyright (C) 2004-2013 Free Software Foundation, Inc.
5 ;; Author: Carsten Dominik <carsten at orgmode dot org>
6 ;; Keywords: outlines, hypermedia, calendar, wp
7 ;; Homepage: http://orgmode.org
8 ;;
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;;; Commentary:
27 ;; This file implements the support for Sebastian Rose's JavaScript
28 ;; org-info.js to display an Org mode file exported to HTML in an
29 ;; Info-like way, or using folding similar to the outline structure of
30 ;; Org mode itself.
32 ;; Documentation for using this module is in the Org manual. The
33 ;; script itself is documented by Sebastian Rose in a file distributed
34 ;; with the script. FIXME: Accurate pointers!
36 ;;; Code:
38 (eval-when-compile (require 'cl))
39 (require 'ox-html)
41 (add-to-list 'org-export-filter-options-functions 'org-infojs-install-script)
44 (defgroup org-export-infojs nil
45 "Options specific for using org-info.js in HTML export."
46 :tag "Org Export HTML INFOJS"
47 :group 'org-export-html)
49 (defcustom org-export-html-use-infojs 'when-configured
50 "Non-nil when Sebastian Rose's Java Script org-info.js should be active.
51 This option can be nil or t to never or always use the script.
52 It can also be the symbol `when-configured', meaning that the
53 script will be linked into the export file if and only if there
54 is a \"#+INFOJS_OPT:\" line in the buffer. See also the variable
55 `org-infojs-options'."
56 :group 'org-export-html
57 :group 'org-export-infojs
58 :type '(choice
59 (const :tag "Never" nil)
60 (const :tag "When configured in buffer" when-configured)
61 (const :tag "Always" t)))
63 (defconst org-infojs-opts-table
64 '((path PATH "http://orgmode.org/org-info.js")
65 (view VIEW "info")
66 (toc TOC :with-toc)
67 (ftoc FIXED_TOC "0")
68 (tdepth TOC_DEPTH "max")
69 (sdepth SECTION_DEPTH "max")
70 (mouse MOUSE_HINT "underline")
71 (buttons VIEW_BUTTONS "0")
72 (ltoc LOCAL_TOC "1")
73 (up LINK_UP :html-link-up)
74 (home LINK_HOME :html-link-home))
75 "JavaScript options, long form for script, default values.")
77 (defvar org-infojs-options)
78 (when (and (boundp 'org-infojs-options)
79 (assq 'runs org-infojs-options))
80 (setq org-infojs-options (delq (assq 'runs org-infojs-options)
81 org-infojs-options)))
83 (defcustom org-infojs-options
84 (mapcar (lambda (x) (cons (car x) (nth 2 x))) org-infojs-opts-table)
85 "Options settings for the INFOJS JavaScript.
86 Each of the options must have an entry in `org-export-html/infojs-opts-table'.
87 The value can either be a string that will be passed to the script, or
88 a property. This property is then assumed to be a property that is defined
89 by the Export/Publishing setup of Org.
90 The `sdepth' and `tdepth' parameters can also be set to \"max\", which
91 means to use the maximum value consistent with other options."
92 :group 'org-export-infojs
93 :type
94 `(set :greedy t :inline t
95 ,@(mapcar
96 (lambda (x)
97 (list 'cons (list 'const (car x))
98 '(choice
99 (symbol :tag "Publishing/Export property")
100 (string :tag "Value"))))
101 org-infojs-opts-table)))
103 (defcustom org-infojs-template
104 "<script type=\"text/javascript\" src=\"%SCRIPT_PATH\">
107 * @source: %SCRIPT_PATH
109 * @licstart The following is the entire license notice for the
110 * JavaScript code in %SCRIPT_PATH.
112 * Copyright (C) 2012-2013 Sebastian Rose
115 * The JavaScript code in this tag is free software: you can
116 * redistribute it and/or modify it under the terms of the GNU
117 * General Public License (GNU GPL) as published by the Free Software
118 * Foundation, either version 3 of the License, or (at your option)
119 * any later version. The code is distributed WITHOUT ANY WARRANTY;
120 * without even the implied warranty of MERCHANTABILITY or FITNESS
121 * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
123 * As additional permission under GNU GPL version 3 section 7, you
124 * may distribute non-source (e.g., minimized or compacted) forms of
125 * that code without the copy of the GNU GPL normally required by
126 * section 4, provided you include this license notice and a URL
127 * through which recipients can access the Corresponding Source.
129 * @licend The above is the entire license notice
130 * for the JavaScript code in %SCRIPT_PATH.
133 </script>
135 <script type=\"text/javascript\">
138 @licstart The following is the entire license notice for the
139 JavaScript code in this tag.
141 Copyright (C) 2012-2013 Free Software Foundation, Inc.
143 The JavaScript code in this tag is free software: you can
144 redistribute it and/or modify it under the terms of the GNU
145 General Public License (GNU GPL) as published by the Free Software
146 Foundation, either version 3 of the License, or (at your option)
147 any later version. The code is distributed WITHOUT ANY WARRANTY;
148 without even the implied warranty of MERCHANTABILITY or FITNESS
149 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
151 As additional permission under GNU GPL version 3 section 7, you
152 may distribute non-source (e.g., minimized or compacted) forms of
153 that code without the copy of the GNU GPL normally required by
154 section 4, provided you include this license notice and a URL
155 through which recipients can access the Corresponding Source.
158 @licend The above is the entire license notice
159 for the JavaScript code in this tag.
162 <!--/*--><![CDATA[/*><!--*/
163 %MANAGER_OPTIONS
164 org_html_manager.setup(); // activate after the parameters are set
165 /*]]>*///-->
166 </script>"
167 "The template for the export style additions when org-info.js is used.
168 Option settings will replace the %MANAGER-OPTIONS cookie."
169 :group 'org-infojs
170 :type 'string)
172 (defun org-infojs-install-script (exp-plist backend)
173 "Install script in export options when appropriate.
174 EXP-PLIST is a plist containing export options. BACKEND is the
175 export back-end currently used."
176 (unless (or (not (org-export-derived-backend-p backend 'html))
177 (not org-export-html-use-infojs)
178 (and (eq org-export-html-use-infojs 'when-configured)
179 (or (not (plist-get exp-plist :infojs-opt))
180 (string-match "\\<view:nil\\>"
181 (plist-get exp-plist :infojs-opt)))))
182 (let* ((template org-infojs-template)
183 (ptoc (plist-get exp-plist :with-toc))
184 (hlevels (plist-get exp-plist :headline-levels))
185 (sdepth hlevels)
186 (tdepth (if (integerp ptoc) (min ptoc hlevels) hlevels))
187 (options (plist-get exp-plist :infojs-opt))
188 (table org-infojs-opts-table)
189 style)
190 (dolist (entry table)
191 (let* ((opt (car entry))
192 (var (nth 1 entry))
193 ;; Compute default values for script option OPT from
194 ;; `org-infojs-options' variable.
195 (default
196 (let ((default (cdr (assq opt org-infojs-options))))
197 (if (and (symbolp default) (not (memq default '(t nil))))
198 (plist-get exp-plist default)
199 default)))
200 ;; Value set through INFOJS_OPT keyword has precedence
201 ;; over the default one.
202 (val (if (and options
203 (string-match (format "\\<%s:\\(\\S-+\\)" opt)
204 options))
205 (match-string 1 options)
206 default)))
207 (case opt
208 (path (setq template
209 (replace-regexp-in-string
210 "%SCRIPT_PATH" val template t t)))
211 (sdepth (when (integerp (read val))
212 (setq sdepth (min (read val) sdepth))))
213 (tdepth (when (integerp (read val))
214 (setq tdepth (min (read val) tdepth))))
215 (otherwise (setq val
216 (cond
217 ((or (eq val t) (equal val "t")) "1")
218 ((or (eq val nil) (equal val "nil")) "0")
219 ((stringp val) val)
220 (t (format "%s" val))))
221 (push (cons var val) style)))))
222 ;; Now we set the depth of the *generated* TOC to SDEPTH,
223 ;; because the toc will actually determine the splitting. How
224 ;; much of the toc will actually be displayed is governed by the
225 ;; TDEPTH option.
226 (setq exp-plist (plist-put exp-plist :with-toc sdepth))
227 ;; The table of contents should not show more sections than we
228 ;; generate.
229 (setq tdepth (min tdepth sdepth))
230 (push (cons "TOC_DEPTH" tdepth) style)
231 ;; Build style string.
232 (setq style (mapconcat
233 (lambda (x) (format "org_html_manager.set(\"%s\", \"%s\");"
234 (car x)
235 (cdr x)))
236 style "\n"))
237 (when (and style (> (length style) 0))
238 (and (string-match "%MANAGER_OPTIONS" template)
239 (setq style (replace-match style t t template))
240 (setq exp-plist
241 (plist-put
242 exp-plist :html-style-extra
243 (concat (or (plist-get exp-plist :html-style-extra) "")
244 "\n"
245 style)))))
246 ;; This script absolutely needs the table of contents, so we
247 ;; change that setting.
248 (unless (plist-get exp-plist :with-toc)
249 (setq exp-plist (plist-put exp-plist :with-toc t)))
250 ;; Return the modified property list.
251 exp-plist)))
255 (provide 'ox-infojs)
256 (provide 'ox-jsinfo)
258 ;; Local variables:
259 ;; generated-autoload-file: "org-loaddefs.el"
260 ;; End:
262 ;;; ox-jsinfo.el ends here