Commit | Line | Data |
---|---|---|
c8d0cf5c CD |
1 | ;;; org-html.el --- HTML export for Org-mode |
2 | ||
ab422c4d | 3 | ;; Copyright (C) 2004-2013 Free Software Foundation, Inc. |
c8d0cf5c CD |
4 | |
5 | ;; Author: Carsten Dominik <carsten at orgmode dot org> | |
6 | ;; Keywords: outlines, hypermedia, calendar, wp | |
7 | ;; Homepage: http://orgmode.org | |
c8d0cf5c CD |
8 | ;; |
9 | ;; This file is part of GNU Emacs. | |
10 | ;; | |
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 | ;; | |
25 | ;;; Commentary: | |
26 | ||
86fbb8ca CD |
27 | ;;; Code: |
28 | ||
c8d0cf5c | 29 | (require 'org-exp) |
3ab2c837 | 30 | (require 'format-spec) |
86fbb8ca | 31 | |
54a0dee5 | 32 | (eval-when-compile (require 'cl)) |
c8d0cf5c CD |
33 | |
34 | (declare-function org-id-find-id-file "org-id" (id)) | |
35 | (declare-function htmlize-region "ext:htmlize" (beg end)) | |
e66ba1df BG |
36 | (declare-function org-pop-to-buffer-same-window |
37 | "org-compat" (&optional buffer-or-name norecord label)) | |
c8d0cf5c CD |
38 | |
39 | (defgroup org-export-html nil | |
40 | "Options specific for HTML export of Org-mode files." | |
41 | :tag "Org Export HTML" | |
42 | :group 'org-export) | |
43 | ||
44 | (defcustom org-export-html-footnotes-section "<div id=\"footnotes\"> | |
45 | <h2 class=\"footnotes\">%s: </h2> | |
46 | <div id=\"text-footnotes\"> | |
47 | %s | |
48 | </div> | |
49 | </div>" | |
50 | "Format for the footnotes section. | |
51 | Should contain a two instances of %s. The first will be replaced with the | |
52 | language-specific word for \"Footnotes\", the second one will be replaced | |
53 | by the footnotes themselves." | |
54 | :group 'org-export-html | |
55 | :type 'string) | |
56 | ||
57 | (defcustom org-export-html-footnote-format "<sup>%s</sup>" | |
58 | "The format for the footnote reference. | |
59 | %s will be replaced by the footnote reference itself." | |
60 | :group 'org-export-html | |
61 | :type 'string) | |
62 | ||
3ab2c837 BG |
63 | |
64 | (defcustom org-export-html-footnote-separator "<sup>, </sup>" | |
65 | "Text used to separate footnotes." | |
66 | :group 'org-export-html | |
372d7b21 | 67 | :version "24.1" |
3ab2c837 BG |
68 | :type 'string) |
69 | ||
c8d0cf5c | 70 | (defcustom org-export-html-coding-system nil |
86fbb8ca | 71 | "Coding system for HTML export, defaults to `buffer-file-coding-system'." |
c8d0cf5c CD |
72 | :group 'org-export-html |
73 | :type 'coding-system) | |
74 | ||
75 | (defcustom org-export-html-extension "html" | |
76 | "The extension for exported HTML files." | |
77 | :group 'org-export-html | |
78 | :type 'string) | |
79 | ||
80 | (defcustom org-export-html-xml-declaration | |
81 | '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>") | |
82 | ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>")) | |
83 | "The extension for exported HTML files. | |
84 | %s will be replaced with the charset of the exported file. | |
85 | This may be a string, or an alist with export extensions | |
86 | and corresponding declarations." | |
87 | :group 'org-export-html | |
88 | :type '(choice | |
89 | (string :tag "Single declaration") | |
90 | (repeat :tag "Dependent on extension" | |
91 | (cons (string :tag "Extension") | |
92 | (string :tag "Declaration"))))) | |
93 | ||
94 | (defcustom org-export-html-style-include-scripts t | |
86fbb8ca | 95 | "Non-nil means include the JavaScript snippets in exported HTML files. |
c8d0cf5c CD |
96 | The actual script is defined in `org-export-html-scripts' and should |
97 | not be modified." | |
98 | :group 'org-export-html | |
99 | :type 'boolean) | |
100 | ||
8223b1d2 BG |
101 | (defvar org-export-html-scripts |
102 | "<script type=\"text/javascript\"> | |
103 | /* | |
104 | @licstart The following is the entire license notice for the | |
105 | JavaScript code in this tag. | |
106 | ||
107 | Copyright (C) 2012 Free Software Foundation, Inc. | |
108 | ||
109 | The JavaScript code in this tag is free software: you can | |
110 | redistribute it and/or modify it under the terms of the GNU | |
111 | General Public License (GNU GPL) as published by the Free Software | |
112 | Foundation, either version 3 of the License, or (at your option) | |
113 | any later version. The code is distributed WITHOUT ANY WARRANTY; | |
114 | without even the implied warranty of MERCHANTABILITY or FITNESS | |
115 | FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
116 | ||
117 | As additional permission under GNU GPL version 3 section 7, you | |
118 | may distribute non-source (e.g., minimized or compacted) forms of | |
119 | that code without the copy of the GNU GPL normally required by | |
120 | section 4, provided you include this license notice and a URL | |
121 | through which recipients can access the Corresponding Source. | |
122 | ||
123 | ||
124 | @licend The above is the entire license notice | |
125 | for the JavaScript code in this tag. | |
126 | */ | |
c8d0cf5c CD |
127 | <!--/*--><![CDATA[/*><!--*/ |
128 | function CodeHighlightOn(elem, id) | |
129 | { | |
130 | var target = document.getElementById(id); | |
131 | if(null != target) { | |
132 | elem.cacheClassElem = elem.className; | |
133 | elem.cacheClassTarget = target.className; | |
134 | target.className = \"code-highlighted\"; | |
135 | elem.className = \"code-highlighted\"; | |
136 | } | |
137 | } | |
138 | function CodeHighlightOff(elem, id) | |
139 | { | |
140 | var target = document.getElementById(id); | |
141 | if(elem.cacheClassElem) | |
142 | elem.className = elem.cacheClassElem; | |
143 | if(elem.cacheClassTarget) | |
144 | target.className = elem.cacheClassTarget; | |
145 | } | |
146 | /*]]>*///--> | |
147 | </script>" | |
8223b1d2 | 148 | "Basic JavaScript that is needed by HTML files produced by Org-mode.") |
c8d0cf5c CD |
149 | |
150 | (defconst org-export-html-style-default | |
8223b1d2 | 151 | "<style type=\"text/css\"> |
c8d0cf5c CD |
152 | <!--/*--><![CDATA[/*><!--*/ |
153 | html { font-family: Times, serif; font-size: 12pt; } | |
154 | .title { text-align: center; } | |
155 | .todo { color: red; } | |
156 | .done { color: green; } | |
157 | .tag { background-color: #add8e6; font-weight:normal } | |
158 | .target { } | |
159 | .timestamp { color: #bebebe; } | |
160 | .timestamp-kwd { color: #5f9ea0; } | |
afe98dfa CD |
161 | .right {margin-left:auto; margin-right:0px; text-align:right;} |
162 | .left {margin-left:0px; margin-right:auto; text-align:left;} | |
163 | .center {margin-left:auto; margin-right:auto; text-align:center;} | |
c8d0cf5c CD |
164 | p.verse { margin-left: 3% } |
165 | pre { | |
166 | border: 1pt solid #AEBDCC; | |
167 | background-color: #F3F5F7; | |
168 | padding: 5pt; | |
169 | font-family: courier, monospace; | |
170 | font-size: 90%; | |
171 | overflow:auto; | |
172 | } | |
173 | table { border-collapse: collapse; } | |
afe98dfa CD |
174 | td, th { vertical-align: top; } |
175 | th.right { text-align:center; } | |
176 | th.left { text-align:center; } | |
177 | th.center { text-align:center; } | |
178 | td.right { text-align:right; } | |
179 | td.left { text-align:left; } | |
180 | td.center { text-align:center; } | |
c8d0cf5c CD |
181 | dt { font-weight: bold; } |
182 | div.figure { padding: 0.5em; } | |
183 | div.figure p { text-align: center; } | |
e66ba1df BG |
184 | div.inlinetask { |
185 | padding:10px; | |
186 | border:2px solid gray; | |
187 | margin:10px; | |
188 | background: #ffffcc; | |
189 | } | |
ed21c5c8 | 190 | textarea { overflow-x: auto; } |
c8d0cf5c CD |
191 | .linenr { font-size:smaller } |
192 | .code-highlighted {background-color:#ffff00;} | |
193 | .org-info-js_info-navigation { border-style:none; } | |
194 | #org-info-js_console-label { font-size:10px; font-weight:bold; | |
195 | white-space:nowrap; } | |
196 | .org-info-js_search-highlight {background-color:#ffff00; color:#000000; | |
197 | font-weight:bold; } | |
198 | /*]]>*/--> | |
199 | </style>" | |
200 | "The default style specification for exported HTML files. | |
201 | Please use the variables `org-export-html-style' and | |
202 | `org-export-html-style-extra' to add to this style. If you wish to not | |
203 | have the default style included, customize the variable | |
204 | `org-export-html-style-include-default'.") | |
205 | ||
206 | (defcustom org-export-html-style-include-default t | |
ed21c5c8 | 207 | "Non-nil means include the default style in exported HTML files. |
c8d0cf5c CD |
208 | The actual style is defined in `org-export-html-style-default' and should |
209 | not be modified. Use the variables `org-export-html-style' to add | |
210 | your own style information." | |
211 | :group 'org-export-html | |
212 | :type 'boolean) | |
bdebdb64 | 213 | |
c8d0cf5c | 214 | ;;;###autoload |
364bc556 | 215 | (put 'org-export-html-style-include-default 'safe-local-variable 'booleanp) |
c8d0cf5c CD |
216 | |
217 | (defcustom org-export-html-style "" | |
218 | "Org-wide style definitions for exported HTML files. | |
219 | ||
220 | This variable needs to contain the full HTML structure to provide a style, | |
221 | including the surrounding HTML tags. If you set the value of this variable, | |
222 | you should consider to include definitions for the following classes: | |
223 | title, todo, done, timestamp, timestamp-kwd, tag, target. | |
224 | ||
225 | For example, a valid value would be: | |
226 | ||
227 | <style type=\"text/css\"> | |
228 | <![CDATA[ | |
229 | p { font-weight: normal; color: gray; } | |
230 | h1 { color: black; } | |
231 | .title { text-align: center; } | |
232 | .todo, .timestamp-kwd { color: red; } | |
233 | .done { color: green; } | |
234 | ]]> | |
235 | </style> | |
236 | ||
3ab2c837 | 237 | If you'd like to refer to an external style file, use something like |
c8d0cf5c CD |
238 | |
239 | <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\"> | |
240 | ||
241 | As the value of this option simply gets inserted into the HTML <head> header, | |
242 | you can \"misuse\" it to add arbitrary text to the header. | |
243 | See also the variable `org-export-html-style-extra'." | |
244 | :group 'org-export-html | |
245 | :type 'string) | |
246 | ;;;###autoload | |
247 | (put 'org-export-html-style 'safe-local-variable 'stringp) | |
248 | ||
249 | (defcustom org-export-html-style-extra "" | |
250 | "Additional style information for HTML export. | |
251 | The value of this variable is inserted into the HTML buffer right after | |
252 | the value of `org-export-html-style'. Use this variable for per-file | |
253 | settings of style information, and do not forget to surround the style | |
254 | settings with <style>...</style> tags." | |
255 | :group 'org-export-html | |
256 | :type 'string) | |
257 | ;;;###autoload | |
258 | (put 'org-export-html-style-extra 'safe-local-variable 'stringp) | |
259 | ||
afe98dfa CD |
260 | (defcustom org-export-html-mathjax-options |
261 | '((path "http://orgmode.org/mathjax/MathJax.js") | |
262 | (scale "100") | |
263 | (align "center") | |
264 | (indent "2em") | |
265 | (mathml nil)) | |
266 | "Options for MathJax setup. | |
267 | ||
268 | path The path where to find MathJax | |
269 | scale Scaling for the HTML-CSS backend, usually between 100 and 133 | |
270 | align How to align display math: left, center, or right | |
271 | indent If align is not center, how far from the left/right side? | |
272 | mathml Should a MathML player be used if available? | |
273 | This is faster and reduces bandwidth use, but currently | |
274 | sometimes has lower spacing quality. Therefore, the default is | |
275 | nil. When browsers get better, this switch can be flipped. | |
276 | ||
277 | You can also customize this for each buffer, using something like | |
278 | ||
279 | #+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\"" | |
280 | :group 'org-export-html | |
372d7b21 | 281 | :version "24.1" |
afe98dfa | 282 | :type '(list :greedy t |
8223b1d2 BG |
283 | (list :tag "path (the path from where to load MathJax.js)" |
284 | (const :format " " path) (string)) | |
285 | (list :tag "scale (scaling for the displayed math)" | |
286 | (const :format " " scale) (string)) | |
287 | (list :tag "align (alignment of displayed equations)" | |
288 | (const :format " " align) (string)) | |
289 | (list :tag "indent (indentation with left or right alignment)" | |
290 | (const :format " " indent) (string)) | |
291 | (list :tag "mathml (should MathML display be used is possible)" | |
292 | (const :format " " mathml) (boolean)))) | |
afe98dfa CD |
293 | |
294 | (defun org-export-html-mathjax-config (template options in-buffer) | |
295 | "Insert the user setup into the matchjax template." | |
296 | (let (name val (yes " ") (no "// ") x) | |
297 | (mapc | |
298 | (lambda (e) | |
299 | (setq name (car e) val (nth 1 e)) | |
300 | (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer) | |
301 | (setq val (car (read-from-string | |
302 | (substring in-buffer (match-end 0)))))) | |
303 | (if (not (stringp val)) (setq val (format "%s" val))) | |
8223b1d2 BG |
304 | (setq template |
305 | (replace-regexp-in-string | |
306 | (concat "%" (upcase (symbol-name name))) val template t t))) | |
afe98dfa CD |
307 | options) |
308 | (setq val (nth 1 (assq 'mathml options))) | |
309 | (if (string-match (concat "\\<mathml:") in-buffer) | |
310 | (setq val (car (read-from-string | |
311 | (substring in-buffer (match-end 0)))))) | |
312 | ;; Exchange prefixes depending on mathml setting | |
313 | (if (not val) (setq x yes yes no no x)) | |
314 | ;; Replace cookies to turn on or off the config/jax lines | |
315 | (if (string-match ":MMLYES:" template) | |
316 | (setq template (replace-match yes t t template))) | |
317 | (if (string-match ":MMLNO:" template) | |
318 | (setq template (replace-match no t t template))) | |
319 | ;; Return the modified template | |
320 | template)) | |
321 | ||
322 | (defcustom org-export-html-mathjax-template | |
323 | "<script type=\"text/javascript\" src=\"%PATH\"> | |
8223b1d2 BG |
324 | /** |
325 | * | |
326 | * @source: %PATH | |
327 | * | |
328 | * @licstart The following is the entire license notice for the | |
329 | * JavaScript code in %PATH. | |
330 | * | |
331 | * Copyright (C) 2012 MathJax | |
332 | * | |
333 | * Licensed under the Apache License, Version 2.0 (the \"License\"); | |
334 | * you may not use this file except in compliance with the License. | |
335 | * You may obtain a copy of the License at | |
336 | * | |
337 | * http://www.apache.org/licenses/LICENSE-2.0 | |
338 | * | |
339 | * Unless required by applicable law or agreed to in writing, software | |
340 | * distributed under the License is distributed on an \"AS IS\" BASIS, | |
341 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
342 | * See the License for the specific language governing permissions and | |
343 | * limitations under the License. | |
344 | * | |
345 | * @licend The above is the entire license notice | |
346 | * for the JavaScript code in %PATH. | |
347 | * | |
348 | */ | |
349 | ||
350 | /* | |
351 | @licstart The following is the entire license notice for the | |
352 | JavaScript code below. | |
353 | ||
354 | Copyright (C) 2012 Free Software Foundation, Inc. | |
355 | ||
356 | The JavaScript code below is free software: you can | |
357 | redistribute it and/or modify it under the terms of the GNU | |
358 | General Public License (GNU GPL) as published by the Free Software | |
359 | Foundation, either version 3 of the License, or (at your option) | |
360 | any later version. The code is distributed WITHOUT ANY WARRANTY; | |
361 | without even the implied warranty of MERCHANTABILITY or FITNESS | |
362 | FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. | |
363 | ||
364 | As additional permission under GNU GPL version 3 section 7, you | |
365 | may distribute non-source (e.g., minimized or compacted) forms of | |
366 | that code without the copy of the GNU GPL normally required by | |
367 | section 4, provided you include this license notice and a URL | |
368 | through which recipients can access the Corresponding Source. | |
369 | ||
370 | ||
371 | @licend The above is the entire license notice | |
372 | for the JavaScript code below. | |
373 | */ | |
afe98dfa CD |
374 | <!--/*--><![CDATA[/*><!--*/ |
375 | MathJax.Hub.Config({ | |
376 | // Only one of the two following lines, depending on user settings | |
377 | // First allows browser-native MathML display, second forces HTML/CSS | |
378 | :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"], | |
379 | :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"], | |
380 | extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\", | |
381 | \"TeX/noUndefined.js\"], | |
382 | tex2jax: { | |
383 | inlineMath: [ [\"\\\\(\",\"\\\\)\"] ], | |
3ab2c837 | 384 | displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ], |
afe98dfa CD |
385 | skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"], |
386 | ignoreClass: \"tex2jax_ignore\", | |
387 | processEscapes: false, | |
388 | processEnvironments: true, | |
389 | preview: \"TeX\" | |
390 | }, | |
391 | showProcessingMessages: true, | |
392 | displayAlign: \"%ALIGN\", | |
393 | displayIndent: \"%INDENT\", | |
394 | ||
395 | \"HTML-CSS\": { | |
396 | scale: %SCALE, | |
397 | availableFonts: [\"STIX\",\"TeX\"], | |
398 | preferredFont: \"TeX\", | |
399 | webFont: \"TeX\", | |
400 | imageFont: \"TeX\", | |
401 | showMathMenu: true, | |
402 | }, | |
403 | MMLorHTML: { | |
404 | prefer: { | |
405 | MSIE: \"MML\", | |
406 | Firefox: \"MML\", | |
407 | Opera: \"HTML\", | |
408 | other: \"HTML\" | |
409 | } | |
410 | } | |
411 | }); | |
412 | /*]]>*///--> | |
413 | </script>" | |
414 | "The MathJax setup for XHTML files." | |
415 | :group 'org-export-html | |
372d7b21 | 416 | :version "24.1" |
afe98dfa CD |
417 | :type 'string) |
418 | ||
c8d0cf5c | 419 | (defcustom org-export-html-tag-class-prefix "" |
86fbb8ca | 420 | "Prefix to class names for TODO keywords. |
c8d0cf5c CD |
421 | Each tag gets a class given by the tag itself, with this prefix. |
422 | The default prefix is empty because it is nice to just use the keyword | |
423 | as a class name. But if you get into conflicts with other, existing | |
86fbb8ca | 424 | CSS classes, then this prefix can be very useful." |
c8d0cf5c CD |
425 | :group 'org-export-html |
426 | :type 'string) | |
427 | ||
428 | (defcustom org-export-html-todo-kwd-class-prefix "" | |
86fbb8ca | 429 | "Prefix to class names for TODO keywords. |
c8d0cf5c CD |
430 | Each TODO keyword gets a class given by the keyword itself, with this prefix. |
431 | The default prefix is empty because it is nice to just use the keyword | |
432 | as a class name. But if you get into conflicts with other, existing | |
86fbb8ca | 433 | CSS classes, then this prefix can be very useful." |
c8d0cf5c CD |
434 | :group 'org-export-html |
435 | :type 'string) | |
436 | ||
e66ba1df BG |
437 | (defcustom org-export-html-headline-anchor-format "<a name=\"%s\" id=\"%s\"></a>" |
438 | "Format for anchors in HTML headlines. | |
439 | It requires to %s: both will be replaced by the anchor referring | |
440 | to the headline (e.g. \"sec-2\"). When set to `nil', don't insert | |
441 | HTML anchors in headlines." | |
442 | :group 'org-export-html | |
372d7b21 | 443 | :version "24.1" |
e66ba1df BG |
444 | :type 'string) |
445 | ||
3ab2c837 BG |
446 | (defcustom org-export-html-preamble t |
447 | "Non-nil means insert a preamble in HTML export. | |
448 | ||
449 | When `t', insert a string as defined by one of the formatting | |
450 | strings in `org-export-html-preamble-format'. When set to a | |
451 | string, this string overrides `org-export-html-preamble-format'. | |
452 | When set to a function, apply this function and insert the | |
e66ba1df BG |
453 | returned string. The function takes no argument, but you can |
454 | use `opt-plist' to access the current export options. | |
3ab2c837 BG |
455 | |
456 | Setting :html-preamble in publishing projects will take | |
457 | precedence over this variable." | |
458 | :group 'org-export-html | |
459 | :type '(choice (const :tag "No preamble" nil) | |
460 | (const :tag "Default preamble" t) | |
8223b1d2 | 461 | (string :tag "Custom format string") |
3ab2c837 BG |
462 | (function :tag "Function (must return a string)"))) |
463 | ||
464 | (defcustom org-export-html-preamble-format '(("en" "")) | |
8223b1d2 BG |
465 | "Alist of languages and format strings for the HTML preamble. |
466 | ||
467 | The first element of each list is the language code, as used for | |
468 | the #+LANGUAGE keyword. | |
469 | ||
470 | The second element of each list is a format string to format the | |
471 | preamble itself. This format string can contain these elements: | |
3ab2c837 BG |
472 | |
473 | %t stands for the title. | |
474 | %a stands for the author's name. | |
475 | %e stands for the author's email. | |
476 | %d stands for the date. | |
477 | ||
478 | If you need to use a \"%\" character, you need to escape it | |
479 | like that: \"%%\"." | |
480 | :group 'org-export-html | |
372d7b21 | 481 | :version "24.1" |
3ab2c837 BG |
482 | :type 'string) |
483 | ||
484 | (defcustom org-export-html-postamble 'auto | |
485 | "Non-nil means insert a postamble in HTML export. | |
486 | ||
8223b1d2 | 487 | When `t', insert a string as defined by the format string in |
3ab2c837 BG |
488 | `org-export-html-postamble-format'. When set to a string, this |
489 | string overrides `org-export-html-postamble-format'. When set to | |
490 | 'auto, discard `org-export-html-postamble-format' and honor | |
491 | `org-export-author/email/creator-info' variables. When set to a | |
492 | function, apply this function and insert the returned string. | |
e66ba1df BG |
493 | The function takes no argument, but you can use `opt-plist' to |
494 | access the current export options. | |
3ab2c837 BG |
495 | |
496 | Setting :html-postamble in publishing projects will take | |
497 | precedence over this variable." | |
498 | :group 'org-export-html | |
499 | :type '(choice (const :tag "No postamble" nil) | |
500 | (const :tag "Auto preamble" 'auto) | |
8223b1d2 BG |
501 | (const :tag "Default format string" t) |
502 | (string :tag "Custom format string") | |
3ab2c837 BG |
503 | (function :tag "Function (must return a string)"))) |
504 | ||
505 | (defcustom org-export-html-postamble-format | |
506 | '(("en" "<p class=\"author\">Author: %a (%e)</p> | |
507 | <p class=\"date\">Date: %d</p> | |
508 | <p class=\"creator\">Generated by %c</p> | |
509 | <p class=\"xhtml-validation\">%v</p> | |
510 | ")) | |
8223b1d2 BG |
511 | "Alist of languages and format strings for the HTML postamble. |
512 | ||
513 | The first element of each list is the language code, as used for | |
514 | the #+LANGUAGE keyword. | |
515 | ||
516 | The second element of each list is a format string to format the | |
517 | postamble itself. This format string can contain these elements: | |
3ab2c837 BG |
518 | |
519 | %a stands for the author's name. | |
520 | %e stands for the author's email. | |
521 | %d stands for the date. | |
522 | %c will be replaced by information about Org/Emacs versions. | |
523 | %v will be replaced by `org-export-html-validation-link'. | |
524 | ||
525 | If you need to use a \"%\" character, you need to escape it | |
526 | like that: \"%%\"." | |
c8d0cf5c | 527 | :group 'org-export-html |
372d7b21 | 528 | :version "24.1" |
c8d0cf5c CD |
529 | :type 'string) |
530 | ||
531 | (defcustom org-export-html-home/up-format | |
5dec9555 | 532 | "<div id=\"org-div-home-and-up\" style=\"text-align:right;font-size:70%%;white-space:nowrap;\"> |
c8d0cf5c CD |
533 | <a accesskey=\"h\" href=\"%s\"> UP </a> |
534 | | | |
535 | <a accesskey=\"H\" href=\"%s\"> HOME </a> | |
536 | </div>" | |
86fbb8ca CD |
537 | "Snippet used to insert the HOME and UP links. |
538 | This is a format string, the first %s will receive the UP link, | |
539 | the second the HOME link. If both `org-export-html-link-up' and | |
540 | `org-export-html-link-home' are empty, the entire snippet will be | |
541 | ignored." | |
c8d0cf5c CD |
542 | :group 'org-export-html |
543 | :type 'string) | |
544 | ||
545 | (defcustom org-export-html-toplevel-hlevel 2 | |
546 | "The <H> level for level 1 headings in HTML export. | |
547 | This is also important for the classes that will be wrapped around headlines | |
548 | and outline structure. If this variable is 1, the top-level headlines will | |
549 | be <h1>, and the corresponding classes will be outline-1, section-number-1, | |
550 | and outline-text-1. If this is 2, all of these will get a 2 instead. | |
551 | The default for this variable is 2, because we use <h1> for formatting the | |
552 | document title." | |
553 | :group 'org-export-html | |
554 | :type 'string) | |
555 | ||
556 | (defcustom org-export-html-link-org-files-as-html t | |
ed21c5c8 | 557 | "Non-nil means make file links to `file.org' point to `file.html'. |
c8d0cf5c CD |
558 | When org-mode is exporting an org-mode file to HTML, links to |
559 | non-html files are directly put into a href tag in HTML. | |
560 | However, links to other Org-mode files (recognized by the | |
561 | extension `.org.) should become links to the corresponding html | |
562 | file, assuming that the linked org-mode file will also be | |
563 | converted to HTML. | |
564 | When nil, the links still point to the plain `.org' file." | |
565 | :group 'org-export-html | |
566 | :type 'boolean) | |
567 | ||
568 | (defcustom org-export-html-inline-images 'maybe | |
ed21c5c8 | 569 | "Non-nil means inline images into exported HTML pages. |
c8d0cf5c CD |
570 | This is done using an <img> tag. When nil, an anchor with href is used to |
571 | link to the image. If this option is `maybe', then images in links with | |
572 | an empty description will be inlined, while images with a description will | |
573 | be linked only." | |
574 | :group 'org-export-html | |
575 | :type '(choice (const :tag "Never" nil) | |
576 | (const :tag "Always" t) | |
577 | (const :tag "When there is no description" maybe))) | |
578 | ||
579 | (defcustom org-export-html-inline-image-extensions | |
afe98dfa | 580 | '("png" "jpeg" "jpg" "gif" "svg") |
c8d0cf5c CD |
581 | "Extensions of image files that can be inlined into HTML." |
582 | :group 'org-export-html | |
583 | :type '(repeat (string :tag "Extension"))) | |
584 | ||
585 | (defcustom org-export-html-table-tag | |
586 | "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">" | |
587 | "The HTML tag that is used to start a table. | |
588 | This must be a <table> tag, but you may change the options like | |
589 | borders and spacing." | |
590 | :group 'org-export-html | |
591 | :type 'string) | |
592 | ||
afe98dfa | 593 | (defcustom org-export-table-header-tags '("<th scope=\"%s\"%s>" . "</th>") |
c8d0cf5c CD |
594 | "The opening tag for table header fields. |
595 | This is customizable so that alignment options can be specified. | |
afe98dfa CD |
596 | The first %s will be filled with the scope of the field, either row or col. |
597 | The second %s will be replaced by a style entry to align the field. | |
598 | See also the variable `org-export-html-table-use-header-tags-for-first-column'. | |
599 | See also the variable `org-export-html-table-align-individual-fields'." | |
c8d0cf5c CD |
600 | :group 'org-export-tables |
601 | :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) | |
602 | ||
afe98dfa | 603 | (defcustom org-export-table-data-tags '("<td%s>" . "</td>") |
c8d0cf5c | 604 | "The opening tag for table data fields. |
afe98dfa CD |
605 | This is customizable so that alignment options can be specified. |
606 | The first %s will be filled with the scope of the field, either row or col. | |
607 | The second %s will be replaced by a style entry to align the field. | |
608 | See also the variable `org-export-html-table-align-individual-fields'." | |
c8d0cf5c CD |
609 | :group 'org-export-tables |
610 | :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) | |
611 | ||
612 | (defcustom org-export-table-row-tags '("<tr>" . "</tr>") | |
613 | "The opening tag for table data fields. | |
614 | This is customizable so that alignment options can be specified. | |
615 | Instead of strings, these can be Lisp forms that will be evaluated | |
616 | for each row in order to construct the table row tags. During evaluation, | |
617 | the variable `head' will be true when this is a header line, nil when this | |
618 | is a body line. And the variable `nline' will contain the line number, | |
619 | starting from 1 in the first header line. For example | |
620 | ||
621 | (setq org-export-table-row-tags | |
622 | (cons '(if head | |
623 | \"<tr>\" | |
624 | (if (= (mod nline 2) 1) | |
625 | \"<tr class=\\\"tr-odd\\\">\" | |
626 | \"<tr class=\\\"tr-even\\\">\")) | |
627 | \"</tr>\")) | |
628 | ||
629 | will give even lines the class \"tr-even\" and odd lines the class \"tr-odd\"." | |
630 | :group 'org-export-tables | |
631 | :type '(cons | |
632 | (choice :tag "Opening tag" | |
633 | (string :tag "Specify") | |
634 | (sexp)) | |
635 | (choice :tag "Closing tag" | |
636 | (string :tag "Specify") | |
637 | (sexp)))) | |
638 | ||
afe98dfa CD |
639 | (defcustom org-export-html-table-align-individual-fields t |
640 | "Non-nil means attach style attributes for alignment to each table field. | |
641 | When nil, alignment will only be specified in the column tags, but this | |
642 | is ignored by some browsers (like Firefox, Safari). Opera does it right | |
643 | though." | |
644 | :group 'org-export-tables | |
372d7b21 | 645 | :version "24.1" |
afe98dfa | 646 | :type 'boolean) |
c8d0cf5c CD |
647 | |
648 | (defcustom org-export-html-table-use-header-tags-for-first-column nil | |
ed21c5c8 | 649 | "Non-nil means format column one in tables with header tags. |
c8d0cf5c CD |
650 | When nil, also column one will use data tags." |
651 | :group 'org-export-tables | |
652 | :type 'boolean) | |
653 | ||
3ab2c837 BG |
654 | (defcustom org-export-html-validation-link |
655 | "<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>" | |
656 | "Link to HTML validation service." | |
c8d0cf5c | 657 | :group 'org-export-html |
3ab2c837 | 658 | :type 'string) |
c8d0cf5c | 659 | |
3ab2c837 BG |
660 | ;; FIXME Obsolete since Org 7.7 |
661 | ;; Use the :timestamp option or `org-export-time-stamp-file' instead | |
662 | (defvar org-export-html-with-timestamp nil | |
663 | "If non-nil, write container for HTML-helper-mode timestamp.") | |
664 | ||
665 | ;; FIXME Obsolete since Org 7.7 | |
666 | (defvar org-export-html-html-helper-timestamp | |
667 | "\n<p><br/><br/>\n<!-- hhmts start --> <!-- hhmts end --></p>\n" | |
668 | "The HTML tag used as timestamp delimiter for HTML-helper-mode.") | |
669 | ||
670 | (defcustom org-export-html-protect-char-alist | |
671 | '(("&" . "&") | |
672 | ("<" . "<") | |
673 | (">" . ">")) | |
674 | "Alist of characters to be converted by `org-html-protect'." | |
c8d0cf5c | 675 | :group 'org-export-html |
372d7b21 | 676 | :version "24.1" |
3ab2c837 BG |
677 | :type '(repeat (cons (string :tag "Character") |
678 | (string :tag "HTML equivalent")))) | |
c8d0cf5c CD |
679 | |
680 | (defgroup org-export-htmlize nil | |
681 | "Options for processing examples with htmlize.el." | |
682 | :tag "Org Export Htmlize" | |
683 | :group 'org-export-html) | |
684 | ||
685 | (defcustom org-export-htmlize-output-type 'inline-css | |
686 | "Output type to be used by htmlize when formatting code snippets. | |
3ab2c837 BG |
687 | Choices are `css', to export the CSS selectors only, or `inline-css', to |
688 | export the CSS attribute values inline in the HTML. We use as default | |
689 | `inline-css', in order to make the resulting HTML self-containing. | |
690 | ||
c8d0cf5c CD |
691 | However, this will fail when using Emacs in batch mode for export, because |
692 | then no rich font definitions are in place. It will also not be good if | |
693 | people with different Emacs setup contribute HTML files to a website, | |
694 | because the fonts will represent the individual setups. In these cases, | |
695 | it is much better to let Org/Htmlize assign classes only, and to use | |
696 | a style file to define the look of these classes. | |
697 | To get a start for your css file, start Emacs session and make sure that | |
698 | all the faces you are interested in are defined, for example by loading files | |
699 | in all modes you want. Then, use the command | |
700 | \\[org-export-htmlize-generate-css] to extract class definitions." | |
701 | :group 'org-export-htmlize | |
702 | :type '(choice (const css) (const inline-css))) | |
703 | ||
704 | (defcustom org-export-htmlize-css-font-prefix "org-" | |
705 | "The prefix for CSS class names for htmlize font specifications." | |
706 | :group 'org-export-htmlize | |
707 | :type 'string) | |
708 | ||
709 | (defcustom org-export-htmlized-org-css-url nil | |
710 | "URL pointing to a CSS file defining text colors for htmlized Emacs buffers. | |
711 | Normally when creating an htmlized version of an Org buffer, htmlize will | |
712 | create CSS to define the font colors. However, this does not work when | |
713 | converting in batch mode, and it also can look bad if different people | |
714 | with different fontification setup work on the same website. | |
715 | When this variable is non-nil, creating an htmlized version of an Org buffer | |
716 | using `org-export-as-org' will remove the internal CSS section and replace it | |
717 | with a link to this URL." | |
718 | :group 'org-export-htmlize | |
719 | :type '(choice | |
720 | (const :tag "Keep internal css" nil) | |
721 | (string :tag "URL or local href"))) | |
722 | ||
3ab2c837 BG |
723 | ;; FIXME: The following variable is obsolete since Org 7.7 but is |
724 | ;; still declared and checked within code for compatibility reasons. | |
725 | ;; Use the custom variables `org-export-html-divs' instead. | |
726 | (defvar org-export-html-content-div "content" | |
727 | "The name of the container DIV that holds all the page contents. | |
728 | ||
729 | This variable is obsolete since Org version 7.7. | |
730 | Please set `org-export-html-divs' instead.") | |
c8d0cf5c | 731 | |
3ab2c837 | 732 | (defcustom org-export-html-divs '("preamble" "content" "postamble") |
e66ba1df BG |
733 | "The name of the main divs for HTML export. |
734 | This is a list of three strings, the first one for the preamble | |
735 | DIV, the second one for the content DIV and the third one for the | |
736 | postamble DIV." | |
3ab2c837 | 737 | :group 'org-export-html |
372d7b21 | 738 | :version "24.1" |
3ab2c837 BG |
739 | :type '(list |
740 | (string :tag " Div for the preamble:") | |
741 | (string :tag " Div for the content:") | |
742 | (string :tag "Div for the postamble:"))) | |
c8d0cf5c | 743 | |
8223b1d2 BG |
744 | (defcustom org-export-html-date-format-string "%Y-%m-%dT%R%z" |
745 | "Format string to format the date and time. | |
746 | ||
747 | The default is an extended format of the ISO 8601 specification." | |
748 | :group 'org-export-html | |
749 | :version "24.1" | |
750 | :type 'string) | |
751 | ||
c8d0cf5c CD |
752 | ;;; Hooks |
753 | ||
754 | (defvar org-export-html-after-blockquotes-hook nil | |
755 | "Hook run during HTML export, after blockquote, verse, center are done.") | |
756 | ||
8d642074 | 757 | (defvar org-export-html-final-hook nil |
ed21c5c8 | 758 | "Hook run at the end of HTML export, in the new buffer.") |
8d642074 | 759 | |
c8d0cf5c CD |
760 | ;;; HTML export |
761 | ||
762 | (defun org-export-html-preprocess (parameters) | |
86fbb8ca | 763 | "Convert LaTeX fragments to images." |
c8d0cf5c CD |
764 | (when (and org-current-export-file |
765 | (plist-get parameters :LaTeX-fragments)) | |
766 | (org-format-latex | |
8223b1d2 | 767 | (concat org-latex-preview-ltxpng-directory (file-name-sans-extension |
c8d0cf5c CD |
768 | (file-name-nondirectory |
769 | org-current-export-file))) | |
86fbb8ca | 770 | org-current-export-dir nil "Creating LaTeX image %s" |
afe98dfa CD |
771 | nil nil |
772 | (cond | |
773 | ((eq (plist-get parameters :LaTeX-fragments) 'verbatim) 'verbatim) | |
774 | ((eq (plist-get parameters :LaTeX-fragments) 'mathjax ) 'mathjax) | |
775 | ((eq (plist-get parameters :LaTeX-fragments) t ) 'mathjax) | |
8223b1d2 BG |
776 | ((eq (plist-get parameters :LaTeX-fragments) 'imagemagick) 'imagemagick) |
777 | ((eq (plist-get parameters :LaTeX-fragments) 'dvipng ) 'dvipng)))) | |
ed21c5c8 CD |
778 | (goto-char (point-min)) |
779 | (let (label l1) | |
780 | (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t) | |
781 | (org-if-unprotected-at (match-beginning 1) | |
782 | (setq label (match-string 1)) | |
783 | (save-match-data | |
784 | (if (string-match "\\`[a-z]\\{1,10\\}:\\(.+\\)" label) | |
785 | (setq l1 (substring label (match-beginning 1))) | |
786 | (setq l1 label))) | |
787 | (replace-match (format "[[#%s][%s]]" label l1) t t))))) | |
c8d0cf5c CD |
788 | |
789 | ;;;###autoload | |
790 | (defun org-export-as-html-and-open (arg) | |
791 | "Export the outline as HTML and immediately open it with a browser. | |
792 | If there is an active region, export only the region. | |
793 | The prefix ARG specifies how many levels of the outline should become | |
794 | headlines. The default is 3. Lower levels will become bulleted lists." | |
795 | (interactive "P") | |
796 | (org-export-as-html arg 'hidden) | |
ed21c5c8 CD |
797 | (org-open-file buffer-file-name) |
798 | (when org-export-kill-product-buffer-when-displayed | |
86fbb8ca | 799 | (kill-buffer (current-buffer)))) |
c8d0cf5c CD |
800 | |
801 | ;;;###autoload | |
802 | (defun org-export-as-html-batch () | |
86fbb8ca CD |
803 | "Call the function `org-export-as-html'. |
804 | This function can be used in batch processing as: | |
c8d0cf5c CD |
805 | emacs --batch |
806 | --load=$HOME/lib/emacs/org.el | |
807 | --eval \"(setq org-export-headline-levels 2)\" | |
808 | --visit=MyFile --funcall org-export-as-html-batch" | |
809 | (org-export-as-html org-export-headline-levels 'hidden)) | |
810 | ||
811 | ;;;###autoload | |
812 | (defun org-export-as-html-to-buffer (arg) | |
813 | "Call `org-export-as-html` with output to a temporary buffer. | |
814 | No file is created. The prefix ARG is passed through to `org-export-as-html'." | |
815 | (interactive "P") | |
816 | (org-export-as-html arg nil nil "*Org HTML Export*") | |
817 | (when org-export-show-temporary-export-buffer | |
818 | (switch-to-buffer-other-window "*Org HTML Export*"))) | |
819 | ||
820 | ;;;###autoload | |
821 | (defun org-replace-region-by-html (beg end) | |
822 | "Assume the current region has org-mode syntax, and convert it to HTML. | |
823 | This can be used in any buffer. For example, you could write an | |
824 | itemized list in org-mode syntax in an HTML buffer and then use this | |
825 | command to convert it." | |
826 | (interactive "r") | |
827 | (let (reg html buf pop-up-frames) | |
828 | (save-window-excursion | |
8223b1d2 | 829 | (if (derived-mode-p 'org-mode) |
c8d0cf5c CD |
830 | (setq html (org-export-region-as-html |
831 | beg end t 'string)) | |
832 | (setq reg (buffer-substring beg end) | |
833 | buf (get-buffer-create "*Org tmp*")) | |
834 | (with-current-buffer buf | |
835 | (erase-buffer) | |
836 | (insert reg) | |
837 | (org-mode) | |
838 | (setq html (org-export-region-as-html | |
839 | (point-min) (point-max) t 'string))) | |
840 | (kill-buffer buf))) | |
841 | (delete-region beg end) | |
842 | (insert html))) | |
843 | ||
844 | ;;;###autoload | |
845 | (defun org-export-region-as-html (beg end &optional body-only buffer) | |
846 | "Convert region from BEG to END in org-mode buffer to HTML. | |
847 | If prefix arg BODY-ONLY is set, omit file header, footer, and table of | |
848 | contents, and only produce the region of converted text, useful for | |
849 | cut-and-paste operations. | |
850 | If BUFFER is a buffer or a string, use/create that buffer as a target | |
851 | of the converted HTML. If BUFFER is the symbol `string', return the | |
852 | produced HTML as a string and leave not buffer behind. For example, | |
853 | a Lisp program could call this function in the following way: | |
854 | ||
855 | (setq html (org-export-region-as-html beg end t 'string)) | |
856 | ||
857 | When called interactively, the output buffer is selected, and shown | |
858 | in a window. A non-interactive call will only return the buffer." | |
859 | (interactive "r\nP") | |
3ab2c837 | 860 | (when (org-called-interactively-p 'any) |
c8d0cf5c CD |
861 | (setq buffer "*Org HTML Export*")) |
862 | (let ((transient-mark-mode t) (zmacs-regions t) | |
863 | ext-plist rtn) | |
8bfe682a | 864 | (setq ext-plist (plist-put ext-plist :ignore-subtree-p t)) |
c8d0cf5c CD |
865 | (goto-char end) |
866 | (set-mark (point)) ;; to activate the region | |
867 | (goto-char beg) | |
868 | (setq rtn (org-export-as-html | |
869 | nil nil ext-plist | |
870 | buffer body-only)) | |
871 | (if (fboundp 'deactivate-mark) (deactivate-mark)) | |
3ab2c837 | 872 | (if (and (org-called-interactively-p 'any) (bufferp rtn)) |
c8d0cf5c CD |
873 | (switch-to-buffer-other-window rtn) |
874 | rtn))) | |
875 | ||
876 | (defvar html-table-tag nil) ; dynamically scoped into this. | |
877 | (defvar org-par-open nil) | |
86fbb8ca CD |
878 | |
879 | ;;; org-html-cvt-link-fn | |
880 | (defconst org-html-cvt-link-fn | |
8223b1d2 BG |
881 | nil |
882 | "Function to convert link URLs to exportable URLs. | |
86fbb8ca CD |
883 | Takes two arguments, TYPE and PATH. |
884 | Returns exportable url as (TYPE PATH), or nil to signal that it | |
885 | didn't handle this case. | |
886 | Intended to be locally bound around a call to `org-export-as-html'." ) | |
887 | ||
888 | (defun org-html-cvt-org-as-html (opt-plist type path) | |
8223b1d2 | 889 | "Convert an org filename to an equivalent html filename. |
86fbb8ca CD |
890 | If TYPE is not file, just return `nil'. |
891 | See variable `org-export-html-link-org-files-as-html'" | |
892 | ||
8223b1d2 BG |
893 | (save-match-data |
894 | (and | |
895 | org-export-html-link-org-files-as-html | |
896 | (string= type "file") | |
897 | (string-match "\\.org$" path) | |
898 | (progn | |
899 | (list | |
900 | "file" | |
901 | (concat | |
902 | (substring path 0 (match-beginning 0)) | |
903 | "." | |
904 | (plist-get opt-plist :html-extension))))))) | |
86fbb8ca CD |
905 | |
906 | ||
907 | ;;; org-html-should-inline-p | |
908 | (defun org-html-should-inline-p (filename descp) | |
8223b1d2 | 909 | "Return non-nil if link FILENAME should be inlined. |
86fbb8ca CD |
910 | The decision to inline the FILENAME link is based on the current |
911 | settings. DESCP is the boolean of whether there was a link | |
912 | description. See variables `org-export-html-inline-images' and | |
913 | `org-export-html-inline-image-extensions'." | |
8223b1d2 BG |
914 | (declare (special |
915 | org-export-html-inline-images | |
916 | org-export-html-inline-image-extensions)) | |
917 | (and (or (eq t org-export-html-inline-images) | |
918 | (and org-export-html-inline-images (not descp))) | |
919 | (org-file-image-p | |
920 | filename org-export-html-inline-image-extensions))) | |
86fbb8ca CD |
921 | |
922 | ;;; org-html-make-link | |
923 | (defun org-html-make-link (opt-plist type path fragment desc attr | |
8223b1d2 BG |
924 | may-inline-p) |
925 | "Make an HTML link. | |
86fbb8ca | 926 | OPT-PLIST is an options list. |
e66ba1df BG |
927 | TYPE is the device-type of the link (THIS://foo.html). |
928 | PATH is the path of the link (http://THIS#location). | |
929 | FRAGMENT is the fragment part of the link, if any (foo.html#THIS). | |
86fbb8ca | 930 | DESC is the link description, if any. |
e66ba1df | 931 | ATTR is a string of other attributes of the \"a\" element. |
86fbb8ca CD |
932 | MAY-INLINE-P allows inlining it as an image." |
933 | ||
8223b1d2 BG |
934 | (declare (special org-par-open)) |
935 | (save-match-data | |
936 | (let* ((filename path) | |
937 | ;;First pass. Just sanity stuff. | |
938 | (components-1 | |
939 | (cond | |
940 | ((string= type "file") | |
941 | (list | |
942 | type | |
943 | ;;Substitute just if original path was absolute. | |
944 | ;;(Otherwise path must remain relative) | |
945 | (if (file-name-absolute-p path) | |
946 | (concat "file://" (expand-file-name path)) | |
947 | path))) | |
948 | ((string= type "") | |
949 | (list nil path)) | |
950 | (t (list type path)))) | |
951 | ||
952 | ;;Second pass. Components converted so they can refer | |
953 | ;;to a remote site. | |
954 | (components-2 | |
955 | (or | |
956 | (and org-html-cvt-link-fn | |
957 | (apply org-html-cvt-link-fn | |
958 | opt-plist components-1)) | |
959 | (apply #'org-html-cvt-org-as-html | |
960 | opt-plist components-1) | |
961 | components-1)) | |
962 | (type (first components-2)) | |
963 | (thefile (second components-2))) | |
964 | ||
965 | ||
966 | ;;Third pass. Build final link except for leading type | |
967 | ;;spec. | |
968 | (cond | |
969 | ((or | |
970 | (not type) | |
971 | (string= type "http") | |
972 | (string= type "https") | |
973 | (string= type "file") | |
974 | (string= type "coderef")) | |
975 | (if fragment | |
976 | (setq thefile (concat thefile "#" fragment)))) | |
977 | ||
978 | (t)) | |
979 | ||
980 | ;;Final URL-build, for all types. | |
981 | (setq thefile | |
86fbb8ca | 982 | (let |
8223b1d2 | 983 | ((str (org-export-html-format-href thefile))) |
3ab2c837 BG |
984 | (if (and type (not (or (string= "file" type) |
985 | (string= "coderef" type)))) | |
86fbb8ca | 986 | (concat type ":" str) |
8223b1d2 | 987 | str))) |
86fbb8ca | 988 | |
8223b1d2 BG |
989 | (if (and |
990 | may-inline-p | |
991 | ;;Can't inline a URL with a fragment. | |
992 | (not fragment)) | |
993 | (progn | |
994 | (message "image %s %s" thefile org-par-open) | |
995 | (org-export-html-format-image thefile org-par-open)) | |
996 | (concat | |
997 | "<a href=\"" thefile "\"" (if attr (concat " " attr)) ">" | |
998 | (org-export-html-format-desc desc) | |
999 | "</a>"))))) | |
1000 | ||
1001 | (defun org-html-handle-links (org-line opt-plist) | |
1002 | "Return ORG-LINE with markup of Org mode links. | |
3ab2c837 BG |
1003 | OPT-PLIST is the export options list." |
1004 | (let ((start 0) | |
1005 | (current-dir (if buffer-file-name | |
8223b1d2 BG |
1006 | (file-name-directory buffer-file-name) |
1007 | default-directory)) | |
3ab2c837 BG |
1008 | (link-validate (plist-get opt-plist :link-validation-function)) |
1009 | type id-file fnc | |
1010 | rpl path attr desc descp desc1 desc2 link) | |
8223b1d2 | 1011 | (while (string-match org-bracket-link-analytic-regexp++ org-line start) |
3ab2c837 BG |
1012 | (setq start (match-beginning 0)) |
1013 | (setq path (save-match-data (org-link-unescape | |
8223b1d2 | 1014 | (match-string 3 org-line)))) |
3ab2c837 | 1015 | (setq type (cond |
8223b1d2 | 1016 | ((match-end 2) (match-string 2 org-line)) |
3ab2c837 BG |
1017 | ((save-match-data |
1018 | (or (file-name-absolute-p path) | |
1019 | (string-match "^\\.\\.?/" path))) | |
1020 | "file") | |
1021 | (t "internal"))) | |
e66ba1df | 1022 | (setq path (org-extract-attributes path)) |
3ab2c837 | 1023 | (setq attr (get-text-property 0 'org-attributes path)) |
8223b1d2 | 1024 | (setq desc1 (if (match-end 5) (match-string 5 org-line)) |
3ab2c837 BG |
1025 | desc2 (if (match-end 2) (concat type ":" path) path) |
1026 | descp (and desc1 (not (equal desc1 desc2))) | |
1027 | desc (or desc1 desc2)) | |
1028 | ;; Make an image out of the description if that is so wanted | |
1029 | (when (and descp (org-file-image-p | |
1030 | desc org-export-html-inline-image-extensions)) | |
1031 | (save-match-data | |
1032 | (if (string-match "^file:" desc) | |
1033 | (setq desc (substring desc (match-end 0))))) | |
1034 | (setq desc (org-add-props | |
e66ba1df | 1035 | (concat "<img src=\"" desc "\" alt=\"" |
3ab2c837 BG |
1036 | (file-name-nondirectory desc) "\"/>") |
1037 | '(org-protected t)))) | |
1038 | (cond | |
1039 | ((equal type "internal") | |
1040 | (let | |
1041 | ((frag-0 | |
1042 | (if (= (string-to-char path) ?#) | |
1043 | (substring path 1) | |
1044 | path))) | |
1045 | (setq rpl | |
1046 | (org-html-make-link | |
1047 | opt-plist | |
1048 | "" | |
1049 | "" | |
1050 | (org-solidify-link-text | |
1051 | (save-match-data (org-link-unescape frag-0)) | |
1052 | nil) | |
1053 | desc attr nil)))) | |
1054 | ((and (equal type "id") | |
1055 | (setq id-file (org-id-find-id-file path))) | |
1056 | ;; This is an id: link to another file (if it was the same file, | |
1057 | ;; it would have become an internal link...) | |
1058 | (save-match-data | |
1059 | (setq id-file (file-relative-name | |
1060 | id-file | |
1061 | (file-name-directory org-current-export-file))) | |
1062 | (setq rpl | |
1063 | (org-html-make-link opt-plist | |
1064 | "file" id-file | |
1065 | (concat (if (org-uuidgen-p path) "ID-") path) | |
1066 | desc | |
1067 | attr | |
1068 | nil)))) | |
1069 | ((member type '("http" "https")) | |
1070 | ;; standard URL, can inline as image | |
1071 | (setq rpl | |
1072 | (org-html-make-link opt-plist | |
1073 | type path nil | |
1074 | desc | |
1075 | attr | |
1076 | (org-html-should-inline-p path descp)))) | |
1077 | ((member type '("ftp" "mailto" "news")) | |
1078 | ;; standard URL, can't inline as image | |
1079 | (setq rpl | |
1080 | (org-html-make-link opt-plist | |
1081 | type path nil | |
1082 | desc | |
1083 | attr | |
1084 | nil))) | |
1085 | ||
1086 | ((string= type "coderef") | |
1087 | (let* | |
1088 | ((coderef-str (format "coderef-%s" path)) | |
1089 | (attr-1 | |
1090 | (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\"" | |
1091 | coderef-str coderef-str))) | |
1092 | (setq rpl | |
1093 | (org-html-make-link opt-plist | |
1094 | type "" coderef-str | |
1095 | (format | |
1096 | (org-export-get-coderef-format | |
1097 | path | |
1098 | (and descp desc)) | |
1099 | (cdr (assoc path org-export-code-refs))) | |
1100 | attr-1 | |
1101 | nil)))) | |
1102 | ||
1103 | ((functionp (setq fnc (nth 2 (assoc type org-link-protocols)))) | |
1104 | ;; The link protocol has a function for format the link | |
1105 | (setq rpl | |
1106 | (save-match-data | |
1107 | (funcall fnc (org-link-unescape path) desc1 'html)))) | |
1108 | ||
1109 | ((string= type "file") | |
1110 | ;; FILE link | |
1111 | (save-match-data | |
1112 | (let* | |
1113 | ((components | |
1114 | (if | |
1115 | (string-match "::\\(.*\\)" path) | |
1116 | (list | |
1117 | (replace-match "" t nil path) | |
1118 | (match-string 1 path)) | |
1119 | (list path nil))) | |
1120 | ||
1121 | ;;The proper path, without a fragment | |
1122 | (path-1 | |
1123 | (first components)) | |
1124 | ||
1125 | ;;The raw fragment | |
1126 | (fragment-0 | |
1127 | (second components)) | |
1128 | ||
1129 | ;;Check the fragment. If it can't be used as | |
1130 | ;;target fragment we'll pass nil instead. | |
1131 | (fragment-1 | |
1132 | (if | |
1133 | (and fragment-0 | |
1134 | (not (string-match "^[0-9]*$" fragment-0)) | |
1135 | (not (string-match "^\\*" fragment-0)) | |
1136 | (not (string-match "^/.*/$" fragment-0))) | |
1137 | (org-solidify-link-text | |
1138 | (org-link-unescape fragment-0)) | |
1139 | nil)) | |
1140 | (desc-2 | |
1141 | ;;Description minus "file:" and ".org" | |
1142 | (if (string-match "^file:" desc) | |
1143 | (let | |
1144 | ((desc-1 (replace-match "" t t desc))) | |
1145 | (if (string-match "\\.org$" desc-1) | |
1146 | (replace-match "" t t desc-1) | |
1147 | desc-1)) | |
1148 | desc))) | |
1149 | ||
1150 | (setq rpl | |
1151 | (if | |
1152 | (and | |
1153 | (functionp link-validate) | |
1154 | (not (funcall link-validate path-1 current-dir))) | |
1155 | desc | |
1156 | (org-html-make-link opt-plist | |
1157 | "file" path-1 fragment-1 desc-2 attr | |
1158 | (org-html-should-inline-p path-1 descp))))))) | |
1159 | ||
1160 | (t | |
1161 | ;; just publish the path, as default | |
e66ba1df | 1162 | (setq rpl (concat "<i><" type ":" |
3ab2c837 | 1163 | (save-match-data (org-link-unescape path)) |
e66ba1df | 1164 | "></i>")))) |
8223b1d2 | 1165 | (setq org-line (replace-match rpl t t org-line) |
3ab2c837 | 1166 | start (+ start (length rpl)))) |
8223b1d2 | 1167 | org-line)) |
3ab2c837 | 1168 | |
86fbb8ca | 1169 | ;;; org-export-as-html |
e66ba1df BG |
1170 | |
1171 | (defvar org-heading-keyword-regexp-format) ; defined in org.el | |
1172 | ||
c8d0cf5c CD |
1173 | ;;;###autoload |
1174 | (defun org-export-as-html (arg &optional hidden ext-plist | |
1175 | to-buffer body-only pub-dir) | |
1176 | "Export the outline as a pretty HTML file. | |
1177 | If there is an active region, export only the region. The prefix | |
1178 | ARG specifies how many levels of the outline should become | |
1179 | headlines. The default is 3. Lower levels will become bulleted | |
1180 | lists. HIDDEN is obsolete and does nothing. | |
1181 | EXT-PLIST is a property list with external parameters overriding | |
1182 | org-mode's default settings, but still inferior to file-local | |
1183 | settings. When TO-BUFFER is non-nil, create a buffer with that | |
1184 | name and export to that buffer. If TO-BUFFER is the symbol | |
1185 | `string', don't leave any buffer behind but just return the | |
1186 | resulting HTML as a string. When BODY-ONLY is set, don't produce | |
1187 | the file header and footer, simply return the content of | |
1188 | <body>...</body>, without even the body tags themselves. When | |
1189 | PUB-DIR is set, use this as the publishing directory." | |
1190 | (interactive "P") | |
ed21c5c8 | 1191 | (run-hooks 'org-export-first-hook) |
c8d0cf5c CD |
1192 | |
1193 | ;; Make sure we have a file name when we need it. | |
1194 | (when (and (not (or to-buffer body-only)) | |
1195 | (not buffer-file-name)) | |
1196 | (if (buffer-base-buffer) | |
1197 | (org-set-local 'buffer-file-name | |
1198 | (with-current-buffer (buffer-base-buffer) | |
1199 | buffer-file-name)) | |
f924a367 | 1200 | (error "Need a file name to be able to export"))) |
c8d0cf5c CD |
1201 | |
1202 | (message "Exporting...") | |
1203 | (setq-default org-todo-line-regexp org-todo-line-regexp) | |
1204 | (setq-default org-deadline-line-regexp org-deadline-line-regexp) | |
1205 | (setq-default org-done-keywords org-done-keywords) | |
1206 | (setq-default org-maybe-keyword-time-regexp org-maybe-keyword-time-regexp) | |
1207 | (let* ((opt-plist | |
1208 | (org-export-process-option-filters | |
1209 | (org-combine-plists (org-default-export-plist) | |
1210 | ext-plist | |
1211 | (org-infile-export-plist)))) | |
1212 | (body-only (or body-only (plist-get opt-plist :body-only))) | |
1213 | (style (concat (if (plist-get opt-plist :style-include-default) | |
1214 | org-export-html-style-default) | |
1215 | (plist-get opt-plist :style) | |
1216 | (plist-get opt-plist :style-extra) | |
1217 | "\n" | |
1218 | (if (plist-get opt-plist :style-include-scripts) | |
1219 | org-export-html-scripts))) | |
1220 | (html-extension (plist-get opt-plist :html-extension)) | |
c8d0cf5c CD |
1221 | valid thetoc have-headings first-heading-pos |
1222 | (odd org-odd-levels-only) | |
1223 | (region-p (org-region-active-p)) | |
1224 | (rbeg (and region-p (region-beginning))) | |
1225 | (rend (and region-p (region-end))) | |
1226 | (subtree-p | |
8bfe682a | 1227 | (if (plist-get opt-plist :ignore-subtree-p) |
c8d0cf5c CD |
1228 | nil |
1229 | (when region-p | |
1230 | (save-excursion | |
1231 | (goto-char rbeg) | |
1232 | (and (org-at-heading-p) | |
1233 | (>= (org-end-of-subtree t t) rend)))))) | |
1234 | (level-offset (if subtree-p | |
1235 | (save-excursion | |
1236 | (goto-char rbeg) | |
1237 | (+ (funcall outline-level) | |
1238 | (if org-odd-levels-only 1 0))) | |
1239 | 0)) | |
1240 | (opt-plist (setq org-export-opt-plist | |
1241 | (if subtree-p | |
1242 | (org-export-add-subtree-options opt-plist rbeg) | |
1243 | opt-plist))) | |
1244 | ;; The following two are dynamically scoped into other | |
1245 | ;; routines below. | |
1246 | (org-current-export-dir | |
1247 | (or pub-dir (org-export-directory :html opt-plist))) | |
1248 | (org-current-export-file buffer-file-name) | |
8223b1d2 | 1249 | (level 0) (org-line "") (origline "") txt todo |
c8d0cf5c CD |
1250 | (umax nil) |
1251 | (umax-toc nil) | |
1252 | (filename (if to-buffer nil | |
1253 | (expand-file-name | |
1254 | (concat | |
1255 | (file-name-sans-extension | |
1256 | (or (and subtree-p | |
1257 | (org-entry-get (region-beginning) | |
1258 | "EXPORT_FILE_NAME" t)) | |
1259 | (file-name-nondirectory buffer-file-name))) | |
1260 | "." html-extension) | |
1261 | (file-name-as-directory | |
1262 | (or pub-dir (org-export-directory :html opt-plist)))))) | |
1263 | (current-dir (if buffer-file-name | |
1264 | (file-name-directory buffer-file-name) | |
1265 | default-directory)) | |
e66ba1df | 1266 | (auto-insert nil); Avoid any auto-insert stuff for the new file |
c8d0cf5c CD |
1267 | (buffer (if to-buffer |
1268 | (cond | |
1269 | ((eq to-buffer 'string) (get-buffer-create "*Org HTML Export*")) | |
1270 | (t (get-buffer-create to-buffer))) | |
1271 | (find-file-noselect filename))) | |
1272 | (org-levels-open (make-vector org-level-max nil)) | |
e66ba1df BG |
1273 | (date (org-html-expand (plist-get opt-plist :date))) |
1274 | (author (org-html-expand (plist-get opt-plist :author))) | |
3ab2c837 BG |
1275 | (html-validation-link (or org-export-html-validation-link "")) |
1276 | (title (org-html-expand | |
1277 | (or (and subtree-p (org-export-get-title-from-subtree)) | |
1278 | (plist-get opt-plist :title) | |
1279 | (and (not body-only) | |
1280 | (not | |
1281 | (plist-get opt-plist :skip-before-1st-heading)) | |
1282 | (org-export-grab-title-from-buffer)) | |
1283 | (and buffer-file-name | |
1284 | (file-name-sans-extension | |
1285 | (file-name-nondirectory buffer-file-name))) | |
1286 | "UNTITLED"))) | |
c8d0cf5c CD |
1287 | (link-up (and (plist-get opt-plist :link-up) |
1288 | (string-match "\\S-" (plist-get opt-plist :link-up)) | |
1289 | (plist-get opt-plist :link-up))) | |
1290 | (link-home (and (plist-get opt-plist :link-home) | |
afe98dfa CD |
1291 | (string-match "\\S-" (plist-get opt-plist :link-home)) |
1292 | (plist-get opt-plist :link-home))) | |
c8d0cf5c CD |
1293 | (dummy (setq opt-plist (plist-put opt-plist :title title))) |
1294 | (html-table-tag (plist-get opt-plist :html-table-tag)) | |
e66ba1df BG |
1295 | (quote-re0 (concat "^ *" org-quote-string "\\( +\\|[ \t]*$\\)")) |
1296 | (quote-re (format org-heading-keyword-regexp-format | |
1297 | org-quote-string)) | |
c8d0cf5c CD |
1298 | (inquote nil) |
1299 | (infixed nil) | |
1300 | (inverse nil) | |
c8d0cf5c CD |
1301 | (email (plist-get opt-plist :email)) |
1302 | (language (plist-get opt-plist :language)) | |
e66ba1df BG |
1303 | (keywords (org-html-expand (plist-get opt-plist :keywords))) |
1304 | (description (org-html-expand (plist-get opt-plist :description))) | |
3ab2c837 | 1305 | (num (plist-get opt-plist :section-numbers)) |
c8d0cf5c CD |
1306 | (lang-words nil) |
1307 | (head-count 0) cnt | |
1308 | (start 0) | |
1309 | (coding-system (and (boundp 'buffer-file-coding-system) | |
1310 | buffer-file-coding-system)) | |
1311 | (coding-system-for-write (or org-export-html-coding-system | |
1312 | coding-system)) | |
1313 | (save-buffer-coding-system (or org-export-html-coding-system | |
1314 | coding-system)) | |
1315 | (charset (and coding-system-for-write | |
1316 | (fboundp 'coding-system-get) | |
1317 | (coding-system-get coding-system-for-write | |
1318 | 'mime-charset))) | |
1319 | (region | |
1320 | (buffer-substring | |
1321 | (if region-p (region-beginning) (point-min)) | |
1322 | (if region-p (region-end) (point-max)))) | |
afe98dfa | 1323 | (org-export-have-math nil) |
3ab2c837 BG |
1324 | (org-export-footnotes-seen nil) |
1325 | (org-export-footnotes-data (org-footnote-all-labels 'with-defs)) | |
8223b1d2 BG |
1326 | (custom-id (or (org-entry-get nil "CUSTOM_ID" t) "")) |
1327 | (footnote-def-prefix (format "fn-%s" custom-id)) | |
1328 | (footnote-ref-prefix (format "fnr-%s" custom-id)) | |
c8d0cf5c CD |
1329 | (lines |
1330 | (org-split-string | |
1331 | (org-export-preprocess-string | |
1332 | region | |
1333 | :emph-multiline t | |
3ab2c837 | 1334 | :for-backend 'html |
c8d0cf5c CD |
1335 | :skip-before-1st-heading |
1336 | (plist-get opt-plist :skip-before-1st-heading) | |
1337 | :drawers (plist-get opt-plist :drawers) | |
1338 | :todo-keywords (plist-get opt-plist :todo-keywords) | |
3ab2c837 | 1339 | :tasks (plist-get opt-plist :tasks) |
c8d0cf5c CD |
1340 | :tags (plist-get opt-plist :tags) |
1341 | :priority (plist-get opt-plist :priority) | |
1342 | :footnotes (plist-get opt-plist :footnotes) | |
1343 | :timestamps (plist-get opt-plist :timestamps) | |
1344 | :archived-trees | |
1345 | (plist-get opt-plist :archived-trees) | |
1346 | :select-tags (plist-get opt-plist :select-tags) | |
1347 | :exclude-tags (plist-get opt-plist :exclude-tags) | |
1348 | :add-text | |
1349 | (plist-get opt-plist :text) | |
1350 | :LaTeX-fragments | |
1351 | (plist-get opt-plist :LaTeX-fragments)) | |
1352 | "[\r\n]")) | |
afe98dfa CD |
1353 | (mathjax |
1354 | (if (or (eq (plist-get opt-plist :LaTeX-fragments) 'mathjax) | |
1355 | (and org-export-have-math | |
1356 | (eq (plist-get opt-plist :LaTeX-fragments) t))) | |
1357 | ||
1358 | (org-export-html-mathjax-config | |
1359 | org-export-html-mathjax-template | |
1360 | org-export-html-mathjax-options | |
1361 | (or (plist-get opt-plist :mathjax) "")) | |
1362 | "")) | |
3ab2c837 | 1363 | table-open |
c8d0cf5c | 1364 | table-buffer table-orig-buffer |
3ab2c837 | 1365 | ind |
c8d0cf5c | 1366 | rpl path attr desc descp desc1 desc2 link |
3ab2c837 | 1367 | snumber fnc |
c8d0cf5c | 1368 | footnotes footref-seen |
8223b1d2 | 1369 | href) |
c8d0cf5c CD |
1370 | |
1371 | (let ((inhibit-read-only t)) | |
1372 | (org-unmodified | |
1373 | (remove-text-properties (point-min) (point-max) | |
1374 | '(:org-license-to-kill t)))) | |
1375 | ||
1376 | (message "Exporting...") | |
1377 | ||
1378 | (setq org-min-level (org-get-min-level lines level-offset)) | |
1379 | (setq org-last-level org-min-level) | |
1380 | (org-init-section-numbers) | |
1381 | ||
1382 | (cond | |
1383 | ((and date (string-match "%" date)) | |
1384 | (setq date (format-time-string date))) | |
1385 | (date) | |
8223b1d2 | 1386 | (t (setq date (format-time-string org-export-html-date-format-string)))) |
c8d0cf5c CD |
1387 | |
1388 | ;; Get the language-dependent settings | |
1389 | (setq lang-words (or (assoc language org-export-language-setup) | |
1390 | (assoc "en" org-export-language-setup))) | |
1391 | ||
1392 | ;; Switch to the output buffer | |
1393 | (set-buffer buffer) | |
1394 | (let ((inhibit-read-only t)) (erase-buffer)) | |
1395 | (fundamental-mode) | |
1396 | (org-install-letbind) | |
1397 | ||
1398 | (and (fboundp 'set-buffer-file-coding-system) | |
1399 | (set-buffer-file-coding-system coding-system-for-write)) | |
1400 | ||
1401 | (let ((case-fold-search nil) | |
1402 | (org-odd-levels-only odd)) | |
1403 | ;; create local variables for all options, to make sure all called | |
1404 | ;; functions get the correct information | |
1405 | (mapc (lambda (x) | |
1406 | (set (make-local-variable (nth 2 x)) | |
1407 | (plist-get opt-plist (car x)))) | |
1408 | org-export-plist-vars) | |
1409 | (setq umax (if arg (prefix-numeric-value arg) | |
1410 | org-export-headline-levels)) | |
1411 | (setq umax-toc (if (integerp org-export-with-toc) | |
1412 | (min org-export-with-toc umax) | |
1413 | umax)) | |
1414 | (unless body-only | |
1415 | ;; File header | |
1416 | (insert (format | |
1417 | "%s | |
1418 | <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" | |
1419 | \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> | |
e66ba1df | 1420 | <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"> |
c8d0cf5c | 1421 | <head> |
c8d0cf5c CD |
1422 | <title>%s</title> |
1423 | <meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/> | |
e66ba1df | 1424 | <meta name=\"title\" content=\"%s\"/> |
c8d0cf5c CD |
1425 | <meta name=\"generator\" content=\"Org-mode\"/> |
1426 | <meta name=\"generated\" content=\"%s\"/> | |
1427 | <meta name=\"author\" content=\"%s\"/> | |
1428 | <meta name=\"description\" content=\"%s\"/> | |
1429 | <meta name=\"keywords\" content=\"%s\"/> | |
1430 | %s | |
afe98dfa | 1431 | %s |
c8d0cf5c CD |
1432 | </head> |
1433 | <body> | |
5dec9555 | 1434 | %s |
c8d0cf5c CD |
1435 | " |
1436 | (format | |
1437 | (or (and (stringp org-export-html-xml-declaration) | |
1438 | org-export-html-xml-declaration) | |
1439 | (cdr (assoc html-extension org-export-html-xml-declaration)) | |
1440 | (cdr (assoc "html" org-export-html-xml-declaration)) | |
1441 | ||
1442 | "") | |
1443 | (or charset "iso-8859-1")) | |
1444 | language language | |
86fbb8ca | 1445 | title |
5dec9555 | 1446 | (or charset "iso-8859-1") |
e66ba1df | 1447 | title date author description keywords |
5dec9555 | 1448 | style |
afe98dfa | 1449 | mathjax |
c8d0cf5c CD |
1450 | (if (or link-up link-home) |
1451 | (concat | |
1452 | (format org-export-html-home/up-format | |
1453 | (or link-up link-home) | |
1454 | (or link-home link-up)) | |
1455 | "\n") | |
5dec9555 | 1456 | ""))) |
c8d0cf5c | 1457 | |
3ab2c837 BG |
1458 | ;; insert html preamble |
1459 | (when (plist-get opt-plist :html-preamble) | |
e66ba1df | 1460 | (let ((html-pre (plist-get opt-plist :html-preamble)) |
153ae947 | 1461 | (html-pre-real-contents "")) |
3ab2c837 | 1462 | (cond ((stringp html-pre) |
e66ba1df BG |
1463 | (setq html-pre-real-contents |
1464 | (format-spec html-pre `((?t . ,title) (?a . ,author) | |
1465 | (?d . ,date) (?e . ,email))))) | |
3ab2c837 | 1466 | ((functionp html-pre) |
e66ba1df BG |
1467 | (insert "<div id=\"" (nth 0 org-export-html-divs) "\">\n") |
1468 | (if (stringp (funcall html-pre)) (insert (funcall html-pre))) | |
1469 | (insert "\n</div>\n")) | |
3ab2c837 | 1470 | (t |
e66ba1df | 1471 | (setq html-pre-real-contents |
8223b1d2 BG |
1472 | (format-spec |
1473 | (or (cadr (assoc (nth 0 lang-words) | |
1474 | org-export-html-preamble-format)) | |
1475 | (cadr (assoc "en" org-export-html-preamble-format))) | |
1476 | `((?t . ,title) (?a . ,author) | |
1477 | (?d . ,date) (?e . ,email)))))) | |
e66ba1df BG |
1478 | ;; don't output an empty preamble DIV |
1479 | (unless (and (functionp html-pre) | |
1480 | (equal html-pre-real-contents "")) | |
1481 | (insert "<div id=\"" (nth 0 org-export-html-divs) "\">\n") | |
1482 | (insert html-pre-real-contents) | |
1483 | (insert "\n</div>\n")))) | |
3ab2c837 BG |
1484 | |
1485 | ;; begin wrap around body | |
e66ba1df | 1486 | (insert (format "\n<div id=\"%s\">" |
3ab2c837 | 1487 | ;; FIXME org-export-html-content-div is obsolete since 7.7 |
e66ba1df | 1488 | (or org-export-html-content-div |
3ab2c837 BG |
1489 | (nth 1 org-export-html-divs))) |
1490 | ;; FIXME this should go in the preamble but is here so | |
1491 | ;; that org-infojs can still find it | |
1492 | "\n<h1 class=\"title\">" title "</h1>\n")) | |
1493 | ||
1494 | ;; insert body | |
8223b1d2 | 1495 | (if org-export-with-toc |
c8d0cf5c CD |
1496 | (progn |
1497 | (push (format "<h%d>%s</h%d>\n" | |
1498 | org-export-html-toplevel-hlevel | |
1499 | (nth 3 lang-words) | |
1500 | org-export-html-toplevel-hlevel) | |
1501 | thetoc) | |
1502 | (push "<div id=\"text-table-of-contents\">\n" thetoc) | |
1503 | (push "<ul>\n<li>" thetoc) | |
1504 | (setq lines | |
e66ba1df | 1505 | (mapcar |
8223b1d2 BG |
1506 | #'(lambda (org-line) |
1507 | (if (and (string-match org-todo-line-regexp org-line) | |
1508 | (not (get-text-property 0 'org-protected org-line))) | |
3ab2c837 BG |
1509 | ;; This is a headline |
1510 | (progn | |
1511 | (setq have-headings t) | |
1512 | (setq level (- (match-end 1) (match-beginning 1) | |
1513 | level-offset) | |
1514 | level (org-tr-level level) | |
1515 | txt (save-match-data | |
1516 | (org-html-expand | |
1517 | (org-export-cleanup-toc-line | |
8223b1d2 | 1518 | (match-string 3 org-line)))) |
3ab2c837 BG |
1519 | todo |
1520 | (or (and org-export-mark-todo-in-toc | |
1521 | (match-beginning 2) | |
8223b1d2 | 1522 | (not (member (match-string 2 org-line) |
3ab2c837 | 1523 | org-done-keywords))) |
c8d0cf5c | 1524 | ; TODO, not DONE |
3ab2c837 BG |
1525 | (and org-export-mark-todo-in-toc |
1526 | (= level umax-toc) | |
1527 | (org-search-todo-below | |
8223b1d2 | 1528 | org-line lines level)))) |
3ab2c837 BG |
1529 | (if (string-match |
1530 | (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt) | |
e66ba1df | 1531 | (setq txt (replace-match |
153ae947 | 1532 | " <span class=\"tag\">\\1</span>" t nil txt))) |
3ab2c837 BG |
1533 | (if (string-match quote-re0 txt) |
1534 | (setq txt (replace-match "" t t txt))) | |
1535 | (setq snumber (org-section-number level)) | |
1536 | (if (and num (if (integerp num) | |
1537 | (>= num level) | |
1538 | num)) | |
1539 | (setq txt (concat snumber " " txt))) | |
1540 | (if (<= level (max umax umax-toc)) | |
1541 | (setq head-count (+ head-count 1))) | |
1542 | (if (<= level umax-toc) | |
1543 | (progn | |
1544 | (if (> level org-last-level) | |
1545 | (progn | |
1546 | (setq cnt (- level org-last-level)) | |
1547 | (while (>= (setq cnt (1- cnt)) 0) | |
1548 | (push "\n<ul>\n<li>" thetoc)) | |
1549 | (push "\n" thetoc))) | |
1550 | (if (< level org-last-level) | |
1551 | (progn | |
1552 | (setq cnt (- org-last-level level)) | |
1553 | (while (>= (setq cnt (1- cnt)) 0) | |
1554 | (push "</li>\n</ul>" thetoc)) | |
1555 | (push "\n" thetoc))) | |
1556 | ;; Check for targets | |
8223b1d2 BG |
1557 | (while (string-match org-any-target-regexp org-line) |
1558 | (setq org-line (replace-match | |
1559 | (concat "@<span class=\"target\">" | |
1560 | (match-string 1 org-line) "@</span> ") | |
1561 | t t org-line))) | |
3ab2c837 BG |
1562 | (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt) |
1563 | (setq txt (replace-match "" t t txt))) | |
1564 | (setq href | |
1565 | (replace-regexp-in-string | |
1566 | "\\." "-" (format "sec-%s" snumber))) | |
e66ba1df BG |
1567 | (setq href (org-solidify-link-text |
1568 | (or (cdr (assoc href | |
3ab2c837 BG |
1569 | org-export-preferred-target-alist)) href))) |
1570 | (push | |
1571 | (format | |
1572 | (if todo | |
1573 | "</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>" | |
1574 | "</li>\n<li><a href=\"#%s\">%s</a>") | |
1575 | href txt) thetoc) | |
e66ba1df | 1576 | |
3ab2c837 | 1577 | (setq org-last-level level))))) |
8223b1d2 | 1578 | org-line) |
3ab2c837 | 1579 | lines)) |
c8d0cf5c CD |
1580 | (while (> org-last-level (1- org-min-level)) |
1581 | (setq org-last-level (1- org-last-level)) | |
1582 | (push "</li>\n</ul>\n" thetoc)) | |
1583 | (push "</div>\n" thetoc) | |
1584 | (setq thetoc (if have-headings (nreverse thetoc) nil)))) | |
e66ba1df | 1585 | |
c8d0cf5c CD |
1586 | (setq head-count 0) |
1587 | (org-init-section-numbers) | |
e66ba1df | 1588 | |
c8d0cf5c | 1589 | (org-open-par) |
e66ba1df | 1590 | |
8223b1d2 | 1591 | (while (setq org-line (pop lines) origline org-line) |
c8d0cf5c | 1592 | (catch 'nextline |
e66ba1df | 1593 | |
c8d0cf5c | 1594 | ;; end of quote section? |
8223b1d2 | 1595 | (when (and inquote (string-match org-outline-regexp-bol org-line)) |
c8d0cf5c CD |
1596 | (insert "</pre>\n") |
1597 | (org-open-par) | |
1598 | (setq inquote nil)) | |
1599 | ;; inside a quote section? | |
1600 | (when inquote | |
8223b1d2 | 1601 | (insert (org-html-protect org-line) "\n") |
c8d0cf5c CD |
1602 | (throw 'nextline nil)) |
1603 | ||
1604 | ;; Fixed-width, verbatim lines (examples) | |
1605 | (when (and org-export-with-fixed-width | |
8223b1d2 | 1606 | (string-match "^[ \t]*:\\(\\([ \t]\\|$\\)\\(.*\\)\\)" org-line)) |
c8d0cf5c CD |
1607 | (when (not infixed) |
1608 | (setq infixed t) | |
1609 | (org-close-par-maybe) | |
1610 | ||
1611 | (insert "<pre class=\"example\">\n")) | |
8223b1d2 | 1612 | (insert (org-html-protect (match-string 3 org-line)) "\n") |
c8d0cf5c CD |
1613 | (when (or (not lines) |
1614 | (not (string-match "^[ \t]*:\\(\\([ \t]\\|$\\)\\(.*\\)\\)" | |
1615 | (car lines)))) | |
1616 | (setq infixed nil) | |
1617 | (insert "</pre>\n") | |
1618 | (org-open-par)) | |
1619 | (throw 'nextline nil)) | |
1620 | ||
c8d0cf5c | 1621 | ;; Protected HTML |
8223b1d2 | 1622 | (when (and (get-text-property 0 'org-protected org-line) |
acedf35c CD |
1623 | ;; Make sure it is the entire line that is protected |
1624 | (not (< (or (next-single-property-change | |
8223b1d2 BG |
1625 | 0 'org-protected org-line) 10000) |
1626 | (length org-line)))) | |
1627 | (let (par (ind (get-text-property 0 'original-indentation org-line))) | |
c8d0cf5c CD |
1628 | (when (re-search-backward |
1629 | "\\(<p>\\)\\([ \t\r\n]*\\)\\=" (- (point) 100) t) | |
1630 | (setq par (match-string 1)) | |
1631 | (replace-match "\\2\n")) | |
8223b1d2 | 1632 | (insert org-line "\n") |
c8d0cf5c CD |
1633 | (while (and lines |
1634 | (or (= (length (car lines)) 0) | |
1635 | (not ind) | |
1636 | (equal ind (get-text-property 0 'original-indentation (car lines)))) | |
1637 | (or (= (length (car lines)) 0) | |
1638 | (get-text-property 0 'org-protected (car lines)))) | |
1639 | (insert (pop lines) "\n")) | |
1640 | (and par (insert "<p>\n"))) | |
1641 | (throw 'nextline nil)) | |
1642 | ||
1643 | ;; Blockquotes, verse, and center | |
8223b1d2 | 1644 | (when (equal "ORG-BLOCKQUOTE-START" org-line) |
c8d0cf5c CD |
1645 | (org-close-par-maybe) |
1646 | (insert "<blockquote>\n") | |
1647 | (org-open-par) | |
1648 | (throw 'nextline nil)) | |
8223b1d2 | 1649 | (when (equal "ORG-BLOCKQUOTE-END" org-line) |
c8d0cf5c CD |
1650 | (org-close-par-maybe) |
1651 | (insert "\n</blockquote>\n") | |
1652 | (org-open-par) | |
1653 | (throw 'nextline nil)) | |
8223b1d2 | 1654 | (when (equal "ORG-VERSE-START" org-line) |
c8d0cf5c CD |
1655 | (org-close-par-maybe) |
1656 | (insert "\n<p class=\"verse\">\n") | |
86fbb8ca | 1657 | (setq org-par-open t) |
c8d0cf5c CD |
1658 | (setq inverse t) |
1659 | (throw 'nextline nil)) | |
8223b1d2 | 1660 | (when (equal "ORG-VERSE-END" org-line) |
c8d0cf5c | 1661 | (insert "</p>\n") |
86fbb8ca | 1662 | (setq org-par-open nil) |
c8d0cf5c CD |
1663 | (org-open-par) |
1664 | (setq inverse nil) | |
1665 | (throw 'nextline nil)) | |
8223b1d2 | 1666 | (when (equal "ORG-CENTER-START" org-line) |
c8d0cf5c CD |
1667 | (org-close-par-maybe) |
1668 | (insert "\n<div style=\"text-align: center\">") | |
1669 | (org-open-par) | |
1670 | (throw 'nextline nil)) | |
8223b1d2 | 1671 | (when (equal "ORG-CENTER-END" org-line) |
c8d0cf5c CD |
1672 | (org-close-par-maybe) |
1673 | (insert "\n</div>") | |
1674 | (org-open-par) | |
1675 | (throw 'nextline nil)) | |
1676 | (run-hooks 'org-export-html-after-blockquotes-hook) | |
1677 | (when inverse | |
8223b1d2 | 1678 | (let ((i (org-get-string-indentation org-line))) |
c8d0cf5c | 1679 | (if (> i 0) |
8223b1d2 BG |
1680 | (setq org-line (concat (mapconcat 'identity |
1681 | (make-list (* 2 i) "\\nbsp") "") | |
1682 | " " (org-trim org-line)))) | |
1683 | (unless (string-match "\\\\\\\\[ \t]*$" org-line) | |
1684 | (setq org-line (concat org-line "\\\\"))))) | |
c8d0cf5c CD |
1685 | |
1686 | ;; make targets to anchors | |
8bfe682a | 1687 | (setq start 0) |
c8d0cf5c | 1688 | (while (string-match |
8223b1d2 | 1689 | "<<<?\\([^<>]*\\)>>>?\\((INVISIBLE)\\)?[ \t]*\n?" org-line start) |
c8d0cf5c | 1690 | (cond |
8223b1d2 | 1691 | ((get-text-property (match-beginning 1) 'org-protected org-line) |
8bfe682a | 1692 | (setq start (match-end 1))) |
c8d0cf5c | 1693 | ((match-end 2) |
8223b1d2 BG |
1694 | (setq org-line (replace-match |
1695 | (format | |
1696 | "@<a name=\"%s\" id=\"%s\">@</a>" | |
1697 | (org-solidify-link-text (match-string 1 org-line)) | |
1698 | (org-solidify-link-text (match-string 1 org-line))) | |
1699 | t t org-line))) | |
1700 | ((and org-export-with-toc (equal (string-to-char org-line) ?*)) | |
c8d0cf5c | 1701 | ;; FIXME: NOT DEPENDENT on TOC????????????????????? |
8223b1d2 BG |
1702 | (setq org-line (replace-match |
1703 | (concat "@<span class=\"target\">" | |
1704 | (match-string 1 org-line) "@</span> ") | |
1705 | ;; (concat "@<i>" (match-string 1 org-line) "@</i> ") | |
1706 | t t org-line))) | |
c8d0cf5c | 1707 | (t |
8223b1d2 BG |
1708 | (setq org-line (replace-match |
1709 | (concat "@<a name=\"" | |
1710 | (org-solidify-link-text (match-string 1 org-line)) | |
1711 | "\" class=\"target\">" (match-string 1 org-line) | |
1712 | "@</a> ") | |
1713 | t t org-line))))) | |
ed21c5c8 | 1714 | |
8223b1d2 | 1715 | (setq org-line (org-html-handle-time-stamps org-line)) |
c8d0cf5c CD |
1716 | |
1717 | ;; replace "&" by "&", "<" and ">" by "<" and ">" | |
1718 | ;; handle @<..> HTML tags (replace "@>..<" by "<..>") | |
1719 | ;; Also handle sub_superscripts and checkboxes | |
8223b1d2 BG |
1720 | (or (string-match org-table-hline-regexp org-line) |
1721 | (string-match "^[ \t]*\\([+]-\\||[ ]\\)[-+ |]*[+|][ \t]*$" org-line) | |
1722 | (setq org-line (org-html-expand org-line))) | |
c8d0cf5c CD |
1723 | |
1724 | ;; Format the links | |
8223b1d2 | 1725 | (setq org-line (org-html-handle-links org-line opt-plist)) |
c8d0cf5c CD |
1726 | |
1727 | ;; TODO items | |
e66ba1df | 1728 | (if (and org-todo-line-regexp |
8223b1d2 | 1729 | (string-match org-todo-line-regexp org-line) |
c8d0cf5c CD |
1730 | (match-beginning 2)) |
1731 | ||
8223b1d2 BG |
1732 | (setq org-line |
1733 | (concat (substring org-line 0 (match-beginning 2)) | |
c8d0cf5c | 1734 | "<span class=\"" |
8223b1d2 | 1735 | (if (member (match-string 2 org-line) |
c8d0cf5c CD |
1736 | org-done-keywords) |
1737 | "done" "todo") | |
e66ba1df | 1738 | " " (org-export-html-get-todo-kwd-class-name |
8223b1d2 BG |
1739 | (match-string 2 org-line)) |
1740 | "\">" (match-string 2 org-line) | |
1741 | "</span>" (substring org-line (match-end 2))))) | |
c8d0cf5c CD |
1742 | |
1743 | ;; Does this contain a reference to a footnote? | |
1744 | (when org-export-with-footnotes | |
1745 | (setq start 0) | |
8223b1d2 | 1746 | (while (string-match "\\([^* \t].*?\\)\\[\\([0-9]+\\)\\]" org-line start) |
3ab2c837 BG |
1747 | ;; Discard protected matches not clearly identified as |
1748 | ;; footnote markers. | |
8223b1d2 BG |
1749 | (if (or (get-text-property (match-beginning 2) 'org-protected org-line) |
1750 | (not (get-text-property (match-beginning 2) 'org-footnote org-line))) | |
c8d0cf5c | 1751 | (setq start (match-end 2)) |
8223b1d2 | 1752 | (let ((n (match-string 2 org-line)) extra a) |
c8d0cf5c CD |
1753 | (if (setq a (assoc n footref-seen)) |
1754 | (progn | |
1755 | (setcdr a (1+ (cdr a))) | |
1756 | (setq extra (format ".%d" (cdr a)))) | |
1757 | (setq extra "") | |
1758 | (push (cons n 1) footref-seen)) | |
8223b1d2 | 1759 | (setq org-line |
c8d0cf5c | 1760 | (replace-match |
3ab2c837 BG |
1761 | (concat |
1762 | (format | |
1763 | (concat "%s" | |
1764 | (format org-export-html-footnote-format | |
8223b1d2 BG |
1765 | (concat "<a class=\"footref\" name=\"" footnote-ref-prefix ".%s%s\" href=\"#" footnote-def-prefix ".%s\">%s</a>"))) |
1766 | (or (match-string 1 org-line) "") n extra n n) | |
3ab2c837 BG |
1767 | ;; If another footnote is following the |
1768 | ;; current one, add a separator. | |
1769 | (if (save-match-data | |
1770 | (string-match "\\`\\[[0-9]+\\]" | |
8223b1d2 | 1771 | (substring org-line (match-end 0)))) |
3ab2c837 BG |
1772 | org-export-html-footnote-separator |
1773 | "")) | |
8223b1d2 | 1774 | t t org-line)))))) |
c8d0cf5c CD |
1775 | |
1776 | (cond | |
8223b1d2 | 1777 | ((string-match "^\\(\\*+\\)\\(?: +\\(.*?\\)\\)?[ \t]*$" org-line) |
c8d0cf5c CD |
1778 | ;; This is a headline |
1779 | (setq level (org-tr-level (- (match-end 1) (match-beginning 1) | |
1780 | level-offset)) | |
8223b1d2 | 1781 | txt (or (match-string 2 org-line) "")) |
c8d0cf5c CD |
1782 | (if (string-match quote-re0 txt) |
1783 | (setq txt (replace-match "" t t txt))) | |
1784 | (if (<= level (max umax umax-toc)) | |
1785 | (setq head-count (+ head-count 1))) | |
c8d0cf5c CD |
1786 | (setq first-heading-pos (or first-heading-pos (point))) |
1787 | (org-html-level-start level txt umax | |
1788 | (and org-export-with-toc (<= level umax)) | |
3ab2c837 | 1789 | head-count opt-plist) |
c8d0cf5c CD |
1790 | |
1791 | ;; QUOTES | |
8223b1d2 | 1792 | (when (string-match quote-re org-line) |
c8d0cf5c CD |
1793 | (org-close-par-maybe) |
1794 | (insert "<pre>") | |
1795 | (setq inquote t))) | |
1796 | ||
c8d0cf5c | 1797 | ((and org-export-with-tables |
8223b1d2 | 1798 | (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" org-line)) |
c8d0cf5c CD |
1799 | (when (not table-open) |
1800 | ;; New table starts | |
1801 | (setq table-open t table-buffer nil table-orig-buffer nil)) | |
1802 | ||
1803 | ;; Accumulate lines | |
8223b1d2 | 1804 | (setq table-buffer (cons org-line table-buffer) |
c8d0cf5c CD |
1805 | table-orig-buffer (cons origline table-orig-buffer)) |
1806 | (when (or (not lines) | |
1807 | (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" | |
1808 | (car lines)))) | |
1809 | (setq table-open nil | |
1810 | table-buffer (nreverse table-buffer) | |
1811 | table-orig-buffer (nreverse table-orig-buffer)) | |
1812 | (org-close-par-maybe) | |
1813 | (insert (org-format-table-html table-buffer table-orig-buffer)))) | |
3ab2c837 BG |
1814 | |
1815 | ;; Normal lines | |
1816 | ||
c8d0cf5c | 1817 | (t |
3ab2c837 | 1818 | ;; This line either is list item or end a list. |
8223b1d2 BG |
1819 | (when (get-text-property 0 'list-item org-line) |
1820 | (setq org-line (org-html-export-list-line | |
1821 | org-line | |
1822 | (get-text-property 0 'list-item org-line) | |
1823 | (get-text-property 0 'list-struct org-line) | |
1824 | (get-text-property 0 'list-prevs org-line)))) | |
c8d0cf5c CD |
1825 | |
1826 | ;; Horizontal line | |
8223b1d2 | 1827 | (when (string-match "^[ \t]*-\\{5,\\}[ \t]*$" org-line) |
c8d0cf5c CD |
1828 | (if org-par-open |
1829 | (insert "\n</p>\n<hr/>\n<p>\n") | |
1830 | (insert "\n<hr/>\n")) | |
1831 | (throw 'nextline nil)) | |
1832 | ||
1833 | ;; Empty lines start a new paragraph. If hand-formatted lists | |
1834 | ;; are not fully interpreted, lines starting with "-", "+", "*" | |
1835 | ;; also start a new paragraph. | |
8223b1d2 | 1836 | (if (string-match "^ [-+*]-\\|^[ \t]*$" org-line) (org-open-par)) |
c8d0cf5c CD |
1837 | |
1838 | ;; Is this the start of a footnote? | |
1839 | (when org-export-with-footnotes | |
1840 | (when (and (boundp 'footnote-section-tag-regexp) | |
1841 | (string-match (concat "^" footnote-section-tag-regexp) | |
8223b1d2 | 1842 | org-line)) |
c8d0cf5c CD |
1843 | ;; ignore this line |
1844 | (throw 'nextline nil)) | |
8223b1d2 | 1845 | (when (string-match "^[ \t]*\\[\\([0-9]+\\)\\]" org-line) |
c8d0cf5c | 1846 | (org-close-par-maybe) |
8223b1d2 | 1847 | (let ((n (match-string 1 org-line))) |
c8d0cf5c | 1848 | (setq org-par-open t |
8223b1d2 BG |
1849 | org-line (replace-match |
1850 | (format | |
1851 | (concat "<p class=\"footnote\">" | |
1852 | (format org-export-html-footnote-format | |
1853 | (concat | |
1854 | "<a class=\"footnum\" name=\"" footnote-def-prefix ".%s\" href=\"#" footnote-ref-prefix ".%s\">%s</a>"))) | |
1855 | n n n) t t org-line))))) | |
c8d0cf5c CD |
1856 | ;; Check if the line break needs to be conserved |
1857 | (cond | |
8223b1d2 BG |
1858 | ((string-match "\\\\\\\\[ \t]*$" org-line) |
1859 | (setq org-line (replace-match "<br/>" t t org-line))) | |
c8d0cf5c | 1860 | (org-export-preserve-breaks |
8223b1d2 | 1861 | (setq org-line (concat org-line "<br/>")))) |
c8d0cf5c CD |
1862 | |
1863 | ;; Check if a paragraph should be started | |
1864 | (let ((start 0)) | |
1865 | (while (and org-par-open | |
8223b1d2 | 1866 | (string-match "\\\\par\\>" org-line start)) |
c8d0cf5c CD |
1867 | ;; Leave a space in the </p> so that the footnote matcher |
1868 | ;; does not see this. | |
1869 | (if (not (get-text-property (match-beginning 0) | |
8223b1d2 BG |
1870 | 'org-protected org-line)) |
1871 | (setq org-line (replace-match "</p ><p >" t t org-line))) | |
c8d0cf5c CD |
1872 | (setq start (match-end 0)))) |
1873 | ||
8223b1d2 | 1874 | (insert org-line "\n"))))) |
c8d0cf5c CD |
1875 | |
1876 | ;; Properly close all local lists and other lists | |
1877 | (when inquote | |
1878 | (insert "</pre>\n") | |
1879 | (org-open-par)) | |
afe98dfa | 1880 | |
c8d0cf5c CD |
1881 | (org-html-level-start 1 nil umax |
1882 | (and org-export-with-toc (<= level umax)) | |
3ab2c837 | 1883 | head-count opt-plist) |
c8d0cf5c CD |
1884 | ;; the </div> to close the last text-... div. |
1885 | (when (and (> umax 0) first-heading-pos) (insert "</div>\n")) | |
1886 | ||
1887 | (save-excursion | |
1888 | (goto-char (point-min)) | |
3ab2c837 BG |
1889 | (while (re-search-forward |
1890 | "\\(\\(<p class=\"footnote\">\\)[^\000]*?\\)\\(\\(\\2\\)\\|\\'\\)" | |
1891 | nil t) | |
1892 | (push (match-string 1) footnotes) | |
1893 | (replace-match "\\4" t nil) | |
1894 | (goto-char (match-beginning 0)))) | |
c8d0cf5c CD |
1895 | (when footnotes |
1896 | (insert (format org-export-html-footnotes-section | |
1897 | (nth 4 lang-words) | |
1898 | (mapconcat 'identity (nreverse footnotes) "\n")) | |
1899 | "\n")) | |
1900 | (let ((bib (org-export-html-get-bibliography))) | |
1901 | (when bib | |
1902 | (insert "\n" bib "\n"))) | |
3ab2c837 | 1903 | |
c8d0cf5c | 1904 | (unless body-only |
3ab2c837 BG |
1905 | ;; end wrap around body |
1906 | (insert "</div>\n") | |
1907 | ||
1908 | ;; export html postamble | |
1909 | (let ((html-post (plist-get opt-plist :html-postamble)) | |
1910 | ||
1911 | (mapconcat (lambda(e) | |
1912 | (format "<a href=\"mailto:%s\">%s</a>" e e)) | |
1913 | (split-string email ",+ *") | |
1914 | ", ")) | |
1915 | (creator-info | |
8223b1d2 BG |
1916 | (concat "<a href=\"http://orgmode.org\">Org</a> version " |
1917 | (org-version) " with <a href=\"http://www.gnu.org/software/emacs/\">Emacs</a> version " | |
3ab2c837 BG |
1918 | (number-to-string emacs-major-version)))) |
1919 | ||
1920 | (when (plist-get opt-plist :html-postamble) | |
1921 | (insert "\n<div id=\"" (nth 2 org-export-html-divs) "\">\n") | |
1922 | (cond ((stringp html-post) | |
1923 | (insert (format-spec html-post | |
1924 | `((?a . ,author) (?e . ,email) | |
1925 | (?d . ,date) (?c . ,creator-info) | |
1926 | (?v . ,html-validation-link))))) | |
1927 | ((functionp html-post) | |
e66ba1df | 1928 | (if (stringp (funcall html-post)) (insert (funcall html-post)))) |
3ab2c837 BG |
1929 | ((eq html-post 'auto) |
1930 | ;; fall back on default postamble | |
1931 | (when (plist-get opt-plist :time-stamp-file) | |
1932 | (insert "<p class=\"date\">" (nth 2 lang-words) ": " date "</p>\n")) | |
1933 | (when (and (plist-get opt-plist :author-info) author) | |
8223b1d2 | 1934 | (insert "<p class=\"author\">" (nth 1 lang-words) ": " author "</p>\n")) |
3ab2c837 BG |
1935 | (when (and (plist-get opt-plist :email-info) email) |
1936 | (insert "<p class=\"email\">" email "</p>\n")) | |
1937 | (when (plist-get opt-plist :creator-info) | |
1938 | (insert "<p class=\"creator\">" | |
8223b1d2 BG |
1939 | (concat "<a href=\"http://orgmode.org\">Org</a> version " |
1940 | (org-version) " with <a href=\"http://www.gnu.org/software/emacs/\">Emacs</a> version " | |
3ab2c837 BG |
1941 | (number-to-string emacs-major-version) "</p>\n"))) |
1942 | (insert html-validation-link "\n")) | |
1943 | (t | |
1944 | (insert (format-spec | |
1945 | (or (cadr (assoc (nth 0 lang-words) | |
1946 | org-export-html-postamble-format)) | |
1947 | (cadr (assoc "en" org-export-html-postamble-format))) | |
1948 | `((?a . ,author) (?e . ,email) | |
1949 | (?d . ,date) (?c . ,creator-info) | |
1950 | (?v . ,html-validation-link)))))) | |
1951 | (insert "\n</div>")))) | |
e66ba1df | 1952 | |
3ab2c837 BG |
1953 | ;; FIXME `org-export-html-with-timestamp' has been declared |
1954 | ;; obsolete since Org 7.7 -- don't forget to remove this. | |
1955 | (if org-export-html-with-timestamp | |
1956 | (insert org-export-html-html-helper-timestamp)) | |
1957 | ||
1958 | (unless body-only (insert "\n</body>\n</html>\n")) | |
c8d0cf5c CD |
1959 | |
1960 | (unless (plist-get opt-plist :buffer-will-be-killed) | |
1961 | (normal-mode) | |
54a0dee5 CD |
1962 | (if (eq major-mode (default-value 'major-mode)) |
1963 | (html-mode))) | |
c8d0cf5c CD |
1964 | |
1965 | ;; insert the table of contents | |
1966 | (goto-char (point-min)) | |
1967 | (when thetoc | |
1968 | (if (or (re-search-forward | |
1969 | "<p>\\s-*\\[TABLE-OF-CONTENTS\\]\\s-*</p>" nil t) | |
1970 | (re-search-forward | |
1971 | "\\[TABLE-OF-CONTENTS\\]" nil t)) | |
1972 | (progn | |
1973 | (goto-char (match-beginning 0)) | |
1974 | (replace-match "")) | |
1975 | (goto-char first-heading-pos) | |
1976 | (when (looking-at "\\s-*</p>") | |
1977 | (goto-char (match-end 0)) | |
1978 | (insert "\n"))) | |
1979 | (insert "<div id=\"table-of-contents\">\n") | |
3ab2c837 BG |
1980 | (let ((beg (point))) |
1981 | (mapc 'insert thetoc) | |
1982 | (insert "</div>\n") | |
1983 | (while (re-search-backward "<li>[ \r\n\t]*</li>\n?" beg t) | |
1984 | (replace-match "")))) | |
1985 | ;; remove empty paragraphs | |
c8d0cf5c CD |
1986 | (goto-char (point-min)) |
1987 | (while (re-search-forward "<p>[ \r\n\t]*</p>" nil t) | |
1988 | (replace-match "")) | |
1989 | (goto-char (point-min)) | |
c8d0cf5c CD |
1990 | ;; Convert whitespace place holders |
1991 | (goto-char (point-min)) | |
1992 | (let (beg end n) | |
1993 | (while (setq beg (next-single-property-change (point) 'org-whitespace)) | |
1994 | (setq n (get-text-property beg 'org-whitespace) | |
1995 | end (next-single-property-change beg 'org-whitespace)) | |
1996 | (goto-char beg) | |
1997 | (delete-region beg end) | |
1998 | (insert (format "<span style=\"visibility:hidden;\">%s</span>" | |
1999 | (make-string n ?x))))) | |
ed21c5c8 CD |
2000 | ;; Remove empty lines at the beginning of the file. |
2001 | (goto-char (point-min)) | |
2002 | (when (looking-at "\\s-+\n") (replace-match "")) | |
2003 | ;; Remove display properties | |
2004 | (remove-text-properties (point-min) (point-max) '(display t)) | |
2005 | ;; Run the hook | |
8d642074 | 2006 | (run-hooks 'org-export-html-final-hook) |
c8d0cf5c CD |
2007 | (or to-buffer (save-buffer)) |
2008 | (goto-char (point-min)) | |
2009 | (or (org-export-push-to-kill-ring "HTML") | |
2010 | (message "Exporting... done")) | |
2011 | (if (eq to-buffer 'string) | |
2012 | (prog1 (buffer-substring (point-min) (point-max)) | |
2013 | (kill-buffer (current-buffer))) | |
2014 | (current-buffer))))) | |
2015 | ||
c8d0cf5c CD |
2016 | (defun org-export-html-format-href (s) |
2017 | "Make sure the S is valid as a href reference in an XHTML document." | |
2018 | (save-match-data | |
2019 | (let ((start 0)) | |
2020 | (while (string-match "&" s start) | |
2021 | (setq start (+ (match-beginning 0) 3) | |
2022 | s (replace-match "&" t t s))))) | |
2023 | s) | |
2024 | ||
2025 | (defun org-export-html-format-desc (s) | |
2026 | "Make sure the S is valid as a description in a link." | |
2027 | (if (and s (not (get-text-property 1 'org-protected s))) | |
2028 | (save-match-data | |
2029 | (org-html-do-expand s)) | |
2030 | s)) | |
2031 | ||
2032 | (defun org-export-html-format-image (src par-open) | |
2033 | "Create image tag with source and attributes." | |
2034 | (save-match-data | |
8223b1d2 | 2035 | (if (string-match (regexp-quote org-latex-preview-ltxpng-directory) src) |
ed21c5c8 CD |
2036 | (format "<img src=\"%s\" alt=\"%s\"/>" |
2037 | src (org-find-text-property-in-string 'org-latex-src src)) | |
c8d0cf5c CD |
2038 | (let* ((caption (org-find-text-property-in-string 'org-caption src)) |
2039 | (attr (org-find-text-property-in-string 'org-attributes src)) | |
2040 | (label (org-find-text-property-in-string 'org-label src))) | |
ed21c5c8 | 2041 | (setq caption (and caption (org-html-do-expand caption))) |
8bfe682a | 2042 | (concat |
8223b1d2 BG |
2043 | (if caption |
2044 | (format "%s<div %sclass=\"figure\"> | |
8bfe682a | 2045 | <p>" |
8223b1d2 BG |
2046 | (if org-par-open "</p>\n" "") |
2047 | (if label (format "id=\"%s\" " (org-solidify-link-text label)) ""))) | |
2048 | (format "<img src=\"%s\"%s />" | |
2049 | src | |
2050 | (if (string-match "\\<alt=" (or attr "")) | |
2051 | (concat " " attr ) | |
2052 | (concat " " attr " alt=\"" src "\""))) | |
2053 | (if caption | |
2054 | (format "</p>%s | |
8bfe682a | 2055 | </div>%s" |
8223b1d2 BG |
2056 | (concat "\n<p>" caption "</p>") |
2057 | (if org-par-open "\n<p>" "")))))))) | |
c8d0cf5c CD |
2058 | |
2059 | (defun org-export-html-get-bibliography () | |
2060 | "Find bibliography, cut it out and return it." | |
2061 | (catch 'exit | |
2062 | (let (beg end (cnt 1) bib) | |
2063 | (save-excursion | |
2064 | (goto-char (point-min)) | |
2065 | (when (re-search-forward "^[ \t]*<div \\(id\\|class\\)=\"bibliography\"" nil t) | |
2066 | (setq beg (match-beginning 0)) | |
2067 | (while (re-search-forward "</?div\\>" nil t) | |
2068 | (setq cnt (+ cnt (if (string= (match-string 0) "<div") +1 -1))) | |
2069 | (when (= cnt 0) | |
2070 | (and (looking-at ">") (forward-char 1)) | |
2071 | (setq bib (buffer-substring beg (point))) | |
2072 | (delete-region beg (point)) | |
8223b1d2 | 2073 | (throw 'exit bib)))) |
c8d0cf5c CD |
2074 | nil)))) |
2075 | ||
2076 | (defvar org-table-number-regexp) ; defined in org-table.el | |
afe98dfa CD |
2077 | (defun org-format-table-html (lines olines &optional no-css) |
2078 | "Find out which HTML converter to use and return the HTML code. | |
2079 | NO-CSS is passed to the exporter." | |
c8d0cf5c CD |
2080 | (if (stringp lines) |
2081 | (setq lines (org-split-string lines "\n"))) | |
2082 | (if (string-match "^[ \t]*|" (car lines)) | |
2083 | ;; A normal org table | |
afe98dfa | 2084 | (org-format-org-table-html lines nil no-css) |
e66ba1df | 2085 | ;; Table made by table.el |
3ab2c837 BG |
2086 | (or (org-format-table-table-html-using-table-generate-source |
2087 | olines (not org-export-prefer-native-exporter-for-tables)) | |
2088 | ;; We are here only when table.el table has NO col or row | |
2089 | ;; spanning and the user prefers using org's own converter for | |
2090 | ;; exporting of such simple table.el tables. | |
2091 | (org-format-table-table-html lines)))) | |
c8d0cf5c CD |
2092 | |
2093 | (defvar org-table-number-fraction) ; defined in org-table.el | |
afe98dfa CD |
2094 | (defun org-format-org-table-html (lines &optional splice no-css) |
2095 | "Format a table into HTML. | |
2096 | LINES is a list of lines. Optional argument SPLICE means, do not | |
2097 | insert header and surrounding <table> tags, just format the lines. | |
2098 | Optional argument NO-CSS means use XHTML attributes instead of CSS | |
2099 | for formatting. This is required for the DocBook exporter." | |
c8d0cf5c CD |
2100 | (require 'org-table) |
2101 | ;; Get rid of hlines at beginning and end | |
2102 | (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines))) | |
2103 | (setq lines (nreverse lines)) | |
2104 | (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines))) | |
2105 | (setq lines (nreverse lines)) | |
2106 | (when org-export-table-remove-special-lines | |
2107 | ;; Check if the table has a marking column. If yes remove the | |
2108 | ;; column and the special lines | |
2109 | (setq lines (org-table-clean-before-export lines))) | |
2110 | ||
ed21c5c8 CD |
2111 | (let* ((caption (org-find-text-property-in-string 'org-caption (car lines))) |
2112 | (label (org-find-text-property-in-string 'org-label (car lines))) | |
e66ba1df BG |
2113 | (col-cookies (org-find-text-property-in-string 'org-col-cookies |
2114 | (car lines))) | |
ed21c5c8 CD |
2115 | (attributes (org-find-text-property-in-string 'org-attributes |
2116 | (car lines))) | |
c8d0cf5c CD |
2117 | (html-table-tag (org-export-splice-attributes |
2118 | html-table-tag attributes)) | |
2119 | (head (and org-export-highlight-first-table-line | |
2120 | (delq nil (mapcar | |
2121 | (lambda (x) (string-match "^[ \t]*|-" x)) | |
2122 | (cdr lines))))) | |
afe98dfa | 2123 | (nline 0) fnum nfields i (cnt 0) |
8223b1d2 | 2124 | tbopen org-line fields html gr colgropen rowstart rowend |
afe98dfa | 2125 | ali align aligns n) |
ed21c5c8 | 2126 | (setq caption (and caption (org-html-do-expand caption))) |
e66ba1df BG |
2127 | (when (and col-cookies org-table-clean-did-remove-column) |
2128 | (setq col-cookies | |
2129 | (mapcar (lambda (x) (cons (1- (car x)) (cdr x))) col-cookies))) | |
c8d0cf5c CD |
2130 | (if splice (setq head nil)) |
2131 | (unless splice (push (if head "<thead>" "<tbody>") html)) | |
2132 | (setq tbopen t) | |
8223b1d2 | 2133 | (while (setq org-line (pop lines)) |
c8d0cf5c | 2134 | (catch 'next-line |
8223b1d2 | 2135 | (if (string-match "^[ \t]*|-" org-line) |
c8d0cf5c CD |
2136 | (progn |
2137 | (unless splice | |
2138 | (push (if head "</thead>" "</tbody>") html) | |
2139 | (if lines (push "<tbody>" html) (setq tbopen nil))) | |
2140 | (setq head nil) ;; head ends here, first time around | |
2141 | ;; ignore this line | |
2142 | (throw 'next-line t))) | |
2143 | ;; Break the line into fields | |
8223b1d2 | 2144 | (setq fields (org-split-string org-line "[ \t]*|[ \t]*")) |
86fbb8ca CD |
2145 | (unless fnum (setq fnum (make-vector (length fields) 0) |
2146 | nfields (length fnum))) | |
c8d0cf5c CD |
2147 | (setq nline (1+ nline) i -1 |
2148 | rowstart (eval (car org-export-table-row-tags)) | |
2149 | rowend (eval (cdr org-export-table-row-tags))) | |
2150 | (push (concat rowstart | |
2151 | (mapconcat | |
2152 | (lambda (x) | |
afe98dfa | 2153 | (setq i (1+ i) ali (format "@@class%03d@@" i)) |
86fbb8ca | 2154 | (if (and (< i nfields) ; make sure no rogue line causes an error here |
c8d0cf5c CD |
2155 | (string-match org-table-number-regexp x)) |
2156 | (incf (aref fnum i))) | |
2157 | (cond | |
2158 | (head | |
2159 | (concat | |
afe98dfa CD |
2160 | (format (car org-export-table-header-tags) |
2161 | "col" ali) | |
c8d0cf5c CD |
2162 | x |
2163 | (cdr org-export-table-header-tags))) | |
2164 | ((and (= i 0) org-export-html-table-use-header-tags-for-first-column) | |
2165 | (concat | |
afe98dfa CD |
2166 | (format (car org-export-table-header-tags) |
2167 | "row" ali) | |
c8d0cf5c CD |
2168 | x |
2169 | (cdr org-export-table-header-tags))) | |
2170 | (t | |
afe98dfa CD |
2171 | (concat (format (car org-export-table-data-tags) ali) |
2172 | x | |
c8d0cf5c CD |
2173 | (cdr org-export-table-data-tags))))) |
2174 | fields "") | |
2175 | rowend) | |
2176 | html))) | |
2177 | (unless splice (if tbopen (push "</tbody>" html))) | |
2178 | (unless splice (push "</table>\n" html)) | |
2179 | (setq html (nreverse html)) | |
2180 | (unless splice | |
8bfe682a | 2181 | ;; Put in col tags with the alignment (unfortunately often ignored...) |
c8d0cf5c CD |
2182 | (unless (car org-table-colgroup-info) |
2183 | (setq org-table-colgroup-info | |
2184 | (cons :start (cdr org-table-colgroup-info)))) | |
afe98dfa | 2185 | (setq i 0) |
c8d0cf5c CD |
2186 | (push (mapconcat |
2187 | (lambda (x) | |
afe98dfa CD |
2188 | (setq gr (pop org-table-colgroup-info) |
2189 | i (1+ i) | |
e66ba1df BG |
2190 | align (if (nth 1 (assoc i col-cookies)) |
2191 | (cdr (assoc (nth 1 (assoc i col-cookies)) | |
afe98dfa CD |
2192 | '(("l" . "left") ("r" . "right") |
2193 | ("c" . "center")))) | |
2194 | (if (> (/ (float x) nline) | |
2195 | org-table-number-fraction) | |
2196 | "right" "left"))) | |
2197 | (push align aligns) | |
2198 | (format (if no-css | |
2199 | "%s<col align=\"%s\" />%s" | |
2200 | "%s<col class=\"%s\" />%s") | |
c8d0cf5c CD |
2201 | (if (memq gr '(:start :startend)) |
2202 | (prog1 | |
afe98dfa CD |
2203 | (if colgropen |
2204 | "</colgroup>\n<colgroup>" | |
2205 | "<colgroup>") | |
c8d0cf5c CD |
2206 | (setq colgropen t)) |
2207 | "") | |
afe98dfa | 2208 | align |
c8d0cf5c CD |
2209 | (if (memq gr '(:end :startend)) |
2210 | (progn (setq colgropen nil) "</colgroup>") | |
2211 | ""))) | |
2212 | fnum "") | |
2213 | html) | |
afe98dfa CD |
2214 | (setq aligns (nreverse aligns)) |
2215 | (if colgropen (setq html (cons (car html) | |
2216 | (cons "</colgroup>" (cdr html))))) | |
c8d0cf5c | 2217 | ;; Since the output of HTML table formatter can also be used in |
8223b1d2 BG |
2218 | ;; DocBook document, include empty captions for the DocBook |
2219 | ;; export only so that it produces valid XML. | |
2220 | (when (or caption (eq org-export-current-backend 'docbook)) | |
2221 | (push (format "<caption>%s</caption>" (or caption "")) html)) | |
3ab2c837 | 2222 | (when label |
8223b1d2 | 2223 | (setq html-table-tag (org-export-splice-attributes html-table-tag (format "id=\"%s\"" (org-solidify-link-text label))))) |
c8d0cf5c | 2224 | (push html-table-tag html)) |
afe98dfa CD |
2225 | (setq html (mapcar |
2226 | (lambda (x) | |
2227 | (replace-regexp-in-string | |
2228 | "@@class\\([0-9]+\\)@@" | |
2229 | (lambda (txt) | |
2230 | (if (not org-export-html-table-align-individual-fields) | |
2231 | "" | |
2232 | (setq n (string-to-number (match-string 1 txt))) | |
2233 | (format (if no-css " align=\"%s\"" " class=\"%s\"") | |
2234 | (or (nth n aligns) "left")))) | |
2235 | x)) | |
2236 | html)) | |
c8d0cf5c CD |
2237 | (concat (mapconcat 'identity html "\n") "\n"))) |
2238 | ||
2239 | (defun org-export-splice-attributes (tag attributes) | |
2240 | "Read attributes in string ATTRIBUTES, add and replace in HTML tag TAG." | |
2241 | (if (not attributes) | |
2242 | tag | |
2243 | (let (oldatt newatt) | |
2244 | (setq oldatt (org-extract-attributes-from-string tag) | |
2245 | tag (pop oldatt) | |
2246 | newatt (cdr (org-extract-attributes-from-string attributes))) | |
2247 | (while newatt | |
2248 | (setq oldatt (plist-put oldatt (pop newatt) (pop newatt)))) | |
2249 | (if (string-match ">" tag) | |
2250 | (setq tag | |
2251 | (replace-match (concat (org-attributes-to-string oldatt) ">") | |
2252 | t t tag))) | |
2253 | tag))) | |
2254 | ||
2255 | (defun org-format-table-table-html (lines) | |
2256 | "Format a table generated by table.el into HTML. | |
2257 | This conversion does *not* use `table-generate-source' from table.el. | |
2258 | This has the advantage that Org-mode's HTML conversions can be used. | |
2259 | But it has the disadvantage, that no cell- or row-spanning is allowed." | |
8223b1d2 BG |
2260 | (let (org-line field-buffer |
2261 | (head org-export-highlight-first-table-line) | |
2262 | fields html empty i) | |
c8d0cf5c | 2263 | (setq html (concat html-table-tag "\n")) |
8223b1d2 | 2264 | (while (setq org-line (pop lines)) |
c8d0cf5c CD |
2265 | (setq empty " ") |
2266 | (catch 'next-line | |
8223b1d2 | 2267 | (if (string-match "^[ \t]*\\+-" org-line) |
c8d0cf5c CD |
2268 | (progn |
2269 | (if field-buffer | |
2270 | (progn | |
2271 | (setq | |
2272 | html | |
2273 | (concat | |
2274 | html | |
2275 | "<tr>" | |
2276 | (mapconcat | |
2277 | (lambda (x) | |
2278 | (if (equal x "") (setq x empty)) | |
2279 | (if head | |
2280 | (concat | |
afe98dfa | 2281 | (format (car org-export-table-header-tags) "col" "") |
c8d0cf5c CD |
2282 | x |
2283 | (cdr org-export-table-header-tags)) | |
afe98dfa | 2284 | (concat (format (car org-export-table-data-tags) "") x |
c8d0cf5c CD |
2285 | (cdr org-export-table-data-tags)))) |
2286 | field-buffer "\n") | |
2287 | "</tr>\n")) | |
2288 | (setq head nil) | |
2289 | (setq field-buffer nil))) | |
2290 | ;; Ignore this line | |
2291 | (throw 'next-line t))) | |
2292 | ;; Break the line into fields and store the fields | |
8223b1d2 | 2293 | (setq fields (org-split-string org-line "[ \t]*|[ \t]*")) |
c8d0cf5c CD |
2294 | (if field-buffer |
2295 | (setq field-buffer (mapcar | |
2296 | (lambda (x) | |
2297 | (concat x "<br/>" (pop fields))) | |
2298 | field-buffer)) | |
2299 | (setq field-buffer fields)))) | |
2300 | (setq html (concat html "</table>\n")) | |
2301 | html)) | |
2302 | ||
3ab2c837 BG |
2303 | (defun org-format-table-table-html-using-table-generate-source (lines |
2304 | &optional | |
2305 | spanned-only) | |
c8d0cf5c | 2306 | "Format a table into html, using `table-generate-source' from table.el. |
3ab2c837 BG |
2307 | Use SPANNED-ONLY to suppress exporting of simple table.el tables. |
2308 | ||
2309 | When SPANNED-ONLY is nil, all table.el tables are exported. When | |
2310 | SPANNED-ONLY is non-nil, only tables with either row or column | |
2311 | spans are exported. | |
2312 | ||
2313 | This routine returns the generated source or nil as appropriate. | |
2314 | ||
2315 | Refer docstring of `org-export-prefer-native-exporter-for-tables' | |
2316 | for further information." | |
c8d0cf5c CD |
2317 | (require 'table) |
2318 | (with-current-buffer (get-buffer-create " org-tmp1 ") | |
2319 | (erase-buffer) | |
2320 | (insert (mapconcat 'identity lines "\n")) | |
2321 | (goto-char (point-min)) | |
2322 | (if (not (re-search-forward "|[^+]" nil t)) | |
2323 | (error "Error processing table")) | |
2324 | (table-recognize-table) | |
3ab2c837 BG |
2325 | (when (or (not spanned-only) |
2326 | (let* ((dim (table-query-dimension)) | |
2327 | (c (nth 4 dim)) (r (nth 5 dim)) (cells (nth 6 dim))) | |
2328 | (not (= (* c r) cells)))) | |
2329 | (with-current-buffer (get-buffer-create " org-tmp2 ") (erase-buffer)) | |
2330 | (table-generate-source 'html " org-tmp2 ") | |
2331 | (set-buffer " org-tmp2 ") | |
2332 | (buffer-substring (point-min) (point-max))))) | |
c8d0cf5c CD |
2333 | |
2334 | (defun org-export-splice-style (style extra) | |
2335 | "Splice EXTRA into STYLE, just before \"</style>\"." | |
2336 | (if (and (stringp extra) | |
2337 | (string-match "\\S-" extra) | |
2338 | (string-match "</style>" style)) | |
2339 | (concat (substring style 0 (match-beginning 0)) | |
2340 | "\n" extra "\n" | |
2341 | (substring style (match-beginning 0))) | |
2342 | style)) | |
2343 | ||
2344 | (defun org-html-handle-time-stamps (s) | |
2345 | "Format time stamps in string S, or remove them." | |
2346 | (catch 'exit | |
2347 | (let (r b) | |
e66ba1df BG |
2348 | (when org-maybe-keyword-time-regexp |
2349 | (while (string-match org-maybe-keyword-time-regexp s) | |
2350 | (or b (setq b (substring s 0 (match-beginning 0)))) | |
2351 | (setq r (concat | |
2352 | r (substring s 0 (match-beginning 0)) | |
2353 | " @<span class=\"timestamp-wrapper\">" | |
2354 | (if (match-end 1) | |
2355 | (format "@<span class=\"timestamp-kwd\">%s @</span>" | |
2356 | (match-string 1 s))) | |
2357 | (format " @<span class=\"timestamp\">%s@</span>" | |
2358 | (substring | |
2359 | (org-translate-time (match-string 3 s)) 1 -1)) | |
2360 | "@</span>") | |
2361 | s (substring s (match-end 0))))) | |
c8d0cf5c CD |
2362 | ;; Line break if line started and ended with time stamp stuff |
2363 | (if (not r) | |
2364 | s | |
2365 | (setq r (concat r s)) | |
2366 | (unless (string-match "\\S-" (concat b s)) | |
2367 | (setq r (concat r "@<br/>"))) | |
2368 | r)))) | |
2369 | ||
2370 | (defvar htmlize-buffer-places) ; from htmlize.el | |
2371 | (defun org-export-htmlize-region-for-paste (beg end) | |
2372 | "Convert the region to HTML, using htmlize.el. | |
2373 | This is much like `htmlize-region-for-paste', only that it uses | |
2374 | the settings define in the org-... variables." | |
2375 | (let* ((htmlize-output-type org-export-htmlize-output-type) | |
2376 | (htmlize-css-name-prefix org-export-htmlize-css-font-prefix) | |
2377 | (htmlbuf (htmlize-region beg end))) | |
2378 | (unwind-protect | |
2379 | (with-current-buffer htmlbuf | |
2380 | (buffer-substring (plist-get htmlize-buffer-places 'content-start) | |
2381 | (plist-get htmlize-buffer-places 'content-end))) | |
2382 | (kill-buffer htmlbuf)))) | |
2383 | ||
c8d0cf5c CD |
2384 | (defun org-export-htmlize-generate-css () |
2385 | "Create the CSS for all font definitions in the current Emacs session. | |
2386 | Use this to create face definitions in your CSS style file that can then | |
2387 | be used by code snippets transformed by htmlize. | |
2388 | This command just produces a buffer that contains class definitions for all | |
2389 | faces used in the current Emacs session. You can copy and paste the ones you | |
2390 | need into your CSS file. | |
2391 | ||
2392 | If you then set `org-export-htmlize-output-type' to `css', calls to | |
2393 | the function `org-export-htmlize-region-for-paste' will produce code | |
2394 | that uses these same face definitions." | |
2395 | (interactive) | |
2396 | (require 'htmlize) | |
2397 | (and (get-buffer "*html*") (kill-buffer "*html*")) | |
2398 | (with-temp-buffer | |
2399 | (let ((fl (face-list)) | |
2400 | (htmlize-css-name-prefix "org-") | |
2401 | (htmlize-output-type 'css) | |
2402 | f i) | |
2403 | (while (setq f (pop fl) | |
2404 | i (and f (face-attribute f :inherit))) | |
2405 | (when (and (symbolp f) (or (not i) (not (listp i)))) | |
2406 | (insert (org-add-props (copy-sequence "1") nil 'face f)))) | |
2407 | (htmlize-region (point-min) (point-max)))) | |
e66ba1df | 2408 | (org-pop-to-buffer-same-window "*html*") |
c8d0cf5c CD |
2409 | (goto-char (point-min)) |
2410 | (if (re-search-forward "<style" nil t) | |
2411 | (delete-region (point-min) (match-beginning 0))) | |
2412 | (if (re-search-forward "</style>" nil t) | |
2413 | (delete-region (1+ (match-end 0)) (point-max))) | |
2414 | (beginning-of-line 1) | |
2415 | (if (looking-at " +") (replace-match "")) | |
2416 | (goto-char (point-min))) | |
2417 | ||
2418 | (defun org-html-protect (s) | |
3ab2c837 BG |
2419 | "Convert characters to HTML equivalent. |
2420 | Possible conversions are set in `org-export-html-protect-char-alist'." | |
2421 | (let ((cl org-export-html-protect-char-alist) c) | |
2422 | (while (setq c (pop cl)) | |
2423 | (let ((start 0)) | |
2424 | (while (string-match (car c) s start) | |
2425 | (setq s (replace-match (cdr c) t t s) | |
2426 | start (1+ (match-beginning 0)))))) | |
2427 | s)) | |
c8d0cf5c CD |
2428 | |
2429 | (defun org-html-expand (string) | |
86fbb8ca | 2430 | "Prepare STRING for HTML export. Apply all active conversions. |
e66ba1df BG |
2431 | If there are links in the string, don't modify these. If STRING |
2432 | is nil, return nil." | |
2433 | (when string | |
2434 | (let* ((re (concat org-bracket-link-regexp "\\|" | |
2435 | (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$"))) | |
2436 | m s l res) | |
2437 | (while (setq m (string-match re string)) | |
2438 | (setq s (substring string 0 m) | |
2439 | l (match-string 0 string) | |
2440 | string (substring string (match-end 0))) | |
2441 | (push (org-html-do-expand s) res) | |
8223b1d2 | 2442 | (push l res)) |
e66ba1df BG |
2443 | (push (org-html-do-expand string) res) |
2444 | (apply 'concat (nreverse res))))) | |
c8d0cf5c CD |
2445 | |
2446 | (defun org-html-do-expand (s) | |
2447 | "Apply all active conversions to translate special ASCII to HTML." | |
2448 | (setq s (org-html-protect s)) | |
2449 | (if org-export-html-expand | |
2450 | (while (string-match "@<\\([^&]*\\)>" s) | |
2451 | (setq s (replace-match "<\\1>" t nil s)))) | |
2452 | (if org-export-with-emphasize | |
2453 | (setq s (org-export-html-convert-emphasize s))) | |
2454 | (if org-export-with-special-strings | |
2455 | (setq s (org-export-html-convert-special-strings s))) | |
2456 | (if org-export-with-sub-superscripts | |
2457 | (setq s (org-export-html-convert-sub-super s))) | |
2458 | (if org-export-with-TeX-macros | |
ed21c5c8 CD |
2459 | (let ((start 0) wd rep) |
2460 | (while (setq start (string-match "\\\\\\([a-zA-Z]+[0-9]*\\)\\({}\\)?" | |
c8d0cf5c CD |
2461 | s start)) |
2462 | (if (get-text-property (match-beginning 0) 'org-protected s) | |
2463 | (setq start (match-end 0)) | |
2464 | (setq wd (match-string 1 s)) | |
ed21c5c8 CD |
2465 | (if (setq rep (org-entity-get-representation wd 'html)) |
2466 | (setq s (replace-match rep t t s)) | |
c8d0cf5c CD |
2467 | (setq start (+ start (length wd)))))))) |
2468 | s) | |
2469 | ||
c8d0cf5c CD |
2470 | (defun org-export-html-convert-special-strings (string) |
2471 | "Convert special characters in STRING to HTML." | |
2472 | (let ((all org-export-html-special-string-regexps) | |
2473 | e a re rpl start) | |
2474 | (while (setq a (pop all)) | |
2475 | (setq re (car a) rpl (cdr a) start 0) | |
2476 | (while (string-match re string start) | |
2477 | (if (get-text-property (match-beginning 0) 'org-protected string) | |
2478 | (setq start (match-end 0)) | |
2479 | (setq string (replace-match rpl t nil string))))) | |
2480 | string)) | |
2481 | ||
2482 | (defun org-export-html-convert-sub-super (string) | |
2483 | "Convert sub- and superscripts in STRING to HTML." | |
2484 | (let (key c (s 0) (requireb (eq org-export-with-sub-superscripts '{}))) | |
2485 | (while (string-match org-match-substring-regexp string s) | |
2486 | (cond | |
2487 | ((and requireb (match-end 8)) (setq s (match-end 2))) | |
2488 | ((get-text-property (match-beginning 2) 'org-protected string) | |
2489 | (setq s (match-end 2))) | |
2490 | (t | |
2491 | (setq s (match-end 1) | |
2492 | key (if (string= (match-string 2 string) "_") "sub" "sup") | |
2493 | c (or (match-string 8 string) | |
2494 | (match-string 6 string) | |
2495 | (match-string 5 string)) | |
2496 | string (replace-match | |
2497 | (concat (match-string 1 string) | |
2498 | "<" key ">" c "</" key ">") | |
2499 | t t string))))) | |
2500 | (while (string-match "\\\\\\([_^]\\)" string) | |
2501 | (setq string (replace-match (match-string 1 string) t t string))) | |
2502 | string)) | |
2503 | ||
2504 | (defun org-export-html-convert-emphasize (string) | |
2505 | "Apply emphasis." | |
2506 | (let ((s 0) rpl) | |
2507 | (while (string-match org-emph-re string s) | |
2508 | (if (not (equal | |
2509 | (substring string (match-beginning 3) (1+ (match-beginning 3))) | |
2510 | (substring string (match-beginning 4) (1+ (match-beginning 4))))) | |
2511 | (setq s (match-beginning 0) | |
2512 | rpl | |
2513 | (concat | |
2514 | (match-string 1 string) | |
2515 | (nth 2 (assoc (match-string 3 string) org-emphasis-alist)) | |
2516 | (match-string 4 string) | |
2517 | (nth 3 (assoc (match-string 3 string) | |
2518 | org-emphasis-alist)) | |
2519 | (match-string 5 string)) | |
2520 | string (replace-match rpl t t string) | |
2521 | s (+ s (- (length rpl) 2))) | |
2522 | (setq s (1+ s)))) | |
2523 | string)) | |
2524 | ||
2525 | (defun org-open-par () | |
2526 | "Insert <p>, but first close previous paragraph if any." | |
2527 | (org-close-par-maybe) | |
2528 | (insert "\n<p>") | |
2529 | (setq org-par-open t)) | |
2530 | (defun org-close-par-maybe () | |
2531 | "Close paragraph if there is one open." | |
2532 | (when org-par-open | |
2533 | (insert "</p>") | |
2534 | (setq org-par-open nil))) | |
2535 | (defun org-close-li (&optional type) | |
2536 | "Close <li> if necessary." | |
2537 | (org-close-par-maybe) | |
2538 | (insert (if (equal type "d") "</dd>\n" "</li>\n"))) | |
2539 | ||
c8d0cf5c | 2540 | (defvar body-only) ; dynamically scoped into this. |
3ab2c837 | 2541 | (defun org-html-level-start (level title umax with-toc head-count &optional opt-plist) |
c8d0cf5c CD |
2542 | "Insert a new level in HTML export. |
2543 | When TITLE is nil, just close all open levels." | |
2544 | (org-close-par-maybe) | |
2545 | (let* ((target (and title (org-get-text-property-any 0 'target title))) | |
ed21c5c8 CD |
2546 | (extra-targets (and target |
2547 | (assoc target org-export-target-aliases))) | |
2548 | (extra-class (and title (org-get-text-property-any 0 'html-container-class title))) | |
2549 | (preferred (and target | |
2550 | (cdr (assoc target org-export-preferred-target-alist)))) | |
c8d0cf5c | 2551 | (l org-level-max) |
3ab2c837 | 2552 | (num (plist-get opt-plist :section-numbers)) |
86fbb8ca | 2553 | snumber snu href suffix) |
acedf35c | 2554 | (setq extra-targets (remove (or preferred target) extra-targets)) |
c8d0cf5c CD |
2555 | (setq extra-targets |
2556 | (mapconcat (lambda (x) | |
3ab2c837 BG |
2557 | (setq x (org-solidify-link-text |
2558 | (if (org-uuidgen-p x) (concat "ID-" x) x))) | |
e66ba1df BG |
2559 | (if (stringp org-export-html-headline-anchor-format) |
2560 | (format org-export-html-headline-anchor-format x x) | |
2561 | "")) | |
c8d0cf5c CD |
2562 | extra-targets |
2563 | "")) | |
2564 | (while (>= l level) | |
2565 | (if (aref org-levels-open (1- l)) | |
2566 | (progn | |
2567 | (org-html-level-close l umax) | |
2568 | (aset org-levels-open (1- l) nil))) | |
2569 | (setq l (1- l))) | |
2570 | (when title | |
2571 | ;; If title is nil, this means this function is called to close | |
2572 | ;; all levels, so the rest is done only if title is given | |
8223b1d2 BG |
2573 | (when (string-match (org-re "\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title) |
2574 | (setq title (replace-match | |
2575 | (if org-export-with-tags | |
2576 | (save-match-data | |
2577 | (concat | |
2578 | " <span class=\"tag\">" | |
2579 | (mapconcat | |
2580 | (lambda (x) | |
2581 | (format "<span class=\"%s\">%s</span>" | |
2582 | (org-export-html-get-tag-class-name x) | |
2583 | x)) | |
2584 | (org-split-string (match-string 1 title) ":") | |
2585 | " ") | |
2586 | "</span>")) | |
2587 | "") | |
2588 | t t title))) | |
c8d0cf5c CD |
2589 | (if (> level umax) |
2590 | (progn | |
2591 | (if (aref org-levels-open (1- level)) | |
2592 | (progn | |
2593 | (org-close-li) | |
2594 | (if target | |
3ab2c837 | 2595 | (insert (format "<li id=\"%s\">" (org-solidify-link-text (or preferred target))) |
acedf35c | 2596 | extra-targets title "<br/>\n") |
c8d0cf5c CD |
2597 | (insert "<li>" title "<br/>\n"))) |
2598 | (aset org-levels-open (1- level) t) | |
2599 | (org-close-par-maybe) | |
2600 | (if target | |
3ab2c837 | 2601 | (insert (format "<ul>\n<li id=\"%s\">" (org-solidify-link-text (or preferred target))) |
c8d0cf5c CD |
2602 | extra-targets title "<br/>\n") |
2603 | (insert "<ul>\n<li>" title "<br/>\n")))) | |
2604 | (aset org-levels-open (1- level) t) | |
86fbb8ca | 2605 | (setq snumber (org-section-number level) |
3ab2c837 | 2606 | snu (replace-regexp-in-string "\\." "-" snumber)) |
c8d0cf5c | 2607 | (setq level (+ level org-export-html-toplevel-hlevel -1)) |
3ab2c837 | 2608 | (if (and num (not body-only)) |
c8d0cf5c CD |
2609 | (setq title (concat |
2610 | (format "<span class=\"section-number-%d\">%s</span>" | |
3ab2c837 BG |
2611 | level |
2612 | (if (and num | |
2613 | (if (integerp num) | |
2614 | ;; fix up num to take into | |
2615 | ;; account the top-level | |
2616 | ;; heading value | |
2617 | (>= (+ num org-export-html-toplevel-hlevel -1) | |
2618 | level) | |
2619 | num)) | |
2620 | snumber | |
2621 | "")) | |
c8d0cf5c CD |
2622 | " " title))) |
2623 | (unless (= head-count 1) (insert "\n</div>\n")) | |
86fbb8ca | 2624 | (setq href (cdr (assoc (concat "sec-" snu) org-export-preferred-target-alist))) |
3ab2c837 BG |
2625 | (setq suffix (org-solidify-link-text (or href snu))) |
2626 | (setq href (org-solidify-link-text (or href (concat "sec-" snu)))) | |
ed21c5c8 CD |
2627 | (insert (format "\n<div id=\"outline-container-%s\" class=\"outline-%d%s\">\n<h%d id=\"%s\">%s%s</h%d>\n<div class=\"outline-text-%d\" id=\"text-%s\">\n" |
2628 | suffix level (if extra-class (concat " " extra-class) "") | |
2629 | level href | |
c8d0cf5c CD |
2630 | extra-targets |
2631 | title level level suffix)) | |
2632 | (org-open-par))))) | |
2633 | ||
2634 | (defun org-export-html-get-tag-class-name (tag) | |
2635 | "Turn tag into a valid class name. | |
2636 | Replaces invalid characters with \"_\" and then prepends a prefix." | |
2637 | (save-match-data | |
2638 | (while (string-match "[^a-zA-Z0-9_]" tag) | |
2639 | (setq tag (replace-match "_" t t tag)))) | |
2640 | (concat org-export-html-tag-class-prefix tag)) | |
2641 | ||
2642 | (defun org-export-html-get-todo-kwd-class-name (kwd) | |
2643 | "Turn todo keyword into a valid class name. | |
2644 | Replaces invalid characters with \"_\" and then prepends a prefix." | |
2645 | (save-match-data | |
2646 | (while (string-match "[^a-zA-Z0-9_]" kwd) | |
2647 | (setq kwd (replace-match "_" t t kwd)))) | |
2648 | (concat org-export-html-todo-kwd-class-prefix kwd)) | |
2649 | ||
2650 | (defun org-html-level-close (level max-outline-level) | |
2651 | "Terminate one level in HTML export." | |
2652 | (if (<= level max-outline-level) | |
2653 | (insert "</div>\n") | |
2654 | (org-close-li) | |
2655 | (insert "</ul>\n"))) | |
2656 | ||
8223b1d2 BG |
2657 | (defun org-html-export-list-line (org-line pos struct prevs) |
2658 | "Insert list syntax in export buffer. Return ORG-LINE, maybe modified. | |
3ab2c837 | 2659 | |
8223b1d2 BG |
2660 | POS is the item position or org-line position the org-line had before |
2661 | modifications to buffer. STRUCT is the list structure. PREVS is | |
3ab2c837 BG |
2662 | the alist of previous items." |
2663 | (let* ((get-type | |
2664 | (function | |
2665 | ;; Translate type of list containing POS to "d", "o" or | |
2666 | ;; "u". | |
2667 | (lambda (pos struct prevs) | |
2668 | (let ((type (org-list-get-list-type pos struct prevs))) | |
2669 | (cond | |
2670 | ((eq 'ordered type) "o") | |
2671 | ((eq 'descriptive type) "d") | |
2672 | (t "u")))))) | |
2673 | (get-closings | |
2674 | (function | |
2675 | ;; Return list of all items and sublists ending at POS, in | |
2676 | ;; reverse order. | |
2677 | (lambda (pos) | |
2678 | (let (out) | |
2679 | (catch 'exit | |
2680 | (mapc (lambda (e) | |
2681 | (let ((end (nth 6 e)) | |
2682 | (item (car e))) | |
2683 | (cond | |
2684 | ((= end pos) (push item out)) | |
2685 | ((>= item pos) (throw 'exit nil))))) | |
2686 | struct)) | |
2687 | out))))) | |
2688 | ;; First close any previous item, or list, ending at POS. | |
2689 | (mapc (lambda (e) | |
2690 | (let* ((lastp (= (org-list-get-last-item e struct prevs) e)) | |
2691 | (first-item (org-list-get-list-begin e struct prevs)) | |
2692 | (type (funcall get-type first-item struct prevs))) | |
2693 | (org-close-par-maybe) | |
2694 | ;; Ending for every item | |
2695 | (org-close-li type) | |
2696 | ;; We're ending last item of the list: end list. | |
2697 | (when lastp | |
2698 | (insert (format "</%sl>\n" type)) | |
2699 | (org-open-par)))) | |
2700 | (funcall get-closings pos)) | |
2701 | (cond | |
2702 | ;; At an item: insert appropriate tags in export buffer. | |
2703 | ((assq pos struct) | |
2704 | (string-match | |
2705 | (concat "[ \t]*\\(\\S-+[ \t]*\\)" | |
2706 | "\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?" | |
2707 | "\\(?:\\(\\[[ X-]\\]\\)[ \t]+\\)?" | |
2708 | "\\(?:\\(.*\\)[ \t]+::\\(?:[ \t]+\\|$\\)\\)?" | |
8223b1d2 BG |
2709 | "\\(.*\\)") org-line) |
2710 | (let* ((checkbox (match-string 3 org-line)) | |
2711 | (desc-tag (or (match-string 4 org-line) "???")) | |
2712 | (body (or (match-string 5 org-line) "")) | |
3ab2c837 BG |
2713 | (list-beg (org-list-get-list-begin pos struct prevs)) |
2714 | (firstp (= list-beg pos)) | |
2715 | ;; Always refer to first item to determine list type, in | |
2716 | ;; case list is ill-formed. | |
2717 | (type (funcall get-type list-beg struct prevs)) | |
2718 | (counter (let ((count-tmp (org-list-get-counter pos struct))) | |
2719 | (cond | |
2720 | ((not count-tmp) nil) | |
2721 | ((string-match "[A-Za-z]" count-tmp) | |
2722 | (- (string-to-char (upcase count-tmp)) 64)) | |
2723 | ((string-match "[0-9]+" count-tmp) | |
2724 | count-tmp))))) | |
2725 | (when firstp | |
2726 | (org-close-par-maybe) | |
2727 | (insert (format "<%sl>\n" type))) | |
2728 | (insert (cond | |
2729 | ((equal type "d") | |
2730 | (format "<dt>%s</dt><dd>" desc-tag)) | |
2731 | ((and (equal type "o") counter) | |
2732 | (format "<li value=\"%s\">" counter)) | |
2733 | (t "<li>"))) | |
2734 | ;; If line had a checkbox, some additional modification is required. | |
2735 | (when checkbox | |
2736 | (setq body | |
2737 | (concat | |
2738 | (cond | |
2739 | ((string-match "X" checkbox) "<code>[X]</code> ") | |
2740 | ((string-match " " checkbox) "<code>[ ]</code> ") | |
2741 | (t "<code>[-]</code> ")) | |
2742 | body))) | |
2743 | ;; Return modified line | |
2744 | body)) | |
2745 | ;; At a list ender: go to next line (side-effects only). | |
8223b1d2 | 2746 | ((equal "ORG-LIST-END-MARKER" org-line) (throw 'nextline nil)) |
3ab2c837 | 2747 | ;; Not at an item: return line unchanged (side-effects only). |
8223b1d2 | 2748 | (t org-line)))) |
3ab2c837 | 2749 | |
c8d0cf5c CD |
2750 | (provide 'org-html) |
2751 | ||
bdebdb64 BG |
2752 | ;; Local variables: |
2753 | ;; generated-autoload-file: "org-loaddefs.el" | |
2754 | ;; End: | |
2755 | ||
c8d0cf5c | 2756 | ;;; org-html.el ends here |