Commit | Line | Data |
---|---|---|
271672fa BG |
1 | ;;; ox-html.el --- HTML Back-End for Org Export Engine |
2 | ||
ba318903 | 3 | ;; Copyright (C) 2011-2014 Free Software Foundation, Inc. |
271672fa BG |
4 | |
5 | ;; Author: Carsten Dominik <carsten at orgmode dot org> | |
6 | ;; Jambunathan K <kjambunathan at gmail dot com> | |
7 | ;; Keywords: outlines, hypermedia, calendar, wp | |
8 | ||
439d6b1c GM |
9 | ;; This file is part of GNU Emacs. |
10 | ||
271672fa BG |
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. | |
15 | ||
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. | |
20 | ||
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 | ||
24 | ;;; Commentary: | |
25 | ||
26 | ;; This library implements a HTML back-end for Org generic exporter. | |
27 | ;; See Org manual for more information. | |
28 | ||
29 | ;;; Code: | |
30 | ||
31 | ;;; Dependencies | |
32 | ||
33 | (require 'ox) | |
34 | (require 'ox-publish) | |
35 | (require 'format-spec) | |
36 | (eval-when-compile (require 'cl) (require 'table nil 'noerror)) | |
37 | ||
38 | \f | |
39 | ;;; Function Declarations | |
40 | ||
41 | (declare-function org-id-find-id-file "org-id" (id)) | |
42 | (declare-function htmlize-region "ext:htmlize" (beg end)) | |
43 | (declare-function org-pop-to-buffer-same-window | |
44 | "org-compat" (&optional buffer-or-name norecord label)) | |
45 | (declare-function mm-url-decode-entities "mm-url" ()) | |
46 | ||
47 | ;;; Define Back-End | |
48 | ||
49 | (org-export-define-backend 'html | |
50 | '((bold . org-html-bold) | |
51 | (center-block . org-html-center-block) | |
52 | (clock . org-html-clock) | |
53 | (code . org-html-code) | |
54 | (drawer . org-html-drawer) | |
55 | (dynamic-block . org-html-dynamic-block) | |
56 | (entity . org-html-entity) | |
57 | (example-block . org-html-example-block) | |
58 | (export-block . org-html-export-block) | |
59 | (export-snippet . org-html-export-snippet) | |
60 | (fixed-width . org-html-fixed-width) | |
61 | (footnote-definition . org-html-footnote-definition) | |
62 | (footnote-reference . org-html-footnote-reference) | |
63 | (headline . org-html-headline) | |
64 | (horizontal-rule . org-html-horizontal-rule) | |
65 | (inline-src-block . org-html-inline-src-block) | |
66 | (inlinetask . org-html-inlinetask) | |
67 | (inner-template . org-html-inner-template) | |
68 | (italic . org-html-italic) | |
69 | (item . org-html-item) | |
70 | (keyword . org-html-keyword) | |
71 | (latex-environment . org-html-latex-environment) | |
72 | (latex-fragment . org-html-latex-fragment) | |
73 | (line-break . org-html-line-break) | |
74 | (link . org-html-link) | |
75 | (paragraph . org-html-paragraph) | |
76 | (plain-list . org-html-plain-list) | |
77 | (plain-text . org-html-plain-text) | |
78 | (planning . org-html-planning) | |
79 | (property-drawer . org-html-property-drawer) | |
80 | (quote-block . org-html-quote-block) | |
81 | (quote-section . org-html-quote-section) | |
82 | (radio-target . org-html-radio-target) | |
83 | (section . org-html-section) | |
84 | (special-block . org-html-special-block) | |
85 | (src-block . org-html-src-block) | |
86 | (statistics-cookie . org-html-statistics-cookie) | |
87 | (strike-through . org-html-strike-through) | |
88 | (subscript . org-html-subscript) | |
89 | (superscript . org-html-superscript) | |
90 | (table . org-html-table) | |
91 | (table-cell . org-html-table-cell) | |
92 | (table-row . org-html-table-row) | |
93 | (target . org-html-target) | |
94 | (template . org-html-template) | |
95 | (timestamp . org-html-timestamp) | |
96 | (underline . org-html-underline) | |
97 | (verbatim . org-html-verbatim) | |
98 | (verse-block . org-html-verse-block)) | |
99 | :export-block "HTML" | |
100 | :filters-alist '((:filter-options . org-html-infojs-install-script) | |
101 | (:filter-final-output . org-html-final-function)) | |
102 | :menu-entry | |
103 | '(?h "Export to HTML" | |
104 | ((?H "As HTML buffer" org-html-export-as-html) | |
105 | (?h "As HTML file" org-html-export-to-html) | |
106 | (?o "As HTML file and open" | |
107 | (lambda (a s v b) | |
108 | (if a (org-html-export-to-html t s v b) | |
109 | (org-open-file (org-html-export-to-html nil s v b))))))) | |
110 | :options-alist | |
111 | '((:html-extension nil nil org-html-extension) | |
112 | (:html-link-org-as-html nil nil org-html-link-org-files-as-html) | |
113 | (:html-doctype "HTML_DOCTYPE" nil org-html-doctype) | |
114 | (:html-container "HTML_CONTAINER" nil org-html-container-element) | |
115 | (:html-html5-fancy nil "html5-fancy" org-html-html5-fancy) | |
116 | (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) | |
117 | (:html-link-home "HTML_LINK_HOME" nil org-html-link-home) | |
118 | (:html-link-up "HTML_LINK_UP" nil org-html-link-up) | |
119 | (:html-mathjax "HTML_MATHJAX" nil "" space) | |
120 | (:html-postamble nil "html-postamble" org-html-postamble) | |
121 | (:html-preamble nil "html-preamble" org-html-preamble) | |
122 | (:html-head "HTML_HEAD" nil org-html-head newline) | |
123 | (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline) | |
124 | (:html-head-include-default-style nil "html-style" org-html-head-include-default-style) | |
125 | (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts) | |
126 | (:html-table-attributes nil nil org-html-table-default-attributes) | |
127 | (:html-table-row-tags nil nil org-html-table-row-tags) | |
128 | (:html-xml-declaration nil nil org-html-xml-declaration) | |
129 | (:html-inline-images nil nil org-html-inline-images) | |
130 | (:infojs-opt "INFOJS_OPT" nil nil) | |
131 | ;; Redefine regular options. | |
132 | (:creator "CREATOR" nil org-html-creator-string) | |
73d3db82 BG |
133 | (:with-latex nil "tex" org-html-with-latex) |
134 | ;; Retrieve LaTeX header for fragments. | |
135 | (:latex-header "LATEX_HEADER" nil nil newline))) | |
271672fa BG |
136 | |
137 | \f | |
138 | ;;; Internal Variables | |
139 | ||
140 | (defvar org-html-format-table-no-css) | |
141 | (defvar htmlize-buffer-places) ; from htmlize.el | |
142 | ||
143 | (defvar org-html--pre/postamble-class "status" | |
144 | "CSS class used for pre/postamble") | |
145 | ||
146 | (defconst org-html-doctype-alist | |
147 | '(("html4-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" | |
148 | \"http://www.w3.org/TR/html4/strict.dtd\">") | |
149 | ("html4-transitional" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" | |
150 | \"http://www.w3.org/TR/html4/loose.dtd\">") | |
151 | ("html4-frameset" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" | |
152 | \"http://www.w3.org/TR/html4/frameset.dtd\">") | |
153 | ||
154 | ("xhtml-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" | |
155 | \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">") | |
156 | ("xhtml-transitional" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" | |
157 | \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">") | |
d1389828 | 158 | ("xhtml-frameset" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" |
271672fa BG |
159 | \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">") |
160 | ("xhtml-11" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" | |
161 | \"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd\">") | |
162 | ||
163 | ("html5" . "<!DOCTYPE html>") | |
164 | ("xhtml5" . "<!DOCTYPE html>")) | |
165 | "An alist mapping (x)html flavors to specific doctypes.") | |
166 | ||
167 | (defconst org-html-html5-elements | |
168 | '("article" "aside" "audio" "canvas" "details" "figcaption" | |
169 | "figure" "footer" "header" "menu" "meter" "nav" "output" | |
170 | "progress" "section" "video") | |
171 | "New elements in html5. | |
172 | ||
30cb51f1 BG |
173 | For blocks that should contain headlines, use the HTML_CONTAINER |
174 | property on the headline itself.") | |
271672fa BG |
175 | |
176 | (defconst org-html-special-string-regexps | |
177 | '(("\\\\-" . "­") ; shy | |
178 | ("---\\([^-]\\)" . "—\\1") ; mdash | |
179 | ("--\\([^-]\\)" . "–\\1") ; ndash | |
180 | ("\\.\\.\\." . "…")) ; hellip | |
181 | "Regular expressions for special string conversion.") | |
182 | ||
183 | (defconst org-html-scripts | |
184 | "<script type=\"text/javascript\"> | |
185 | /* | |
186 | @licstart The following is the entire license notice for the | |
187 | JavaScript code in this tag. | |
188 | ||
30cb51f1 | 189 | Copyright (C) 2012-2013 Free Software Foundation, Inc. |
271672fa BG |
190 | |
191 | The JavaScript code in this tag is free software: you can | |
192 | redistribute it and/or modify it under the terms of the GNU | |
193 | General Public License (GNU GPL) as published by the Free Software | |
194 | Foundation, either version 3 of the License, or (at your option) | |
195 | any later version. The code is distributed WITHOUT ANY WARRANTY; | |
196 | without even the implied warranty of MERCHANTABILITY or FITNESS | |
197 | FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
198 | ||
199 | As additional permission under GNU GPL version 3 section 7, you | |
200 | may distribute non-source (e.g., minimized or compacted) forms of | |
201 | that code without the copy of the GNU GPL normally required by | |
202 | section 4, provided you include this license notice and a URL | |
203 | through which recipients can access the Corresponding Source. | |
204 | ||
205 | ||
206 | @licend The above is the entire license notice | |
207 | for the JavaScript code in this tag. | |
208 | */ | |
209 | <!--/*--><![CDATA[/*><!--*/ | |
210 | function CodeHighlightOn(elem, id) | |
211 | { | |
212 | var target = document.getElementById(id); | |
213 | if(null != target) { | |
214 | elem.cacheClassElem = elem.className; | |
215 | elem.cacheClassTarget = target.className; | |
216 | target.className = \"code-highlighted\"; | |
217 | elem.className = \"code-highlighted\"; | |
218 | } | |
219 | } | |
220 | function CodeHighlightOff(elem, id) | |
221 | { | |
222 | var target = document.getElementById(id); | |
223 | if(elem.cacheClassElem) | |
224 | elem.className = elem.cacheClassElem; | |
225 | if(elem.cacheClassTarget) | |
226 | target.className = elem.cacheClassTarget; | |
227 | } | |
228 | /*]]>*///--> | |
229 | </script>" | |
230 | "Basic JavaScript that is needed by HTML files produced by Org mode.") | |
231 | ||
232 | (defconst org-html-style-default | |
233 | "<style type=\"text/css\"> | |
234 | <!--/*--><![CDATA[/*><!--*/ | |
235 | .title { text-align: center; } | |
236 | .todo { font-family: monospace; color: red; } | |
237 | .done { color: green; } | |
238 | .tag { background-color: #eee; font-family: monospace; | |
239 | padding: 2px; font-size: 80%; font-weight: normal; } | |
240 | .timestamp { color: #bebebe; } | |
241 | .timestamp-kwd { color: #5f9ea0; } | |
242 | .right { margin-left: auto; margin-right: 0px; text-align: right; } | |
243 | .left { margin-left: 0px; margin-right: auto; text-align: left; } | |
244 | .center { margin-left: auto; margin-right: auto; text-align: center; } | |
245 | .underline { text-decoration: underline; } | |
246 | #postamble p, #preamble p { font-size: 90%; margin: .2em; } | |
247 | p.verse { margin-left: 3%; } | |
248 | pre { | |
249 | border: 1px solid #ccc; | |
250 | box-shadow: 3px 3px 3px #eee; | |
251 | padding: 8pt; | |
252 | font-family: monospace; | |
253 | overflow: auto; | |
254 | margin: 1.2em; | |
255 | } | |
256 | pre.src { | |
257 | position: relative; | |
258 | overflow: visible; | |
259 | padding-top: 1.2em; | |
260 | } | |
261 | pre.src:before { | |
262 | display: none; | |
263 | position: absolute; | |
264 | background-color: white; | |
265 | top: -10px; | |
266 | right: 10px; | |
267 | padding: 3px; | |
268 | border: 1px solid black; | |
269 | } | |
270 | pre.src:hover:before { display: inline;} | |
271 | pre.src-sh:before { content: 'sh'; } | |
272 | pre.src-bash:before { content: 'sh'; } | |
273 | pre.src-emacs-lisp:before { content: 'Emacs Lisp'; } | |
274 | pre.src-R:before { content: 'R'; } | |
275 | pre.src-perl:before { content: 'Perl'; } | |
276 | pre.src-java:before { content: 'Java'; } | |
277 | pre.src-sql:before { content: 'SQL'; } | |
278 | ||
279 | table { border-collapse:collapse; } | |
3c8b09ca BG |
280 | caption.t-above { caption-side: top; } |
281 | caption.t-bottom { caption-side: bottom; } | |
271672fa BG |
282 | td, th { vertical-align:top; } |
283 | th.right { text-align: center; } | |
284 | th.left { text-align: center; } | |
285 | th.center { text-align: center; } | |
286 | td.right { text-align: right; } | |
287 | td.left { text-align: left; } | |
288 | td.center { text-align: center; } | |
289 | dt { font-weight: bold; } | |
290 | .footpara:nth-child(2) { display: inline; } | |
291 | .footpara { display: block; } | |
292 | .footdef { margin-bottom: 1em; } | |
293 | .figure { padding: 1em; } | |
294 | .figure p { text-align: center; } | |
295 | .inlinetask { | |
296 | padding: 10px; | |
297 | border: 2px solid gray; | |
298 | margin: 10px; | |
299 | background: #ffffcc; | |
300 | } | |
301 | #org-div-home-and-up | |
302 | { text-align: right; font-size: 70%; white-space: nowrap; } | |
303 | textarea { overflow-x: auto; } | |
304 | .linenr { font-size: smaller } | |
305 | .code-highlighted { background-color: #ffff00; } | |
306 | .org-info-js_info-navigation { border-style: none; } | |
307 | #org-info-js_console-label | |
308 | { font-size: 10px; font-weight: bold; white-space: nowrap; } | |
309 | .org-info-js_search-highlight | |
310 | { background-color: #ffff00; color: #000000; font-weight: bold; } | |
311 | /*]]>*/--> | |
312 | </style>" | |
313 | "The default style specification for exported HTML files. | |
314 | You can use `org-html-head' and `org-html-head-extra' to add to | |
315 | this style. If you don't want to include this default style, | |
316 | customize `org-html-head-include-default-style'.") | |
317 | ||
318 | \f | |
319 | ;;; User Configuration Variables | |
320 | ||
321 | (defgroup org-export-html nil | |
322 | "Options for exporting Org mode files to HTML." | |
323 | :tag "Org Export HTML" | |
324 | :group 'org-export) | |
325 | ||
326 | ;;;; Handle infojs | |
327 | ||
328 | (defvar org-html-infojs-opts-table | |
329 | '((path PATH "http://orgmode.org/org-info.js") | |
330 | (view VIEW "info") | |
331 | (toc TOC :with-toc) | |
332 | (ftoc FIXED_TOC "0") | |
333 | (tdepth TOC_DEPTH "max") | |
334 | (sdepth SECTION_DEPTH "max") | |
335 | (mouse MOUSE_HINT "underline") | |
336 | (buttons VIEW_BUTTONS "0") | |
337 | (ltoc LOCAL_TOC "1") | |
338 | (up LINK_UP :html-link-up) | |
339 | (home LINK_HOME :html-link-home)) | |
340 | "JavaScript options, long form for script, default values.") | |
341 | ||
342 | (defcustom org-html-use-infojs 'when-configured | |
343 | "Non-nil when Sebastian Rose's Java Script org-info.js should be active. | |
344 | This option can be nil or t to never or always use the script. | |
345 | It can also be the symbol `when-configured', meaning that the | |
346 | script will be linked into the export file if and only if there | |
347 | is a \"#+INFOJS_OPT:\" line in the buffer. See also the variable | |
348 | `org-html-infojs-options'." | |
349 | :group 'org-export-html | |
350 | :version "24.4" | |
351 | :package-version '(Org . "8.0") | |
352 | :type '(choice | |
353 | (const :tag "Never" nil) | |
354 | (const :tag "When configured in buffer" when-configured) | |
355 | (const :tag "Always" t))) | |
356 | ||
357 | (defcustom org-html-infojs-options | |
358 | (mapcar (lambda (x) (cons (car x) (nth 2 x))) org-html-infojs-opts-table) | |
359 | "Options settings for the INFOJS JavaScript. | |
360 | Each of the options must have an entry in `org-html-infojs-opts-table'. | |
361 | The value can either be a string that will be passed to the script, or | |
362 | a property. This property is then assumed to be a property that is defined | |
363 | by the Export/Publishing setup of Org. | |
364 | The `sdepth' and `tdepth' parameters can also be set to \"max\", which | |
365 | means to use the maximum value consistent with other options." | |
366 | :group 'org-export-html | |
367 | :version "24.4" | |
368 | :package-version '(Org . "8.0") | |
369 | :type | |
370 | `(set :greedy t :inline t | |
371 | ,@(mapcar | |
372 | (lambda (x) | |
373 | (list 'cons (list 'const (car x)) | |
374 | '(choice | |
375 | (symbol :tag "Publishing/Export property") | |
376 | (string :tag "Value")))) | |
377 | org-html-infojs-opts-table))) | |
378 | ||
379 | (defcustom org-html-infojs-template | |
380 | "<script type=\"text/javascript\" src=\"%SCRIPT_PATH\"> | |
381 | /** | |
382 | * | |
383 | * @source: %SCRIPT_PATH | |
384 | * | |
385 | * @licstart The following is the entire license notice for the | |
386 | * JavaScript code in %SCRIPT_PATH. | |
387 | * | |
30cb51f1 | 388 | * Copyright (C) 2012-2013 Free Software Foundation, Inc. |
271672fa BG |
389 | * |
390 | * | |
391 | * The JavaScript code in this tag is free software: you can | |
392 | * redistribute it and/or modify it under the terms of the GNU | |
393 | * General Public License (GNU GPL) as published by the Free Software | |
394 | * Foundation, either version 3 of the License, or (at your option) | |
395 | * any later version. The code is distributed WITHOUT ANY WARRANTY; | |
396 | * without even the implied warranty of MERCHANTABILITY or FITNESS | |
397 | * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
398 | * | |
399 | * As additional permission under GNU GPL version 3 section 7, you | |
400 | * may distribute non-source (e.g., minimized or compacted) forms of | |
401 | * that code without the copy of the GNU GPL normally required by | |
402 | * section 4, provided you include this license notice and a URL | |
403 | * through which recipients can access the Corresponding Source. | |
404 | * | |
405 | * @licend The above is the entire license notice | |
406 | * for the JavaScript code in %SCRIPT_PATH. | |
407 | * | |
408 | */ | |
409 | </script> | |
410 | ||
411 | <script type=\"text/javascript\"> | |
412 | ||
413 | /* | |
414 | @licstart The following is the entire license notice for the | |
415 | JavaScript code in this tag. | |
416 | ||
30cb51f1 | 417 | Copyright (C) 2012-2013 Free Software Foundation, Inc. |
271672fa BG |
418 | |
419 | The JavaScript code in this tag is free software: you can | |
420 | redistribute it and/or modify it under the terms of the GNU | |
421 | General Public License (GNU GPL) as published by the Free Software | |
422 | Foundation, either version 3 of the License, or (at your option) | |
423 | any later version. The code is distributed WITHOUT ANY WARRANTY; | |
424 | without even the implied warranty of MERCHANTABILITY or FITNESS | |
425 | FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
426 | ||
427 | As additional permission under GNU GPL version 3 section 7, you | |
428 | may distribute non-source (e.g., minimized or compacted) forms of | |
429 | that code without the copy of the GNU GPL normally required by | |
430 | section 4, provided you include this license notice and a URL | |
431 | through which recipients can access the Corresponding Source. | |
432 | ||
433 | ||
434 | @licend The above is the entire license notice | |
435 | for the JavaScript code in this tag. | |
436 | */ | |
437 | ||
438 | <!--/*--><![CDATA[/*><!--*/ | |
439 | %MANAGER_OPTIONS | |
440 | org_html_manager.setup(); // activate after the parameters are set | |
441 | /*]]>*///--> | |
442 | </script>" | |
443 | "The template for the export style additions when org-info.js is used. | |
444 | Option settings will replace the %MANAGER-OPTIONS cookie." | |
445 | :group 'org-export-html | |
446 | :version "24.4" | |
447 | :package-version '(Org . "8.0") | |
448 | :type 'string) | |
449 | ||
450 | (defun org-html-infojs-install-script (exp-plist backend) | |
451 | "Install script in export options when appropriate. | |
452 | EXP-PLIST is a plist containing export options. BACKEND is the | |
453 | export back-end currently used." | |
454 | (unless (or (memq 'body-only (plist-get exp-plist :export-options)) | |
455 | (not org-html-use-infojs) | |
456 | (and (eq org-html-use-infojs 'when-configured) | |
457 | (or (not (plist-get exp-plist :infojs-opt)) | |
30cb51f1 | 458 | (string= "" (plist-get exp-plist :infojs-opt)) |
271672fa BG |
459 | (string-match "\\<view:nil\\>" |
460 | (plist-get exp-plist :infojs-opt))))) | |
461 | (let* ((template org-html-infojs-template) | |
462 | (ptoc (plist-get exp-plist :with-toc)) | |
463 | (hlevels (plist-get exp-plist :headline-levels)) | |
464 | (sdepth hlevels) | |
465 | (tdepth (if (integerp ptoc) (min ptoc hlevels) hlevels)) | |
466 | (options (plist-get exp-plist :infojs-opt)) | |
467 | (table org-html-infojs-opts-table) | |
468 | style) | |
469 | (dolist (entry table) | |
470 | (let* ((opt (car entry)) | |
471 | (var (nth 1 entry)) | |
472 | ;; Compute default values for script option OPT from | |
473 | ;; `org-html-infojs-options' variable. | |
474 | (default | |
475 | (let ((default (cdr (assq opt org-html-infojs-options)))) | |
476 | (if (and (symbolp default) (not (memq default '(t nil)))) | |
477 | (plist-get exp-plist default) | |
478 | default))) | |
479 | ;; Value set through INFOJS_OPT keyword has precedence | |
480 | ;; over the default one. | |
481 | (val (if (and options | |
482 | (string-match (format "\\<%s:\\(\\S-+\\)" opt) | |
483 | options)) | |
484 | (match-string 1 options) | |
485 | default))) | |
486 | (case opt | |
487 | (path (setq template | |
488 | (replace-regexp-in-string | |
489 | "%SCRIPT_PATH" val template t t))) | |
490 | (sdepth (when (integerp (read val)) | |
491 | (setq sdepth (min (read val) sdepth)))) | |
492 | (tdepth (when (integerp (read val)) | |
493 | (setq tdepth (min (read val) tdepth)))) | |
494 | (otherwise (setq val | |
495 | (cond | |
496 | ((or (eq val t) (equal val "t")) "1") | |
497 | ((or (eq val nil) (equal val "nil")) "0") | |
498 | ((stringp val) val) | |
499 | (t (format "%s" val)))) | |
500 | (push (cons var val) style))))) | |
501 | ;; Now we set the depth of the *generated* TOC to SDEPTH, | |
502 | ;; because the toc will actually determine the splitting. How | |
503 | ;; much of the toc will actually be displayed is governed by the | |
504 | ;; TDEPTH option. | |
505 | (setq exp-plist (plist-put exp-plist :with-toc sdepth)) | |
506 | ;; The table of contents should not show more sections than we | |
507 | ;; generate. | |
508 | (setq tdepth (min tdepth sdepth)) | |
509 | (push (cons "TOC_DEPTH" tdepth) style) | |
510 | ;; Build style string. | |
511 | (setq style (mapconcat | |
512 | (lambda (x) (format "org_html_manager.set(\"%s\", \"%s\");" | |
513 | (car x) | |
514 | (cdr x))) | |
515 | style "\n")) | |
516 | (when (and style (> (length style) 0)) | |
517 | (and (string-match "%MANAGER_OPTIONS" template) | |
518 | (setq style (replace-match style t t template)) | |
519 | (setq exp-plist | |
520 | (plist-put | |
521 | exp-plist :html-head-extra | |
522 | (concat (or (plist-get exp-plist :html-head-extra) "") | |
523 | "\n" | |
524 | style))))) | |
525 | ;; This script absolutely needs the table of contents, so we | |
526 | ;; change that setting. | |
527 | (unless (plist-get exp-plist :with-toc) | |
528 | (setq exp-plist (plist-put exp-plist :with-toc t))) | |
529 | ;; Return the modified property list. | |
530 | exp-plist))) | |
531 | ||
532 | ;;;; Bold, etc. | |
533 | ||
534 | (defcustom org-html-text-markup-alist | |
535 | '((bold . "<b>%s</b>") | |
536 | (code . "<code>%s</code>") | |
537 | (italic . "<i>%s</i>") | |
538 | (strike-through . "<del>%s</del>") | |
539 | (underline . "<span class=\"underline\">%s</span>") | |
540 | (verbatim . "<code>%s</code>")) | |
541 | "Alist of HTML expressions to convert text markup. | |
542 | ||
543 | The key must be a symbol among `bold', `code', `italic', | |
544 | `strike-through', `underline' and `verbatim'. The value is | |
545 | a formatting string to wrap fontified text with. | |
546 | ||
547 | If no association can be found for a given markup, text will be | |
548 | returned as-is." | |
549 | :group 'org-export-html | |
73d3db82 BG |
550 | :version "24.4" |
551 | :package-version '(Org . "8.0") | |
271672fa BG |
552 | :type '(alist :key-type (symbol :tag "Markup type") |
553 | :value-type (string :tag "Format string")) | |
554 | :options '(bold code italic strike-through underline verbatim)) | |
555 | ||
556 | (defcustom org-html-indent nil | |
557 | "Non-nil means to indent the generated HTML. | |
558 | Warning: non-nil may break indentation of source code blocks." | |
559 | :group 'org-export-html | |
560 | :version "24.4" | |
561 | :package-version '(Org . "8.0") | |
562 | :type 'boolean) | |
563 | ||
564 | (defcustom org-html-use-unicode-chars nil | |
565 | "Non-nil means to use unicode characters instead of HTML entities." | |
566 | :group 'org-export-html | |
567 | :version "24.4" | |
568 | :package-version '(Org . "8.0") | |
569 | :type 'boolean) | |
570 | ||
571 | ;;;; Drawers | |
572 | ||
73d3db82 BG |
573 | (defcustom org-html-format-drawer-function |
574 | (lambda (name contents) contents) | |
271672fa BG |
575 | "Function called to format a drawer in HTML code. |
576 | ||
577 | The function must accept two parameters: | |
578 | NAME the drawer name, like \"LOGBOOK\" | |
579 | CONTENTS the contents of the drawer. | |
580 | ||
581 | The function should return the string to be exported. | |
582 | ||
583 | For example, the variable could be set to the following function | |
3c8b09ca | 584 | in order to mimic default behaviour: |
271672fa | 585 | |
73d3db82 | 586 | The default value simply returns the value of CONTENTS." |
271672fa | 587 | :group 'org-export-html |
73d3db82 BG |
588 | :version "24.4" |
589 | :package-version '(Org . "8.0") | |
271672fa BG |
590 | :type 'function) |
591 | ||
592 | ;;;; Footnotes | |
593 | ||
594 | (defcustom org-html-footnotes-section "<div id=\"footnotes\"> | |
595 | <h2 class=\"footnotes\">%s: </h2> | |
596 | <div id=\"text-footnotes\"> | |
597 | %s | |
598 | </div> | |
599 | </div>" | |
600 | "Format for the footnotes section. | |
601 | Should contain a two instances of %s. The first will be replaced with the | |
602 | language-specific word for \"Footnotes\", the second one will be replaced | |
603 | by the footnotes themselves." | |
604 | :group 'org-export-html | |
605 | :type 'string) | |
606 | ||
607 | (defcustom org-html-footnote-format "<sup>%s</sup>" | |
608 | "The format for the footnote reference. | |
609 | %s will be replaced by the footnote reference itself." | |
610 | :group 'org-export-html | |
611 | :type 'string) | |
612 | ||
613 | (defcustom org-html-footnote-separator "<sup>, </sup>" | |
614 | "Text used to separate footnotes." | |
615 | :group 'org-export-html | |
616 | :type 'string) | |
617 | ||
618 | ;;;; Headline | |
619 | ||
620 | (defcustom org-html-toplevel-hlevel 2 | |
621 | "The <H> level for level 1 headings in HTML export. | |
622 | This is also important for the classes that will be wrapped around headlines | |
623 | and outline structure. If this variable is 1, the top-level headlines will | |
624 | be <h1>, and the corresponding classes will be outline-1, section-number-1, | |
625 | and outline-text-1. If this is 2, all of these will get a 2 instead. | |
626 | The default for this variable is 2, because we use <h1> for formatting the | |
627 | document title." | |
628 | :group 'org-export-html | |
629 | :type 'integer) | |
630 | ||
73d3db82 | 631 | (defcustom org-html-format-headline-function 'ignore |
271672fa BG |
632 | "Function to format headline text. |
633 | ||
634 | This function will be called with 5 arguments: | |
635 | TODO the todo keyword (string or nil). | |
636 | TODO-TYPE the type of todo (symbol: `todo', `done', nil) | |
637 | PRIORITY the priority of the headline (integer or nil) | |
638 | TEXT the main headline text (string). | |
639 | TAGS the tags (string or nil). | |
640 | ||
641 | The function result will be used in the section format string." | |
642 | :group 'org-export-html | |
73d3db82 BG |
643 | :version "24.4" |
644 | :package-version '(Org . "8.0") | |
271672fa BG |
645 | :type 'function) |
646 | ||
647 | ;;;; HTML-specific | |
648 | ||
649 | (defcustom org-html-allow-name-attribute-in-anchors t | |
650 | "When nil, do not set \"name\" attribute in anchors. | |
651 | By default, anchors are formatted with both \"id\" and \"name\" | |
652 | attributes, when appropriate." | |
653 | :group 'org-export-html | |
654 | :version "24.4" | |
655 | :package-version '(Org . "8.0") | |
656 | :type 'boolean) | |
657 | ||
658 | ;;;; Inlinetasks | |
659 | ||
73d3db82 | 660 | (defcustom org-html-format-inlinetask-function 'ignore |
271672fa BG |
661 | "Function called to format an inlinetask in HTML code. |
662 | ||
663 | The function must accept six parameters: | |
664 | TODO the todo keyword, as a string | |
665 | TODO-TYPE the todo type, a symbol among `todo', `done' and nil. | |
666 | PRIORITY the inlinetask priority, as a string | |
667 | NAME the inlinetask name, as a string. | |
668 | TAGS the inlinetask tags, as a list of strings. | |
669 | CONTENTS the contents of the inlinetask, as a string. | |
670 | ||
671 | The function should return the string to be exported." | |
672 | :group 'org-export-html | |
73d3db82 BG |
673 | :version "24.4" |
674 | :package-version '(Org . "8.0") | |
271672fa BG |
675 | :type 'function) |
676 | ||
677 | ;;;; LaTeX | |
678 | ||
679 | (defcustom org-html-with-latex org-export-with-latex | |
680 | "Non-nil means process LaTeX math snippets. | |
681 | ||
682 | When set, the exporter will process LaTeX environments and | |
683 | fragments. | |
684 | ||
685 | This option can also be set with the +OPTIONS line, | |
686 | e.g. \"tex:mathjax\". Allowed values are: | |
687 | ||
688 | nil Ignore math snippets. | |
689 | `verbatim' Keep everything in verbatim | |
690 | `dvipng' Process the LaTeX fragments to images. This will also | |
691 | include processing of non-math environments. | |
692 | `imagemagick' Convert the LaTeX fragments to pdf files and use | |
693 | imagemagick to convert pdf files to png files. | |
694 | `mathjax' Do MathJax preprocessing and arrange for MathJax.js to | |
695 | be loaded. | |
696 | t Synonym for `mathjax'." | |
697 | :group 'org-export-html | |
698 | :version "24.4" | |
699 | :package-version '(Org . "8.0") | |
700 | :type '(choice | |
701 | (const :tag "Do not process math in any way" nil) | |
702 | (const :tag "Use dvipng to make images" dvipng) | |
703 | (const :tag "Use imagemagick to make images" imagemagick) | |
704 | (const :tag "Use MathJax to display math" mathjax) | |
705 | (const :tag "Leave math verbatim" verbatim))) | |
706 | ||
707 | ;;;; Links :: Generic | |
708 | ||
709 | (defcustom org-html-link-org-files-as-html t | |
710 | "Non-nil means make file links to `file.org' point to `file.html'. | |
711 | When `org-mode' is exporting an `org-mode' file to HTML, links to | |
712 | non-html files are directly put into a href tag in HTML. | |
713 | However, links to other Org-mode files (recognized by the | |
714 | extension `.org.) should become links to the corresponding html | |
715 | file, assuming that the linked `org-mode' file will also be | |
716 | converted to HTML. | |
717 | When nil, the links still point to the plain `.org' file." | |
718 | :group 'org-export-html | |
719 | :type 'boolean) | |
720 | ||
721 | ;;;; Links :: Inline images | |
722 | ||
723 | (defcustom org-html-inline-images t | |
724 | "Non-nil means inline images into exported HTML pages. | |
725 | This is done using an <img> tag. When nil, an anchor with href is used to | |
726 | link to the image." | |
727 | :group 'org-export-html | |
728 | :version "24.4" | |
729 | :package-version '(Org . "8.1") | |
730 | :type 'boolean) | |
731 | ||
732 | (defcustom org-html-inline-image-rules | |
733 | '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'") | |
734 | ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'") | |
735 | ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")) | |
736 | "Rules characterizing image files that can be inlined into HTML. | |
737 | A rule consists in an association whose key is the type of link | |
738 | to consider, and value is a regexp that will be matched against | |
739 | link's path." | |
740 | :group 'org-export-html | |
741 | :version "24.4" | |
742 | :package-version '(Org . "8.0") | |
743 | :type '(alist :key-type (string :tag "Type") | |
744 | :value-type (regexp :tag "Path"))) | |
745 | ||
746 | ;;;; Plain Text | |
747 | ||
748 | (defcustom org-html-protect-char-alist | |
749 | '(("&" . "&") | |
750 | ("<" . "<") | |
751 | (">" . ">")) | |
752 | "Alist of characters to be converted by `org-html-protect'." | |
753 | :group 'org-export-html | |
754 | :type '(repeat (cons (string :tag "Character") | |
755 | (string :tag "HTML equivalent")))) | |
756 | ||
757 | ;;;; Src Block | |
758 | ||
759 | (defcustom org-html-htmlize-output-type 'inline-css | |
760 | "Output type to be used by htmlize when formatting code snippets. | |
761 | Choices are `css', to export the CSS selectors only, or `inline-css', to | |
762 | export the CSS attribute values inline in the HTML. We use as default | |
763 | `inline-css', in order to make the resulting HTML self-containing. | |
764 | ||
765 | However, this will fail when using Emacs in batch mode for export, because | |
766 | then no rich font definitions are in place. It will also not be good if | |
767 | people with different Emacs setup contribute HTML files to a website, | |
768 | because the fonts will represent the individual setups. In these cases, | |
769 | it is much better to let Org/Htmlize assign classes only, and to use | |
770 | a style file to define the look of these classes. | |
771 | To get a start for your css file, start Emacs session and make sure that | |
772 | all the faces you are interested in are defined, for example by loading files | |
773 | in all modes you want. Then, use the command | |
774 | \\[org-html-htmlize-generate-css] to extract class definitions." | |
775 | :group 'org-export-html | |
776 | :type '(choice (const css) (const inline-css))) | |
777 | ||
778 | (defcustom org-html-htmlize-font-prefix "org-" | |
779 | "The prefix for CSS class names for htmlize font specifications." | |
780 | :group 'org-export-html | |
781 | :type 'string) | |
782 | ||
783 | ;;;; Table | |
784 | ||
785 | (defcustom org-html-table-default-attributes | |
786 | '(:border "2" :cellspacing "0" :cellpadding "6" :rules "groups" :frame "hsides") | |
787 | "Default attributes and values which will be used in table tags. | |
788 | This is a plist where attributes are symbols, starting with | |
789 | colons, and values are strings. | |
790 | ||
791 | When exporting to HTML5, these values will be disregarded." | |
792 | :group 'org-export-html | |
793 | :version "24.4" | |
794 | :package-version '(Org . "8.0") | |
795 | :type '(plist :key-type (symbol :tag "Property") | |
796 | :value-type (string :tag "Value"))) | |
797 | ||
798 | (defcustom org-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>") | |
799 | "The opening tag for table header fields. | |
800 | This is customizable so that alignment options can be specified. | |
801 | The first %s will be filled with the scope of the field, either row or col. | |
802 | The second %s will be replaced by a style entry to align the field. | |
803 | See also the variable `org-html-table-use-header-tags-for-first-column'. | |
804 | See also the variable `org-html-table-align-individual-fields'." | |
805 | :group 'org-export-html | |
806 | :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) | |
807 | ||
808 | (defcustom org-html-table-data-tags '("<td%s>" . "</td>") | |
809 | "The opening tag for table data fields. | |
810 | This is customizable so that alignment options can be specified. | |
811 | The first %s will be filled with the scope of the field, either row or col. | |
812 | The second %s will be replaced by a style entry to align the field. | |
813 | See also the variable `org-html-table-align-individual-fields'." | |
814 | :group 'org-export-html | |
815 | :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) | |
816 | ||
817 | (defcustom org-html-table-row-tags '("<tr>" . "</tr>") | |
818 | "The opening and ending tags for table rows. | |
819 | This is customizable so that alignment options can be specified. | |
820 | Instead of strings, these can be Lisp forms that will be | |
821 | evaluated for each row in order to construct the table row tags. | |
822 | ||
823 | During evaluation, these variables will be dynamically bound so that | |
824 | you can reuse them: | |
825 | ||
826 | `row-number': row number (0 is the first row) | |
827 | `rowgroup-number': group number of current row | |
828 | `start-rowgroup-p': non-nil means the row starts a group | |
829 | `end-rowgroup-p': non-nil means the row ends a group | |
830 | `top-row-p': non-nil means this is the top row | |
831 | `bottom-row-p': non-nil means this is the bottom row | |
832 | ||
833 | For example: | |
834 | ||
835 | \(setq org-html-table-row-tags | |
836 | (cons '(cond (top-row-p \"<tr class=\\\"tr-top\\\">\") | |
837 | (bottom-row-p \"<tr class=\\\"tr-bottom\\\">\") | |
838 | (t (if (= (mod row-number 2) 1) | |
839 | \"<tr class=\\\"tr-odd\\\">\" | |
840 | \"<tr class=\\\"tr-even\\\">\"))) | |
841 | \"</tr>\")) | |
842 | ||
843 | will use the \"tr-top\" and \"tr-bottom\" classes for the top row | |
844 | and the bottom row, and otherwise alternate between \"tr-odd\" and | |
845 | \"tr-even\" for odd and even rows." | |
846 | :group 'org-export-html | |
847 | :type '(cons | |
848 | (choice :tag "Opening tag" | |
849 | (string :tag "Specify") | |
850 | (sexp)) | |
851 | (choice :tag "Closing tag" | |
852 | (string :tag "Specify") | |
853 | (sexp)))) | |
854 | ||
855 | (defcustom org-html-table-align-individual-fields t | |
856 | "Non-nil means attach style attributes for alignment to each table field. | |
857 | When nil, alignment will only be specified in the column tags, but this | |
858 | is ignored by some browsers (like Firefox, Safari). Opera does it right | |
859 | though." | |
860 | :group 'org-export-html | |
861 | :type 'boolean) | |
862 | ||
863 | (defcustom org-html-table-use-header-tags-for-first-column nil | |
864 | "Non-nil means format column one in tables with header tags. | |
865 | When nil, also column one will use data tags." | |
866 | :group 'org-export-html | |
867 | :type 'boolean) | |
868 | ||
869 | (defcustom org-html-table-caption-above t | |
870 | "When non-nil, place caption string at the beginning of the table. | |
871 | Otherwise, place it near the end." | |
872 | :group 'org-export-html | |
873 | :type 'boolean) | |
874 | ||
875 | ;;;; Tags | |
876 | ||
877 | (defcustom org-html-tag-class-prefix "" | |
878 | "Prefix to class names for TODO keywords. | |
879 | Each tag gets a class given by the tag itself, with this prefix. | |
880 | The default prefix is empty because it is nice to just use the keyword | |
881 | as a class name. But if you get into conflicts with other, existing | |
882 | CSS classes, then this prefix can be very useful." | |
883 | :group 'org-export-html | |
884 | :type 'string) | |
885 | ||
886 | ;;;; Template :: Generic | |
887 | ||
888 | (defcustom org-html-extension "html" | |
889 | "The extension for exported HTML files." | |
890 | :group 'org-export-html | |
891 | :type 'string) | |
892 | ||
893 | (defcustom org-html-xml-declaration | |
894 | '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>") | |
895 | ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>")) | |
896 | "The extension for exported HTML files. | |
897 | %s will be replaced with the charset of the exported file. | |
898 | This may be a string, or an alist with export extensions | |
899 | and corresponding declarations. | |
900 | ||
901 | This declaration only applies when exporting to XHTML." | |
902 | :group 'org-export-html | |
903 | :type '(choice | |
904 | (string :tag "Single declaration") | |
905 | (repeat :tag "Dependent on extension" | |
906 | (cons (string :tag "Extension") | |
907 | (string :tag "Declaration"))))) | |
908 | ||
909 | (defcustom org-html-coding-system 'utf-8 | |
910 | "Coding system for HTML export. | |
911 | Use utf-8 as the default value." | |
912 | :group 'org-export-html | |
913 | :version "24.4" | |
914 | :package-version '(Org . "8.0") | |
915 | :type 'coding-system) | |
916 | ||
917 | (defcustom org-html-doctype "xhtml-strict" | |
918 | "Document type definition to use for exported HTML files. | |
919 | Can be set with the in-buffer HTML_DOCTYPE property or for | |
920 | publishing, with :html-doctype." | |
921 | :group 'org-export-html | |
922 | :version "24.4" | |
923 | :package-version '(Org . "8.0") | |
924 | :type 'string) | |
925 | ||
926 | (defcustom org-html-html5-fancy nil | |
927 | "Non-nil means using new HTML5 elements. | |
928 | This variable is ignored for anything other than HTML5 export. | |
929 | ||
930 | For compatibility with Internet Explorer, it's probably a good | |
931 | idea to download some form of the html5shiv (for instance | |
932 | https://code.google.com/p/html5shiv/) and add it to your | |
933 | HTML_HEAD_EXTRA, so that your pages don't break for users of IE | |
934 | versions 8 and below." | |
935 | :group 'org-export-html | |
936 | :version "24.4" | |
937 | :package-version '(Org . "8.0") | |
938 | :type 'boolean) | |
939 | ||
940 | (defcustom org-html-container-element "div" | |
941 | "HTML element to use for wrapping top level sections. | |
942 | Can be set with the in-buffer HTML_CONTAINER property or for | |
943 | publishing, with :html-container. | |
944 | ||
945 | Note that changing the default will prevent you from using | |
946 | org-info.js for your website." | |
947 | :group 'org-export-html | |
948 | :version "24.4" | |
949 | :package-version '(Org . "8.0") | |
950 | :type 'string) | |
951 | ||
952 | (defcustom org-html-divs | |
953 | '((preamble "div" "preamble") | |
954 | (content "div" "content") | |
955 | (postamble "div" "postamble")) | |
956 | "Alist of the three section elements for HTML export. | |
957 | The car of each entry is one of 'preamble, 'content or 'postamble. | |
958 | The cdrs of each entry are the ELEMENT_TYPE and ID for each | |
959 | section of the exported document. | |
960 | ||
961 | Note that changing the default will prevent you from using | |
962 | org-info.js for your website." | |
963 | :group 'org-export-html | |
964 | :version "24.4" | |
965 | :package-version '(Org . "8.0") | |
966 | :type '(list :greedy t | |
967 | (list :tag "Preamble" | |
968 | (const :format "" preamble) | |
969 | (string :tag "element") (string :tag " id")) | |
970 | (list :tag "Content" | |
971 | (const :format "" content) | |
972 | (string :tag "element") (string :tag " id")) | |
973 | (list :tag "Postamble" (const :format "" postamble) | |
974 | (string :tag " id") (string :tag "element")))) | |
975 | ||
976 | (defcustom org-html-metadata-timestamp-format "%Y-%m-%d %a %H:%M" | |
977 | "Format used for timestamps in preamble, postamble and metadata. | |
978 | See `format-time-string' for more information on its components." | |
979 | :group 'org-export-html | |
980 | :version "24.4" | |
981 | :package-version '(Org . "8.0") | |
982 | :type 'string) | |
983 | ||
984 | ;;;; Template :: Mathjax | |
985 | ||
986 | (defcustom org-html-mathjax-options | |
987 | '((path "http://orgmode.org/mathjax/MathJax.js") | |
988 | (scale "100") | |
989 | (align "center") | |
990 | (indent "2em") | |
991 | (mathml nil)) | |
992 | "Options for MathJax setup. | |
993 | ||
994 | path The path where to find MathJax | |
995 | scale Scaling for the HTML-CSS backend, usually between 100 and 133 | |
996 | align How to align display math: left, center, or right | |
997 | indent If align is not center, how far from the left/right side? | |
998 | mathml Should a MathML player be used if available? | |
999 | This is faster and reduces bandwidth use, but currently | |
1000 | sometimes has lower spacing quality. Therefore, the default is | |
1001 | nil. When browsers get better, this switch can be flipped. | |
1002 | ||
1003 | You can also customize this for each buffer, using something like | |
1004 | ||
1005 | #+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\"" | |
1006 | :group 'org-export-html | |
1007 | :type '(list :greedy t | |
1008 | (list :tag "path (the path from where to load MathJax.js)" | |
1009 | (const :format " " path) (string)) | |
1010 | (list :tag "scale (scaling for the displayed math)" | |
1011 | (const :format " " scale) (string)) | |
1012 | (list :tag "align (alignment of displayed equations)" | |
1013 | (const :format " " align) (string)) | |
1014 | (list :tag "indent (indentation with left or right alignment)" | |
1015 | (const :format " " indent) (string)) | |
1016 | (list :tag "mathml (should MathML display be used is possible)" | |
1017 | (const :format " " mathml) (boolean)))) | |
1018 | ||
1019 | (defcustom org-html-mathjax-template | |
1020 | "<script type=\"text/javascript\" src=\"%PATH\"></script> | |
1021 | <script type=\"text/javascript\"> | |
1022 | <!--/*--><![CDATA[/*><!--*/ | |
1023 | MathJax.Hub.Config({ | |
1024 | // Only one of the two following lines, depending on user settings | |
1025 | // First allows browser-native MathML display, second forces HTML/CSS | |
1026 | :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"], | |
1027 | :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"], | |
1028 | extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\", | |
1029 | \"TeX/noUndefined.js\"], | |
1030 | tex2jax: { | |
1031 | inlineMath: [ [\"\\\\(\",\"\\\\)\"] ], | |
1032 | displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ], | |
1033 | skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"], | |
1034 | ignoreClass: \"tex2jax_ignore\", | |
1035 | processEscapes: false, | |
1036 | processEnvironments: true, | |
1037 | preview: \"TeX\" | |
1038 | }, | |
1039 | showProcessingMessages: true, | |
1040 | displayAlign: \"%ALIGN\", | |
1041 | displayIndent: \"%INDENT\", | |
1042 | ||
1043 | \"HTML-CSS\": { | |
1044 | scale: %SCALE, | |
1045 | availableFonts: [\"STIX\",\"TeX\"], | |
1046 | preferredFont: \"TeX\", | |
1047 | webFont: \"TeX\", | |
1048 | imageFont: \"TeX\", | |
1049 | showMathMenu: true, | |
1050 | }, | |
1051 | MMLorHTML: { | |
1052 | prefer: { | |
1053 | MSIE: \"MML\", | |
1054 | Firefox: \"MML\", | |
1055 | Opera: \"HTML\", | |
1056 | other: \"HTML\" | |
1057 | } | |
1058 | } | |
1059 | }); | |
1060 | /*]]>*///--> | |
1061 | </script>" | |
1062 | "The MathJax setup for XHTML files." | |
1063 | :group 'org-export-html | |
1064 | :type 'string) | |
1065 | ||
1066 | ;;;; Template :: Postamble | |
1067 | ||
1068 | (defcustom org-html-postamble 'auto | |
1069 | "Non-nil means insert a postamble in HTML export. | |
1070 | ||
1071 | When set to 'auto, check against the | |
1072 | `org-export-with-author/email/creator/date' variables to set the | |
1073 | content of the postamble. When set to a string, use this string | |
1074 | as the postamble. When t, insert a string as defined by the | |
1075 | formatting string in `org-html-postamble-format'. | |
1076 | ||
1077 | When set to a function, apply this function and insert the | |
1078 | returned string. The function takes the property list of export | |
1079 | options as its only argument. | |
1080 | ||
1081 | Setting :html-postamble in publishing projects will take | |
1082 | precedence over this variable." | |
1083 | :group 'org-export-html | |
1084 | :type '(choice (const :tag "No postamble" nil) | |
1085 | (const :tag "Auto postamble" auto) | |
1086 | (const :tag "Default formatting string" t) | |
1087 | (string :tag "Custom formatting string") | |
1088 | (function :tag "Function (must return a string)"))) | |
1089 | ||
1090 | (defcustom org-html-postamble-format | |
1091 | '(("en" "<p class=\"author\">Author: %a (%e)</p> | |
1092 | <p class=\"date\">Date: %d</p> | |
1093 | <p class=\"creator\">%c</p> | |
1094 | <p class=\"validation\">%v</p>")) | |
1095 | "Alist of languages and format strings for the HTML postamble. | |
1096 | ||
1097 | The first element of each list is the language code, as used for | |
1098 | the LANGUAGE keyword. See `org-export-default-language'. | |
1099 | ||
1100 | The second element of each list is a format string to format the | |
1101 | postamble itself. This format string can contain these elements: | |
1102 | ||
1103 | %t stands for the title. | |
1104 | %a stands for the author's name. | |
1105 | %e stands for the author's email. | |
1106 | %d stands for the date. | |
1107 | %c will be replaced by `org-html-creator-string'. | |
1108 | %v will be replaced by `org-html-validation-link'. | |
1109 | %T will be replaced by the export time. | |
1110 | %C will be replaced by the last modification time. | |
1111 | ||
1112 | If you need to use a \"%\" character, you need to escape it | |
1113 | like that: \"%%\"." | |
1114 | :group 'org-export-html | |
1115 | :type '(repeat | |
1116 | (list (string :tag "Language") | |
1117 | (string :tag "Format string")))) | |
1118 | ||
1119 | (defcustom org-html-validation-link | |
1120 | "<a href=\"http://validator.w3.org/check?uri=referer\">Validate</a>" | |
1121 | "Link to HTML validation service." | |
1122 | :group 'org-export-html | |
1123 | :type 'string) | |
1124 | ||
1125 | (defcustom org-html-creator-string | |
1126 | (format "<a href=\"http://www.gnu.org/software/emacs/\">Emacs</a> %s (<a href=\"http://orgmode.org\">Org</a> mode %s)" | |
1127 | emacs-version | |
1128 | (if (fboundp 'org-version) (org-version) "unknown version")) | |
1129 | "Information about the creator of the HTML document. | |
1130 | This option can also be set on with the CREATOR keyword." | |
1131 | :group 'org-export-html | |
73d3db82 BG |
1132 | :version "24.4" |
1133 | :package-version '(Org . "8.0") | |
271672fa BG |
1134 | :type '(string :tag "Creator string")) |
1135 | ||
1136 | ;;;; Template :: Preamble | |
1137 | ||
1138 | (defcustom org-html-preamble t | |
1139 | "Non-nil means insert a preamble in HTML export. | |
1140 | ||
1141 | When t, insert a string as defined by the formatting string in | |
1142 | `org-html-preamble-format'. When set to a string, use this | |
1143 | formatting string instead (see `org-html-postamble-format' for an | |
1144 | example of such a formatting string). | |
1145 | ||
1146 | When set to a function, apply this function and insert the | |
1147 | returned string. The function takes the property list of export | |
1148 | options as its only argument. | |
1149 | ||
1150 | Setting :html-preamble in publishing projects will take | |
1151 | precedence over this variable." | |
1152 | :group 'org-export-html | |
1153 | :type '(choice (const :tag "No preamble" nil) | |
1154 | (const :tag "Default preamble" t) | |
1155 | (string :tag "Custom formatting string") | |
1156 | (function :tag "Function (must return a string)"))) | |
1157 | ||
1158 | (defcustom org-html-preamble-format '(("en" "")) | |
1159 | "Alist of languages and format strings for the HTML preamble. | |
1160 | ||
1161 | The first element of each list is the language code, as used for | |
1162 | the LANGUAGE keyword. See `org-export-default-language'. | |
1163 | ||
1164 | The second element of each list is a format string to format the | |
1165 | preamble itself. This format string can contain these elements: | |
1166 | ||
1167 | %t stands for the title. | |
1168 | %a stands for the author's name. | |
1169 | %e stands for the author's email. | |
1170 | %d stands for the date. | |
1171 | %c will be replaced by `org-html-creator-string'. | |
1172 | %v will be replaced by `org-html-validation-link'. | |
1173 | %T will be replaced by the export time. | |
1174 | %C will be replaced by the last modification time. | |
1175 | ||
1176 | If you need to use a \"%\" character, you need to escape it | |
1177 | like that: \"%%\". | |
1178 | ||
1179 | See the default value of `org-html-postamble-format' for an | |
1180 | example." | |
1181 | :group 'org-export-html | |
1182 | :type '(repeat | |
1183 | (list (string :tag "Language") | |
1184 | (string :tag "Format string")))) | |
1185 | ||
1186 | (defcustom org-html-link-up "" | |
1187 | "Where should the \"UP\" link of exported HTML pages lead?" | |
1188 | :group 'org-export-html | |
1189 | :type '(string :tag "File or URL")) | |
1190 | ||
1191 | (defcustom org-html-link-home "" | |
1192 | "Where should the \"HOME\" link of exported HTML pages lead?" | |
1193 | :group 'org-export-html | |
1194 | :type '(string :tag "File or URL")) | |
1195 | ||
1196 | (defcustom org-html-link-use-abs-url nil | |
1197 | "Should we prepend relative links with HTML_LINK_HOME?" | |
1198 | :group 'org-export-html | |
1199 | :version "24.4" | |
1200 | :package-version '(Org . "8.1") | |
1201 | :type 'boolean) | |
1202 | ||
1203 | (defcustom org-html-home/up-format | |
1204 | "<div id=\"org-div-home-and-up\"> | |
1205 | <a accesskey=\"h\" href=\"%s\"> UP </a> | |
1206 | | | |
1207 | <a accesskey=\"H\" href=\"%s\"> HOME </a> | |
1208 | </div>" | |
1209 | "Snippet used to insert the HOME and UP links. | |
1210 | This is a format string, the first %s will receive the UP link, | |
1211 | the second the HOME link. If both `org-html-link-up' and | |
1212 | `org-html-link-home' are empty, the entire snippet will be | |
1213 | ignored." | |
1214 | :group 'org-export-html | |
1215 | :type 'string) | |
1216 | ||
1217 | ;;;; Template :: Scripts | |
1218 | ||
1219 | (define-obsolete-variable-alias | |
1220 | 'org-html-style-include-scripts 'org-html-head-include-scripts "24.4") | |
1221 | (defcustom org-html-head-include-scripts t | |
1222 | "Non-nil means include the JavaScript snippets in exported HTML files. | |
1223 | The actual script is defined in `org-html-scripts' and should | |
1224 | not be modified." | |
1225 | :group 'org-export-html | |
1226 | :version "24.4" | |
1227 | :package-version '(Org . "8.0") | |
1228 | :type 'boolean) | |
1229 | ||
1230 | ;;;; Template :: Styles | |
1231 | ||
1232 | (define-obsolete-variable-alias | |
1233 | 'org-html-style-include-default 'org-html-head-include-default-style "24.4") | |
1234 | (defcustom org-html-head-include-default-style t | |
1235 | "Non-nil means include the default style in exported HTML files. | |
1236 | The actual style is defined in `org-html-style-default' and | |
1237 | should not be modified. Use `org-html-head' to use your own | |
1238 | style information." | |
1239 | :group 'org-export-html | |
1240 | :version "24.4" | |
1241 | :package-version '(Org . "8.0") | |
1242 | :type 'boolean) | |
1243 | ;;;###autoload | |
1244 | (put 'org-html-head-include-default-style 'safe-local-variable 'booleanp) | |
1245 | ||
1246 | (define-obsolete-variable-alias 'org-html-style 'org-html-head "24.4") | |
1247 | (defcustom org-html-head "" | |
1248 | "Org-wide head definitions for exported HTML files. | |
1249 | ||
1250 | This variable can contain the full HTML structure to provide a | |
1251 | style, including the surrounding HTML tags. You can consider | |
1252 | including definitions for the following classes: title, todo, | |
1253 | done, timestamp, timestamp-kwd, tag, target. | |
1254 | ||
1255 | For example, a valid value would be: | |
1256 | ||
1257 | <style type=\"text/css\"> | |
1258 | <![CDATA[ | |
1259 | p { font-weight: normal; color: gray; } | |
1260 | h1 { color: black; } | |
1261 | .title { text-align: center; } | |
1262 | .todo, .timestamp-kwd { color: red; } | |
1263 | .done { color: green; } | |
1264 | ]]> | |
1265 | </style> | |
1266 | ||
1267 | If you want to refer to an external style, use something like | |
1268 | ||
1269 | <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\" /> | |
1270 | ||
1271 | As the value of this option simply gets inserted into the HTML | |
1272 | <head> header, you can use it to add any arbitrary text to the | |
1273 | header. | |
1274 | ||
1275 | You can set this on a per-file basis using #+HTML_HEAD:, | |
1276 | or for publication projects using the :html-head property." | |
1277 | :group 'org-export-html | |
1278 | :version "24.4" | |
1279 | :package-version '(Org . "8.0") | |
1280 | :type 'string) | |
1281 | ;;;###autoload | |
1282 | (put 'org-html-head 'safe-local-variable 'stringp) | |
1283 | ||
1284 | (defcustom org-html-head-extra "" | |
1285 | "More head information to add in the HTML output. | |
1286 | ||
1287 | You can set this on a per-file basis using #+HTML_HEAD_EXTRA:, | |
1288 | or for publication projects using the :html-head-extra property." | |
1289 | :group 'org-export-html | |
1290 | :version "24.4" | |
1291 | :package-version '(Org . "8.0") | |
1292 | :type 'string) | |
1293 | ;;;###autoload | |
1294 | (put 'org-html-head-extra 'safe-local-variable 'stringp) | |
1295 | ||
1296 | ;;;; Todos | |
1297 | ||
1298 | (defcustom org-html-todo-kwd-class-prefix "" | |
1299 | "Prefix to class names for TODO keywords. | |
1300 | Each TODO keyword gets a class given by the keyword itself, with this prefix. | |
1301 | The default prefix is empty because it is nice to just use the keyword | |
1302 | as a class name. But if you get into conflicts with other, existing | |
1303 | CSS classes, then this prefix can be very useful." | |
1304 | :group 'org-export-html | |
1305 | :type 'string) | |
1306 | ||
1307 | \f | |
1308 | ;;; Internal Functions | |
1309 | ||
1310 | (defun org-html-xhtml-p (info) | |
1311 | (let ((dt (downcase (plist-get info :html-doctype)))) | |
1312 | (string-match-p "xhtml" dt))) | |
1313 | ||
1314 | (defun org-html-html5-p (info) | |
1315 | (let ((dt (downcase (plist-get info :html-doctype)))) | |
1316 | (member dt '("html5" "xhtml5" "<!doctype html>")))) | |
1317 | ||
1318 | (defun org-html-close-tag (tag attr info) | |
1319 | (concat "<" tag " " attr | |
1320 | (if (org-html-xhtml-p info) " />" ">"))) | |
1321 | ||
1322 | (defun org-html-doctype (info) | |
1323 | "Return correct html doctype tag from `org-html-doctype-alist', | |
1324 | or the literal value of :html-doctype from INFO if :html-doctype | |
1325 | is not found in the alist. | |
1326 | INFO is a plist used as a communication channel." | |
1327 | (let ((dt (plist-get info :html-doctype))) | |
1328 | (or (cdr (assoc dt org-html-doctype-alist)) dt))) | |
1329 | ||
1330 | (defun org-html--make-attribute-string (attributes) | |
1331 | "Return a list of attributes, as a string. | |
1332 | ATTRIBUTES is a plist where values are either strings or nil. An | |
1333 | attributes with a nil value will be omitted from the result." | |
1334 | (let (output) | |
1335 | (dolist (item attributes (mapconcat 'identity (nreverse output) " ")) | |
1336 | (cond ((null item) (pop output)) | |
1337 | ((symbolp item) (push (substring (symbol-name item) 1) output)) | |
1338 | (t (let ((key (car output)) | |
1339 | (value (replace-regexp-in-string | |
1340 | "\"" """ (org-html-encode-plain-text item)))) | |
1341 | (setcar output (format "%s=\"%s\"" key value)))))))) | |
1342 | ||
1343 | (defun org-html--wrap-image (contents info &optional caption label) | |
1344 | "Wrap CONTENTS string within an appropriate environment for images. | |
1345 | INFO is a plist used as a communication channel. When optional | |
1346 | arguments CAPTION and LABEL are given, use them for caption and | |
1347 | \"id\" attribute." | |
1348 | (let ((html5-fancy (and (org-html-html5-p info) | |
1349 | (plist-get info :html-html5-fancy)))) | |
1350 | (format (if html5-fancy "\n<figure%s>%s%s\n</figure>" | |
1351 | "\n<div%s class=\"figure\">%s%s\n</div>") | |
1352 | ;; ID. | |
1353 | (if (not (org-string-nw-p label)) "" | |
1354 | (format " id=\"%s\"" (org-export-solidify-link-text label))) | |
1355 | ;; Contents. | |
1356 | (format "\n<p>%s</p>" contents) | |
1357 | ;; Caption. | |
1358 | (if (not (org-string-nw-p caption)) "" | |
1359 | (format (if html5-fancy "\n<figcaption>%s</figcaption>" | |
1360 | "\n<p>%s</p>") | |
1361 | caption))))) | |
1362 | ||
1363 | (defun org-html--format-image (source attributes info) | |
1364 | "Return \"img\" tag with given SOURCE and ATTRIBUTES. | |
1365 | SOURCE is a string specifying the location of the image. | |
1366 | ATTRIBUTES is a plist, as returned by | |
1367 | `org-export-read-attribute'. INFO is a plist used as | |
1368 | a communication channel." | |
1369 | (org-html-close-tag | |
1370 | "img" | |
1371 | (org-html--make-attribute-string | |
1372 | (org-combine-plists | |
1373 | (list :src source | |
1374 | :alt (if (string-match-p "^ltxpng/" source) | |
1375 | (org-html-encode-plain-text | |
1376 | (org-find-text-property-in-string 'org-latex-src source)) | |
1377 | (file-name-nondirectory source))) | |
1378 | attributes)) | |
1379 | info)) | |
1380 | ||
1381 | (defun org-html--textarea-block (element) | |
1382 | "Transcode ELEMENT into a textarea block. | |
1383 | ELEMENT is either a src block or an example block." | |
1384 | (let* ((code (car (org-export-unravel-code element))) | |
1385 | (attr (org-export-read-attribute :attr_html element))) | |
1386 | (format "<p>\n<textarea cols=\"%s\" rows=\"%s\">\n%s</textarea>\n</p>" | |
1387 | (or (plist-get attr :width) 80) | |
1388 | (or (plist-get attr :height) (org-count-lines code)) | |
1389 | code))) | |
1390 | ||
1391 | (defun org-html--has-caption-p (element &optional info) | |
1392 | "Non-nil when ELEMENT has a caption affiliated keyword. | |
1393 | INFO is a plist used as a communication channel. This function | |
1394 | is meant to be used as a predicate for `org-export-get-ordinal' or | |
1395 | a value to `org-html-standalone-image-predicate'." | |
1396 | (org-element-property :caption element)) | |
1397 | ||
1398 | ;;;; Table | |
1399 | ||
1400 | (defun org-html-htmlize-region-for-paste (beg end) | |
1401 | "Convert the region between BEG and END to HTML, using htmlize.el. | |
1402 | This is much like `htmlize-region-for-paste', only that it uses | |
1403 | the settings define in the org-... variables." | |
1404 | (let* ((htmlize-output-type org-html-htmlize-output-type) | |
1405 | (htmlize-css-name-prefix org-html-htmlize-font-prefix) | |
1406 | (htmlbuf (htmlize-region beg end))) | |
1407 | (unwind-protect | |
1408 | (with-current-buffer htmlbuf | |
1409 | (buffer-substring (plist-get htmlize-buffer-places 'content-start) | |
1410 | (plist-get htmlize-buffer-places 'content-end))) | |
1411 | (kill-buffer htmlbuf)))) | |
1412 | ||
1413 | ;;;###autoload | |
1414 | (defun org-html-htmlize-generate-css () | |
1415 | "Create the CSS for all font definitions in the current Emacs session. | |
1416 | Use this to create face definitions in your CSS style file that can then | |
1417 | be used by code snippets transformed by htmlize. | |
1418 | This command just produces a buffer that contains class definitions for all | |
1419 | faces used in the current Emacs session. You can copy and paste the ones you | |
1420 | need into your CSS file. | |
1421 | ||
1422 | If you then set `org-html-htmlize-output-type' to `css', calls | |
1423 | to the function `org-html-htmlize-region-for-paste' will | |
1424 | produce code that uses these same face definitions." | |
1425 | (interactive) | |
1426 | (require 'htmlize) | |
1427 | (and (get-buffer "*html*") (kill-buffer "*html*")) | |
1428 | (with-temp-buffer | |
1429 | (let ((fl (face-list)) | |
1430 | (htmlize-css-name-prefix "org-") | |
1431 | (htmlize-output-type 'css) | |
1432 | f i) | |
1433 | (while (setq f (pop fl) | |
1434 | i (and f (face-attribute f :inherit))) | |
1435 | (when (and (symbolp f) (or (not i) (not (listp i)))) | |
1436 | (insert (org-add-props (copy-sequence "1") nil 'face f)))) | |
1437 | (htmlize-region (point-min) (point-max)))) | |
1438 | (org-pop-to-buffer-same-window "*html*") | |
1439 | (goto-char (point-min)) | |
1440 | (if (re-search-forward "<style" nil t) | |
1441 | (delete-region (point-min) (match-beginning 0))) | |
1442 | (if (re-search-forward "</style>" nil t) | |
1443 | (delete-region (1+ (match-end 0)) (point-max))) | |
1444 | (beginning-of-line 1) | |
1445 | (if (looking-at " +") (replace-match "")) | |
1446 | (goto-char (point-min))) | |
1447 | ||
1448 | (defun org-html--make-string (n string) | |
1449 | "Build a string by concatenating N times STRING." | |
1450 | (let (out) (dotimes (i n out) (setq out (concat string out))))) | |
1451 | ||
1452 | (defun org-html-fix-class-name (kwd) ; audit callers of this function | |
1453 | "Turn todo keyword KWD into a valid class name. | |
1454 | Replaces invalid characters with \"_\"." | |
1455 | (save-match-data | |
1456 | (while (string-match "[^a-zA-Z0-9_]" kwd) | |
1457 | (setq kwd (replace-match "_" t t kwd)))) | |
1458 | kwd) | |
1459 | ||
1460 | (defun org-html-format-footnote-reference (n def refcnt) | |
1461 | "Format footnote reference N with definition DEF into HTML." | |
1462 | (let ((extra (if (= refcnt 1) "" (format ".%d" refcnt)))) | |
1463 | (format org-html-footnote-format | |
1464 | (let* ((id (format "fnr.%s%s" n extra)) | |
1465 | (href (format " href=\"#fn.%s\"" n)) | |
1466 | (attributes (concat " class=\"footref\"" href))) | |
1467 | (org-html--anchor id n attributes))))) | |
1468 | ||
1469 | (defun org-html-format-footnotes-section (section-name definitions) | |
1470 | "Format footnotes section SECTION-NAME." | |
1471 | (if (not definitions) "" | |
1472 | (format org-html-footnotes-section section-name definitions))) | |
1473 | ||
1474 | (defun org-html-format-footnote-definition (fn) | |
1475 | "Format the footnote definition FN." | |
1476 | (let ((n (car fn)) (def (cdr fn))) | |
1477 | (format | |
1478 | "<div class=\"footdef\">%s %s</div>\n" | |
1479 | (format org-html-footnote-format | |
1480 | (let* ((id (format "fn.%s" n)) | |
1481 | (href (format " href=\"#fnr.%s\"" n)) | |
1482 | (attributes (concat " class=\"footnum\"" href))) | |
1483 | (org-html--anchor id n attributes))) | |
1484 | def))) | |
1485 | ||
1486 | (defun org-html-footnote-section (info) | |
1487 | "Format the footnote section. | |
1488 | INFO is a plist used as a communication channel." | |
1489 | (let* ((fn-alist (org-export-collect-footnote-definitions | |
1490 | (plist-get info :parse-tree) info)) | |
1491 | (fn-alist | |
1492 | (loop for (n type raw) in fn-alist collect | |
1493 | (cons n (if (eq (org-element-type raw) 'org-data) | |
1494 | (org-trim (org-export-data raw info)) | |
1495 | (format "<p>%s</p>" | |
1496 | (org-trim (org-export-data raw info)))))))) | |
1497 | (when fn-alist | |
1498 | (org-html-format-footnotes-section | |
1499 | (org-html--translate "Footnotes" info) | |
1500 | (format | |
1501 | "\n%s\n" | |
1502 | (mapconcat 'org-html-format-footnote-definition fn-alist "\n")))))) | |
1503 | ||
1504 | \f | |
1505 | ;;; Template | |
1506 | ||
1507 | (defun org-html--build-meta-info (info) | |
1508 | "Return meta tags for exported document. | |
1509 | INFO is a plist used as a communication channel." | |
1510 | (let ((protect-string | |
1511 | (lambda (str) | |
1512 | (replace-regexp-in-string | |
1513 | "\"" """ (org-html-encode-plain-text str)))) | |
1514 | (title (org-export-data (plist-get info :title) info)) | |
1515 | (author (and (plist-get info :with-author) | |
1516 | (let ((auth (plist-get info :author))) | |
1517 | (and auth | |
1518 | ;; Return raw Org syntax, skipping non | |
1519 | ;; exportable objects. | |
1520 | (org-element-interpret-data | |
1521 | (org-element-map auth | |
1522 | (cons 'plain-text org-element-all-objects) | |
1523 | 'identity info)))))) | |
1524 | (description (plist-get info :description)) | |
1525 | (keywords (plist-get info :keywords)) | |
1526 | (charset (or (and org-html-coding-system | |
1527 | (fboundp 'coding-system-get) | |
1528 | (coding-system-get org-html-coding-system | |
1529 | 'mime-charset)) | |
1530 | "iso-8859-1"))) | |
1531 | (concat | |
1532 | (format "<title>%s</title>\n" title) | |
1533 | (when (plist-get info :time-stamp-file) | |
1534 | (format-time-string | |
1535 | (concat "<!-- " org-html-metadata-timestamp-format " -->\n"))) | |
1536 | (format | |
1537 | (if (org-html-html5-p info) | |
1538 | (org-html-close-tag "meta" " charset=\"%s\"" info) | |
1539 | (org-html-close-tag | |
1540 | "meta" " http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"" | |
1541 | info)) | |
1542 | charset) "\n" | |
1543 | (org-html-close-tag "meta" " name=\"generator\" content=\"Org-mode\"" info) | |
1544 | "\n" | |
1545 | (and (org-string-nw-p author) | |
1546 | (concat | |
1547 | (org-html-close-tag "meta" | |
1548 | (format " name=\"author\" content=\"%s\"" | |
1549 | (funcall protect-string author)) | |
1550 | info) | |
1551 | "\n")) | |
1552 | (and (org-string-nw-p description) | |
1553 | (concat | |
1554 | (org-html-close-tag "meta" | |
1555 | (format " name=\"description\" content=\"%s\"\n" | |
1556 | (funcall protect-string description)) | |
1557 | info) | |
1558 | "\n")) | |
1559 | (and (org-string-nw-p keywords) | |
1560 | (concat | |
1561 | (org-html-close-tag "meta" | |
1562 | (format " name=\"keywords\" content=\"%s\"" | |
1563 | (funcall protect-string keywords)) | |
1564 | info) | |
1565 | "\n"))))) | |
1566 | ||
1567 | (defun org-html--build-head (info) | |
1568 | "Return information for the <head>..</head> of the HTML output. | |
1569 | INFO is a plist used as a communication channel." | |
1570 | (org-element-normalize-string | |
1571 | (concat | |
1572 | (when (plist-get info :html-head-include-default-style) | |
1573 | (org-element-normalize-string org-html-style-default)) | |
1574 | (org-element-normalize-string (plist-get info :html-head)) | |
1575 | (org-element-normalize-string (plist-get info :html-head-extra)) | |
1576 | (when (and (plist-get info :html-htmlized-css-url) | |
1577 | (eq org-html-htmlize-output-type 'css)) | |
1578 | (org-html-close-tag "link" | |
1579 | (format " rel=\"stylesheet\" href=\"%s\" type=\"text/css\"" | |
1580 | (plist-get info :html-htmlized-css-url)) | |
1581 | info)) | |
1582 | (when (plist-get info :html-head-include-scripts) org-html-scripts)))) | |
1583 | ||
1584 | (defun org-html--build-mathjax-config (info) | |
1585 | "Insert the user setup into the mathjax template. | |
1586 | INFO is a plist used as a communication channel." | |
1587 | (when (and (memq (plist-get info :with-latex) '(mathjax t)) | |
1588 | (org-element-map (plist-get info :parse-tree) | |
1589 | '(latex-fragment latex-environment) 'identity info t)) | |
1590 | (let ((template org-html-mathjax-template) | |
1591 | (options org-html-mathjax-options) | |
1592 | (in-buffer (or (plist-get info :html-mathjax) "")) | |
1593 | name val (yes " ") (no "// ") x) | |
1594 | (mapc | |
1595 | (lambda (e) | |
1596 | (setq name (car e) val (nth 1 e)) | |
1597 | (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer) | |
1598 | (setq val (car (read-from-string | |
1599 | (substring in-buffer (match-end 0)))))) | |
1600 | (if (not (stringp val)) (setq val (format "%s" val))) | |
1601 | (if (string-match (concat "%" (upcase (symbol-name name))) template) | |
1602 | (setq template (replace-match val t t template)))) | |
1603 | options) | |
1604 | (setq val (nth 1 (assq 'mathml options))) | |
1605 | (if (string-match (concat "\\<mathml:") in-buffer) | |
1606 | (setq val (car (read-from-string | |
1607 | (substring in-buffer (match-end 0)))))) | |
1608 | ;; Exchange prefixes depending on mathml setting. | |
1609 | (if (not val) (setq x yes yes no no x)) | |
1610 | ;; Replace cookies to turn on or off the config/jax lines. | |
1611 | (if (string-match ":MMLYES:" template) | |
1612 | (setq template (replace-match yes t t template))) | |
1613 | (if (string-match ":MMLNO:" template) | |
1614 | (setq template (replace-match no t t template))) | |
1615 | ;; Return the modified template. | |
1616 | (org-element-normalize-string template)))) | |
1617 | ||
1618 | (defun org-html-format-spec (info) | |
1619 | "Return format specification for elements that can be | |
1620 | used in the preamble or postamble." | |
1621 | `((?t . ,(org-export-data (plist-get info :title) info)) | |
1622 | (?d . ,(org-export-data (org-export-get-date info) info)) | |
1623 | (?T . ,(format-time-string org-html-metadata-timestamp-format)) | |
1624 | (?a . ,(org-export-data (plist-get info :author) info)) | |
1625 | (?e . ,(mapconcat | |
1626 | (lambda (e) | |
1627 | (format "<a href=\"mailto:%s\">%s</a>" e e)) | |
1628 | (split-string (plist-get info :email) ",+ *") | |
1629 | ", ")) | |
1630 | (?c . ,(plist-get info :creator)) | |
1631 | (?C . ,(let ((file (plist-get info :input-file))) | |
1632 | (format-time-string org-html-metadata-timestamp-format | |
1633 | (if file (nth 5 (file-attributes file)) | |
1634 | (current-time))))) | |
1635 | (?v . ,(or org-html-validation-link "")))) | |
1636 | ||
1637 | (defun org-html--build-pre/postamble (type info) | |
1638 | "Return document preamble or postamble as a string, or nil. | |
1639 | TYPE is either 'preamble or 'postamble, INFO is a plist used as a | |
1640 | communication channel." | |
1641 | (let ((section (plist-get info (intern (format ":html-%s" type)))) | |
1642 | (spec (org-html-format-spec info))) | |
1643 | (when section | |
1644 | (let ((section-contents | |
1645 | (if (functionp section) (funcall section info) | |
1646 | (cond | |
1647 | ((stringp section) (format-spec section spec)) | |
1648 | ((eq section 'auto) | |
1649 | (let ((date (cdr (assq ?d spec))) | |
1650 | (author (cdr (assq ?a spec))) | |
1651 | (email (cdr (assq ?e spec))) | |
1652 | (creator (cdr (assq ?c spec))) | |
1653 | (timestamp (cdr (assq ?T spec))) | |
1654 | (validation-link (cdr (assq ?v spec)))) | |
1655 | (concat | |
1656 | (when (and (plist-get info :with-date) | |
1657 | (org-string-nw-p date)) | |
1658 | (format "<p class=\"date\">%s: %s</p>\n" | |
1659 | (org-html--translate "Date" info) | |
1660 | date)) | |
1661 | (when (and (plist-get info :with-author) | |
1662 | (org-string-nw-p author)) | |
1663 | (format "<p class=\"author\">%s: %s</p>\n" | |
1664 | (org-html--translate "Author" info) | |
1665 | author)) | |
1666 | (when (and (plist-get info :with-email) | |
1667 | (org-string-nw-p email)) | |
1668 | (format "<p class=\"email\">%s: %s</p>\n" | |
1669 | (org-html--translate "Email" info) | |
1670 | email)) | |
1671 | (when (plist-get info :time-stamp-file) | |
1672 | (format | |
1673 | "<p class=\"date\">%s: %s</p>\n" | |
1674 | (org-html--translate "Created" info) | |
1675 | (format-time-string org-html-metadata-timestamp-format))) | |
1676 | (when (plist-get info :with-creator) | |
1677 | (format "<p class=\"creator\">%s</p>\n" creator)) | |
1678 | (format "<p class=\"validation\">%s</p>\n" | |
1679 | validation-link)))) | |
1680 | (t (format-spec | |
1681 | (or (cadr (assoc | |
1682 | (plist-get info :language) | |
1683 | (eval (intern | |
1684 | (format "org-html-%s-format" type))))) | |
1685 | (cadr | |
1686 | (assoc | |
1687 | "en" | |
1688 | (eval | |
1689 | (intern (format "org-html-%s-format" type)))))) | |
1690 | spec)))))) | |
1691 | (when (org-string-nw-p section-contents) | |
1692 | (concat | |
1693 | (format "<%s id=\"%s\" class=\"%s\">\n" | |
1694 | (nth 1 (assq type org-html-divs)) | |
1695 | (nth 2 (assq type org-html-divs)) | |
1696 | org-html--pre/postamble-class) | |
1697 | (org-element-normalize-string section-contents) | |
1698 | (format "</%s>\n" (nth 1 (assq type org-html-divs))))))))) | |
1699 | ||
1700 | (defun org-html-inner-template (contents info) | |
1701 | "Return body of document string after HTML conversion. | |
1702 | CONTENTS is the transcoded contents string. INFO is a plist | |
1703 | holding export options." | |
1704 | (concat | |
1705 | ;; Table of contents. | |
1706 | (let ((depth (plist-get info :with-toc))) | |
1707 | (when depth (org-html-toc depth info))) | |
1708 | ;; Document contents. | |
1709 | contents | |
1710 | ;; Footnotes section. | |
1711 | (org-html-footnote-section info))) | |
1712 | ||
1713 | (defun org-html-template (contents info) | |
1714 | "Return complete document string after HTML conversion. | |
1715 | CONTENTS is the transcoded contents string. INFO is a plist | |
1716 | holding export options." | |
1717 | (concat | |
1718 | (when (and (not (org-html-html5-p info)) (org-html-xhtml-p info)) | |
1719 | (let ((decl (or (and (stringp org-html-xml-declaration) | |
1720 | org-html-xml-declaration) | |
1721 | (cdr (assoc (plist-get info :html-extension) | |
1722 | org-html-xml-declaration)) | |
1723 | (cdr (assoc "html" org-html-xml-declaration)) | |
1724 | ||
1725 | ""))) | |
1726 | (when (not (or (eq nil decl) (string= "" decl))) | |
1727 | (format "%s\n" | |
1728 | (format decl | |
1729 | (or (and org-html-coding-system | |
1730 | (fboundp 'coding-system-get) | |
1731 | (coding-system-get org-html-coding-system 'mime-charset)) | |
1732 | "iso-8859-1")))))) | |
1733 | (org-html-doctype info) | |
1734 | "\n" | |
1735 | (concat "<html" | |
1736 | (when (org-html-xhtml-p info) | |
1737 | (format | |
1738 | " xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"" | |
1739 | (plist-get info :language) (plist-get info :language))) | |
1740 | ">\n") | |
1741 | "<head>\n" | |
1742 | (org-html--build-meta-info info) | |
1743 | (org-html--build-head info) | |
1744 | (org-html--build-mathjax-config info) | |
1745 | "</head>\n" | |
1746 | "<body>\n" | |
1747 | (let ((link-up (org-trim (plist-get info :html-link-up))) | |
1748 | (link-home (org-trim (plist-get info :html-link-home)))) | |
1749 | (unless (and (string= link-up "") (string= link-home "")) | |
1750 | (format org-html-home/up-format | |
1751 | (or link-up link-home) | |
1752 | (or link-home link-up)))) | |
1753 | ;; Preamble. | |
1754 | (org-html--build-pre/postamble 'preamble info) | |
1755 | ;; Document contents. | |
1756 | (format "<%s id=\"%s\">\n" | |
1757 | (nth 1 (assq 'content org-html-divs)) | |
1758 | (nth 2 (assq 'content org-html-divs))) | |
1759 | ;; Document title. | |
1760 | (let ((title (plist-get info :title))) | |
1761 | (format "<h1 class=\"title\">%s</h1>\n" (org-export-data (or title "") info))) | |
1762 | contents | |
1763 | (format "</%s>\n" | |
1764 | (nth 1 (assq 'content org-html-divs))) | |
1765 | ;; Postamble. | |
1766 | (org-html--build-pre/postamble 'postamble info) | |
1767 | ;; Closing document. | |
1768 | "</body>\n</html>")) | |
1769 | ||
1770 | (defun org-html--translate (s info) | |
1771 | "Translate string S according to specified language. | |
1772 | INFO is a plist used as a communication channel." | |
1773 | (org-export-translate s :html info)) | |
1774 | ||
1775 | ;;;; Anchor | |
1776 | ||
1777 | (defun org-html--anchor (&optional id desc attributes) | |
1778 | "Format a HTML anchor." | |
1779 | (let* ((name (and org-html-allow-name-attribute-in-anchors id)) | |
1780 | (attributes (concat (and id (format " id=\"%s\"" id)) | |
1781 | (and name (format " name=\"%s\"" name)) | |
1782 | attributes))) | |
1783 | (format "<a%s>%s</a>" attributes (or desc "")))) | |
1784 | ||
1785 | ;;;; Todo | |
1786 | ||
1787 | (defun org-html--todo (todo) | |
1788 | "Format TODO keywords into HTML." | |
1789 | (when todo | |
1790 | (format "<span class=\"%s %s%s\">%s</span>" | |
1791 | (if (member todo org-done-keywords) "done" "todo") | |
1792 | org-html-todo-kwd-class-prefix (org-html-fix-class-name todo) | |
1793 | todo))) | |
1794 | ||
1795 | ;;;; Tags | |
1796 | ||
1797 | (defun org-html--tags (tags) | |
1798 | "Format TAGS into HTML." | |
1799 | (when tags | |
1800 | (format "<span class=\"tag\">%s</span>" | |
1801 | (mapconcat | |
1802 | (lambda (tag) | |
1803 | (format "<span class=\"%s\">%s</span>" | |
1804 | (concat org-html-tag-class-prefix | |
1805 | (org-html-fix-class-name tag)) | |
1806 | tag)) | |
1807 | tags " ")))) | |
1808 | ||
1809 | ;;;; Headline | |
1810 | ||
1811 | (defun* org-html-format-headline | |
1812 | (todo todo-type priority text tags | |
1813 | &key level section-number headline-label &allow-other-keys) | |
1814 | "Format a headline in HTML." | |
1815 | (let ((section-number | |
1816 | (when section-number | |
1817 | (format "<span class=\"section-number-%d\">%s</span> " | |
1818 | level section-number))) | |
1819 | (todo (org-html--todo todo)) | |
1820 | (tags (org-html--tags tags))) | |
1821 | (concat section-number todo (and todo " ") text | |
1822 | (and tags "   ") tags))) | |
1823 | ||
1824 | ;;;; Src Code | |
1825 | ||
1826 | (defun org-html-fontify-code (code lang) | |
1827 | "Color CODE with htmlize library. | |
1828 | CODE is a string representing the source code to colorize. LANG | |
1829 | is the language used for CODE, as a string, or nil." | |
1830 | (when code | |
1831 | (cond | |
1832 | ;; Case 1: No lang. Possibly an example block. | |
1833 | ((not lang) | |
1834 | ;; Simple transcoding. | |
1835 | (org-html-encode-plain-text code)) | |
1836 | ;; Case 2: No htmlize or an inferior version of htmlize | |
1837 | ((not (and (require 'htmlize nil t) (fboundp 'htmlize-region-for-paste))) | |
1838 | ;; Emit a warning. | |
1839 | (message "Cannot fontify src block (htmlize.el >= 1.34 required)") | |
1840 | ;; Simple transcoding. | |
1841 | (org-html-encode-plain-text code)) | |
1842 | (t | |
1843 | ;; Map language | |
1844 | (setq lang (or (assoc-default lang org-src-lang-modes) lang)) | |
1845 | (let* ((lang-mode (and lang (intern (format "%s-mode" lang))))) | |
1846 | (cond | |
1847 | ;; Case 1: Language is not associated with any Emacs mode | |
1848 | ((not (functionp lang-mode)) | |
1849 | ;; Simple transcoding. | |
1850 | (org-html-encode-plain-text code)) | |
1851 | ;; Case 2: Default. Fontify code. | |
1852 | (t | |
1853 | ;; htmlize | |
1854 | (setq code (with-temp-buffer | |
1855 | ;; Switch to language-specific mode. | |
1856 | (funcall lang-mode) | |
1857 | (insert code) | |
1858 | ;; Fontify buffer. | |
6711a21f | 1859 | (org-font-lock-ensure) |
271672fa BG |
1860 | ;; Remove formatting on newline characters. |
1861 | (save-excursion | |
1862 | (let ((beg (point-min)) | |
1863 | (end (point-max))) | |
1864 | (goto-char beg) | |
1865 | (while (progn (end-of-line) (< (point) end)) | |
1866 | (put-text-property (point) (1+ (point)) 'face nil) | |
1867 | (forward-char 1)))) | |
1868 | (org-src-mode) | |
1869 | (set-buffer-modified-p nil) | |
1870 | ;; Htmlize region. | |
1871 | (org-html-htmlize-region-for-paste | |
1872 | (point-min) (point-max)))) | |
1873 | ;; Strip any enclosing <pre></pre> tags. | |
1874 | (let* ((beg (and (string-match "\\`<pre[^>]*>\n*" code) (match-end 0))) | |
1875 | (end (and beg (string-match "</pre>\\'" code)))) | |
1876 | (if (and beg end) (substring code beg end) code))))))))) | |
1877 | ||
1878 | (defun org-html-do-format-code | |
1879 | (code &optional lang refs retain-labels num-start) | |
1880 | "Format CODE string as source code. | |
1881 | Optional arguments LANG, REFS, RETAIN-LABELS and NUM-START are, | |
1882 | respectively, the language of the source code, as a string, an | |
1883 | alist between line numbers and references (as returned by | |
1884 | `org-export-unravel-code'), a boolean specifying if labels should | |
1885 | appear in the source code, and the number associated to the first | |
1886 | line of code." | |
1887 | (let* ((code-lines (org-split-string code "\n")) | |
1888 | (code-length (length code-lines)) | |
1889 | (num-fmt | |
1890 | (and num-start | |
1891 | (format "%%%ds: " | |
1892 | (length (number-to-string (+ code-length num-start)))))) | |
1893 | (code (org-html-fontify-code code lang))) | |
1894 | (org-export-format-code | |
1895 | code | |
1896 | (lambda (loc line-num ref) | |
1897 | (setq loc | |
1898 | (concat | |
1899 | ;; Add line number, if needed. | |
1900 | (when num-start | |
1901 | (format "<span class=\"linenr\">%s</span>" | |
1902 | (format num-fmt line-num))) | |
1903 | ;; Transcoded src line. | |
1904 | loc | |
1905 | ;; Add label, if needed. | |
1906 | (when (and ref retain-labels) (format " (%s)" ref)))) | |
1907 | ;; Mark transcoded line as an anchor, if needed. | |
1908 | (if (not ref) loc | |
1909 | (format "<span id=\"coderef-%s\" class=\"coderef-off\">%s</span>" | |
1910 | ref loc))) | |
1911 | num-start refs))) | |
1912 | ||
1913 | (defun org-html-format-code (element info) | |
1914 | "Format contents of ELEMENT as source code. | |
1915 | ELEMENT is either an example block or a src block. INFO is | |
1916 | a plist used as a communication channel." | |
1917 | (let* ((lang (org-element-property :language element)) | |
1918 | ;; Extract code and references. | |
1919 | (code-info (org-export-unravel-code element)) | |
1920 | (code (car code-info)) | |
1921 | (refs (cdr code-info)) | |
1922 | ;; Does the src block contain labels? | |
1923 | (retain-labels (org-element-property :retain-labels element)) | |
1924 | ;; Does it have line numbers? | |
1925 | (num-start (case (org-element-property :number-lines element) | |
1926 | (continued (org-export-get-loc element info)) | |
1927 | (new 0)))) | |
1928 | (org-html-do-format-code code lang refs retain-labels num-start))) | |
1929 | ||
1930 | \f | |
1931 | ;;; Tables of Contents | |
1932 | ||
1933 | (defun org-html-toc (depth info) | |
1934 | "Build a table of contents. | |
1935 | DEPTH is an integer specifying the depth of the table. INFO is a | |
1936 | plist used as a communication channel. Return the table of | |
1937 | contents as a string, or nil if it is empty." | |
1938 | (let ((toc-entries | |
1939 | (mapcar (lambda (headline) | |
1940 | (cons (org-html--format-toc-headline headline info) | |
1941 | (org-export-get-relative-level headline info))) | |
1942 | (org-export-collect-headlines info depth))) | |
1943 | (outer-tag (if (and (org-html-html5-p info) | |
1944 | (plist-get info :html-html5-fancy)) | |
1945 | "nav" | |
1946 | "div"))) | |
1947 | (when toc-entries | |
1948 | (concat (format "<%s id=\"table-of-contents\">\n" outer-tag) | |
1949 | (format "<h%d>%s</h%d>\n" | |
1950 | org-html-toplevel-hlevel | |
1951 | (org-html--translate "Table of Contents" info) | |
1952 | org-html-toplevel-hlevel) | |
1953 | "<div id=\"text-table-of-contents\">" | |
1954 | (org-html--toc-text toc-entries) | |
1955 | "</div>\n" | |
1956 | (format "</%s>\n" outer-tag))))) | |
1957 | ||
1958 | (defun org-html--toc-text (toc-entries) | |
1959 | "Return innards of a table of contents, as a string. | |
1960 | TOC-ENTRIES is an alist where key is an entry title, as a string, | |
1961 | and value is its relative level, as an integer." | |
1962 | (let* ((prev-level (1- (cdar toc-entries))) | |
1963 | (start-level prev-level)) | |
1964 | (concat | |
1965 | (mapconcat | |
1966 | (lambda (entry) | |
1967 | (let ((headline (car entry)) | |
1968 | (level (cdr entry))) | |
1969 | (concat | |
1970 | (let* ((cnt (- level prev-level)) | |
1971 | (times (if (> cnt 0) (1- cnt) (- cnt))) | |
1972 | rtn) | |
1973 | (setq prev-level level) | |
1974 | (concat | |
1975 | (org-html--make-string | |
1976 | times (cond ((> cnt 0) "\n<ul>\n<li>") | |
1977 | ((< cnt 0) "</li>\n</ul>\n"))) | |
1978 | (if (> cnt 0) "\n<ul>\n<li>" "</li>\n<li>"))) | |
1979 | headline))) | |
1980 | toc-entries "") | |
1981 | (org-html--make-string (- prev-level start-level) "</li>\n</ul>\n")))) | |
1982 | ||
1983 | (defun org-html--format-toc-headline (headline info) | |
1984 | "Return an appropriate table of contents entry for HEADLINE. | |
1985 | INFO is a plist used as a communication channel." | |
73d3db82 BG |
1986 | (let* ((headline-number (org-export-get-headline-number headline info)) |
1987 | (todo (and (plist-get info :with-todo-keywords) | |
271672fa BG |
1988 | (let ((todo (org-element-property :todo-keyword headline))) |
1989 | (and todo (org-export-data todo info))))) | |
1990 | (todo-type (and todo (org-element-property :todo-type headline))) | |
1991 | (priority (and (plist-get info :with-priority) | |
1992 | (org-element-property :priority headline))) | |
1993 | (text (org-export-data-with-backend | |
1994 | (org-export-get-alt-title headline info) | |
1995 | ;; Create an anonymous back-end that will ignore any | |
1996 | ;; footnote-reference, link, radio-target and target | |
1997 | ;; in table of contents. | |
1998 | (org-export-create-backend | |
1999 | :parent 'html | |
2000 | :transcoders '((footnote-reference . ignore) | |
2001 | (link . (lambda (object c i) c)) | |
2002 | (radio-target . (lambda (object c i) c)) | |
2003 | (target . ignore))) | |
2004 | info)) | |
2005 | (tags (and (eq (plist-get info :with-tags) t) | |
2006 | (org-export-get-tags headline info)))) | |
2007 | (format "<a href=\"#%s\">%s</a>" | |
73d3db82 | 2008 | ;; Label. |
271672fa BG |
2009 | (org-export-solidify-link-text |
2010 | (or (org-element-property :CUSTOM_ID headline) | |
2011 | (concat "sec-" | |
73d3db82 BG |
2012 | (mapconcat #'number-to-string headline-number "-")))) |
2013 | ;; Body. | |
2014 | (concat | |
2015 | (and (not (org-export-low-level-p headline info)) | |
2016 | (org-export-numbered-headline-p headline info) | |
2017 | (concat (mapconcat #'number-to-string headline-number ".") | |
2018 | ". ")) | |
2019 | (apply (if (not (eq org-html-format-headline-function 'ignore)) | |
2020 | (lambda (todo todo-type priority text tags &rest ignore) | |
2021 | (funcall org-html-format-headline-function | |
2022 | todo todo-type priority text tags)) | |
2023 | #'org-html-format-headline) | |
2024 | todo todo-type priority text tags :section-number nil))))) | |
271672fa BG |
2025 | |
2026 | (defun org-html-list-of-listings (info) | |
2027 | "Build a list of listings. | |
2028 | INFO is a plist used as a communication channel. Return the list | |
2029 | of listings as a string, or nil if it is empty." | |
2030 | (let ((lol-entries (org-export-collect-listings info))) | |
2031 | (when lol-entries | |
2032 | (concat "<div id=\"list-of-listings\">\n" | |
2033 | (format "<h%d>%s</h%d>\n" | |
2034 | org-html-toplevel-hlevel | |
2035 | (org-html--translate "List of Listings" info) | |
2036 | org-html-toplevel-hlevel) | |
2037 | "<div id=\"text-list-of-listings\">\n<ul>\n" | |
2038 | (let ((count 0) | |
2039 | (initial-fmt (format "<span class=\"listing-number\">%s</span>" | |
2040 | (org-html--translate "Listing %d:" info)))) | |
2041 | (mapconcat | |
2042 | (lambda (entry) | |
2043 | (let ((label (org-element-property :name entry)) | |
2044 | (title (org-trim | |
2045 | (org-export-data | |
2046 | (or (org-export-get-caption entry t) | |
2047 | (org-export-get-caption entry)) | |
2048 | info)))) | |
2049 | (concat | |
2050 | "<li>" | |
2051 | (if (not label) | |
2052 | (concat (format initial-fmt (incf count)) " " title) | |
2053 | (format "<a href=\"#%s\">%s %s</a>" | |
2054 | (org-export-solidify-link-text label) | |
2055 | (format initial-fmt (incf count)) | |
2056 | title)) | |
2057 | "</li>"))) | |
2058 | lol-entries "\n")) | |
2059 | "\n</ul>\n</div>\n</div>")))) | |
2060 | ||
2061 | (defun org-html-list-of-tables (info) | |
2062 | "Build a list of tables. | |
2063 | INFO is a plist used as a communication channel. Return the list | |
2064 | of tables as a string, or nil if it is empty." | |
2065 | (let ((lol-entries (org-export-collect-tables info))) | |
2066 | (when lol-entries | |
2067 | (concat "<div id=\"list-of-tables\">\n" | |
2068 | (format "<h%d>%s</h%d>\n" | |
2069 | org-html-toplevel-hlevel | |
2070 | (org-html--translate "List of Tables" info) | |
2071 | org-html-toplevel-hlevel) | |
2072 | "<div id=\"text-list-of-tables\">\n<ul>\n" | |
2073 | (let ((count 0) | |
2074 | (initial-fmt (format "<span class=\"table-number\">%s</span>" | |
2075 | (org-html--translate "Table %d:" info)))) | |
2076 | (mapconcat | |
2077 | (lambda (entry) | |
2078 | (let ((label (org-element-property :name entry)) | |
2079 | (title (org-trim | |
2080 | (org-export-data | |
2081 | (or (org-export-get-caption entry t) | |
2082 | (org-export-get-caption entry)) | |
2083 | info)))) | |
2084 | (concat | |
2085 | "<li>" | |
2086 | (if (not label) | |
2087 | (concat (format initial-fmt (incf count)) " " title) | |
2088 | (format "<a href=\"#%s\">%s %s</a>" | |
2089 | (org-export-solidify-link-text label) | |
2090 | (format initial-fmt (incf count)) | |
2091 | title)) | |
2092 | "</li>"))) | |
2093 | lol-entries "\n")) | |
2094 | "\n</ul>\n</div>\n</div>")))) | |
2095 | ||
2096 | \f | |
2097 | ;;; Transcode Functions | |
2098 | ||
2099 | ;;;; Bold | |
2100 | ||
2101 | (defun org-html-bold (bold contents info) | |
2102 | "Transcode BOLD from Org to HTML. | |
2103 | CONTENTS is the text with bold markup. INFO is a plist holding | |
2104 | contextual information." | |
2105 | (format (or (cdr (assq 'bold org-html-text-markup-alist)) "%s") | |
2106 | contents)) | |
2107 | ||
2108 | ;;;; Center Block | |
2109 | ||
2110 | (defun org-html-center-block (center-block contents info) | |
2111 | "Transcode a CENTER-BLOCK element from Org to HTML. | |
2112 | CONTENTS holds the contents of the block. INFO is a plist | |
2113 | holding contextual information." | |
2114 | (format "<div class=\"center\">\n%s</div>" contents)) | |
2115 | ||
2116 | ;;;; Clock | |
2117 | ||
2118 | (defun org-html-clock (clock contents info) | |
2119 | "Transcode a CLOCK element from Org to HTML. | |
2120 | CONTENTS is nil. INFO is a plist used as a communication | |
2121 | channel." | |
2122 | (format "<p> | |
2123 | <span class=\"timestamp-wrapper\"> | |
2124 | <span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>%s | |
2125 | </span> | |
2126 | </p>" | |
2127 | org-clock-string | |
2128 | (org-translate-time | |
2129 | (org-element-property :raw-value | |
2130 | (org-element-property :value clock))) | |
2131 | (let ((time (org-element-property :duration clock))) | |
2132 | (and time (format " <span class=\"timestamp\">(%s)</span>" time))))) | |
2133 | ||
2134 | ;;;; Code | |
2135 | ||
2136 | (defun org-html-code (code contents info) | |
2137 | "Transcode CODE from Org to HTML. | |
2138 | CONTENTS is nil. INFO is a plist holding contextual | |
2139 | information." | |
2140 | (format (or (cdr (assq 'code org-html-text-markup-alist)) "%s") | |
2141 | (org-html-encode-plain-text (org-element-property :value code)))) | |
2142 | ||
2143 | ;;;; Drawer | |
2144 | ||
2145 | (defun org-html-drawer (drawer contents info) | |
2146 | "Transcode a DRAWER element from Org to HTML. | |
2147 | CONTENTS holds the contents of the block. INFO is a plist | |
2148 | holding contextual information." | |
2149 | (if (functionp org-html-format-drawer-function) | |
2150 | (funcall org-html-format-drawer-function | |
2151 | (org-element-property :drawer-name drawer) | |
2152 | contents) | |
2153 | ;; If there's no user defined function: simply | |
2154 | ;; display contents of the drawer. | |
2155 | contents)) | |
2156 | ||
2157 | ;;;; Dynamic Block | |
2158 | ||
2159 | (defun org-html-dynamic-block (dynamic-block contents info) | |
2160 | "Transcode a DYNAMIC-BLOCK element from Org to HTML. | |
2161 | CONTENTS holds the contents of the block. INFO is a plist | |
2162 | holding contextual information. See `org-export-data'." | |
2163 | contents) | |
2164 | ||
2165 | ;;;; Entity | |
2166 | ||
2167 | (defun org-html-entity (entity contents info) | |
2168 | "Transcode an ENTITY object from Org to HTML. | |
2169 | CONTENTS are the definition itself. INFO is a plist holding | |
2170 | contextual information." | |
2171 | (org-element-property :html entity)) | |
2172 | ||
2173 | ;;;; Example Block | |
2174 | ||
2175 | (defun org-html-example-block (example-block contents info) | |
2176 | "Transcode a EXAMPLE-BLOCK element from Org to HTML. | |
2177 | CONTENTS is nil. INFO is a plist holding contextual | |
2178 | information." | |
2179 | (if (org-export-read-attribute :attr_html example-block :textarea) | |
2180 | (org-html--textarea-block example-block) | |
2181 | (format "<pre class=\"example\">\n%s</pre>" | |
2182 | (org-html-format-code example-block info)))) | |
2183 | ||
2184 | ;;;; Export Snippet | |
2185 | ||
2186 | (defun org-html-export-snippet (export-snippet contents info) | |
2187 | "Transcode a EXPORT-SNIPPET object from Org to HTML. | |
2188 | CONTENTS is nil. INFO is a plist holding contextual | |
2189 | information." | |
2190 | (when (eq (org-export-snippet-backend export-snippet) 'html) | |
2191 | (org-element-property :value export-snippet))) | |
2192 | ||
2193 | ;;;; Export Block | |
2194 | ||
2195 | (defun org-html-export-block (export-block contents info) | |
2196 | "Transcode a EXPORT-BLOCK element from Org to HTML. | |
2197 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2198 | (when (string= (org-element-property :type export-block) "HTML") | |
2199 | (org-remove-indentation (org-element-property :value export-block)))) | |
2200 | ||
2201 | ;;;; Fixed Width | |
2202 | ||
2203 | (defun org-html-fixed-width (fixed-width contents info) | |
2204 | "Transcode a FIXED-WIDTH element from Org to HTML. | |
2205 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2206 | (format "<pre class=\"example\">\n%s</pre>" | |
2207 | (org-html-do-format-code | |
2208 | (org-remove-indentation | |
2209 | (org-element-property :value fixed-width))))) | |
2210 | ||
2211 | ;;;; Footnote Reference | |
2212 | ||
2213 | (defun org-html-footnote-reference (footnote-reference contents info) | |
2214 | "Transcode a FOOTNOTE-REFERENCE element from Org to HTML. | |
2215 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2216 | (concat | |
2217 | ;; Insert separator between two footnotes in a row. | |
2218 | (let ((prev (org-export-get-previous-element footnote-reference info))) | |
2219 | (when (eq (org-element-type prev) 'footnote-reference) | |
2220 | org-html-footnote-separator)) | |
2221 | (cond | |
2222 | ((not (org-export-footnote-first-reference-p footnote-reference info)) | |
2223 | (org-html-format-footnote-reference | |
2224 | (org-export-get-footnote-number footnote-reference info) | |
2225 | "IGNORED" 100)) | |
2226 | ;; Inline definitions are secondary strings. | |
2227 | ((eq (org-element-property :type footnote-reference) 'inline) | |
2228 | (org-html-format-footnote-reference | |
2229 | (org-export-get-footnote-number footnote-reference info) | |
2230 | "IGNORED" 1)) | |
2231 | ;; Non-inline footnotes definitions are full Org data. | |
2232 | (t (org-html-format-footnote-reference | |
2233 | (org-export-get-footnote-number footnote-reference info) | |
2234 | "IGNORED" 1))))) | |
2235 | ||
2236 | ;;;; Headline | |
2237 | ||
2238 | (defun org-html-format-headline--wrap | |
2239 | (headline info &optional format-function &rest extra-keys) | |
2240 | "Transcode a HEADLINE element from Org to HTML. | |
2241 | CONTENTS holds the contents of the headline. INFO is a plist | |
2242 | holding contextual information." | |
2243 | (let* ((level (+ (org-export-get-relative-level headline info) | |
2244 | (1- org-html-toplevel-hlevel))) | |
2245 | (headline-number (org-export-get-headline-number headline info)) | |
2246 | (section-number (and (not (org-export-low-level-p headline info)) | |
2247 | (org-export-numbered-headline-p headline info) | |
2248 | (mapconcat 'number-to-string | |
2249 | headline-number "."))) | |
2250 | (todo (and (plist-get info :with-todo-keywords) | |
2251 | (let ((todo (org-element-property :todo-keyword headline))) | |
2252 | (and todo (org-export-data todo info))))) | |
2253 | (todo-type (and todo (org-element-property :todo-type headline))) | |
2254 | (priority (and (plist-get info :with-priority) | |
2255 | (org-element-property :priority headline))) | |
2256 | (text (org-export-data (org-element-property :title headline) info)) | |
2257 | (tags (and (plist-get info :with-tags) | |
2258 | (org-export-get-tags headline info))) | |
2259 | (headline-label (or (org-element-property :CUSTOM_ID headline) | |
2260 | (concat "sec-" (mapconcat 'number-to-string | |
2261 | headline-number "-")))) | |
2262 | (format-function | |
2263 | (cond ((functionp format-function) format-function) | |
73d3db82 | 2264 | ((not (eq org-html-format-headline-function 'ignore)) |
271672fa BG |
2265 | (lambda (todo todo-type priority text tags &rest ignore) |
2266 | (funcall org-html-format-headline-function | |
2267 | todo todo-type priority text tags))) | |
2268 | (t 'org-html-format-headline)))) | |
2269 | (apply format-function | |
2270 | todo todo-type priority text tags | |
2271 | :headline-label headline-label :level level | |
2272 | :section-number section-number extra-keys))) | |
2273 | ||
2274 | (defun org-html-headline (headline contents info) | |
2275 | "Transcode a HEADLINE element from Org to HTML. | |
2276 | CONTENTS holds the contents of the headline. INFO is a plist | |
2277 | holding contextual information." | |
2278 | ;; Empty contents? | |
2279 | (setq contents (or contents "")) | |
2280 | (let* ((numberedp (org-export-numbered-headline-p headline info)) | |
2281 | (level (org-export-get-relative-level headline info)) | |
2282 | (text (org-export-data (org-element-property :title headline) info)) | |
2283 | (todo (and (plist-get info :with-todo-keywords) | |
2284 | (let ((todo (org-element-property :todo-keyword headline))) | |
2285 | (and todo (org-export-data todo info))))) | |
2286 | (todo-type (and todo (org-element-property :todo-type headline))) | |
2287 | (tags (and (plist-get info :with-tags) | |
2288 | (org-export-get-tags headline info))) | |
2289 | (priority (and (plist-get info :with-priority) | |
2290 | (org-element-property :priority headline))) | |
2291 | (section-number (and (org-export-numbered-headline-p headline info) | |
2292 | (mapconcat 'number-to-string | |
2293 | (org-export-get-headline-number | |
2294 | headline info) "."))) | |
2295 | ;; Create the headline text. | |
2296 | (full-text (org-html-format-headline--wrap headline info))) | |
2297 | (cond | |
2298 | ;; Case 1: This is a footnote section: ignore it. | |
2299 | ((org-element-property :footnote-section-p headline) nil) | |
2300 | ;; Case 2. This is a deep sub-tree: export it as a list item. | |
2301 | ;; Also export as items headlines for which no section | |
2302 | ;; format has been found. | |
2303 | ((org-export-low-level-p headline info) | |
2304 | ;; Build the real contents of the sub-tree. | |
2305 | (let* ((type (if numberedp 'ordered 'unordered)) | |
2306 | (itemized-body (org-html-format-list-item | |
2307 | contents type nil info nil full-text))) | |
2308 | (concat | |
2309 | (and (org-export-first-sibling-p headline info) | |
2310 | (org-html-begin-plain-list type)) | |
2311 | itemized-body | |
2312 | (and (org-export-last-sibling-p headline info) | |
2313 | (org-html-end-plain-list type))))) | |
2314 | ;; Case 3. Standard headline. Export it as a section. | |
2315 | (t | |
2316 | (let* ((section-number (mapconcat 'number-to-string | |
2317 | (org-export-get-headline-number | |
2318 | headline info) "-")) | |
2319 | (ids (remove 'nil | |
2320 | (list (org-element-property :CUSTOM_ID headline) | |
2321 | (concat "sec-" section-number) | |
2322 | (org-element-property :ID headline)))) | |
2323 | (preferred-id (car ids)) | |
2324 | (extra-ids (cdr ids)) | |
2325 | (extra-class (org-element-property :HTML_CONTAINER_CLASS headline)) | |
2326 | (level1 (+ level (1- org-html-toplevel-hlevel))) | |
2327 | (first-content (car (org-element-contents headline)))) | |
2328 | (format "<%s id=\"%s\" class=\"%s\">%s%s</%s>\n" | |
2329 | (org-html--container headline info) | |
2330 | (format "outline-container-%s" | |
2331 | (or (org-element-property :CUSTOM_ID headline) | |
2332 | (concat "sec-" section-number))) | |
2333 | (concat (format "outline-%d" level1) (and extra-class " ") | |
2334 | extra-class) | |
2335 | (format "\n<h%d id=\"%s\">%s%s</h%d>\n" | |
2336 | level1 | |
2337 | preferred-id | |
2338 | (mapconcat | |
2339 | (lambda (x) | |
2340 | (let ((id (org-export-solidify-link-text | |
2341 | (if (org-uuidgen-p x) (concat "ID-" x) | |
2342 | x)))) | |
2343 | (org-html--anchor id))) | |
2344 | extra-ids "") | |
2345 | full-text | |
2346 | level1) | |
2347 | ;; When there is no section, pretend there is an empty | |
2348 | ;; one to get the correct <div class="outline- ...> | |
2349 | ;; which is needed by `org-info.js'. | |
2350 | (if (not (eq (org-element-type first-content) 'section)) | |
2351 | (concat (org-html-section first-content "" info) | |
2352 | contents) | |
2353 | contents) | |
2354 | (org-html--container headline info))))))) | |
2355 | ||
2356 | (defun org-html--container (headline info) | |
2357 | (or (org-element-property :HTML_CONTAINER headline) | |
2358 | (if (= 1 (org-export-get-relative-level headline info)) | |
2359 | (plist-get info :html-container) | |
2360 | "div"))) | |
2361 | ||
2362 | ;;;; Horizontal Rule | |
2363 | ||
2364 | (defun org-html-horizontal-rule (horizontal-rule contents info) | |
2365 | "Transcode an HORIZONTAL-RULE object from Org to HTML. | |
2366 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2367 | (org-html-close-tag "hr" nil info)) | |
2368 | ||
2369 | ;;;; Inline Src Block | |
2370 | ||
2371 | (defun org-html-inline-src-block (inline-src-block contents info) | |
2372 | "Transcode an INLINE-SRC-BLOCK element from Org to HTML. | |
2373 | CONTENTS holds the contents of the item. INFO is a plist holding | |
2374 | contextual information." | |
2375 | (let* ((org-lang (org-element-property :language inline-src-block)) | |
2376 | (code (org-element-property :value inline-src-block))) | |
2377 | (error "Cannot export inline src block"))) | |
2378 | ||
2379 | ;;;; Inlinetask | |
2380 | ||
2381 | (defun org-html-format-section (text class &optional id) | |
2382 | "Format a section with TEXT into a HTML div with CLASS and ID." | |
2383 | (let ((extra (concat (when id (format " id=\"%s\"" id))))) | |
2384 | (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n"))) | |
2385 | ||
2386 | (defun org-html-inlinetask (inlinetask contents info) | |
2387 | "Transcode an INLINETASK element from Org to HTML. | |
2388 | CONTENTS holds the contents of the block. INFO is a plist | |
2389 | holding contextual information." | |
2390 | (cond | |
73d3db82 | 2391 | ;; If `org-html-format-inlinetask-function' is not 'ignore, call it |
271672fa | 2392 | ;; with appropriate arguments. |
73d3db82 | 2393 | ((not (eq org-html-format-inlinetask-function 'ignore)) |
271672fa BG |
2394 | (let ((format-function |
2395 | (function* | |
2396 | (lambda (todo todo-type priority text tags | |
2397 | &key contents &allow-other-keys) | |
2398 | (funcall org-html-format-inlinetask-function | |
2399 | todo todo-type priority text tags contents))))) | |
2400 | (org-html-format-headline--wrap | |
2401 | inlinetask info format-function :contents contents))) | |
2402 | ;; Otherwise, use a default template. | |
2403 | (t (format "<div class=\"inlinetask\">\n<b>%s</b>%s\n%s</div>" | |
2404 | (org-html-format-headline--wrap inlinetask info) | |
2405 | (org-html-close-tag "br" nil info) | |
2406 | contents)))) | |
2407 | ||
2408 | ;;;; Italic | |
2409 | ||
2410 | (defun org-html-italic (italic contents info) | |
2411 | "Transcode ITALIC from Org to HTML. | |
2412 | CONTENTS is the text with italic markup. INFO is a plist holding | |
2413 | contextual information." | |
2414 | (format (or (cdr (assq 'italic org-html-text-markup-alist)) "%s") contents)) | |
2415 | ||
2416 | ;;;; Item | |
2417 | ||
2418 | (defun org-html-checkbox (checkbox) | |
2419 | "Format CHECKBOX into HTML." | |
2420 | (case checkbox (on "<code>[X]</code>") | |
2421 | (off "<code>[ ]</code>") | |
2422 | (trans "<code>[-]</code>") | |
2423 | (t ""))) | |
2424 | ||
2425 | (defun org-html-format-list-item (contents type checkbox info | |
2426 | &optional term-counter-id | |
2427 | headline) | |
2428 | "Format a list item into HTML." | |
2429 | (let ((checkbox (concat (org-html-checkbox checkbox) (and checkbox " "))) | |
2430 | (br (org-html-close-tag "br" nil info))) | |
2431 | (concat | |
2432 | (case type | |
2433 | (ordered | |
2434 | (let* ((counter term-counter-id) | |
2435 | (extra (if counter (format " value=\"%s\"" counter) ""))) | |
2436 | (concat | |
2437 | (format "<li%s>" extra) | |
2438 | (when headline (concat headline br))))) | |
2439 | (unordered | |
2440 | (let* ((id term-counter-id) | |
2441 | (extra (if id (format " id=\"%s\"" id) ""))) | |
2442 | (concat | |
2443 | (format "<li%s>" extra) | |
2444 | (when headline (concat headline br))))) | |
2445 | (descriptive | |
2446 | (let* ((term term-counter-id)) | |
2447 | (setq term (or term "(no term)")) | |
2448 | ;; Check-boxes in descriptive lists are associated to tag. | |
2449 | (concat (format "<dt> %s </dt>" | |
2450 | (concat checkbox term)) | |
2451 | "<dd>")))) | |
2452 | (unless (eq type 'descriptive) checkbox) | |
2453 | contents | |
2454 | (case type | |
2455 | (ordered "</li>") | |
2456 | (unordered "</li>") | |
2457 | (descriptive "</dd>"))))) | |
2458 | ||
2459 | (defun org-html-item (item contents info) | |
2460 | "Transcode an ITEM element from Org to HTML. | |
2461 | CONTENTS holds the contents of the item. INFO is a plist holding | |
2462 | contextual information." | |
2463 | (let* ((plain-list (org-export-get-parent item)) | |
2464 | (type (org-element-property :type plain-list)) | |
2465 | (counter (org-element-property :counter item)) | |
2466 | (checkbox (org-element-property :checkbox item)) | |
2467 | (tag (let ((tag (org-element-property :tag item))) | |
2468 | (and tag (org-export-data tag info))))) | |
2469 | (org-html-format-list-item | |
2470 | contents type checkbox info (or tag counter)))) | |
2471 | ||
2472 | ;;;; Keyword | |
2473 | ||
2474 | (defun org-html-keyword (keyword contents info) | |
2475 | "Transcode a KEYWORD element from Org to HTML. | |
2476 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2477 | (let ((key (org-element-property :key keyword)) | |
2478 | (value (org-element-property :value keyword))) | |
2479 | (cond | |
2480 | ((string= key "HTML") value) | |
2481 | ((string= key "TOC") | |
2482 | (let ((value (downcase value))) | |
2483 | (cond | |
2484 | ((string-match "\\<headlines\\>" value) | |
2485 | (let ((depth (or (and (string-match "[0-9]+" value) | |
2486 | (string-to-number (match-string 0 value))) | |
2487 | (plist-get info :with-toc)))) | |
2488 | (org-html-toc depth info))) | |
2489 | ((string= "listings" value) (org-html-list-of-listings info)) | |
2490 | ((string= "tables" value) (org-html-list-of-tables info)))))))) | |
2491 | ||
2492 | ;;;; Latex Environment | |
2493 | ||
73d3db82 BG |
2494 | (defun org-html-format-latex (latex-frag processing-type info) |
2495 | "Format a LaTeX fragment LATEX-FRAG into HTML. | |
2496 | PROCESSING-TYPE designates the tool used for conversion. It is | |
2497 | a symbol among `mathjax', `dvipng', `imagemagick', `verbatim' nil | |
2498 | and t. See `org-html-with-latex' for more information. INFO is | |
2499 | a plist containing export properties." | |
271672fa BG |
2500 | (let ((cache-relpath "") (cache-dir "")) |
2501 | (unless (eq processing-type 'mathjax) | |
2502 | (let ((bfn (or (buffer-file-name) | |
2503 | (make-temp-name | |
73d3db82 BG |
2504 | (expand-file-name "latex" temporary-file-directory)))) |
2505 | (latex-header | |
2506 | (let ((header (plist-get info :latex-header))) | |
2507 | (and header | |
2508 | (concat (mapconcat | |
2509 | (lambda (line) (concat "#+LATEX_HEADER: " line)) | |
2510 | (org-split-string header "\n") | |
2511 | "\n") | |
2512 | "\n"))))) | |
271672fa BG |
2513 | (setq cache-relpath |
2514 | (concat "ltxpng/" | |
2515 | (file-name-sans-extension | |
2516 | (file-name-nondirectory bfn))) | |
73d3db82 BG |
2517 | cache-dir (file-name-directory bfn)) |
2518 | ;; Re-create LaTeX environment from original buffer in | |
2519 | ;; temporary buffer so that dvipng/imagemagick can properly | |
2520 | ;; turn the fragment into an image. | |
2521 | (setq latex-frag (concat latex-header latex-frag)))) | |
271672fa BG |
2522 | (with-temp-buffer |
2523 | (insert latex-frag) | |
2524 | (org-format-latex cache-relpath cache-dir nil "Creating LaTeX Image..." | |
2525 | nil nil processing-type) | |
2526 | (buffer-string)))) | |
2527 | ||
2528 | (defun org-html-latex-environment (latex-environment contents info) | |
2529 | "Transcode a LATEX-ENVIRONMENT element from Org to HTML. | |
2530 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2531 | (let ((processing-type (plist-get info :with-latex)) | |
2532 | (latex-frag (org-remove-indentation | |
2533 | (org-element-property :value latex-environment))) | |
2534 | (attributes (org-export-read-attribute :attr_html latex-environment))) | |
2535 | (case processing-type | |
2536 | ((t mathjax) | |
73d3db82 | 2537 | (org-html-format-latex latex-frag 'mathjax info)) |
271672fa | 2538 | ((dvipng imagemagick) |
73d3db82 BG |
2539 | (let ((formula-link |
2540 | (org-html-format-latex latex-frag processing-type info))) | |
271672fa BG |
2541 | (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) |
2542 | ;; Do not provide a caption or a name to be consistent with | |
2543 | ;; `mathjax' handling. | |
2544 | (org-html--wrap-image | |
2545 | (org-html--format-image | |
2546 | (match-string 1 formula-link) attributes info) info)))) | |
2547 | (t latex-frag)))) | |
2548 | ||
2549 | ;;;; Latex Fragment | |
2550 | ||
2551 | (defun org-html-latex-fragment (latex-fragment contents info) | |
2552 | "Transcode a LATEX-FRAGMENT object from Org to HTML. | |
2553 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2554 | (let ((latex-frag (org-element-property :value latex-fragment)) | |
2555 | (processing-type (plist-get info :with-latex))) | |
2556 | (case processing-type | |
2557 | ((t mathjax) | |
73d3db82 | 2558 | (org-html-format-latex latex-frag 'mathjax info)) |
271672fa | 2559 | ((dvipng imagemagick) |
73d3db82 BG |
2560 | (let ((formula-link |
2561 | (org-html-format-latex latex-frag processing-type info))) | |
271672fa BG |
2562 | (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) |
2563 | (org-html--format-image (match-string 1 formula-link) nil info)))) | |
2564 | (t latex-frag)))) | |
2565 | ||
2566 | ;;;; Line Break | |
2567 | ||
2568 | (defun org-html-line-break (line-break contents info) | |
2569 | "Transcode a LINE-BREAK object from Org to HTML. | |
2570 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2571 | (concat (org-html-close-tag "br" nil info) "\n")) | |
2572 | ||
2573 | ;;;; Link | |
2574 | ||
2575 | (defun org-html-inline-image-p (link info) | |
2576 | "Non-nil when LINK is meant to appear as an image. | |
2577 | INFO is a plist used as a communication channel. LINK is an | |
2578 | inline image when it has no description and targets an image | |
2579 | file (see `org-html-inline-image-rules' for more information), or | |
2580 | if its description is a single link targeting an image file." | |
2581 | (if (not (org-element-contents link)) | |
2582 | (org-export-inline-image-p link org-html-inline-image-rules) | |
2583 | (not | |
2584 | (let ((link-count 0)) | |
2585 | (org-element-map (org-element-contents link) | |
2586 | (cons 'plain-text org-element-all-objects) | |
2587 | (lambda (obj) | |
2588 | (case (org-element-type obj) | |
2589 | (plain-text (org-string-nw-p obj)) | |
2590 | (link (if (= link-count 1) t | |
2591 | (incf link-count) | |
2592 | (not (org-export-inline-image-p | |
2593 | obj org-html-inline-image-rules)))) | |
2594 | (otherwise t))) | |
2595 | info t))))) | |
2596 | ||
2597 | (defvar org-html-standalone-image-predicate) | |
2598 | (defun org-html-standalone-image-p (element info) | |
2599 | "Test if ELEMENT is a standalone image. | |
2600 | ||
2601 | INFO is a plist holding contextual information. | |
2602 | ||
2603 | Return non-nil, if ELEMENT is of type paragraph and its sole | |
2604 | content, save for white spaces, is a link that qualifies as an | |
2605 | inline image. | |
2606 | ||
2607 | Return non-nil, if ELEMENT is of type link and its containing | |
2608 | paragraph has no other content save white spaces. | |
2609 | ||
2610 | Return nil, otherwise. | |
2611 | ||
2612 | Bind `org-html-standalone-image-predicate' to constrain paragraph | |
2613 | further. For example, to check for only captioned standalone | |
2614 | images, set it to: | |
2615 | ||
2616 | \(lambda (paragraph) (org-element-property :caption paragraph))" | |
2617 | (let ((paragraph (case (org-element-type element) | |
2618 | (paragraph element) | |
2619 | (link (org-export-get-parent element))))) | |
2620 | (and (eq (org-element-type paragraph) 'paragraph) | |
2621 | (or (not (and (boundp 'org-html-standalone-image-predicate) | |
2622 | (functionp org-html-standalone-image-predicate))) | |
2623 | (funcall org-html-standalone-image-predicate paragraph)) | |
2624 | (not (let ((link-count 0)) | |
2625 | (org-element-map (org-element-contents paragraph) | |
2626 | (cons 'plain-text org-element-all-objects) | |
2627 | (lambda (obj) (case (org-element-type obj) | |
2628 | (plain-text (org-string-nw-p obj)) | |
2629 | (link | |
2630 | (or (> (incf link-count) 1) | |
2631 | (not (org-html-inline-image-p obj info)))) | |
2632 | (otherwise t))) | |
2633 | info 'first-match 'link)))))) | |
2634 | ||
2635 | (defun org-html-link (link desc info) | |
2636 | "Transcode a LINK object from Org to HTML. | |
2637 | ||
2638 | DESC is the description part of the link, or the empty string. | |
2639 | INFO is a plist holding contextual information. See | |
2640 | `org-export-data'." | |
2641 | (let* ((home (when (plist-get info :html-link-home) | |
2642 | (org-trim (plist-get info :html-link-home)))) | |
2643 | (use-abs-url (plist-get info :html-link-use-abs-url)) | |
2644 | (link-org-files-as-html-maybe | |
2645 | (function | |
2646 | (lambda (raw-path info) | |
2647 | "Treat links to `file.org' as links to `file.html', if needed. | |
2648 | See `org-html-link-org-files-as-html'." | |
2649 | (cond | |
2650 | ((and org-html-link-org-files-as-html | |
2651 | (string= ".org" | |
2652 | (downcase (file-name-extension raw-path ".")))) | |
2653 | (concat (file-name-sans-extension raw-path) "." | |
2654 | (plist-get info :html-extension))) | |
2655 | (t raw-path))))) | |
2656 | (type (org-element-property :type link)) | |
2657 | (raw-path (org-element-property :path link)) | |
2658 | ;; Ensure DESC really exists, or set it to nil. | |
2659 | (desc (org-string-nw-p desc)) | |
2660 | (path | |
2661 | (cond | |
2662 | ((member type '("http" "https" "ftp" "mailto")) | |
30cb51f1 BG |
2663 | (org-link-escape |
2664 | (org-link-unescape | |
2665 | (concat type ":" raw-path)) org-link-escape-chars-browser)) | |
271672fa BG |
2666 | ((string= type "file") |
2667 | ;; Treat links to ".org" files as ".html", if needed. | |
2668 | (setq raw-path | |
2669 | (funcall link-org-files-as-html-maybe raw-path info)) | |
2670 | ;; If file path is absolute, prepend it with protocol | |
30cb51f1 BG |
2671 | ;; component - "file:". |
2672 | (cond | |
2673 | ((file-name-absolute-p raw-path) | |
2674 | (setq raw-path (concat "file:" raw-path))) | |
2675 | ((and home use-abs-url) | |
2676 | (setq raw-path (concat (file-name-as-directory home) raw-path)))) | |
271672fa BG |
2677 | ;; Add search option, if any. A search option can be |
2678 | ;; relative to a custom-id or a headline title. Any other | |
2679 | ;; option is ignored. | |
2680 | (let ((option (org-element-property :search-option link))) | |
2681 | (cond ((not option) raw-path) | |
2682 | ((eq (aref option 0) ?#) (concat raw-path option)) | |
2683 | ;; External fuzzy link: try to resolve it if path | |
2684 | ;; belongs to current project, if any. | |
2685 | ((eq (aref option 0) ?*) | |
2686 | (concat | |
2687 | raw-path | |
2688 | (let ((numbers | |
2689 | (org-publish-resolve-external-fuzzy-link | |
2690 | (org-element-property :path link) option))) | |
2691 | (and numbers (concat "#sec-" | |
2692 | (mapconcat 'number-to-string | |
2693 | numbers "-")))))) | |
2694 | (t raw-path)))) | |
2695 | (t raw-path))) | |
2696 | ;; Extract attributes from parent's paragraph. HACK: Only do | |
2697 | ;; this for the first link in parent (inner image link for | |
2698 | ;; inline images). This is needed as long as attributes | |
2699 | ;; cannot be set on a per link basis. | |
2700 | (attributes-plist | |
2701 | (let* ((parent (org-export-get-parent-element link)) | |
2702 | (link (let ((container (org-export-get-parent link))) | |
2703 | (if (and (eq (org-element-type container) 'link) | |
2704 | (org-html-inline-image-p link info)) | |
2705 | container | |
2706 | link)))) | |
2707 | (and (eq (org-element-map parent 'link 'identity info t) link) | |
2708 | (org-export-read-attribute :attr_html parent)))) | |
2709 | (attributes | |
2710 | (let ((attr (org-html--make-attribute-string attributes-plist))) | |
2711 | (if (org-string-nw-p attr) (concat " " attr) ""))) | |
2712 | protocol) | |
2713 | (cond | |
2714 | ;; Image file. | |
2715 | ((and org-html-inline-images | |
2716 | (org-export-inline-image-p link org-html-inline-image-rules)) | |
2717 | (org-html--format-image path attributes-plist info)) | |
2718 | ;; Radio target: Transcode target's contents and use them as | |
2719 | ;; link's description. | |
2720 | ((string= type "radio") | |
2721 | (let ((destination (org-export-resolve-radio-link link info))) | |
2722 | (when destination | |
2723 | (format "<a href=\"#%s\"%s>%s</a>" | |
30cb51f1 BG |
2724 | (org-export-solidify-link-text |
2725 | (org-element-property :value destination)) | |
2726 | attributes desc)))) | |
271672fa BG |
2727 | ;; Links pointing to a headline: Find destination and build |
2728 | ;; appropriate referencing command. | |
2729 | ((member type '("custom-id" "fuzzy" "id")) | |
2730 | (let ((destination (if (string= type "fuzzy") | |
2731 | (org-export-resolve-fuzzy-link link info) | |
2732 | (org-export-resolve-id-link link info)))) | |
2733 | (case (org-element-type destination) | |
2734 | ;; ID link points to an external file. | |
2735 | (plain-text | |
2736 | (let ((fragment (concat "ID-" path)) | |
2737 | ;; Treat links to ".org" files as ".html", if needed. | |
2738 | (path (funcall link-org-files-as-html-maybe | |
2739 | destination info))) | |
2740 | (format "<a href=\"%s#%s\"%s>%s</a>" | |
2741 | path fragment attributes (or desc destination)))) | |
2742 | ;; Fuzzy link points nowhere. | |
2743 | ((nil) | |
2744 | (format "<i>%s</i>" | |
2745 | (or desc | |
2746 | (org-export-data | |
2747 | (org-element-property :raw-link link) info)))) | |
2748 | ;; Link points to a headline. | |
2749 | (headline | |
2750 | (let ((href | |
2751 | ;; What href to use? | |
2752 | (cond | |
2753 | ;; Case 1: Headline is linked via it's CUSTOM_ID | |
2754 | ;; property. Use CUSTOM_ID. | |
2755 | ((string= type "custom-id") | |
2756 | (org-element-property :CUSTOM_ID destination)) | |
2757 | ;; Case 2: Headline is linked via it's ID property | |
2758 | ;; or through other means. Use the default href. | |
2759 | ((member type '("id" "fuzzy")) | |
2760 | (format "sec-%s" | |
2761 | (mapconcat 'number-to-string | |
2762 | (org-export-get-headline-number | |
2763 | destination info) "-"))) | |
2764 | (t (error "Shouldn't reach here")))) | |
2765 | ;; What description to use? | |
2766 | (desc | |
2767 | ;; Case 1: Headline is numbered and LINK has no | |
2768 | ;; description. Display section number. | |
2769 | (if (and (org-export-numbered-headline-p destination info) | |
2770 | (not desc)) | |
2771 | (mapconcat 'number-to-string | |
2772 | (org-export-get-headline-number | |
2773 | destination info) ".") | |
2774 | ;; Case 2: Either the headline is un-numbered or | |
2775 | ;; LINK has a custom description. Display LINK's | |
2776 | ;; description or headline's title. | |
2777 | (or desc (org-export-data (org-element-property | |
2778 | :title destination) info))))) | |
2779 | (format "<a href=\"#%s\"%s>%s</a>" | |
2780 | (org-export-solidify-link-text href) attributes desc))) | |
2781 | ;; Fuzzy link points to a target or an element. | |
2782 | (t | |
2783 | (let* ((path (org-export-solidify-link-text path)) | |
2784 | (org-html-standalone-image-predicate 'org-html--has-caption-p) | |
2785 | (number (cond | |
2786 | (desc nil) | |
2787 | ((org-html-standalone-image-p destination info) | |
2788 | (org-export-get-ordinal | |
2789 | (org-element-map destination 'link | |
2790 | 'identity info t) | |
2791 | info 'link 'org-html-standalone-image-p)) | |
2792 | (t (org-export-get-ordinal | |
2793 | destination info nil 'org-html--has-caption-p)))) | |
2794 | (desc (cond (desc) | |
2795 | ((not number) "No description for this link") | |
2796 | ((numberp number) (number-to-string number)) | |
2797 | (t (mapconcat 'number-to-string number "."))))) | |
2798 | (format "<a href=\"#%s\"%s>%s</a>" path attributes desc)))))) | |
2799 | ;; Coderef: replace link with the reference name or the | |
2800 | ;; equivalent line number. | |
2801 | ((string= type "coderef") | |
2802 | (let ((fragment (concat "coderef-" path))) | |
2803 | (format "<a href=\"#%s\"%s%s>%s</a>" | |
2804 | fragment | |
2805 | (org-trim | |
2806 | (format (concat "class=\"coderef\"" | |
2807 | " onmouseover=\"CodeHighlightOn(this, '%s');\"" | |
2808 | " onmouseout=\"CodeHighlightOff(this, '%s');\"") | |
2809 | fragment fragment)) | |
2810 | attributes | |
2811 | (format (org-export-get-coderef-format path desc) | |
2812 | (org-export-resolve-coderef path info))))) | |
2813 | ;; Link type is handled by a special function. | |
2814 | ((functionp (setq protocol (nth 2 (assoc type org-link-protocols)))) | |
2815 | (funcall protocol (org-link-unescape path) desc 'html)) | |
2816 | ;; External link with a description part. | |
2817 | ((and path desc) (format "<a href=\"%s\"%s>%s</a>" path attributes desc)) | |
2818 | ;; External link without a description part. | |
2819 | (path (format "<a href=\"%s\"%s>%s</a>" path attributes path)) | |
2820 | ;; No path, only description. Try to do something useful. | |
2821 | (t (format "<i>%s</i>" desc))))) | |
2822 | ||
2823 | ;;;; Paragraph | |
2824 | ||
2825 | (defun org-html-paragraph (paragraph contents info) | |
2826 | "Transcode a PARAGRAPH element from Org to HTML. | |
2827 | CONTENTS is the contents of the paragraph, as a string. INFO is | |
2828 | the plist used as a communication channel." | |
2829 | (let* ((parent (org-export-get-parent paragraph)) | |
2830 | (parent-type (org-element-type parent)) | |
2831 | (style '((footnote-definition " class=\"footpara\""))) | |
2832 | (extra (or (cadr (assoc parent-type style)) ""))) | |
2833 | (cond | |
2834 | ((and (eq (org-element-type parent) 'item) | |
2835 | (= (org-element-property :begin paragraph) | |
2836 | (org-element-property :contents-begin parent))) | |
2837 | ;; Leading paragraph in a list item have no tags. | |
2838 | contents) | |
2839 | ((org-html-standalone-image-p paragraph info) | |
2840 | ;; Standalone image. | |
2841 | (let ((caption | |
2842 | (let ((raw (org-export-data | |
2843 | (org-export-get-caption paragraph) info)) | |
2844 | (org-html-standalone-image-predicate | |
2845 | 'org-html--has-caption-p)) | |
2846 | (if (not (org-string-nw-p raw)) raw | |
2847 | (concat | |
2848 | "<span class=\"figure-number\">" | |
2849 | (format (org-html--translate "Figure %d:" info) | |
2850 | (org-export-get-ordinal | |
2851 | (org-element-map paragraph 'link | |
2852 | 'identity info t) | |
2853 | info nil 'org-html-standalone-image-p)) | |
2854 | "</span> " raw)))) | |
2855 | (label (org-element-property :name paragraph))) | |
2856 | (org-html--wrap-image contents info caption label))) | |
2857 | ;; Regular paragraph. | |
2858 | (t (format "<p%s>\n%s</p>" extra contents))))) | |
2859 | ||
2860 | ;;;; Plain List | |
2861 | ||
2862 | ;; FIXME Maybe arg1 is not needed because <li value="20"> already sets | |
2863 | ;; the correct value for the item counter | |
2864 | (defun org-html-begin-plain-list (type &optional arg1) | |
2865 | "Insert the beginning of the HTML list depending on TYPE. | |
2866 | When ARG1 is a string, use it as the start parameter for ordered | |
2867 | lists." | |
2868 | (case type | |
2869 | (ordered | |
2870 | (format "<ol class=\"org-ol\"%s>" | |
2871 | (if arg1 (format " start=\"%d\"" arg1) ""))) | |
2872 | (unordered "<ul class=\"org-ul\">") | |
2873 | (descriptive "<dl class=\"org-dl\">"))) | |
2874 | ||
2875 | (defun org-html-end-plain-list (type) | |
2876 | "Insert the end of the HTML list depending on TYPE." | |
2877 | (case type | |
2878 | (ordered "</ol>") | |
2879 | (unordered "</ul>") | |
2880 | (descriptive "</dl>"))) | |
2881 | ||
2882 | (defun org-html-plain-list (plain-list contents info) | |
2883 | "Transcode a PLAIN-LIST element from Org to HTML. | |
2884 | CONTENTS is the contents of the list. INFO is a plist holding | |
2885 | contextual information." | |
2886 | (let* (arg1 ;; (assoc :counter (org-element-map plain-list 'item | |
2887 | (type (org-element-property :type plain-list))) | |
2888 | (format "%s\n%s%s" | |
2889 | (org-html-begin-plain-list type) | |
2890 | contents (org-html-end-plain-list type)))) | |
2891 | ||
2892 | ;;;; Plain Text | |
2893 | ||
2894 | (defun org-html-convert-special-strings (string) | |
2895 | "Convert special characters in STRING to HTML." | |
2896 | (let ((all org-html-special-string-regexps) | |
2897 | e a re rpl start) | |
2898 | (while (setq a (pop all)) | |
2899 | (setq re (car a) rpl (cdr a) start 0) | |
2900 | (while (string-match re string start) | |
2901 | (setq string (replace-match rpl t nil string)))) | |
2902 | string)) | |
2903 | ||
2904 | (defun org-html-encode-plain-text (text) | |
2905 | "Convert plain text characters from TEXT to HTML equivalent. | |
2906 | Possible conversions are set in `org-html-protect-char-alist'." | |
2907 | (mapc | |
2908 | (lambda (pair) | |
2909 | (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t))) | |
2910 | org-html-protect-char-alist) | |
2911 | text) | |
2912 | ||
2913 | (defun org-html-plain-text (text info) | |
2914 | "Transcode a TEXT string from Org to HTML. | |
2915 | TEXT is the string to transcode. INFO is a plist holding | |
2916 | contextual information." | |
2917 | (let ((output text)) | |
2918 | ;; Protect following characters: <, >, &. | |
2919 | (setq output (org-html-encode-plain-text output)) | |
2920 | ;; Handle smart quotes. Be sure to provide original string since | |
2921 | ;; OUTPUT may have been modified. | |
2922 | (when (plist-get info :with-smart-quotes) | |
2923 | (setq output (org-export-activate-smart-quotes output :html info text))) | |
2924 | ;; Handle special strings. | |
2925 | (when (plist-get info :with-special-strings) | |
2926 | (setq output (org-html-convert-special-strings output))) | |
2927 | ;; Handle break preservation if required. | |
2928 | (when (plist-get info :preserve-breaks) | |
2929 | (setq output | |
2930 | (replace-regexp-in-string | |
2931 | "\\(\\\\\\\\\\)?[ \t]*\n" | |
2932 | (concat (org-html-close-tag "br" nil info) "\n") output))) | |
2933 | ;; Return value. | |
2934 | output)) | |
2935 | ||
2936 | ||
2937 | ;; Planning | |
2938 | ||
2939 | (defun org-html-planning (planning contents info) | |
2940 | "Transcode a PLANNING element from Org to HTML. | |
2941 | CONTENTS is nil. INFO is a plist used as a communication | |
2942 | channel." | |
2943 | (let ((span-fmt "<span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>")) | |
2944 | (format | |
2945 | "<p><span class=\"timestamp-wrapper\">%s</span></p>" | |
2946 | (mapconcat | |
2947 | 'identity | |
2948 | (delq nil | |
2949 | (list | |
2950 | (let ((closed (org-element-property :closed planning))) | |
2951 | (when closed | |
2952 | (format span-fmt org-closed-string | |
2953 | (org-translate-time | |
2954 | (org-element-property :raw-value closed))))) | |
2955 | (let ((deadline (org-element-property :deadline planning))) | |
2956 | (when deadline | |
2957 | (format span-fmt org-deadline-string | |
2958 | (org-translate-time | |
2959 | (org-element-property :raw-value deadline))))) | |
2960 | (let ((scheduled (org-element-property :scheduled planning))) | |
2961 | (when scheduled | |
2962 | (format span-fmt org-scheduled-string | |
2963 | (org-translate-time | |
2964 | (org-element-property :raw-value scheduled))))))) | |
2965 | " ")))) | |
2966 | ||
2967 | ;;;; Property Drawer | |
2968 | ||
2969 | (defun org-html-property-drawer (property-drawer contents info) | |
2970 | "Transcode a PROPERTY-DRAWER element from Org to HTML. | |
2971 | CONTENTS is nil. INFO is a plist holding contextual | |
2972 | information." | |
2973 | ;; The property drawer isn't exported but we want separating blank | |
2974 | ;; lines nonetheless. | |
2975 | "") | |
2976 | ||
2977 | ;;;; Quote Block | |
2978 | ||
2979 | (defun org-html-quote-block (quote-block contents info) | |
2980 | "Transcode a QUOTE-BLOCK element from Org to HTML. | |
2981 | CONTENTS holds the contents of the block. INFO is a plist | |
2982 | holding contextual information." | |
2983 | (format "<blockquote>\n%s</blockquote>" contents)) | |
2984 | ||
2985 | ;;;; Quote Section | |
2986 | ||
2987 | (defun org-html-quote-section (quote-section contents info) | |
2988 | "Transcode a QUOTE-SECTION element from Org to HTML. | |
2989 | CONTENTS is nil. INFO is a plist holding contextual information." | |
2990 | (let ((value (org-remove-indentation | |
2991 | (org-element-property :value quote-section)))) | |
2992 | (when value (format "<pre>\n%s</pre>" value)))) | |
2993 | ||
2994 | ;;;; Section | |
2995 | ||
2996 | (defun org-html-section (section contents info) | |
2997 | "Transcode a SECTION element from Org to HTML. | |
2998 | CONTENTS holds the contents of the section. INFO is a plist | |
2999 | holding contextual information." | |
3000 | (let ((parent (org-export-get-parent-headline section))) | |
3001 | ;; Before first headline: no container, just return CONTENTS. | |
3002 | (if (not parent) contents | |
3003 | ;; Get div's class and id references. | |
3004 | (let* ((class-num (+ (org-export-get-relative-level parent info) | |
3005 | (1- org-html-toplevel-hlevel))) | |
3006 | (section-number | |
3007 | (mapconcat | |
3008 | 'number-to-string | |
3009 | (org-export-get-headline-number parent info) "-"))) | |
3010 | ;; Build return value. | |
3011 | (format "<div class=\"outline-text-%d\" id=\"text-%s\">\n%s</div>" | |
3012 | class-num | |
3013 | (or (org-element-property :CUSTOM_ID parent) section-number) | |
3014 | contents))))) | |
3015 | ||
3016 | ;;;; Radio Target | |
3017 | ||
3018 | (defun org-html-radio-target (radio-target text info) | |
3019 | "Transcode a RADIO-TARGET object from Org to HTML. | |
3020 | TEXT is the text of the target. INFO is a plist holding | |
3021 | contextual information." | |
3022 | (let ((id (org-export-solidify-link-text | |
3023 | (org-element-property :value radio-target)))) | |
3024 | (org-html--anchor id text))) | |
3025 | ||
3026 | ;;;; Special Block | |
3027 | ||
3028 | (defun org-html-special-block (special-block contents info) | |
3029 | "Transcode a SPECIAL-BLOCK element from Org to HTML. | |
3030 | CONTENTS holds the contents of the block. INFO is a plist | |
3031 | holding contextual information." | |
3032 | (let* ((block-type (downcase | |
3033 | (org-element-property :type special-block))) | |
3034 | (contents (or contents "")) | |
3035 | (html5-fancy (and (org-html-html5-p info) | |
3036 | (plist-get info :html-html5-fancy) | |
3037 | (member block-type org-html-html5-elements))) | |
3038 | (attributes (org-export-read-attribute :attr_html special-block))) | |
3039 | (unless html5-fancy | |
3040 | (let ((class (plist-get attributes :class))) | |
3041 | (setq attributes (plist-put attributes :class | |
3042 | (if class (concat class " " block-type) | |
3043 | block-type))))) | |
3044 | (setq attributes (org-html--make-attribute-string attributes)) | |
3045 | (when (not (equal attributes "")) | |
3046 | (setq attributes (concat " " attributes))) | |
3047 | (if html5-fancy | |
3048 | (format "<%s%s>\n%s</%s>" block-type attributes | |
3049 | contents block-type) | |
3050 | (format "<div%s>\n%s\n</div>" attributes contents)))) | |
3051 | ||
3052 | ;;;; Src Block | |
3053 | ||
3054 | (defun org-html-src-block (src-block contents info) | |
3055 | "Transcode a SRC-BLOCK element from Org to HTML. | |
3056 | CONTENTS holds the contents of the item. INFO is a plist holding | |
3057 | contextual information." | |
3058 | (if (org-export-read-attribute :attr_html src-block :textarea) | |
3059 | (org-html--textarea-block src-block) | |
3060 | (let ((lang (org-element-property :language src-block)) | |
3061 | (caption (org-export-get-caption src-block)) | |
3062 | (code (org-html-format-code src-block info)) | |
3063 | (label (let ((lbl (org-element-property :name src-block))) | |
3064 | (if (not lbl) "" | |
3065 | (format " id=\"%s\"" | |
3066 | (org-export-solidify-link-text lbl)))))) | |
3067 | (if (not lang) (format "<pre class=\"example\"%s>\n%s</pre>" label code) | |
3068 | (format | |
3069 | "<div class=\"org-src-container\">\n%s%s\n</div>" | |
3070 | (if (not caption) "" | |
3071 | (format "<label class=\"org-src-name\">%s</label>" | |
3072 | (org-export-data caption info))) | |
3073 | (format "\n<pre class=\"src src-%s\"%s>%s</pre>" lang label code)))))) | |
3074 | ||
3075 | ;;;; Statistics Cookie | |
3076 | ||
3077 | (defun org-html-statistics-cookie (statistics-cookie contents info) | |
3078 | "Transcode a STATISTICS-COOKIE object from Org to HTML. | |
3079 | CONTENTS is nil. INFO is a plist holding contextual information." | |
3080 | (let ((cookie-value (org-element-property :value statistics-cookie))) | |
3081 | (format "<code>%s</code>" cookie-value))) | |
3082 | ||
3083 | ;;;; Strike-Through | |
3084 | ||
3085 | (defun org-html-strike-through (strike-through contents info) | |
3086 | "Transcode STRIKE-THROUGH from Org to HTML. | |
3087 | CONTENTS is the text with strike-through markup. INFO is a plist | |
3088 | holding contextual information." | |
3089 | (format (or (cdr (assq 'strike-through org-html-text-markup-alist)) "%s") | |
3090 | contents)) | |
3091 | ||
3092 | ;;;; Subscript | |
3093 | ||
3094 | (defun org-html-subscript (subscript contents info) | |
3095 | "Transcode a SUBSCRIPT object from Org to HTML. | |
3096 | CONTENTS is the contents of the object. INFO is a plist holding | |
3097 | contextual information." | |
3098 | (format "<sub>%s</sub>" contents)) | |
3099 | ||
3100 | ;;;; Superscript | |
3101 | ||
3102 | (defun org-html-superscript (superscript contents info) | |
3103 | "Transcode a SUPERSCRIPT object from Org to HTML. | |
3104 | CONTENTS is the contents of the object. INFO is a plist holding | |
3105 | contextual information." | |
3106 | (format "<sup>%s</sup>" contents)) | |
3107 | ||
d1389828 | 3108 | ;;;; Table Cell |
271672fa BG |
3109 | |
3110 | (defun org-html-table-cell (table-cell contents info) | |
3111 | "Transcode a TABLE-CELL element from Org to HTML. | |
3112 | CONTENTS is nil. INFO is a plist used as a communication | |
3113 | channel." | |
3114 | (let* ((table-row (org-export-get-parent table-cell)) | |
3115 | (table (org-export-get-parent-table table-cell)) | |
3116 | (cell-attrs | |
3117 | (if (not org-html-table-align-individual-fields) "" | |
3118 | (format (if (and (boundp 'org-html-format-table-no-css) | |
3119 | org-html-format-table-no-css) | |
3120 | " align=\"%s\"" " class=\"%s\"") | |
3121 | (org-export-table-cell-alignment table-cell info))))) | |
3122 | (when (or (not contents) (string= "" (org-trim contents))) | |
3123 | (setq contents " ")) | |
3124 | (cond | |
3125 | ((and (org-export-table-has-header-p table info) | |
3126 | (= 1 (org-export-table-row-group table-row info))) | |
3127 | (concat "\n" (format (car org-html-table-header-tags) "col" cell-attrs) | |
3128 | contents (cdr org-html-table-header-tags))) | |
3129 | ((and org-html-table-use-header-tags-for-first-column | |
3130 | (zerop (cdr (org-export-table-cell-address table-cell info)))) | |
3131 | (concat "\n" (format (car org-html-table-header-tags) "row" cell-attrs) | |
3132 | contents (cdr org-html-table-header-tags))) | |
3133 | (t (concat "\n" (format (car org-html-table-data-tags) cell-attrs) | |
3134 | contents (cdr org-html-table-data-tags)))))) | |
3135 | ||
3136 | ;;;; Table Row | |
3137 | ||
3138 | (defun org-html-table-row (table-row contents info) | |
3139 | "Transcode a TABLE-ROW element from Org to HTML. | |
3140 | CONTENTS is the contents of the row. INFO is a plist used as a | |
3141 | communication channel." | |
3142 | ;; Rules are ignored since table separators are deduced from | |
3143 | ;; borders of the current row. | |
3144 | (when (eq (org-element-property :type table-row) 'standard) | |
3145 | (let* ((rowgroup-number (org-export-table-row-group table-row info)) | |
3146 | (row-number (org-export-table-row-number table-row info)) | |
3147 | (start-rowgroup-p | |
3148 | (org-export-table-row-starts-rowgroup-p table-row info)) | |
3149 | (end-rowgroup-p | |
3150 | (org-export-table-row-ends-rowgroup-p table-row info)) | |
3151 | ;; `top-row-p' and `end-rowgroup-p' are not used directly | |
3152 | ;; but should be set so that `org-html-table-row-tags' can | |
3153 | ;; use them (see the docstring of this variable.) | |
3154 | (top-row-p (and (equal start-rowgroup-p '(top)) | |
3155 | (equal end-rowgroup-p '(below top)))) | |
3156 | (bottom-row-p (and (equal start-rowgroup-p '(above)) | |
3157 | (equal end-rowgroup-p '(bottom above)))) | |
3158 | (rowgroup-tags | |
3159 | (cond | |
3160 | ;; Case 1: Row belongs to second or subsequent rowgroups. | |
3161 | ((not (= 1 rowgroup-number)) | |
3162 | '("<tbody>" . "\n</tbody>")) | |
3163 | ;; Case 2: Row is from first rowgroup. Table has >=1 rowgroups. | |
3164 | ((org-export-table-has-header-p | |
3165 | (org-export-get-parent-table table-row) info) | |
3166 | '("<thead>" . "\n</thead>")) | |
3167 | ;; Case 2: Row is from first and only row group. | |
3168 | (t '("<tbody>" . "\n</tbody>"))))) | |
3169 | (concat | |
3170 | ;; Begin a rowgroup? | |
3171 | (when start-rowgroup-p (car rowgroup-tags)) | |
3172 | ;; Actual table row | |
3173 | (concat "\n" (eval (car org-html-table-row-tags)) | |
3174 | contents | |
3175 | "\n" | |
3176 | (eval (cdr org-html-table-row-tags))) | |
3177 | ;; End a rowgroup? | |
3178 | (when end-rowgroup-p (cdr rowgroup-tags)))))) | |
3179 | ||
3180 | ;;;; Table | |
3181 | ||
3182 | (defun org-html-table-first-row-data-cells (table info) | |
3183 | "Transcode the first row of TABLE. | |
3184 | INFO is a plist used as a communication channel." | |
3185 | (let ((table-row | |
3186 | (org-element-map table 'table-row | |
3187 | (lambda (row) | |
3188 | (unless (eq (org-element-property :type row) 'rule) row)) | |
3189 | info 'first-match)) | |
3190 | (special-column-p (org-export-table-has-special-column-p table))) | |
3191 | (if (not special-column-p) (org-element-contents table-row) | |
3192 | (cdr (org-element-contents table-row))))) | |
3193 | ||
3194 | (defun org-html-table--table.el-table (table info) | |
3195 | "Format table.el tables into HTML. | |
3196 | INFO is a plist used as a communication channel." | |
3197 | (when (eq (org-element-property :type table) 'table.el) | |
3198 | (require 'table) | |
3199 | (let ((outbuf (with-current-buffer | |
3200 | (get-buffer-create "*org-export-table*") | |
3201 | (erase-buffer) (current-buffer)))) | |
3202 | (with-temp-buffer | |
3203 | (insert (org-element-property :value table)) | |
3204 | (goto-char 1) | |
3205 | (re-search-forward "^[ \t]*|[^|]" nil t) | |
3206 | (table-generate-source 'html outbuf)) | |
3207 | (with-current-buffer outbuf | |
3208 | (prog1 (org-trim (buffer-string)) | |
3209 | (kill-buffer) ))))) | |
3210 | ||
3211 | (defun org-html-table (table contents info) | |
3212 | "Transcode a TABLE element from Org to HTML. | |
3213 | CONTENTS is the contents of the table. INFO is a plist holding | |
3214 | contextual information." | |
3215 | (case (org-element-property :type table) | |
3216 | ;; Case 1: table.el table. Convert it using appropriate tools. | |
3217 | (table.el (org-html-table--table.el-table table info)) | |
3218 | ;; Case 2: Standard table. | |
3219 | (t | |
3220 | (let* ((label (org-element-property :name table)) | |
3221 | (caption (org-export-get-caption table)) | |
3222 | (number (org-export-get-ordinal | |
3223 | table info nil 'org-html--has-caption-p)) | |
3224 | (attributes | |
3225 | (org-html--make-attribute-string | |
3226 | (org-combine-plists | |
3227 | (and label (list :id (org-export-solidify-link-text label))) | |
3228 | (and (not (org-html-html5-p info)) | |
3229 | (plist-get info :html-table-attributes)) | |
3230 | (org-export-read-attribute :attr_html table)))) | |
3231 | (alignspec | |
3232 | (if (and (boundp 'org-html-format-table-no-css) | |
3233 | org-html-format-table-no-css) | |
3234 | "align=\"%s\"" "class=\"%s\"")) | |
3235 | (table-column-specs | |
3236 | (function | |
3237 | (lambda (table info) | |
3238 | (mapconcat | |
3239 | (lambda (table-cell) | |
3240 | (let ((alignment (org-export-table-cell-alignment | |
3241 | table-cell info))) | |
3242 | (concat | |
3243 | ;; Begin a colgroup? | |
3244 | (when (org-export-table-cell-starts-colgroup-p | |
3245 | table-cell info) | |
3246 | "\n<colgroup>") | |
3247 | ;; Add a column. Also specify it's alignment. | |
3248 | (format "\n%s" | |
3249 | (org-html-close-tag | |
3250 | "col" (concat " " (format alignspec alignment)) info)) | |
3251 | ;; End a colgroup? | |
3252 | (when (org-export-table-cell-ends-colgroup-p | |
3253 | table-cell info) | |
3254 | "\n</colgroup>")))) | |
3255 | (org-html-table-first-row-data-cells table info) "\n"))))) | |
3256 | (format "<table%s>\n%s\n%s\n%s</table>" | |
3257 | (if (equal attributes "") "" (concat " " attributes)) | |
3258 | (if (not caption) "" | |
3259 | (format (if org-html-table-caption-above | |
3c8b09ca BG |
3260 | "<caption class=\"t-above\">%s</caption>" |
3261 | "<caption class=\"t-bottom\">%s</caption>") | |
271672fa BG |
3262 | (concat |
3263 | "<span class=\"table-number\">" | |
3264 | (format (org-html--translate "Table %d:" info) number) | |
3265 | "</span> " (org-export-data caption info)))) | |
3266 | (funcall table-column-specs table info) | |
3267 | contents))))) | |
3268 | ||
3269 | ;;;; Target | |
3270 | ||
3271 | (defun org-html-target (target contents info) | |
3272 | "Transcode a TARGET object from Org to HTML. | |
3273 | CONTENTS is nil. INFO is a plist holding contextual | |
3274 | information." | |
3275 | (let ((id (org-export-solidify-link-text | |
3276 | (org-element-property :value target)))) | |
3277 | (org-html--anchor id))) | |
3278 | ||
3279 | ;;;; Timestamp | |
3280 | ||
3281 | (defun org-html-timestamp (timestamp contents info) | |
3282 | "Transcode a TIMESTAMP object from Org to HTML. | |
3283 | CONTENTS is nil. INFO is a plist holding contextual | |
3284 | information." | |
3285 | (let ((value (org-html-plain-text | |
3286 | (org-timestamp-translate timestamp) info))) | |
3287 | (format "<span class=\"timestamp-wrapper\"><span class=\"timestamp\">%s</span></span>" | |
3288 | (replace-regexp-in-string "--" "–" value)))) | |
3289 | ||
3290 | ;;;; Underline | |
3291 | ||
3292 | (defun org-html-underline (underline contents info) | |
3293 | "Transcode UNDERLINE from Org to HTML. | |
3294 | CONTENTS is the text with underline markup. INFO is a plist | |
3295 | holding contextual information." | |
3296 | (format (or (cdr (assq 'underline org-html-text-markup-alist)) "%s") | |
3297 | contents)) | |
3298 | ||
3299 | ;;;; Verbatim | |
3300 | ||
3301 | (defun org-html-verbatim (verbatim contents info) | |
3302 | "Transcode VERBATIM from Org to HTML. | |
3303 | CONTENTS is nil. INFO is a plist holding contextual | |
3304 | information." | |
3305 | (format (or (cdr (assq 'verbatim org-html-text-markup-alist)) "%s") | |
3306 | (org-html-encode-plain-text (org-element-property :value verbatim)))) | |
3307 | ||
3308 | ;;;; Verse Block | |
3309 | ||
3310 | (defun org-html-verse-block (verse-block contents info) | |
3311 | "Transcode a VERSE-BLOCK element from Org to HTML. | |
3312 | CONTENTS is verse block contents. INFO is a plist holding | |
3313 | contextual information." | |
3314 | ;; Replace each newline character with line break. Also replace | |
3315 | ;; each blank line with a line break. | |
3316 | (setq contents (replace-regexp-in-string | |
3317 | "^ *\\\\\\\\$" (format "%s\n" (org-html-close-tag "br" nil info)) | |
3318 | (replace-regexp-in-string | |
3319 | "\\(\\\\\\\\\\)?[ \t]*\n" | |
3320 | (format "%s\n" (org-html-close-tag "br" nil info)) contents))) | |
3321 | ;; Replace each white space at beginning of a line with a | |
3322 | ;; non-breaking space. | |
3323 | (while (string-match "^[ \t]+" contents) | |
3324 | (let* ((num-ws (length (match-string 0 contents))) | |
3325 | (ws (let (out) (dotimes (i num-ws out) | |
3326 | (setq out (concat out " ")))))) | |
3327 | (setq contents (replace-match ws nil t contents)))) | |
3328 | (format "<p class=\"verse\">\n%s</p>" contents)) | |
3329 | ||
3330 | \f | |
3331 | ;;; Filter Functions | |
3332 | ||
3333 | (defun org-html-final-function (contents backend info) | |
3334 | "Filter to indent the HTML and convert HTML entities." | |
3335 | (with-temp-buffer | |
3336 | (insert contents) | |
3337 | (set-auto-mode t) | |
3338 | (if org-html-indent | |
3339 | (indent-region (point-min) (point-max))) | |
3340 | (when org-html-use-unicode-chars | |
3341 | (require 'mm-url) | |
3342 | (mm-url-decode-entities)) | |
3343 | (buffer-substring-no-properties (point-min) (point-max)))) | |
3344 | ||
3345 | \f | |
3346 | ;;; End-user functions | |
3347 | ||
3348 | ;;;###autoload | |
3349 | (defun org-html-export-as-html | |
3350 | (&optional async subtreep visible-only body-only ext-plist) | |
3351 | "Export current buffer to an HTML buffer. | |
3352 | ||
3353 | If narrowing is active in the current buffer, only export its | |
3354 | narrowed part. | |
3355 | ||
3356 | If a region is active, export that region. | |
3357 | ||
3358 | A non-nil optional argument ASYNC means the process should happen | |
3359 | asynchronously. The resulting buffer should be accessible | |
3360 | through the `org-export-stack' interface. | |
3361 | ||
3362 | When optional argument SUBTREEP is non-nil, export the sub-tree | |
3363 | at point, extracting information from the headline properties | |
3364 | first. | |
3365 | ||
3366 | When optional argument VISIBLE-ONLY is non-nil, don't export | |
3367 | contents of hidden elements. | |
3368 | ||
3369 | When optional argument BODY-ONLY is non-nil, only write code | |
3370 | between \"<body>\" and \"</body>\" tags. | |
3371 | ||
3372 | EXT-PLIST, when provided, is a property list with external | |
3373 | parameters overriding Org default settings, but still inferior to | |
3374 | file-local settings. | |
3375 | ||
3376 | Export is done in a buffer named \"*Org HTML Export*\", which | |
3377 | will be displayed when `org-export-show-temporary-export-buffer' | |
3378 | is non-nil." | |
3379 | (interactive) | |
3380 | (org-export-to-buffer 'html "*Org HTML Export*" | |
3381 | async subtreep visible-only body-only ext-plist | |
3382 | (lambda () (set-auto-mode t)))) | |
3383 | ||
3384 | ;;;###autoload | |
3385 | (defun org-html-convert-region-to-html () | |
3386 | "Assume the current region has org-mode syntax, and convert it to HTML. | |
3387 | This can be used in any buffer. For example, you can write an | |
3388 | itemized list in org-mode syntax in an HTML buffer and use this | |
3389 | command to convert it." | |
3390 | (interactive) | |
3391 | (org-export-replace-region-by 'html)) | |
3392 | ||
3393 | ;;;###autoload | |
3394 | (defun org-html-export-to-html | |
3395 | (&optional async subtreep visible-only body-only ext-plist) | |
3396 | "Export current buffer to a HTML file. | |
3397 | ||
3398 | If narrowing is active in the current buffer, only export its | |
3399 | narrowed part. | |
3400 | ||
3401 | If a region is active, export that region. | |
3402 | ||
3403 | A non-nil optional argument ASYNC means the process should happen | |
3404 | asynchronously. The resulting file should be accessible through | |
3405 | the `org-export-stack' interface. | |
3406 | ||
3407 | When optional argument SUBTREEP is non-nil, export the sub-tree | |
3408 | at point, extracting information from the headline properties | |
3409 | first. | |
3410 | ||
3411 | When optional argument VISIBLE-ONLY is non-nil, don't export | |
3412 | contents of hidden elements. | |
3413 | ||
3414 | When optional argument BODY-ONLY is non-nil, only write code | |
3415 | between \"<body>\" and \"</body>\" tags. | |
3416 | ||
3417 | EXT-PLIST, when provided, is a property list with external | |
3418 | parameters overriding Org default settings, but still inferior to | |
3419 | file-local settings. | |
3420 | ||
3421 | Return output file's name." | |
3422 | (interactive) | |
3423 | (let* ((extension (concat "." org-html-extension)) | |
3424 | (file (org-export-output-file-name extension subtreep)) | |
3425 | (org-export-coding-system org-html-coding-system)) | |
3426 | (org-export-to-file 'html file | |
3427 | async subtreep visible-only body-only ext-plist))) | |
3428 | ||
3429 | ;;;###autoload | |
3430 | (defun org-html-publish-to-html (plist filename pub-dir) | |
3431 | "Publish an org file to HTML. | |
3432 | ||
3433 | FILENAME is the filename of the Org file to be published. PLIST | |
3434 | is the property list for the given project. PUB-DIR is the | |
3435 | publishing directory. | |
3436 | ||
3437 | Return output file name." | |
3438 | (org-publish-org-to 'html filename | |
3439 | (concat "." (or (plist-get plist :html-extension) | |
3440 | org-html-extension "html")) | |
3441 | plist pub-dir)) | |
3442 | ||
271672fa BG |
3443 | |
3444 | (provide 'ox-html) | |
3445 | ||
3446 | ;; Local variables: | |
3447 | ;; generated-autoload-file: "org-loaddefs.el" | |
3448 | ;; End: | |
3449 | ||
3450 | ;;; ox-html.el ends here |