org-e-html: Use prefix consistently and cleanup some code
[org-mode/org-mode-NeilSmithlineMods.git] / EXPERIMENTAL / org-e-html.el
blobc75274e20a4689b3e659c496d664ade2a9b390a6
1 ;;; org-e-html.el --- HTML Back-End For Org Export Engine
3 ;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
5 ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
6 ;; Keywords: outlines, hypermedia, calendar, wp
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ;;; Commentary:
23 ;; This library implements a HTML back-end for Org generic exporter.
25 ;; To test it, run
27 ;; M-: (org-export-to-buffer 'e-html "*Test e-HTML*") RET
29 ;; in an org-mode buffer then switch to the buffer to see the HTML
30 ;; export. See contrib/lisp/org-export.el for more details on how
31 ;; this exporter works.
33 ;; It introduces three new buffer keywords: "LATEX_CLASS",
34 ;; "LATEX_CLASS_OPTIONS" and "LATEX_HEADER".
36 ;;; Code:
38 ;;; org-xhtml.el
40 (defvar org-e-html-debug nil)
41 (defvar org-e-html-pp t)
43 (defun org-e-html-debug (fmt &rest args)
44 (when org-e-html-debug
45 (with-current-buffer (get-buffer "*debug*")
46 (insert "\n" (apply 'format fmt args)))))
48 (defun org-element-debug (header text)
49 (insert "\n" "===== [" header "] =====")
50 (insert "\n" (pp-to-string text)))
52 (defun org-elements-debug (args)
53 (with-current-buffer "*debug*"
54 (insert "\n\n\n\n\n-------------------------\n")
55 (while args
56 (let* ((header (pop args))
57 (text (pop args)))
58 (org-element-debug (format "%s" header) text)))
59 (insert "\n--------------------------\n")))
61 (defvar org-elements-debug-depth 0)
62 (defmacro org-e-html-pp (&rest args)
63 (if org-e-html-pp
64 (let ((newargs))
65 (while args
66 (let ((e (pop args)))
67 (setq newargs (append newargs (list e (eval e))))))
68 ;; (pp-eval-expression 'newargs)
70 `(org-elements-debug (quote ,newargs)))
71 (list 'ignore)))
73 (require 'org-exp)
74 (require 'format-spec)
75 (eval-when-compile (require 'cl) (require 'table))
77 (declare-function org-id-find-id-file "org-id" (id))
78 (declare-function htmlize-region "ext:htmlize" (beg end))
79 (declare-function org-pop-to-buffer-same-window
80 "org-compat" (&optional buffer-or-name norecord label))
82 (defgroup org-export-e-html nil
83 "Options specific for HTML export of Org-mode files."
84 :tag "Org Export HTML"
85 :group 'org-export)
87 (defconst org-e-html-special-string-regexps
88 '(("\\\\-" . "&shy;")
89 ("---\\([^-]\\)" . "&mdash;\\1")
90 ("--\\([^-]\\)" . "&ndash;\\1")
91 ("\\.\\.\\." . "&hellip;"))
92 "Regular expressions for special string conversion.")
94 (defcustom org-e-html-footnotes-section "<div id=\"footnotes\">
95 <h2 class=\"footnotes\">%s: </h2>
96 <div id=\"text-footnotes\">
98 </div>
99 </div>"
100 "Format for the footnotes section.
101 Should contain a two instances of %s. The first will be replaced with the
102 language-specific word for \"Footnotes\", the second one will be replaced
103 by the footnotes themselves."
104 :group 'org-export-e-html
105 :type 'string)
107 (defcustom org-e-html-footnote-format "<sup>%s</sup>"
108 "The format for the footnote reference.
109 %s will be replaced by the footnote reference itself."
110 :group 'org-export-e-html
111 :type 'string)
114 (defcustom org-e-html-footnote-separator "<sup>, </sup>"
115 "Text used to separate footnotes."
116 :group 'org-export-e-html
117 :type 'string)
119 (defcustom org-e-html-coding-system nil
120 "Coding system for HTML export, defaults to `buffer-file-coding-system'."
121 :group 'org-export-e-html
122 :type 'coding-system)
124 (defcustom org-e-html-extension "html"
125 "The extension for exported HTML files."
126 :group 'org-export-e-html
127 :type 'string)
129 (defcustom org-e-html-xml-declaration
130 '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>")
131 ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>"))
132 "The extension for exported HTML files.
133 %s will be replaced with the charset of the exported file.
134 This may be a string, or an alist with export extensions
135 and corresponding declarations."
136 :group 'org-export-e-html
137 :type '(choice
138 (string :tag "Single declaration")
139 (repeat :tag "Dependent on extension"
140 (cons (string :tag "Extension")
141 (string :tag "Declaration")))))
143 (defcustom org-e-html-style-include-scripts t
144 "Non-nil means include the JavaScript snippets in exported HTML files.
145 The actual script is defined in `org-e-html-scripts' and should
146 not be modified."
147 :group 'org-export-e-html
148 :type 'boolean)
150 (defconst org-e-html-scripts
151 "<script type=\"text/javascript\">
152 <!--/*--><![CDATA[/*><!--*/
153 function CodeHighlightOn(elem, id)
155 var target = document.getElementById(id);
156 if(null != target) {
157 elem.cacheClassElem = elem.className;
158 elem.cacheClassTarget = target.className;
159 target.className = \"code-highlighted\";
160 elem.className = \"code-highlighted\";
163 function CodeHighlightOff(elem, id)
165 var target = document.getElementById(id);
166 if(elem.cacheClassElem)
167 elem.className = elem.cacheClassElem;
168 if(elem.cacheClassTarget)
169 target.className = elem.cacheClassTarget;
171 /*]]>*///-->
172 </script>"
173 "Basic JavaScript that is needed by HTML files produced by Org-mode.")
175 (defconst org-e-html-style-default
176 "<style type=\"text/css\">
177 <!--/*--><![CDATA[/*><!--*/
178 html { font-family: Times, serif; font-size: 12pt; }
179 .title { text-align: center; }
180 .todo { color: red; }
181 .done { color: green; }
182 .tag { background-color: #add8e6; font-weight:normal }
183 .target { }
184 .timestamp { color: #bebebe; }
185 .timestamp-kwd { color: #5f9ea0; }
186 .right {margin-left:auto; margin-right:0px; text-align:right;}
187 .left {margin-left:0px; margin-right:auto; text-align:left;}
188 .center {margin-left:auto; margin-right:auto; text-align:center;}
189 p.verse { margin-left: 3% }
190 pre {
191 border: 1pt solid #AEBDCC;
192 background-color: #F3F5F7;
193 padding: 5pt;
194 font-family: courier, monospace;
195 font-size: 90%;
196 overflow:auto;
198 table { border-collapse: collapse; }
199 td, th { vertical-align: top; }
200 th.right { text-align:center; }
201 th.left { text-align:center; }
202 th.center { text-align:center; }
203 td.right { text-align:right; }
204 td.left { text-align:left; }
205 td.center { text-align:center; }
206 dt { font-weight: bold; }
207 div.figure { padding: 0.5em; }
208 div.figure p { text-align: center; }
209 div.inlinetask {
210 padding:10px;
211 border:2px solid gray;
212 margin:10px;
213 background: #ffffcc;
215 textarea { overflow-x: auto; }
216 .linenr { font-size:smaller }
217 .code-highlighted {background-color:#ffff00;}
218 .org-info-js_info-navigation { border-style:none; }
219 #org-info-js_console-label { font-size:10px; font-weight:bold;
220 white-space:nowrap; }
221 .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
222 font-weight:bold; }
223 /*]]>*/-->
224 </style>"
225 "The default style specification for exported HTML files.
226 Please use the variables `org-e-html-style' and
227 `org-e-html-style-extra' to add to this style. If you wish to not
228 have the default style included, customize the variable
229 `org-e-html-style-include-default'.")
231 (defcustom org-e-html-style-include-default t
232 "Non-nil means include the default style in exported HTML files.
233 The actual style is defined in `org-e-html-style-default' and should
234 not be modified. Use the variables `org-e-html-style' to add
235 your own style information."
236 :group 'org-export-e-html
237 :type 'boolean)
238 ;;;###autoload
239 (put 'org-e-html-style-include-default 'safe-local-variable 'booleanp)
241 (defcustom org-e-html-style ""
242 "Org-wide style definitions for exported HTML files.
244 This variable needs to contain the full HTML structure to provide a style,
245 including the surrounding HTML tags. If you set the value of this variable,
246 you should consider to include definitions for the following classes:
247 title, todo, done, timestamp, timestamp-kwd, tag, target.
249 For example, a valid value would be:
251 <style type=\"text/css\">
252 <![CDATA[
253 p { font-weight: normal; color: gray; }
254 h1 { color: black; }
255 .title { text-align: center; }
256 .todo, .timestamp-kwd { color: red; }
257 .done { color: green; }
259 </style>
261 If you'd like to refer to an external style file, use something like
263 <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
265 As the value of this option simply gets inserted into the HTML <head> header,
266 you can \"misuse\" it to add arbitrary text to the header.
267 See also the variable `org-e-html-style-extra'."
268 :group 'org-export-e-html
269 :type 'string)
270 ;;;###autoload
271 (put 'org-e-html-style 'safe-local-variable 'stringp)
273 (defcustom org-e-html-style-extra ""
274 "Additional style information for HTML export.
275 The value of this variable is inserted into the HTML buffer right after
276 the value of `org-e-html-style'. Use this variable for per-file
277 settings of style information, and do not forget to surround the style
278 settings with <style>...</style> tags."
279 :group 'org-export-e-html
280 :type 'string)
281 ;;;###autoload
282 (put 'org-e-html-style-extra 'safe-local-variable 'stringp)
284 (defcustom org-e-html-mathjax-options
285 '((path "http://orgmode.org/mathjax/MathJax.js")
286 (scale "100")
287 (align "center")
288 (indent "2em")
289 (mathml nil))
290 "Options for MathJax setup.
292 path The path where to find MathJax
293 scale Scaling for the HTML-CSS backend, usually between 100 and 133
294 align How to align display math: left, center, or right
295 indent If align is not center, how far from the left/right side?
296 mathml Should a MathML player be used if available?
297 This is faster and reduces bandwidth use, but currently
298 sometimes has lower spacing quality. Therefore, the default is
299 nil. When browsers get better, this switch can be flipped.
301 You can also customize this for each buffer, using something like
303 #+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\""
304 :group 'org-export-e-html
305 :type '(list :greedy t
306 (list :tag "path (the path from where to load MathJax.js)"
307 (const :format " " path) (string))
308 (list :tag "scale (scaling for the displayed math)"
309 (const :format " " scale) (string))
310 (list :tag "align (alignment of displayed equations)"
311 (const :format " " align) (string))
312 (list :tag "indent (indentation with left or right alignment)"
313 (const :format " " indent) (string))
314 (list :tag "mathml (should MathML display be used is possible)"
315 (const :format " " mathml) (boolean))))
317 (defun org-e-html-mathjax-config (template options in-buffer)
318 "Insert the user setup into the matchjax template."
319 (let (name val (yes " ") (no "// ") x)
320 (mapc
321 (lambda (e)
322 (setq name (car e) val (nth 1 e))
323 (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer)
324 (setq val (car (read-from-string
325 (substring in-buffer (match-end 0))))))
326 (if (not (stringp val)) (setq val (format "%s" val)))
327 (if (string-match (concat "%" (upcase (symbol-name name))) template)
328 (setq template (replace-match val t t template))))
329 options)
330 (setq val (nth 1 (assq 'mathml options)))
331 (if (string-match (concat "\\<mathml:") in-buffer)
332 (setq val (car (read-from-string
333 (substring in-buffer (match-end 0))))))
334 ;; Exchange prefixes depending on mathml setting
335 (if (not val) (setq x yes yes no no x))
336 ;; Replace cookies to turn on or off the config/jax lines
337 (if (string-match ":MMLYES:" template)
338 (setq template (replace-match yes t t template)))
339 (if (string-match ":MMLNO:" template)
340 (setq template (replace-match no t t template)))
341 ;; Return the modified template
342 template))
344 (defcustom org-e-html-mathjax-template
345 "<script type=\"text/javascript\" src=\"%PATH\">
346 <!--/*--><![CDATA[/*><!--*/
347 MathJax.Hub.Config({
348 // Only one of the two following lines, depending on user settings
349 // First allows browser-native MathML display, second forces HTML/CSS
350 :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"],
351 :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"],
352 extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\",
353 \"TeX/noUndefined.js\"],
354 tex2jax: {
355 inlineMath: [ [\"\\\\(\",\"\\\\)\"] ],
356 displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ],
357 skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"],
358 ignoreClass: \"tex2jax_ignore\",
359 processEscapes: false,
360 processEnvironments: true,
361 preview: \"TeX\"
363 showProcessingMessages: true,
364 displayAlign: \"%ALIGN\",
365 displayIndent: \"%INDENT\",
367 \"HTML-CSS\": {
368 scale: %SCALE,
369 availableFonts: [\"STIX\",\"TeX\"],
370 preferredFont: \"TeX\",
371 webFont: \"TeX\",
372 imageFont: \"TeX\",
373 showMathMenu: true,
375 MMLorHTML: {
376 prefer: {
377 MSIE: \"MML\",
378 Firefox: \"MML\",
379 Opera: \"HTML\",
380 other: \"HTML\"
384 /*]]>*///-->
385 </script>"
386 "The MathJax setup for XHTML files."
387 :group 'org-export-e-html
388 :type 'string)
390 (defcustom org-e-html-tag-class-prefix ""
391 "Prefix to class names for TODO keywords.
392 Each tag gets a class given by the tag itself, with this prefix.
393 The default prefix is empty because it is nice to just use the keyword
394 as a class name. But if you get into conflicts with other, existing
395 CSS classes, then this prefix can be very useful."
396 :group 'org-export-e-html
397 :type 'string)
399 (defcustom org-e-html-todo-kwd-class-prefix ""
400 "Prefix to class names for TODO keywords.
401 Each TODO keyword gets a class given by the keyword itself, with this prefix.
402 The default prefix is empty because it is nice to just use the keyword
403 as a class name. But if you get into conflicts with other, existing
404 CSS classes, then this prefix can be very useful."
405 :group 'org-export-e-html
406 :type 'string)
408 (defcustom org-e-html-preamble t
409 "Non-nil means insert a preamble in HTML export.
411 When `t', insert a string as defined by one of the formatting
412 strings in `org-e-html-preamble-format'. When set to a
413 string, this string overrides `org-e-html-preamble-format'.
414 When set to a function, apply this function and insert the
415 returned string. The function takes the property list of export
416 options as its only argument.
418 Setting :html-preamble in publishing projects will take
419 precedence over this variable."
420 :group 'org-export-e-html
421 :type '(choice (const :tag "No preamble" nil)
422 (const :tag "Default preamble" t)
423 (string :tag "Custom formatting string")
424 (function :tag "Function (must return a string)")))
426 (defcustom org-e-html-preamble-format '(("en" ""))
427 "The format for the HTML preamble.
429 %t stands for the title.
430 %a stands for the author's name.
431 %e stands for the author's email.
432 %d stands for the date.
434 If you need to use a \"%\" character, you need to escape it
435 like that: \"%%\"."
436 :group 'org-export-e-html
437 :type 'string)
439 (defcustom org-e-html-postamble 'auto
440 "Non-nil means insert a postamble in HTML export.
442 When `t', insert a string as defined by the formatting string in
443 `org-e-html-postamble-format'. When set to a string, this
444 string overrides `org-e-html-postamble-format'. When set to
445 'auto, discard `org-e-html-postamble-format' and honor
446 `org-export-author/email/creator-info' variables. When set to a
447 function, apply this function and insert the returned string.
448 The function takes the property list of export options as its
449 only argument.
451 Setting :html-postamble in publishing projects will take
452 precedence over this variable."
453 :group 'org-export-e-html
454 :type '(choice (const :tag "No postamble" nil)
455 (const :tag "Auto preamble" 'auto)
456 (const :tag "Default formatting string" t)
457 (string :tag "Custom formatting string")
458 (function :tag "Function (must return a string)")))
460 (defcustom org-e-html-postamble-format
461 '(("en" "<p class=\"author\">Author: %a (%e)</p>
462 <p class=\"date\">Date: %d</p>
463 <p class=\"creator\">Generated by %c</p>
464 <p class=\"xhtml-validation\">%v</p>
466 "The format for the HTML postamble.
468 %a stands for the author's name.
469 %e stands for the author's email.
470 %d stands for the date.
471 %c will be replaced by information about Org/Emacs versions.
472 %v will be replaced by `org-e-html-validation-link'.
474 If you need to use a \"%\" character, you need to escape it
475 like that: \"%%\"."
476 :group 'org-export-e-html
477 :type 'string)
479 (defcustom org-e-html-home/up-format
480 "<div id=\"org-div-home-and-up\" style=\"text-align:right;font-size:70%%;white-space:nowrap;\">
481 <a accesskey=\"h\" href=\"%s\"> UP </a>
483 <a accesskey=\"H\" href=\"%s\"> HOME </a>
484 </div>"
485 "Snippet used to insert the HOME and UP links.
486 This is a format string, the first %s will receive the UP link,
487 the second the HOME link. If both `org-e-html-link-up' and
488 `org-e-html-link-home' are empty, the entire snippet will be
489 ignored."
490 :group 'org-export-e-html
491 :type 'string)
493 (defcustom org-e-html-toplevel-hlevel 2
494 "The <H> level for level 1 headings in HTML export.
495 This is also important for the classes that will be wrapped around headlines
496 and outline structure. If this variable is 1, the top-level headlines will
497 be <h1>, and the corresponding classes will be outline-1, section-number-1,
498 and outline-text-1. If this is 2, all of these will get a 2 instead.
499 The default for this variable is 2, because we use <h1> for formatting the
500 document title."
501 :group 'org-export-e-html
502 :type 'string)
504 (defcustom org-e-html-link-org-files-as-html t
505 "Non-nil means make file links to `file.org' point to `file.html'.
506 When org-mode is exporting an org-mode file to HTML, links to
507 non-html files are directly put into a href tag in HTML.
508 However, links to other Org-mode files (recognized by the
509 extension `.org.) should become links to the corresponding html
510 file, assuming that the linked org-mode file will also be
511 converted to HTML.
512 When nil, the links still point to the plain `.org' file."
513 :group 'org-export-e-html
514 :type 'boolean)
516 (defcustom org-e-html-inline-images 'maybe
517 "Non-nil means inline images into exported HTML pages.
518 This is done using an <img> tag. When nil, an anchor with href is used to
519 link to the image. If this option is `maybe', then images in links with
520 an empty description will be inlined, while images with a description will
521 be linked only."
522 :group 'org-export-e-html
523 :type '(choice (const :tag "Never" nil)
524 (const :tag "Always" t)
525 (const :tag "When there is no description" maybe)))
527 (defcustom org-e-html-inline-image-extensions
528 '("png" "jpeg" "jpg" "gif" "svg")
529 "Extensions of image files that can be inlined into HTML."
530 :group 'org-export-e-html
531 :type '(repeat (string :tag "Extension")))
533 (defcustom org-e-html-table-tag
534 "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">"
535 "The HTML tag that is used to start a table.
536 This must be a <table> tag, but you may change the options like
537 borders and spacing."
538 :group 'org-export-e-html
539 :type 'string)
541 (defcustom org-export-table-header-tags '("<th scope=\"%s\"%s>" . "</th>")
542 "The opening tag for table header fields.
543 This is customizable so that alignment options can be specified.
544 The first %s will be filled with the scope of the field, either row or col.
545 The second %s will be replaced by a style entry to align the field.
546 See also the variable `org-e-html-table-use-header-tags-for-first-column'.
547 See also the variable `org-e-html-table-align-individual-fields'."
548 :group 'org-export-tables
549 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
551 (defcustom org-export-table-data-tags '("<td%s>" . "</td>")
552 "The opening tag for table data fields.
553 This is customizable so that alignment options can be specified.
554 The first %s will be filled with the scope of the field, either row or col.
555 The second %s will be replaced by a style entry to align the field.
556 See also the variable `org-e-html-table-align-individual-fields'."
557 :group 'org-export-tables
558 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
560 (defcustom org-export-table-row-tags '("<tr>" . "</tr>")
561 "The opening tag for table data fields.
562 This is customizable so that alignment options can be specified.
563 Instead of strings, these can be Lisp forms that will be evaluated
564 for each row in order to construct the table row tags. During evaluation,
565 the variable `head' will be true when this is a header line, nil when this
566 is a body line. And the variable `nline' will contain the line number,
567 starting from 1 in the first header line. For example
569 (setq org-export-table-row-tags
570 (cons '(if head
571 \"<tr>\"
572 (if (= (mod nline 2) 1)
573 \"<tr class=\\\"tr-odd\\\">\"
574 \"<tr class=\\\"tr-even\\\">\"))
575 \"</tr>\"))
577 will give even lines the class \"tr-even\" and odd lines the class \"tr-odd\"."
578 :group 'org-export-tables
579 :type '(cons
580 (choice :tag "Opening tag"
581 (string :tag "Specify")
582 (sexp))
583 (choice :tag "Closing tag"
584 (string :tag "Specify")
585 (sexp))))
587 (defcustom org-e-html-table-align-individual-fields t
588 "Non-nil means attach style attributes for alignment to each table field.
589 When nil, alignment will only be specified in the column tags, but this
590 is ignored by some browsers (like Firefox, Safari). Opera does it right
591 though."
592 :group 'org-export-tables
593 :type 'boolean)
595 (defcustom org-e-html-table-use-header-tags-for-first-column nil
596 "Non-nil means format column one in tables with header tags.
597 When nil, also column one will use data tags."
598 :group 'org-export-tables
599 :type 'boolean)
601 (defcustom org-e-html-validation-link
602 "<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>"
603 "Link to HTML validation service."
604 :group 'org-export-e-html
605 :type 'string)
607 ;; FIXME Obsolete since Org 7.7
608 ;; Use the :timestamp option or `org-export-time-stamp-file' instead
609 (defvar org-e-html-with-timestamp nil
610 "If non-nil, write container for HTML-helper-mode timestamp.")
612 ;; FIXME Obsolete since Org 7.7
613 (defvar org-e-html-html-helper-timestamp
614 "\n<p><br/><br/>\n<!-- hhmts start --> <!-- hhmts end --></p>\n"
615 "The HTML tag used as timestamp delimiter for HTML-helper-mode.")
617 (defcustom org-e-html-protect-char-alist
618 '(("&" . "&amp;")
619 ("<" . "&lt;")
620 (">" . "&gt;"))
621 "Alist of characters to be converted by `org-e-html-protect'."
622 :group 'org-export-e-html
623 :type '(repeat (cons (string :tag "Character")
624 (string :tag "HTML equivalent"))))
626 (defgroup org-export-e-htmlize nil
627 "Options for processing examples with htmlize.el."
628 :tag "Org Export Htmlize"
629 :group 'org-export-e-html)
631 (defcustom org-export-e-htmlize-output-type 'inline-css
632 "Output type to be used by htmlize when formatting code snippets.
633 Choices are `css', to export the CSS selectors only, or `inline-css', to
634 export the CSS attribute values inline in the HTML. We use as default
635 `inline-css', in order to make the resulting HTML self-containing.
637 However, this will fail when using Emacs in batch mode for export, because
638 then no rich font definitions are in place. It will also not be good if
639 people with different Emacs setup contribute HTML files to a website,
640 because the fonts will represent the individual setups. In these cases,
641 it is much better to let Org/Htmlize assign classes only, and to use
642 a style file to define the look of these classes.
643 To get a start for your css file, start Emacs session and make sure that
644 all the faces you are interested in are defined, for example by loading files
645 in all modes you want. Then, use the command
646 \\[org-export-e-htmlize-generate-css] to extract class definitions."
647 :group 'org-export-e-htmlize
648 :type '(choice (const css) (const inline-css)))
650 (defcustom org-export-e-htmlize-css-font-prefix "org-"
651 "The prefix for CSS class names for htmlize font specifications."
652 :group 'org-export-e-htmlize
653 :type 'string)
655 (defcustom org-export-e-htmlized-org-css-url nil
656 "URL pointing to a CSS file defining text colors for htmlized Emacs buffers.
657 Normally when creating an htmlized version of an Org buffer, htmlize will
658 create CSS to define the font colors. However, this does not work when
659 converting in batch mode, and it also can look bad if different people
660 with different fontification setup work on the same website.
661 When this variable is non-nil, creating an htmlized version of an Org buffer
662 using `org-export-as-org' will remove the internal CSS section and replace it
663 with a link to this URL."
664 :group 'org-export-e-htmlize
665 :type '(choice
666 (const :tag "Keep internal css" nil)
667 (string :tag "URL or local href")))
669 ;; FIXME: The following variable is obsolete since Org 7.7 but is
670 ;; still declared and checked within code for compatibility reasons.
671 ;; Use the custom variables `org-e-html-divs' instead.
672 (defvar org-e-html-content-div "content"
673 "The name of the container DIV that holds all the page contents.
675 This variable is obsolete since Org version 7.7.
676 Please set `org-e-html-divs' instead.")
678 (defcustom org-e-html-divs '("preamble" "content" "postamble")
679 "The name of the main divs for HTML export.
680 This is a list of three strings, the first one for the preamble
681 DIV, the second one for the content DIV and the third one for the
682 postamble DIV."
683 :group 'org-export-e-html
684 :type '(list
685 (string :tag " Div for the preamble:")
686 (string :tag " Div for the content:")
687 (string :tag "Div for the postamble:")))
689 ;;; Hooks
691 (defvar org-e-html-after-blockquotes-hook nil
692 "Hook run during HTML export, after blockquote, verse, center are done.")
694 (defvar org-e-html-final-hook nil
695 "Hook run at the end of HTML export, in the new buffer.")
697 (defun org-e-html-preprocess-label-references ()
698 (goto-char (point-min))
699 (let (label l1)
700 (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t)
701 (org-if-unprotected-at (match-beginning 1)
702 (setq label (match-string 1))
703 (save-match-data
704 (if (string-match "\\`[a-z]\\{1,10\\}:\\(.+\\)" label)
705 (setq l1 (substring label (match-beginning 1)))
706 (setq l1 label)))
707 (replace-match (format "[[#%s][%s]]" label l1) t t)))))
709 (defun org-e-html-preprocess (parameters)
710 (org-e-html-preprocess-label-references))
712 (defvar html-table-tag nil) ; dynamically scoped into this.
715 ;; FIXME: it already exists in org-e-html.el
716 (defconst org-e-html-cvt-link-fn
718 "Function to convert link URLs to exportable URLs.
719 Takes two arguments, TYPE and PATH.
720 Returns exportable url as (TYPE PATH), or nil to signal that it
721 didn't handle this case.
722 Intended to be locally bound around a call to `org-export-as-html'." )
725 ;; FIXME: it already exists in org-e-html.el
726 (defun org-e-html-cvt-org-as-html (opt-plist type path)
727 "Convert an org filename to an equivalent html filename.
728 If TYPE is not file, just return `nil'.
729 See variable `org-e-html-link-org-files-as-html'"
731 (save-match-data
732 (and
733 org-e-html-link-org-files-as-html
734 (string= type "file")
735 (string-match "\\.org$" path)
736 (progn
737 (list
738 "file"
739 (concat
740 (substring path 0 (match-beginning 0))
742 (plist-get opt-plist :html-extension)))))))
744 (defun org-e-html-format-org-link (opt-plist type-1 path fragment desc attr
745 descp)
746 "Make an HTML link.
747 OPT-PLIST is an options list.
748 TYPE is the device-type of the link (THIS://foo.html).
749 PATH is the path of the link (http://THIS#location).
750 FRAGMENT is the fragment part of the link, if any (foo.html#THIS).
751 DESC is the link description, if any.
752 ATTR is a string of other attributes of the \"a\" element."
753 (declare (special org-lparse-par-open))
754 (save-match-data
755 (when (string= type-1 "coderef")
756 (let ((ref fragment))
757 (setq desc (format (org-export-get-coderef-format ref (and descp desc))
758 (cdr (assoc ref org-export-code-refs)))
759 fragment (concat "coderef-" ref)
760 attr (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\""
761 fragment fragment))))
762 (let* ((may-inline-p
763 (and (member type-1 '("http" "https" "file"))
764 (org-lparse-should-inline-p path descp)
765 (not fragment)))
766 (type (if (equal type-1 "id") "file" type-1))
767 (filename path)
768 ;;First pass. Just sanity stuff.
769 (components-1
770 (cond
771 ((string= type "file")
772 (list
773 type
774 ;;Substitute just if original path was absolute.
775 ;;(Otherwise path must remain relative)
776 (if (file-name-absolute-p path)
777 (concat "file://" (expand-file-name path))
778 path)))
779 ((string= type "")
780 (list nil path))
781 (t (list type path))))
783 ;;Second pass. Components converted so they can refer
784 ;;to a remote site.
785 (components-2
787 (and org-e-html-cvt-link-fn
788 (apply org-e-html-cvt-link-fn
789 opt-plist components-1))
790 (apply #'org-e-html-cvt-org-as-html
791 opt-plist components-1)
792 components-1))
793 (type (first components-2))
794 (thefile (second components-2)))
797 ;;Third pass. Build final link except for leading type
798 ;;spec.
799 (cond
800 ((or
801 (not type)
802 (string= type "http")
803 (string= type "https")
804 (string= type "file")
805 (string= type "coderef"))
806 (if fragment
807 (setq thefile (concat thefile "#" fragment))))
809 (t))
811 ;;Final URL-build, for all types.
812 (setq thefile
813 (let
814 ((str (org-xml-format-href thefile)))
815 (if (and type (not (or (string= "file" type)
816 (string= "coderef" type))))
817 (concat type ":" str)
818 str)))
820 (if may-inline-p
821 (org-e-html-format-image thefile)
822 (org-lparse-format
823 'LINK (org-xml-format-desc desc) thefile attr)))))
825 (defun org-e-html-format-inline-image (path &optional caption label attr)
826 ;; FIXME: alt text missing here?
827 (let ((inline-image (format "<img src=\"%s\" alt=\"%s\"/>"
828 path (file-name-nondirectory path))))
829 (if (not label) inline-image
830 (org-e-html-format-section inline-image "figure" label))))
832 ;; FIXME: the org-lparse defvar belongs to org-lparse.el
833 (defvar org-lparse-link-description-is-image)
835 (defun org-e-html-format-image (src)
836 "Create image tag with source and attributes."
837 (save-match-data
838 (let* ((caption (org-find-text-property-in-string 'org-caption src))
839 (attr (org-find-text-property-in-string 'org-attributes src))
840 (label (org-find-text-property-in-string 'org-label src))
841 (caption (and caption (org-xml-encode-org-text caption)))
842 (img-extras (if (string-match "^ltxpng/" src)
843 (format " alt=\"%s\""
844 (org-find-text-property-in-string
845 'org-latex-src src))
846 (if (string-match "\\<alt=" (or attr ""))
847 (concat " " attr )
848 (concat " " attr " alt=\"" src "\""))))
849 (img (format "<img src=\"%s\"%s />" src img-extras))
850 (extra (concat
851 (and label
852 (format "id=\"%s\" " (org-solidify-link-text label)))
853 "class=\"figure\"")))
854 (if caption
855 (with-temp-buffer
856 (with-org-lparse-preserve-paragraph-state
857 (insert
858 (org-lparse-format
859 '("<div %s>" . "\n</div>")
860 (concat
861 (org-lparse-format '("\n<p>" . "</p>") img)
862 (org-lparse-format '("\n<p>" . "</p>") caption))
863 extra)))
864 (buffer-string))
865 img))))
867 (defun org-e-html-bibliography ()
868 "Find bibliography, cut it out and return it."
869 (catch 'exit
870 (let (beg end (cnt 1) bib)
871 (save-excursion
872 (goto-char (point-min))
873 (when (re-search-forward "^[ \t]*<div \\(id\\|class\\)=\"bibliography\"" nil t)
874 (setq beg (match-beginning 0))
875 (while (re-search-forward "</?div\\>" nil t)
876 (setq cnt (+ cnt (if (string= (match-string 0) "<div") +1 -1)))
877 (when (= cnt 0)
878 (and (looking-at ">") (forward-char 1))
879 (setq bib (buffer-substring beg (point)))
880 (delete-region beg (point))
881 (throw 'exit bib))))
882 nil))))
884 (defun org-e-html-format-table (lines olines)
885 (let ((org-e-html-format-table-no-css nil))
886 (org-lparse-format-table lines olines)))
888 ;; Following variable is defined for native tables i.e., when
889 ;; `org-lparse-table-is-styled' evals to t.
890 (defvar org-e-html-format-table-no-css)
891 (defvar org-table-number-regexp) ; defined in org-table.el
893 (defun org-format-table-html (lines olines &optional no-css)
894 "Find out which HTML converter to use and return the HTML code.
895 NO-CSS is passed to the exporter."
896 (error "FIXME"))
898 (defun org-format-org-table-html (lines &optional splice no-css)
899 (error "FIXME"))
901 (defun org-export-splice-attributes (tag attributes)
902 "Read attributes in string ATTRIBUTES, add and replace in HTML tag TAG."
903 (if (not attributes)
905 (let (oldatt newatt)
906 (setq oldatt (org-extract-attributes-from-string tag)
907 tag (pop oldatt)
908 newatt (cdr (org-extract-attributes-from-string attributes)))
909 (while newatt
910 (setq oldatt (plist-put oldatt (pop newatt) (pop newatt))))
911 (if (string-match ">" tag)
912 (setq tag
913 (replace-match (concat (org-attributes-to-string oldatt) ">")
914 t t tag)))
915 tag)))
917 (defun org-format-table-table-html (lines)
918 (error "FIXME"))
920 (defun org-export-splice-style (style extra)
921 "Splice EXTRA into STYLE, just before \"</style>\"."
922 (if (and (stringp extra)
923 (string-match "\\S-" extra)
924 (string-match "</style>" style))
925 (concat (substring style 0 (match-beginning 0))
926 "\n" extra "\n"
927 (substring style (match-beginning 0)))
928 style))
930 (defvar htmlize-buffer-places) ; from htmlize.el
931 (defun org-export-e-htmlize-region-for-paste (beg end)
932 "Convert the region to HTML, using htmlize.el.
933 This is much like `htmlize-region-for-paste', only that it uses
934 the settings define in the org-... variables."
935 (let* ((htmlize-output-type org-export-e-htmlize-output-type)
936 (htmlize-css-name-prefix org-export-e-htmlize-css-font-prefix)
937 (htmlbuf (htmlize-region beg end)))
938 (unwind-protect
939 (with-current-buffer htmlbuf
940 (buffer-substring (plist-get htmlize-buffer-places 'content-start)
941 (plist-get htmlize-buffer-places 'content-end)))
942 (kill-buffer htmlbuf))))
944 ;;;###autoload
945 (defun org-export-e-htmlize-generate-css ()
946 "Create the CSS for all font definitions in the current Emacs session.
947 Use this to create face definitions in your CSS style file that can then
948 be used by code snippets transformed by htmlize.
949 This command just produces a buffer that contains class definitions for all
950 faces used in the current Emacs session. You can copy and paste the ones you
951 need into your CSS file.
953 If you then set `org-export-e-htmlize-output-type' to `css', calls to
954 the function `org-export-e-htmlize-region-for-paste' will produce code
955 that uses these same face definitions."
956 (interactive)
957 (require 'htmlize)
958 (and (get-buffer "*html*") (kill-buffer "*html*"))
959 (with-temp-buffer
960 (let ((fl (face-list))
961 (htmlize-css-name-prefix "org-")
962 (htmlize-output-type 'css)
963 f i)
964 (while (setq f (pop fl)
965 i (and f (face-attribute f :inherit)))
966 (when (and (symbolp f) (or (not i) (not (listp i))))
967 (insert (org-add-props (copy-sequence "1") nil 'face f))))
968 (htmlize-region (point-min) (point-max))))
969 (org-pop-to-buffer-same-window "*html*")
970 (goto-char (point-min))
971 (if (re-search-forward "<style" nil t)
972 (delete-region (point-min) (match-beginning 0)))
973 (if (re-search-forward "</style>" nil t)
974 (delete-region (1+ (match-end 0)) (point-max)))
975 (beginning-of-line 1)
976 (if (looking-at " +") (replace-match ""))
977 (goto-char (point-min)))
979 (defvar body-only) ; dynamically scoped into this.
981 ;; Following variable is let bound when `org-do-lparse' is in
982 ;; progress. See org-lparse.el.
984 ;; FIXME: the org-lparse defvar belongs to org-lparse.el
985 (defvar org-lparse-toc)
987 (defvar org-lparse-dyn-first-heading-pos)
989 (defun org-e-html-end-export ()
990 ;; insert the table of contents
991 (when (and org-export-with-toc (not body-only) org-lparse-toc)
992 (org-e-html-insert-toc org-lparse-toc))
994 ;; Convert whitespace place holders
995 (goto-char (point-min))
996 (let (beg end n)
997 (while (setq beg (next-single-property-change (point) 'org-whitespace))
998 (setq n (get-text-property beg 'org-whitespace)
999 end (next-single-property-change beg 'org-whitespace))
1000 (goto-char beg)
1001 (delete-region beg end)
1002 (insert (format "<span style=\"visibility:hidden;\">%s</span>"
1003 (make-string n ?x)))))
1005 ;; Remove empty lines at the beginning of the file.
1006 (goto-char (point-min))
1007 (when (looking-at "\\s-+\n") (replace-match ""))
1009 ;; Remove display properties
1010 (remove-text-properties (point-min) (point-max) '(display t))
1012 ;; Run the hook
1013 (run-hooks 'org-e-html-final-hook))
1015 (defun org-e-html-format-toc-entry (snumber todo headline tags href)
1016 (setq headline (concat
1017 (and org-export-with-section-numbers
1018 (concat snumber " "))
1019 headline
1020 (and tags
1021 (concat
1022 (org-lparse-format 'SPACES 3)
1023 (org-lparse-format 'FONTIFY tags "tag")))))
1024 (when todo
1025 (setq headline (org-lparse-format 'FONTIFY headline "todo")))
1026 (org-lparse-format 'LINK headline (concat "#" href)))
1028 (defun org-e-html-format-toc-item (toc-entry level org-last-level)
1029 (when (> level org-last-level)
1030 (let ((cnt (- level org-last-level)))
1031 (while (>= (setq cnt (1- cnt)) 0)
1032 (org-lparse-begin-list 'unordered)
1033 (org-lparse-begin-list-item 'unordered))))
1034 (when (< level org-last-level)
1035 (let ((cnt (- org-last-level level)))
1036 (while (>= (setq cnt (1- cnt)) 0)
1037 (org-lparse-end-list-item-1)
1038 (org-lparse-end-list 'unordered))))
1040 (org-lparse-end-list-item-1)
1041 (org-lparse-begin-list-item 'unordered)
1042 (insert toc-entry))
1044 (defun org-e-html-begin-toc (lang-specific-heading max-level)
1045 (org-lparse-insert-tag "<div id=\"table-of-contents\">")
1046 (insert
1047 (org-lparse-format 'HEADING lang-specific-heading
1048 (or (org-lparse-get 'TOPLEVEL-HLEVEL) 1)))
1049 (org-lparse-insert-tag "<div id=\"text-table-of-contents\">")
1050 (org-lparse-begin-list 'unordered)
1051 (org-lparse-begin-list-item 'unordered))
1053 (defun org-e-html-end-toc ()
1054 (while (> org-last-level (1- org-min-level))
1055 (setq org-last-level (1- org-last-level))
1056 (org-lparse-end-list-item-1)
1057 (org-lparse-end-list 'unordered))
1058 (org-lparse-insert-tag "</div>")
1059 (org-lparse-insert-tag "</div>")
1061 ;; cleanup empty list items in toc
1062 (while (re-search-backward "<li>[ \r\n\t]*</li>\n?" (point-min) t)
1063 (replace-match "")))
1065 ;;;###autoload
1066 (defun org-export-as-html-and-open (arg)
1067 "Export the outline as HTML and immediately open it with a browser.
1068 If there is an active region, export only the region.
1069 The prefix ARG specifies how many levels of the outline should become
1070 headlines. The default is 3. Lower levels will become bulleted lists."
1071 (interactive "P")
1072 (error "FIXME"))
1074 ;;;###autoload
1075 (defun org-export-as-html-batch ()
1076 "Call the function `org-lparse-batch'.
1077 This function can be used in batch processing as:
1078 emacs --batch
1079 --load=$HOME/lib/emacs/org.el
1080 --eval \"(setq org-export-headline-levels 2)\"
1081 --visit=MyFile --funcall org-export-as-html-batch"
1082 (error "FIXME"))
1084 ;;;###autoload
1085 (defun org-export-as-html-to-buffer (arg)
1086 "Call `org-lparse-to-buffer` with output to a temporary buffer.
1087 No file is created. The prefix ARG is passed through to `org-lparse-to-buffer'."
1088 (interactive "P")
1089 (error "FIXME"))
1091 ;;;###autoload
1092 (defun org-replace-region-by-html (beg end)
1093 "Assume the current region has org-mode syntax, and convert it to HTML.
1094 This can be used in any buffer. For example, you could write an
1095 itemized list in org-mode syntax in an HTML buffer and then use this
1096 command to convert it."
1097 (interactive "r")
1098 (error "FIXME"))
1100 ;;;###autoload
1101 (defun org-export-region-as-html (beg end &optional body-only buffer)
1102 "Convert region from BEG to END in `org-mode' buffer to HTML.
1103 If prefix arg BODY-ONLY is set, omit file header, footer, and table of
1104 contents, and only produce the region of converted text, useful for
1105 cut-and-paste operations.
1106 If BUFFER is a buffer or a string, use/create that buffer as a target
1107 of the converted HTML. If BUFFER is the symbol `string', return the
1108 produced HTML as a string and leave not buffer behind. For example,
1109 a Lisp program could call this function in the following way:
1111 (setq html (org-export-region-as-html beg end t 'string))
1113 When called interactively, the output buffer is selected, and shown
1114 in a window. A non-interactive call will only return the buffer."
1115 (interactive "r\nP")
1116 (error "FIXME"))
1118 ;;; org-export-as-html
1119 ;;;###autoload
1120 (defun org-export-as-html (arg &optional hidden ext-plist
1121 to-buffer body-only pub-dir)
1122 "Export the outline as a pretty HTML file.
1123 Use `org-lparse' internally to perform the actual export. This
1124 routine merely binds the TARGET-BACKEND and NATIVE-BACKEND args
1125 of `org-lparse' to \"html\"."
1126 (interactive "P")
1127 (error "FIXME"))
1129 (defun org-e-html-begin-outline (level1 snumber title tags
1130 target extra-targets extra-class)
1131 (let* ((class (format "outline-%d" level1))
1132 (class (if extra-class (concat class " " extra-class) class))
1133 (id (format "outline-container-%s"
1134 (org-lparse-suffix-from-snumber snumber)))
1135 (extra (concat (when id (format " id=\"%s\"" id))
1136 (when class (format " class=\"%s\"" class)))))
1137 (org-lparse-insert-tag "<div%s>" extra)
1138 (insert
1139 (org-lparse-format 'HEADING
1140 (org-lparse-format
1141 'HEADLINE title extra-targets tags snumber level1)
1142 level1 target))))
1144 (defun org-e-html-end-outline ()
1145 (org-lparse-insert-tag "</div>"))
1148 ;; (defun org-e-html-format-heading (text level &optional id)
1149 ;; (let* ((extra (concat (when id (format " id=\"%s\"" id)))))
1150 ;; (concat (format "<h%d%s>" level extra) text (format "</h%d>" level))))
1152 (defun org-e-html-suffix-from-snumber (snumber)
1153 (let* ((snu (replace-regexp-in-string "\\." "-" snumber))
1154 (href (cdr (assoc (concat "sec-" snu)
1155 org-export-preferred-target-alist))))
1156 (org-solidify-link-text (or href snu))))
1158 (defun org-e-html-format-outline (contents level1 snumber title
1159 tags target extra-targets extra-class)
1160 (let* ((class (format "outline-%d" level1))
1161 (class (if extra-class (concat class " " extra-class) class))
1162 (id (and snumber ;; FIXME
1163 (format "outline-container-%s"
1164 (org-e-html-suffix-from-snumber snumber))))
1165 (extra (concat (when id (format " id=\"%s\"" id))
1166 (when class (format " class=\"%s\"" class)))))
1167 (concat
1168 (format "<div%s>\n" extra)
1169 (org-e-html-format-heading
1170 (org-e-html-format-headline title extra-targets tags snumber level1)
1171 level1 target)
1173 contents
1175 "</div>")))
1177 (defun org-e-html-begin-outline-text (level1 snumber extra-class)
1178 (let* ((class (format "outline-text-%d" level1))
1179 (class (if extra-class (concat class " " extra-class) class))
1180 (id (format "text-%s" (org-lparse-suffix-from-snumber snumber)))
1181 (extra (concat (when id (format " id=\"%s\"" id))
1182 (when class (format " class=\"%s\"" class)))))
1183 (org-lparse-insert-tag "<div%s>" extra)))
1185 (defun org-e-html-end-outline-text ()
1186 (org-lparse-insert-tag "</div>"))
1188 (defun org-e-html-begin-paragraph (&optional style)
1189 (let* ((class (cdr (assoc style '((footnote . "footnote")
1190 (verse . nil)))))
1191 (extra (if class (format " class=\"%s\"" class) "")))
1192 (org-lparse-insert-tag "<p%s>" extra)))
1194 (defun org-e-html-end-paragraph ()
1195 (insert "</p>"))
1197 ;; Following variables are let bound when table emission is in
1198 ;; progress. See org-lparse.el.
1200 ;; FIXME: the org-lparse defvar belongs to org-lparse.el
1201 (defvar org-lparse-table-begin-marker)
1202 (defvar org-lparse-table-ncols)
1203 (defvar org-lparse-table-rowgrp-open)
1204 (defvar org-lparse-table-rownum)
1205 (defvar org-lparse-table-cur-rowgrp-is-hdr)
1206 (defvar org-lparse-table-is-styled)
1207 (defvar org-lparse-table-rowgrp-info)
1208 (defvar org-lparse-table-colalign-vector)
1209 (defvar org-lparse-table-num-numeric-items-per-column)
1211 (defun org-e-html-format-footnote-definition (contents n)
1212 (concat
1213 (format
1214 (format org-e-html-footnote-format
1215 "<a class=\"footnum\" name=\"fn.%s\" href=\"#fnr.%s\">%s</a>")
1216 n n n)
1218 contents))
1220 ;; (defun org-e-html-format-spaces (n)
1221 ;; (let ((space (or (and org-lparse-encode-pending "\\nbsp") "&nbsp;")) out)
1222 ;; (while (> n 0)
1223 ;; (setq out (concat out space))
1224 ;; (setq n (1- n))) out))
1226 (defun org-e-html-format-tabs (&optional n)
1227 (ignore))
1229 (defun org-e-html-format-line-break ()
1230 (org-e-html-format-tags "<br/>" ""))
1232 (defun org-e-html-format-horizontal-line ()
1233 (concat "\n" "<hr/>" "\n"))
1235 ;; (defun org-e-html-format-line (line)
1236 ;; (case org-lparse-dyn-current-environment
1237 ;; ((quote fixedwidth) (concat (org-e-html-encode-plain-text line) "\n"))
1238 ;; (t (concat line "\n"))))
1240 (defun org-e-html-format-comment (fmt &rest args)
1241 (let ((comment (apply 'format fmt args)))
1242 (format "\n<!-- %s -->\n" comment)))
1244 (defun org-e-html-fix-class-name (kwd) ; audit callers of this function
1245 "Turn todo keyword into a valid class name.
1246 Replaces invalid characters with \"_\"."
1247 (save-match-data
1248 (while (string-match "[^a-zA-Z0-9_]" kwd)
1249 (setq kwd (replace-match "_" t t kwd))))
1250 kwd)
1252 (defun org-e-html-format-fontify (text style &optional id)
1253 (let (class extra how)
1254 (cond
1255 ((eq style 'underline)
1256 (setq extra " style=\"text-decoration:underline;\"" ))
1257 ((setq how (cdr (assoc style
1258 '((bold . ("<b>" . "</b>"))
1259 (emphasis . ("<i>" . "</i>"))
1260 (code . ("<code>" . "</code>"))
1261 (verbatim . ("<code>" . "</code>"))
1262 (strike . ("<del>" . "</del>"))
1263 (subscript . ("<sub>" . "</sub>"))
1264 (superscript . ("<sup>" . "</sup>")))))))
1265 ((listp style)
1266 (setq class (mapconcat 'identity style " ")))
1267 ((stringp style)
1268 (setq class style))
1269 (t (error "Unknown style %S" style)))
1271 (setq extra (concat (when class (format " class=\"%s\"" class))
1272 (when id (format " id=\"%s\"" id))
1273 extra))
1275 (let ((tags (or how '("<span%s>" . "</span>"))))
1276 (concat (format (car tags) extra) text (cdr tags)))))
1278 (defun org-e-html-format-link (text href &optional extra)
1279 (let ((extra (concat (format " href=\"%s\"" href)
1280 (and extra (concat " " extra)))))
1281 (format "<a%s>%s</a>" extra text)))
1283 (defun org-e-html-format-internal-link (text href &optional extra)
1284 (org-e-html-format-link text (concat "#" href) extra))
1286 (defun org-e-html-format-heading (text level &optional id)
1287 (let* ((extra (concat (when id (format " id=\"%s\"" id)))))
1288 (concat (format "<h%d%s>" level extra) text (format "</h%d>" level))))
1290 (defun org-e-html-format-anchor (text name &optional class)
1291 (let* ((id name)
1292 (extra (concat
1293 (when name (format " name=\"%s\"" name))
1294 (when id (format " id=\"%s\"" id))
1295 (when class (format " class=\"%s\"" class)))))
1296 (format "<a%s>%s</a>" extra text)))
1298 (defun org-e-html-format-extra-targets (extra-targets)
1299 (if (not extra-targets) ""
1300 (mapconcat (lambda (x)
1301 (when x
1302 (setq x (org-solidify-link-text
1303 (if (org-uuidgen-p x) (concat "ID-" x) x)))
1304 (org-e-html-format-anchor "" x))) extra-targets "")))
1306 (defun org-e-html-format-spaces (n)
1307 (let (out) (dotimes (i n out) (setq out (concat out "&nbsp;")))))
1309 (defun org-e-html-format-org-tags (tags)
1310 (if (not tags) ""
1311 (org-e-html-format-fontify
1312 (mapconcat
1313 (lambda (x)
1314 (org-e-html-format-fontify
1315 x (concat org-e-html-tag-class-prefix
1316 (org-e-html-fix-class-name x))))
1317 (org-split-string tags ":")
1318 (org-e-html-format-spaces 1)) "tag")))
1320 (defun org-e-html-format-section-number (&optional snumber level)
1321 ;; FIXME
1322 (and org-export-with-section-numbers
1323 ;; (not org-lparse-body-only)
1324 snumber level
1325 (org-e-html-format-fontify snumber (format "section-number-%d" level))))
1327 (defun org-e-html-format-headline (title extra-targets tags
1328 &optional snumber level)
1329 (concat
1330 (org-e-html-format-extra-targets extra-targets)
1331 (concat (org-e-html-format-section-number snumber level) " ")
1332 title
1333 (and tags (concat (org-e-html-format-spaces 3)
1334 (org-e-html-format-org-tags tags)))))
1336 (defun org-e-html-format-footnote-reference (n def refcnt)
1337 (let ((extra (if (= refcnt 1) "" (format ".%d" refcnt))))
1338 (format org-e-html-footnote-format
1339 (format
1340 "<a class=\"footref\" name=\"fnr.%s%s\" href=\"#fn.%s\">%s</a>"
1341 n extra n n))))
1343 (defun org-e-html-format-footnotes-section (section-name definitions)
1344 (if (not definitions) ""
1345 (format org-e-html-footnotes-section section-name definitions)))
1347 (defun org-e-html-format-org-entity (wd)
1348 (org-entity-get-representation wd 'html))
1350 (defun org-e-html-format-tags (tag text &rest args)
1351 (let ((prefix ;; (when org-lparse-encode-pending "@")
1353 (suffix ;; (when org-lparse-encode-pending "@")
1355 (apply 'org-lparse-format-tags tag text prefix suffix args)))
1357 (defun org-e-html-get (what &optional opt-plist)
1358 (case what
1359 (BACKEND 'html)
1360 (INIT-METHOD nil)
1361 (SAVE-METHOD nil)
1362 (CLEANUP-METHOD nil)
1363 ;; (OTHER-BACKENDS
1364 ;; ;; There is a provision to register a per-backend converter and
1365 ;; ;; output formats. Refer `org-lparse-get-converter' and
1366 ;; ;; `org-lparse-get-other-backends'.
1368 ;; ;; The default behaviour is to use `org-lparse-convert-process'
1369 ;; ;; and `org-lparse-convert-capabilities'.
1370 ;; )
1371 ;; (CONVERT-METHOD
1372 ;; ;; See note above
1373 ;; )
1374 (EXPORT-DIR (org-export-directory :html opt-plist))
1375 (FILE-NAME-EXTENSION (plist-get opt-plist :html-extension))
1376 (EXPORT-BUFFER-NAME "*Org HTML Export*")
1377 (TOPLEVEL-HLEVEL org-e-html-toplevel-hlevel)
1378 (SPECIAL-STRING-REGEXPS org-e-html-special-string-regexps)
1379 (CODING-SYSTEM-FOR-WRITE org-e-html-coding-system)
1380 (CODING-SYSTEM-FOR-SAVE org-e-html-coding-system)
1381 (INLINE-IMAGES org-e-html-inline-images)
1382 (INLINE-IMAGE-EXTENSIONS org-e-html-inline-image-extensions)
1383 (PLAIN-TEXT-MAP org-e-html-protect-char-alist)
1384 (TABLE-FIRST-COLUMN-AS-LABELS
1385 org-e-html-table-use-header-tags-for-first-column)
1386 (TODO-KWD-CLASS-PREFIX org-e-html-todo-kwd-class-prefix)
1387 (TAG-CLASS-PREFIX org-e-html-tag-class-prefix)
1388 (FOOTNOTE-SEPARATOR org-e-html-footnote-separator)
1389 (t (error "Unknown property: %s" what))))
1391 (defun org-e-html-get-coding-system-for-write ()
1392 (or org-e-html-coding-system
1393 (and (boundp 'buffer-file-coding-system) buffer-file-coding-system)))
1395 (defun org-e-html-get-coding-system-for-save ()
1396 (or org-e-html-coding-system
1397 (and (boundp 'buffer-file-coding-system) buffer-file-coding-system)))
1399 (defun org-e-html-format-date (info)
1400 (let ((date (plist-get info :date)))
1401 (cond
1402 ((and date (string-match "%" date))
1403 (format-time-string date))
1404 (date date)
1405 (t (format-time-string "%Y-%m-%d %T %Z")))))
1407 (defun org-e-html-footnote-section (info)
1408 (when org-e-html-footnotes-alist
1409 (setq org-e-html-footnotes-alist (nreverse org-e-html-footnotes-alist))
1410 (org-e-html-format-footnotes-section
1411 (nth 4 (or (assoc (plist-get info :language)
1412 org-export-language-setup)
1413 (assoc "en" org-export-language-setup)))
1415 (format "
1416 <table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">
1418 </table>
1421 (mapconcat
1422 (lambda (x)
1423 (let ((n (car x))
1424 (def (cdr x)))
1425 (format "
1426 <tr>
1427 <td>%s</td>
1428 <td>%s</td>
1429 </tr>
1431 (format
1432 (format org-e-html-footnote-format
1433 "<a class=\"footnum\" name=\"fn.%s\" href=\"#fnr.%s\">%s</a>")
1434 n n n) def)))
1435 org-e-html-footnotes-alist "\n")))))
1437 (eval-when-compile (require 'cl))
1438 ;;; org-e-html.el
1440 (declare-function org-element-get-property "org-element" (property element))
1441 (declare-function org-element-normalize-string "org-element" (s))
1442 (declare-function org-element-parse-secondary-string
1443 "org-element" (string restriction &optional buffer))
1444 (defvar org-element-string-restrictions)
1446 (declare-function org-export-clean-table "org-export" (table specialp))
1447 (declare-function org-export-data "org-export" (data backend info))
1448 (declare-function org-export-directory "org-export" (type plist))
1449 (declare-function org-export-expand-macro "org-export" (macro info))
1450 (declare-function org-export-first-sibling-p "org-export" (headline info))
1451 (declare-function org-export-footnote-first-reference-p "org-export"
1452 (footnote-reference info))
1453 (declare-function org-export-get-coderef-format "org-export" (path desc))
1454 (declare-function org-export-get-footnote-definition "org-export"
1455 (footnote-reference info))
1456 (declare-function org-export-get-footnote-number "org-export" (footnote info))
1457 (declare-function org-export-get-previous-element "org-export" (blob info))
1458 (declare-function org-export-get-relative-level "org-export" (headline info))
1459 (declare-function org-export-handle-code
1460 "org-export" (element info &optional num-fmt ref-fmt delayed))
1461 (declare-function org-export-included-file "org-export" (keyword backend info))
1462 (declare-function org-export-inline-image-p "org-export"
1463 (link &optional extensions))
1464 (declare-function org-export-last-sibling-p "org-export" (headline info))
1465 (declare-function org-export-low-level-p "org-export" (headline info))
1466 (declare-function org-export-output-file-name
1467 "org-export" (extension &optional subtreep pub-dir))
1468 (declare-function org-export-resolve-coderef "org-export" (ref info))
1469 (declare-function org-export-resolve-fuzzy-link "org-export" (link info))
1470 (declare-function org-export-secondary-string "org-export"
1471 (secondary backend info))
1472 (declare-function org-export-solidify-link-text "org-export" (s))
1473 (declare-function org-export-table-format-info "org-export" (table))
1474 (declare-function
1475 org-export-to-buffer "org-export"
1476 (backend buffer &optional subtreep visible-only body-only ext-plist))
1477 (declare-function
1478 org-export-to-file "org-export"
1479 (backend file &optional subtreep visible-only body-only ext-plist))
1483 ;;; Internal Variables
1485 (defconst org-e-html-option-alist
1486 '((:agenda-style nil nil org-agenda-export-html-style)
1487 (:convert-org-links nil nil org-e-html-link-org-files-as-html)
1488 ;; FIXME Use (org-xml-encode-org-text-skip-links s) ??
1489 ;; (:expand-quoted-html nil "@" org-e-html-expand)
1490 (:inline-images nil nil org-e-html-inline-images)
1491 ;; (:link-home nil nil org-e-html-link-home) FIXME
1492 ;; (:link-up nil nil org-e-html-link-up) FIXME
1493 (:style nil nil org-e-html-style)
1494 (:style-extra nil nil org-e-html-style-extra)
1495 (:style-include-default nil nil org-e-html-style-include-default)
1496 (:style-include-scripts nil nil org-e-html-style-include-scripts)
1497 (:timestamp nil nil org-e-html-with-timestamp)
1498 (:html-extension nil nil org-e-html-extension)
1499 (:html-postamble nil nil org-e-html-postamble)
1500 (:html-preamble nil nil org-e-html-preamble)
1501 (:html-table-tag nil nil org-e-html-table-tag)
1502 (:xml-declaration nil nil org-e-html-xml-declaration)
1503 (:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments))
1504 "Alist between export properties and ways to set them.
1506 The car of the alist is the property name, and the cdr is a list
1507 like \(KEYWORD OPTION DEFAULT BEHAVIOUR\) where:
1509 KEYWORD is a string representing a buffer keyword, or nil.
1510 OPTION is a string that could be found in an #+OPTIONS: line.
1511 DEFAULT is the default value for the property.
1512 BEHAVIOUR determine how Org should handle multiple keywords for
1513 the same property. It is a symbol among:
1514 nil Keep old value and discard the new one.
1515 t Replace old value with the new one.
1516 `space' Concatenate the values, separating them with a space.
1517 `newline' Concatenate the values, separating them with
1518 a newline.
1519 `split' Split values at white spaces, and cons them to the
1520 previous list.
1522 KEYWORD and OPTION have precedence over DEFAULT.
1524 All these properties should be back-end agnostic. For back-end
1525 specific properties, define a similar variable named
1526 `org-BACKEND-option-alist', replacing BACKEND with the name of
1527 the appropriate back-end. You can also redefine properties
1528 there, as they have precedence over these.")
1532 ;;; User Configurable Variables
1534 (defgroup org-export-e-html nil
1535 "Options for exporting Org mode files to HTML."
1536 :tag "Org Export HTML"
1537 :group 'org-export)
1540 ;;;; Preamble
1542 (defcustom org-e-html-inputenc-alist nil
1543 "Alist of inputenc coding system names, and what should really be used.
1544 For example, adding an entry
1546 (\"utf8\" . \"utf8x\")
1548 will cause \\usepackage[utf8x]{inputenc} to be used for buffers that
1549 are written as utf8 files."
1550 :group 'org-export-e-html
1551 :type '(repeat
1552 (cons
1553 (string :tag "Derived from buffer")
1554 (string :tag "Use this instead"))))
1556 (defcustom org-e-html-date-format
1557 "\\today"
1558 "Format string for \\date{...}."
1559 :group 'org-export-e-html
1560 :type 'boolean)
1562 (defcustom org-e-html-title-command "\\maketitle"
1563 "The command used to insert the title just after \\begin{document}.
1564 If this string contains the formatting specification \"%s\" then
1565 it will be used as a formatting string, passing the title as an
1566 argument."
1567 :group 'org-export-e-html
1568 :type 'string)
1571 ;;;; Headline
1573 (defcustom org-e-html-format-headline-function nil
1574 "Function to format headline text.
1576 This function will be called with 5 arguments:
1577 TODO the todo keyword \(string or nil\).
1578 TODO-TYPE the type of todo \(symbol: `todo', `done', nil\)
1579 PRIORITY the priority of the headline \(integer or nil\)
1580 TEXT the main headline text \(string\).
1581 TAGS the tags string, separated with colons \(string or nil\).
1583 The function result will be used in the section format string.
1585 As an example, one could set the variable to the following, in
1586 order to reproduce the default set-up:
1588 \(defun org-e-html-format-headline \(todo todo-type priority text tags\)
1589 \"Default format function for an headline.\"
1590 \(concat \(when todo
1591 \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
1592 \(when priority
1593 \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
1594 text
1595 \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
1596 :group 'org-export-e-html
1597 :type 'function)
1600 ;;;; Emphasis
1602 (defcustom org-e-html-emphasis-alist
1603 '(("*" . "\\textbf{%s}")
1604 ("/" . "\\emph{%s}")
1605 ("_" . "\\underline{%s}")
1606 ("+" . "\\st{%s}")
1607 ("=" . protectedtexttt)
1608 ("~" . verb))
1609 "Alist of HTML expressions to convert emphasis fontifiers.
1611 The key is the character used as a marker for fontification. The
1612 value is a formatting string to wrap fontified text with.
1614 Value can also be set to the following symbols: `verb' and
1615 `protectedtexttt'. For the former, Org will use \"\\verb\" to
1616 create a format string and select a delimiter character that
1617 isn't in the string. For the latter, Org will use \"\\texttt\"
1618 to typeset and try to protect special characters."
1619 :group 'org-export-e-html
1620 :type 'alist)
1623 ;;;; Footnotes
1625 (defcustom org-e-html-footnote-separator "<sup>, </sup>"
1626 "Text used to separate footnotes."
1627 :group 'org-export-e-html
1628 :type 'string)
1631 ;;;; Time-stamps
1633 (defcustom org-e-html-active-timestamp-format "\\textit{%s}"
1634 "A printf format string to be applied to active time-stamps."
1635 :group 'org-export-e-html
1636 :type 'string)
1638 (defcustom org-e-html-inactive-timestamp-format "\\textit{%s}"
1639 "A printf format string to be applied to inactive time-stamps."
1640 :group 'org-export-e-html
1641 :type 'string)
1643 (defcustom org-e-html-diary-timestamp-format "\\textit{%s}"
1644 "A printf format string to be applied to diary time-stamps."
1645 :group 'org-export-e-html
1646 :type 'string)
1649 ;;;; Links
1651 (defcustom org-e-html-image-default-option "width=.9\\linewidth"
1652 "Default option for images."
1653 :group 'org-export-e-html
1654 :type 'string)
1656 (defcustom org-e-html-default-figure-position "htb"
1657 "Default position for latex figures."
1658 :group 'org-export-e-html
1659 :type 'string)
1661 (defcustom org-e-html-inline-image-rules
1662 '(("file" . "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\)\\'"))
1663 "Rules characterizing image files that can be inlined into HTML.
1665 A rule consists in an association whose key is the type of link
1666 to consider, and value is a regexp that will be matched against
1667 link's path.
1669 Note that, by default, the image extension *actually* allowed
1670 depend on the way the HTML file is processed. When used with
1671 pdflatex, pdf, jpg and png images are OK. When processing
1672 through dvi to Postscript, only ps and eps are allowed. The
1673 default we use here encompasses both."
1674 :group 'org-export-e-html
1675 :type '(alist :key-type (string :tag "Type")
1676 :value-type (regexp :tag "Path")))
1679 ;;;; Tables
1681 (defcustom org-e-html-default-table-environment "tabular"
1682 "Default environment used to build tables."
1683 :group 'org-export-e-html
1684 :type 'string)
1686 (defcustom org-e-html-tables-centered t
1687 "When non-nil, tables are exported in a center environment."
1688 :group 'org-export-e-html
1689 :type 'boolean)
1691 (defcustom org-e-html-tables-verbatim nil
1692 "When non-nil, tables are exported verbatim."
1693 :group 'org-export-e-html
1694 :type 'boolean)
1696 (defcustom org-e-html-tables-booktabs nil
1697 "When non-nil, display tables in a formal \"booktabs\" style.
1698 This option assumes that the \"booktabs\" package is properly
1699 loaded in the header of the document. This value can be ignored
1700 locally with \"booktabs=yes\" and \"booktabs=no\" HTML
1701 attributes."
1702 :group 'org-export-e-html
1703 :type 'boolean)
1705 (defcustom org-e-html-table-caption-above t
1706 "When non-nil, place caption string at the beginning of the table.
1707 Otherwise, place it near the end."
1708 :group 'org-export-e-html
1709 :type 'boolean)
1712 ;;;; Drawers
1714 (defcustom org-e-html-format-drawer-function nil
1715 "Function called to format a drawer in HTML code.
1717 The function must accept two parameters:
1718 NAME the drawer name, like \"LOGBOOK\"
1719 CONTENTS the contents of the drawer.
1721 The function should return the string to be exported.
1723 For example, the variable could be set to the following function
1724 in order to mimic default behaviour:
1726 \(defun org-e-html-format-drawer-default \(name contents\)
1727 \"Format a drawer element for HTML export.\"
1728 contents\)"
1729 :group 'org-export-e-html
1730 :type 'function)
1733 ;;;; Inlinetasks
1735 (defcustom org-e-html-format-inlinetask-function nil
1736 "Function called to format an inlinetask in HTML code.
1738 The function must accept six parameters:
1739 TODO the todo keyword, as a string
1740 TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
1741 PRIORITY the inlinetask priority, as a string
1742 NAME the inlinetask name, as a string.
1743 TAGS the inlinetask tags, as a string.
1744 CONTENTS the contents of the inlinetask, as a string.
1746 The function should return the string to be exported.
1748 For example, the variable could be set to the following function
1749 in order to mimic default behaviour:
1751 \(defun org-e-html-format-inlinetask \(todo type priority name tags contents\)
1752 \"Format an inline task element for HTML export.\"
1753 \(let \(\(full-title
1754 \(concat
1755 \(when todo
1756 \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
1757 \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
1758 title
1759 \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
1760 \(format \(concat \"\\\\begin{center}\\n\"
1761 \"\\\\fbox{\\n\"
1762 \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
1763 \"%s\\n\\n\"
1764 \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
1765 \"%s\"
1766 \"\\\\end{minipage}}\"
1767 \"\\\\end{center}\"\)
1768 full-title contents\)\)"
1769 :group 'org-export-e-html
1770 :type 'function)
1773 ;; Src blocks
1775 ;;;; Plain text
1777 (defcustom org-e-html-quotes
1778 '(("fr" ("\\(\\s-\\|[[(]\\)\"" . "«~") ("\\(\\S-\\)\"" . "~»") ("\\(\\s-\\|(\\)'" . "'"))
1779 ("en" ("\\(\\s-\\|[[(]\\)\"" . "``") ("\\(\\S-\\)\"" . "''") ("\\(\\s-\\|(\\)'" . "`")))
1780 "Alist for quotes to use when converting english double-quotes.
1782 The CAR of each item in this alist is the language code.
1783 The CDR of each item in this alist is a list of three CONS:
1784 - the first CONS defines the opening quote;
1785 - the second CONS defines the closing quote;
1786 - the last CONS defines single quotes.
1788 For each item in a CONS, the first string is a regexp
1789 for allowed characters before/after the quote, the second
1790 string defines the replacement string for this quote."
1791 :group 'org-export-e-html
1792 :type '(list
1793 (cons :tag "Opening quote"
1794 (string :tag "Regexp for char before")
1795 (string :tag "Replacement quote "))
1796 (cons :tag "Closing quote"
1797 (string :tag "Regexp for char after ")
1798 (string :tag "Replacement quote "))
1799 (cons :tag "Single quote"
1800 (string :tag "Regexp for char before")
1801 (string :tag "Replacement quote "))))
1804 ;;;; Compilation
1806 (defcustom org-e-html-pdf-process
1807 '("pdflatex -interaction nonstopmode -output-directory %o %f"
1808 "pdflatex -interaction nonstopmode -output-directory %o %f"
1809 "pdflatex -interaction nonstopmode -output-directory %o %f")
1810 "Commands to process a HTML file to a PDF file.
1811 This is a list of strings, each of them will be given to the
1812 shell as a command. %f in the command will be replaced by the
1813 full file name, %b by the file base name \(i.e. without
1814 extension) and %o by the base directory of the file.
1816 The reason why this is a list is that it usually takes several
1817 runs of `pdflatex', maybe mixed with a call to `bibtex'. Org
1818 does not have a clever mechanism to detect which of these
1819 commands have to be run to get to a stable result, and it also
1820 does not do any error checking.
1822 By default, Org uses 3 runs of `pdflatex' to do the processing.
1823 If you have texi2dvi on your system and if that does not cause
1824 the infamous egrep/locale bug:
1826 http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html
1828 then `texi2dvi' is the superior choice. Org does offer it as one
1829 of the customize options.
1831 Alternatively, this may be a Lisp function that does the
1832 processing, so you could use this to apply the machinery of
1833 AUCTeX or the Emacs HTML mode. This function should accept the
1834 file name as its single argument."
1835 :group 'org-export-pdf
1836 :type '(choice
1837 (repeat :tag "Shell command sequence"
1838 (string :tag "Shell command"))
1839 (const :tag "2 runs of pdflatex"
1840 ("pdflatex -interaction nonstopmode -output-directory %o %f"
1841 "pdflatex -interaction nonstopmode -output-directory %o %f"))
1842 (const :tag "3 runs of pdflatex"
1843 ("pdflatex -interaction nonstopmode -output-directory %o %f"
1844 "pdflatex -interaction nonstopmode -output-directory %o %f"
1845 "pdflatex -interaction nonstopmode -output-directory %o %f"))
1846 (const :tag "pdflatex,bibtex,pdflatex,pdflatex"
1847 ("pdflatex -interaction nonstopmode -output-directory %o %f"
1848 "bibtex %b"
1849 "pdflatex -interaction nonstopmode -output-directory %o %f"
1850 "pdflatex -interaction nonstopmode -output-directory %o %f"))
1851 (const :tag "texi2dvi"
1852 ("texi2dvi -p -b -c -V %f"))
1853 (const :tag "rubber"
1854 ("rubber -d --into %o %f"))
1855 (function)))
1857 (defcustom org-e-html-logfiles-extensions
1858 '("aux" "idx" "log" "out" "toc" "nav" "snm" "vrb")
1859 "The list of file extensions to consider as HTML logfiles."
1860 :group 'org-export-e-html
1861 :type '(repeat (string :tag "Extension")))
1863 (defcustom org-e-html-remove-logfiles t
1864 "Non-nil means remove the logfiles produced by PDF production.
1865 These are the .aux, .log, .out, and .toc files."
1866 :group 'org-export-e-html
1867 :type 'boolean)
1871 ;;; Internal Functions
1873 (defun org-e-html--caption/label-string (caption label info)
1874 "Return caption and label HTML string for floats.
1876 CAPTION is a cons cell of secondary strings, the car being the
1877 standard caption and the cdr its short form. LABEL is a string
1878 representing the label. INFO is a plist holding contextual
1879 information.
1881 If there's no caption nor label, return the empty string.
1883 For non-floats, see `org-e-html--wrap-label'."
1884 (setq label nil) ;; FIXME
1886 (let ((label-str (if label (format "\\label{%s}" label) "")))
1887 (cond
1888 ((and (not caption) (not label)) "")
1889 ((not caption) (format "\\label{%s}\n" label))
1890 ;; Option caption format with short name.
1891 ((cdr caption)
1892 (format "\\caption[%s]{%s%s}\n"
1893 (org-export-secondary-string (cdr caption) 'e-html info)
1894 label-str
1895 (org-export-secondary-string (car caption) 'e-html info)))
1896 ;; Standard caption format.
1897 ;; (t (format "\\caption{%s%s}\n"
1898 ;; label-str
1899 ;; (org-export-secondary-string (car caption) 'e-html info)))
1901 (t (org-export-secondary-string (car caption) 'e-html info)))))
1903 (defun org-e-html--find-verb-separator (s)
1904 "Return a character not used in string S.
1905 This is used to choose a separator for constructs like \\verb."
1906 (let ((ll "~,./?;':\"|!@#%^&-_=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>()[]{}"))
1907 (loop for c across ll
1908 when (not (string-match (regexp-quote (char-to-string c)) s))
1909 return (char-to-string c))))
1911 (defun org-e-html--make-option-string (options)
1912 "Return a comma separated string of keywords and values.
1913 OPTIONS is an alist where the key is the options keyword as
1914 a string, and the value a list containing the keyword value, or
1915 nil."
1916 (mapconcat (lambda (pair)
1917 (concat (first pair)
1918 (when (> (length (second pair)) 0)
1919 (concat "=" (second pair)))))
1920 options
1921 ","))
1923 (defun org-e-html--quotation-marks (text info)
1924 "Export quotation marks depending on language conventions.
1925 TEXT is a string containing quotation marks to be replaced. INFO
1926 is a plist used as a communication channel."
1927 (mapc (lambda(l)
1928 (let ((start 0))
1929 (while (setq start (string-match (car l) text start))
1930 (let ((new-quote (concat (match-string 1 text) (cdr l))))
1931 (setq text (replace-match new-quote t t text))))))
1932 (cdr (or (assoc (plist-get info :language) org-e-html-quotes)
1933 ;; Falls back on English.
1934 (assoc "en" org-e-html-quotes))))
1935 text)
1937 (defun org-e-html--wrap-label (element output)
1938 "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
1939 This function shouldn't be used for floats. See
1940 `org-e-html--caption/label-string'."
1941 ;; (let ((label (org-element-get-property :name element)))
1942 ;; (if (or (not output) (not label) (string= output "") (string= label ""))
1943 ;; output
1944 ;; (concat (format "\\label{%s}\n" label) output)))
1945 output)
1949 ;;; Template
1951 ;; (defun org-e-html-template (contents info)
1952 ;; "Return complete document string after HTML conversion.
1953 ;; CONTENTS is the transcoded contents string. INFO is a plist
1954 ;; holding export options."
1955 ;; (let ((title (org-export-secondary-string
1956 ;; (plist-get info :title) 'e-html info)))
1957 ;; (concat
1958 ;; ;; 1. Time-stamp.
1959 ;; (and (plist-get info :time-stamp-file)
1960 ;; (format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
1961 ;; ;; 2. Document class and packages.
1962 ;; (let ((class (plist-get info :latex-class))
1963 ;; (class-options (plist-get info :latex-class-options)))
1964 ;; (org-element-normalize-string
1965 ;; (let* ((header (nth 1 (assoc class org-e-html-classes)))
1966 ;; (document-class-string
1967 ;; (and (stringp header)
1968 ;; (if class-options
1969 ;; (replace-regexp-in-string
1970 ;; "^[ \t]*\\\\documentclass\\(\\[.*?\\]\\)"
1971 ;; class-options header t nil 1)
1972 ;; header))))
1973 ;; (org-e-html--guess-inputenc
1974 ;; (org-splice-latex-header
1975 ;; document-class-string
1976 ;; org-export-latex-default-packages-alist ; defined in org.el
1977 ;; org-export-latex-packages-alist nil ; defined in org.el
1978 ;; (plist-get info :latex-header-extra))))))
1979 ;; ;; 3. Define alert if not yet defined.
1980 ;; "\\providecommand{\\alert}[1]{\\textbf{#1}}\n"
1981 ;; ;; 4. Possibly limit depth for headline numbering.
1982 ;; (let ((sec-num (plist-get info :section-numbers)))
1983 ;; (when (integerp sec-num)
1984 ;; (format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
1985 ;; ;; 5. Author.
1986 ;; (let ((author (and (plist-get info :with-author)
1987 ;; (let ((auth (plist-get info :author)))
1988 ;; (and auth (org-export-secondary-string
1989 ;; auth 'e-html info)))))
1990 ;; (email (and (plist-get info :with-email)
1991 ;; (org-export-secondary-string
1992 ;; (plist-get info :email) 'e-html info))))
1993 ;; (cond ((and author email (not (string= "" email)))
1994 ;; (format "\\author{%s\\thanks{%s}}\n" author email))
1995 ;; (author (format "\\author{%s}\n" author))
1996 ;; (t "\\author{}\n")))
1997 ;; ;; 6. Date.
1998 ;; (let ((date (plist-get info :date)))
1999 ;; (and date (format "\\date{%s}\n" date)))
2000 ;; ;; 7. Title
2001 ;; (format "\\title{%s}\n" title)
2002 ;; ;; 8. Hyperref options.
2003 ;; (format "\\hypersetup{\n pdfkeywords={%s},\n pdfsubject={%s},\n pdfcreator={%s}}\n"
2004 ;; (or (plist-get info :keywords) "")
2005 ;; (or (plist-get info :description) "")
2006 ;; (if (not (plist-get info :with-creator)) ""
2007 ;; (plist-get info :creator)))
2008 ;; ;; 9. Document start.
2009 ;; "\\begin{document}\n\n"
2010 ;; ;; 10. Title command.
2011 ;; (org-element-normalize-string
2012 ;; (cond ((string= "" title) nil)
2013 ;; ((not (stringp org-e-html-title-command)) nil)
2014 ;; ((string-match "\\(?:[^%]\\|^\\)%s"
2015 ;; org-e-html-title-command)
2016 ;; (format org-e-html-title-command title))
2017 ;; (t org-e-html-title-command)))
2018 ;; ;; 11. Table of contents.
2019 ;; (let ((depth (plist-get info :with-toc)))
2020 ;; (when depth
2021 ;; (concat (when (wholenump depth)
2022 ;; (format "\\setcounter{tocdepth}{%d}\n" depth))
2023 ;; "\\tableofcontents\n\\vspace*{1cm}\n\n")))
2024 ;; ;; 12. Document's body.
2025 ;; contents
2026 ;; ;; 13. Creator.
2027 ;; (let ((creator-info (plist-get info :with-creator)))
2028 ;; (cond
2029 ;; ((not creator-info) "")
2030 ;; ((eq creator-info 'comment)
2031 ;; (format "%% %s\n" (plist-get info :creator)))
2032 ;; (t (concat (plist-get info :creator) "\n"))))
2033 ;; ;; 14. Document end.
2034 ;; "\\end{document}")))
2036 (defun org-e-html-meta-info (info)
2037 (concat
2038 (format "
2039 <title>%s</title>" (plist-get info :title))
2040 (format "
2041 <meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>"
2042 (and coding-system-for-write
2043 (fboundp 'coding-system-get)
2044 (coding-system-get coding-system-for-write
2045 'mime-charset)))
2046 (format "
2047 <meta name=\"title\" content=\"%s\"/>" (plist-get info :title))
2049 <meta name=\"generator\" content=\"Org-mode\"/>"
2050 (format "
2051 <meta name=\"generated\" content=\"%s\"/>" (org-e-html-format-date info))
2052 (format "
2053 <meta name=\"author\" content=\"%s\"/>" (plist-get info :author))
2054 (format "
2055 <meta name=\"description\" content=\"%s\"/>" (plist-get info :description))
2056 (format "
2057 <meta name=\"keywords\" content=\"%s\"/>" (plist-get info :keywords))))
2059 (defun org-e-html-style (info)
2060 (concat
2061 (when (plist-get info :style-include-default)
2062 org-e-html-style-default)
2063 (plist-get info :style)
2064 (plist-get info :style-extra)
2065 "\n"
2066 (when (plist-get info :style-include-scripts)
2067 org-e-html-scripts)))
2069 (defun org-e-html-mathjax (info)
2070 (when (or (eq (plist-get info :HTML-fragments) 'mathjax)
2071 (and org-export-have-math
2072 (eq (plist-get info :HTML-fragments) t)))
2073 (org-e-html-mathjax-config
2074 org-e-html-mathjax-template
2075 org-e-html-mathjax-options
2076 (or (plist-get info :mathjax) ""))))
2078 (defun org-e-html-preamble (info)
2079 (when (plist-get info :html-preamble)
2080 (let* ((title (plist-get info :title))
2081 (date (org-e-html-format-date info))
2082 (author (plist-get info :author))
2083 (lang-words (or (assoc (plist-get info :language)
2084 org-export-language-setup)
2085 (assoc "en" org-export-language-setup)))
2086 (email (plist-get info :email))
2087 (html-pre-real-contents
2088 (cond
2089 ((functionp (plist-get info :html-preamble))
2090 (with-temp-buffer
2091 (funcall (plist-get info :html-preamble))
2092 (buffer-string)))
2093 ((stringp (plist-get info :html-preamble))
2094 (format-spec (plist-get info :html-preamble)
2095 `((?t . ,title) (?a . ,author)
2096 (?d . ,date) (?e . ,email))))
2098 (format-spec
2099 (or (cadr (assoc (nth 0 lang-words)
2100 org-e-html-preamble-format))
2101 (cadr (assoc "en" org-e-html-preamble-format)))
2102 `((?t . ,title) (?a . ,author)
2103 (?d . ,date) (?e . ,email)))))))
2104 (when (not (equal html-pre-real-contents ""))
2105 (concat
2106 (format "
2107 <div id=\"%s\"> " (nth 0 org-e-html-divs))
2110 html-pre-real-contents
2112 </div>")))))
2114 (defun org-e-html-postamble (info)
2115 (concat
2116 (when (and (not body-only)
2117 (plist-get info :html-postamble))
2118 (let* ((html-post (plist-get info :html-postamble))
2119 (date (org-e-html-format-date info))
2120 (author (plist-get info :author))
2121 (email (plist-get info :email))
2122 (lang-words (or (assoc (plist-get info :language)
2123 org-export-language-setup)
2124 (assoc "en" org-export-language-setup)))
2125 (email
2126 (mapconcat (lambda(e)
2127 (format "<a href=\"mailto:%s\">%s</a>" e e))
2128 (split-string email ",+ *")
2129 ", "))
2130 (html-validation-link (or org-e-html-validation-link ""))
2131 (creator-info
2132 (concat "Org version " org-version " with Emacs version "
2133 (number-to-string emacs-major-version))))
2134 (concat
2135 ;; begin postamble
2137 <div id=\"" (nth 2 org-e-html-divs) "\">"
2138 (cond
2139 ;; auto postamble
2140 ((eq (plist-get info :html-postamble) 'auto)
2141 (concat
2142 (when (plist-get info :time-stamp-file)
2143 (format "
2144 <p class=\"date\"> %s: %s </p> " (nth 2 lang-words) date))
2145 (when (and (plist-get info :with-author) author)
2146 (format "
2147 <p class=\"author\"> %s : %s</p>" (nth 1 lang-words) author))
2148 (when (and (plist-get info :with-email) email)
2149 (format "
2150 <p class=\"email\"> %s </p>" email))
2151 (when (plist-get info :with-creator)
2152 (format "
2153 <p class=\"creator\"> %s </p>" creator-info))
2154 html-validation-link "\n"))
2155 ;; postamble from a string
2156 ((stringp (plist-get info :html-postamble))
2157 (format-spec (plist-get info :html-postamble)
2158 `((?a . ,author) (?e . ,email)
2159 (?d . ,date) (?c . ,creator-info)
2160 (?v . ,html-validation-link))))
2162 ;; postamble from a function
2163 ((functionp (plist-get info :html-postamble))
2164 (with-temp-buffer
2165 (funcall (plist-get info :html-postamble))
2166 (buffer-string)))
2167 ;; default postamble
2169 (format-spec
2170 (or (cadr (assoc (nth 0 lang-words)
2171 org-e-html-postamble-format))
2172 (cadr (assoc "en" org-e-html-postamble-format)))
2173 `((?a . ,author) (?e . ,email)
2174 (?d . ,date) (?c . ,creator-info)
2175 (?v . ,html-validation-link)))))
2177 </div>")))
2178 org-e-html-html-helper-timestamp))
2180 (defun org-e-html-template (contents info)
2181 "Return complete document string after HTML conversion.
2182 CONTENTS is the transcoded contents string. RAW-DATA is the
2183 original parsed data. INFO is a plist holding export options."
2184 (concat
2185 (format
2186 (or (and (stringp org-e-html-xml-declaration)
2187 org-e-html-xml-declaration)
2188 (cdr (assoc (plist-get info :html-extension)
2189 org-e-html-xml-declaration))
2190 (cdr (assoc "html" org-e-html-xml-declaration))
2193 (or (and coding-system-for-write
2194 (fboundp 'coding-system-get)
2195 (coding-system-get coding-system-for-write
2196 'mime-charset))
2197 "iso-8859-1"))
2199 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
2200 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
2201 (format "
2202 <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"> "
2203 (plist-get info :language) (plist-get info :language))
2205 <head>"
2206 (org-e-html-meta-info info) ; meta
2207 (org-e-html-style info) ; style
2208 (org-e-html-mathjax info) ; mathjax
2210 </head>"
2213 <body>"
2214 (let ((link-up (and (plist-get info :link-up)
2215 (string-match "\\S-" (plist-get info :link-up))
2216 (plist-get info :link-up)))
2217 (link-home (and (plist-get info :link-home)
2218 (string-match "\\S-" (plist-get info :link-home))
2219 (plist-get info :link-home))))
2220 (when (or link-up link-home)
2221 (format org-e-html-home/up-format
2222 (or link-up link-home)
2223 (or link-home link-up))))
2224 ;; preamble
2225 (org-e-html-preamble info)
2227 ;; content
2228 (format "
2229 <div id=\"%s\">" (or org-e-html-content-div
2230 (nth 1 org-e-html-divs)))
2231 (format "
2232 <h1 class=\"title\"> %s </h1>\n" (plist-get info :title))
2234 contents
2235 (org-e-html-footnote-section info)
2236 (org-e-html-bibliography)
2238 (unless body-only
2240 </div>")
2242 ;; postamble
2243 (org-e-html-postamble info)
2245 (unless body-only
2247 </body>")
2249 </html>"))
2253 ;;; Transcode Functions
2255 ;;;; Block
2257 (defun org-e-html-center-block (center-block contents info)
2258 "Transcode a CENTER-BLOCK element from Org to HTML.
2259 CONTENTS holds the contents of the block. INFO is a plist
2260 holding contextual information."
2261 (org-e-html--wrap-label
2262 center-block
2263 (format "<div style=\"text-align: center\">\n%s</div>" contents)))
2266 ;;;; Comment
2268 ;; Comments are ignored.
2271 ;;;; Comment Block
2273 ;; Comment Blocks are ignored.
2276 ;;;; Drawer
2278 (defun org-e-html-drawer (drawer contents info)
2279 "Transcode a DRAWER element from Org to HTML.
2280 CONTENTS holds the contents of the block. INFO is a plist
2281 holding contextual information."
2282 (let* ((name (org-element-get-property :drawer-name drawer))
2283 (output (if (functionp org-e-html-format-drawer-function)
2284 (funcall org-e-html-format-drawer-function
2285 name contents)
2286 ;; If there's no user defined function: simply
2287 ;; display contents of the drawer.
2288 contents)))
2289 (org-e-html--wrap-label drawer output)))
2292 ;;;; Dynamic Block
2294 (defun org-e-html-dynamic-block (dynamic-block contents info)
2295 "Transcode a DYNAMIC-BLOCK element from Org to HTML.
2296 CONTENTS holds the contents of the block. INFO is a plist
2297 holding contextual information. See
2298 `org-export-data'."
2299 (org-e-html--wrap-label dynamic-block contents))
2302 ;;;; Emphasis
2304 (defun org-e-html-emphasis (emphasis contents info)
2305 "Transcode EMPHASIS from Org to HTML.
2306 CONTENTS is the contents of the emphasized text. INFO is a plist
2307 holding contextual information.."
2308 ;; (format (cdr (assoc (org-element-get-property :marker emphasis)
2309 ;; org-e-html-emphasis-alist))
2310 ;; contents)
2311 (org-e-html-format-fontify
2312 contents (cadr (assoc
2313 (org-element-get-property :marker emphasis)
2314 '(("*" bold)
2315 ("/" emphasis)
2316 ("_" underline)
2317 ("=" code)
2318 ("~" verbatim)
2319 ("+" strike))))))
2322 ;;;; Entity
2324 (defun org-e-html-entity (entity contents info)
2325 "Transcode an ENTITY object from Org to HTML.
2326 CONTENTS are the definition itself. INFO is a plist holding
2327 contextual information."
2328 ;; (let ((ent (org-element-get-property :latex entity)))
2329 ;; (if (org-element-get-property :latex-math-p entity)
2330 ;; (format "$%s$" ent)
2331 ;; ent))
2332 (org-element-get-property :html entity))
2335 ;;;; Example Block
2338 ;; (defun org-odt-format-source-code-or-example-colored
2339 ;; (lines lang caption textareap cols rows num cont rpllbl fmt))
2341 (defun org-e-html-format-source-code-or-example-plain
2342 (lines lang caption textareap cols rows num cont rpllbl fmt)
2343 (setq lines
2344 (concat
2345 "<pre class=\"example\">\n"
2346 (cond
2347 (textareap
2348 (concat
2349 (format "<p>\n<textarea cols=\"%d\" rows=\"%d\">"
2350 cols rows)
2351 lines "</textarea>\n</p>\n"))
2353 (with-temp-buffer
2354 (insert lines)
2355 (goto-char (point-min))
2356 (while (re-search-forward "[<>&]" nil t)
2357 (replace-match (cdr (assq (char-before)
2358 '((?&."&amp;")(?<."&lt;")(?>."&gt;"))))
2359 t t))
2360 (buffer-string))))
2361 "</pre>\n"))
2363 (unless textareap
2364 (setq lines (org-export-number-lines lines 1 1 num cont rpllbl fmt)))
2366 ;; (when (string-match "\\(\\`<[^>]*>\\)\n" lines)
2367 ;; (setq lines (replace-match "\\1" t nil lines)))
2369 lines)
2371 (defun org-e-html-format-source-code-or-example-colored
2372 (lines lang caption textareap cols rows num cont rpllbl fmt)
2373 (let* ((lang-m (when lang
2374 (or (cdr (assoc lang org-src-lang-modes))
2375 lang)))
2376 (mode (and lang-m (intern
2377 (concat
2378 (if (symbolp lang-m)
2379 (symbol-name lang-m)
2380 lang-m)
2381 "-mode"))))
2382 (org-inhibit-startup t)
2383 (org-startup-folded nil))
2384 (setq lines
2385 (with-temp-buffer
2386 (insert lines)
2387 (if (functionp mode)
2388 (funcall mode)
2389 (fundamental-mode))
2390 (font-lock-fontify-buffer)
2391 ;; markup each line separately
2392 (org-remove-formatting-on-newlines-in-region
2393 (point-min) (point-max))
2394 (org-src-mode)
2395 (set-buffer-modified-p nil)
2396 (org-export-e-htmlize-region-for-paste
2397 (point-min) (point-max))))
2399 (when (string-match "<pre\\([^>]*\\)>\n*" lines)
2400 (setq lines (replace-match
2401 (format "<pre class=\"src src-%s\">\n" lang) t t lines)))
2403 (when caption
2404 (setq lines
2405 (concat
2406 "<div class=\"org-src-container\">"
2407 (format "<label class=\"org-src-name\">%s</label>" caption)
2408 lines "</div>")))
2410 (unless textareap
2411 (setq lines (org-export-number-lines lines 1 1 num cont rpllbl fmt)))
2413 ;; (when (string-match "\\(\\`<[^>]*>\\)\n" lines)
2414 ;; (setq lines (replace-match "\\1" t nil lines)))
2415 lines))
2417 (defun org-e-html-format-source-code-or-example
2418 (lang code &optional opts indent caption)
2419 "Format CODE from language LANG and return it formatted for export.
2420 The CODE is marked up in `org-export-current-backend' format.
2422 Check if a function by name
2423 \"org-<backend>-format-source-code-or-example\" is bound. If yes,
2424 use it as the custom formatter. Otherwise, use the default
2425 formatter. Default formatters are provided for docbook, html,
2426 latex and ascii backends. For example, use
2427 `org-e-html-format-source-code-or-example' to provide a custom
2428 formatter for export to \"html\".
2430 If LANG is nil, do not add any fontification.
2431 OPTS contains formatting options, like `-n' for triggering numbering lines,
2432 and `+n' for continuing previous numbering.
2433 Code formatting according to language currently only works for HTML.
2434 Numbering lines works for all three major backends (html, latex, and ascii).
2435 INDENT was the original indentation of the block."
2436 (save-match-data
2437 (let* ((backend-formatter 'org-e-html-format-source-code-or-example-plain)
2438 num cont rtn rpllbl keepp textareap preserve-indentp cols rows fmt)
2439 (setq opts (or opts "")
2440 num (string-match "[-+]n\\>" opts)
2441 cont (string-match "\\+n\\>" opts)
2442 rpllbl (string-match "-r\\>" opts)
2443 keepp (string-match "-k\\>" opts)
2444 textareap (string-match "-t\\>" opts)
2445 preserve-indentp (or org-src-preserve-indentation
2446 (string-match "-i\\>" opts))
2447 cols (if (string-match "-w[ \t]+\\([0-9]+\\)" opts)
2448 (string-to-number (match-string 1 opts))
2450 rows (if (string-match "-h[ \t]+\\([0-9]+\\)" opts)
2451 (string-to-number (match-string 1 opts))
2452 (org-count-lines code))
2453 fmt (if (string-match "-l[ \t]+\"\\([^\"\n]+\\)\"" opts)
2454 (match-string 1 opts)))
2455 (when (and textareap
2456 ;; (eq org-export-current-backend 'html)
2458 ;; we cannot use numbering or highlighting.
2459 (setq num nil cont nil lang nil))
2460 (if keepp (setq rpllbl 'keep))
2461 (setq rtn (if preserve-indentp code (org-remove-indentation code)))
2462 (when (string-match "^," rtn)
2463 (setq rtn (with-temp-buffer
2464 (insert rtn)
2465 ;; Free up the protected lines
2466 (goto-char (point-min))
2467 (while (re-search-forward "^," nil t)
2468 (if (or (equal lang "org")
2469 (save-match-data
2470 (looking-at "\\([*#]\\|[ \t]*#\\+\\)")))
2471 (replace-match ""))
2472 (end-of-line 1))
2473 (buffer-string))))
2474 (when lang
2475 (if (featurep 'xemacs)
2476 (require 'htmlize)
2477 (require 'htmlize nil t)))
2479 (setq backend-formatter
2480 (cond
2481 ((fboundp 'htmlize-region-for-paste)
2482 'org-e-html-format-source-code-or-example-colored)
2484 (message
2485 "htmlize.el 1.34 or later is needed for source code formatting")
2486 'org-e-html-format-source-code-or-example-plain)))
2487 (funcall backend-formatter rtn lang caption textareap cols rows
2488 num cont rpllbl fmt))))
2490 (defun org-e-html-example-block (example-block contents info)
2491 "Transcode a EXAMPLE-BLOCK element from Org to HTML.
2492 CONTENTS is nil. INFO is a plist holding contextual information."
2493 (let* ((options (or (org-element-get-property :options example-block) ""))
2494 (value (org-export-handle-code example-block info)))
2495 ;; (org-e-html--wrap-label
2496 ;; example-block (format "\\begin{verbatim}\n%s\\end{verbatim}" value))
2497 (org-e-html--wrap-label
2498 example-block (org-e-html-format-source-code-or-example nil value))))
2501 ;;;; Export Snippet
2503 (defun org-e-html-export-snippet (export-snippet contents info)
2504 "Transcode a EXPORT-SNIPPET object from Org to HTML.
2505 CONTENTS is nil. INFO is a plist holding contextual information."
2506 (org-element-get-property :value export-snippet))
2509 ;;;; Export Block
2511 (defun org-e-html-export-block (export-block contents info)
2512 "Transcode a EXPORT-BLOCK element from Org to HTML.
2513 CONTENTS is nil. INFO is a plist holding contextual information."
2514 (when (string= (org-element-get-property :type export-block) "latex")
2515 (org-remove-indentation (org-element-get-property :value export-block))))
2518 ;;;; Fixed Width
2520 (defun org-e-html-fixed-width (fixed-width contents info)
2521 "Transcode a FIXED-WIDTH element from Org to HTML.
2522 CONTENTS is nil. INFO is a plist holding contextual information."
2523 (let* ((value (org-element-normalize-string
2524 (replace-regexp-in-string
2525 "^[ \t]*: ?" ""
2526 (org-element-get-property :value fixed-width)))))
2527 (org-e-html--wrap-label
2528 fixed-width (org-e-html-format-source-code-or-example nil value))))
2531 ;;;; Footnote Definition
2533 ;; Footnote Definitions are ignored.
2536 ;;;; Footnote Reference
2538 (defun org-e-html-footnote-reference (footnote-reference contents info)
2539 "Transcode a FOOTNOTE-REFERENCE element from Org to HTML.
2540 CONTENTS is nil. INFO is a plist holding contextual information."
2541 (concat
2542 ;; Insert separator between two footnotes in a row.
2543 (let ((prev (org-export-get-previous-element footnote-reference info)))
2544 (when (and (listp prev) (eq (car prev) 'footnote-reference))
2545 org-e-html-footnote-separator))
2546 (cond
2547 ((not (org-export-footnote-first-reference-p footnote-reference info))
2548 (org-e-html-format-footnote-reference
2549 (org-export-get-footnote-number footnote-reference info)
2550 "FIXME" 100))
2551 ;; Inline definitions are secondary strings.
2552 ((eq (org-element-get-property :type footnote-reference) 'inline)
2553 (let ((n (org-export-get-footnote-number footnote-reference info))
2554 (def (format
2555 "<p>%s</p>"
2556 (org-trim
2557 (org-export-secondary-string
2558 (org-export-get-footnote-definition footnote-reference info)
2559 'e-html info)))))
2560 (push (cons n def) org-e-html-footnotes-alist)
2561 (org-e-html-format-footnote-reference n def 1)))
2562 ;; Non-inline footnotes definitions are full Org data.
2564 (let ((n (org-export-get-footnote-number footnote-reference info))
2565 (def (org-trim
2566 (org-export-data
2567 (org-export-get-footnote-definition footnote-reference info)
2568 'e-html info))))
2570 (push (cons n def) org-e-html-footnotes-alist)
2571 (org-e-html-format-footnote-reference n def 1))))))
2574 ;;;; Headline
2576 (defun org-e-html-todo (todo)
2577 (when todo
2578 (org-e-html-format-fontify
2579 (concat
2580 ;; (ignore-errors (org-lparse-get 'TODO-KWD-CLASS-PREFIX))
2581 org-e-html-todo-kwd-class-prefix
2582 (org-e-html-fix-class-name todo))
2583 (list (if (member todo org-done-keywords) "done" "todo")
2584 todo))))
2586 (defun org-e-html-headline (headline contents info)
2587 "Transcode an HEADLINE element from Org to HTML.
2588 CONTENTS holds the contents of the headline. INFO is a plist
2589 holding contextual information."
2590 (let* ((class (plist-get info :latex-class))
2591 (numberedp (plist-get info :section-numbers))
2592 ;; Get level relative to current parsed data.
2593 (level (org-export-get-relative-level headline info))
2594 ;; (class-sectionning (assoc class org-e-html-classes))
2595 ;; Section formatting will set two placeholders: one for the
2596 ;; title and the other for the contents.
2597 ;; (section-fmt
2598 ;; (let ((sec (if (and (symbolp (nth 2 class-sectionning))
2599 ;; (fboundp (nth 2 class-sectionning)))
2600 ;; (funcall (nth 2 class-sectionning) level numberedp)
2601 ;; (nth (1+ level) class-sectionning))))
2602 ;; (cond
2603 ;; ;; No section available for that LEVEL.
2604 ;; ((not sec) nil)
2605 ;; ;; Section format directly returned by a function.
2606 ;; ((stringp sec) sec)
2607 ;; ;; (numbered-section . unnumbered-section)
2608 ;; ((not (consp (cdr sec)))
2609 ;; (concat (funcall (if numberedp #'car #'cdr) sec) "\n%s"))
2610 ;; ;; (numbered-open numbered-close)
2611 ;; ((= (length sec) 2)
2612 ;; (when numberedp (concat (car sec) "\n%s" (nth 1 sec))))
2613 ;; ;; (num-in num-out no-num-in no-num-out)
2614 ;; ((= (length sec) 4)
2615 ;; (if numberedp
2616 ;; (concat (car sec) "\n%s" (nth 1 sec))
2617 ;; (concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
2618 (text (org-export-secondary-string
2619 (org-element-get-property :title headline) 'e-html info))
2620 (todo (and (plist-get info :with-todo-keywords)
2621 (let ((todo (org-element-get-property
2622 :todo-keyword headline)))
2623 (and todo
2624 (org-export-secondary-string todo 'e-html info)))))
2625 (todo-type (and todo (org-element-get-property :todo-type headline)))
2626 (tags (and (plist-get info :with-tags)
2627 (org-element-get-property :tags headline)))
2628 (priority (and (plist-get info :with-priority)
2629 (org-element-get-property :priority headline)))
2630 ;; Create the headline text.
2631 (full-text (if (functionp org-e-html-format-headline-function)
2632 ;; User-defined formatting function.
2633 (funcall org-e-html-format-headline-function
2634 todo todo-type priority text tags)
2635 ;; Default formatting.
2636 (concat
2637 ;; (when todo
2638 ;; (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
2639 (org-e-html-todo todo) " "
2640 (when priority (format "\\framebox{\\#%c} " priority))
2641 text
2642 ;; (when tags (format "\\hfill{}\\textsc{%s}" tags))
2644 ;; Associate some \label to the headline for internal links.
2645 ;; (headline-label
2646 ;; (format "\\label{sec-%s}\n"
2647 ;; (mapconcat 'number-to-string
2648 ;; (org-export-get-headline-number headline info)
2649 ;; "-")))
2651 ;; FIXME - begin
2652 (headline-no (org-export-get-headline-number headline info))
2653 (headline-label
2654 (format "sec-%s" (mapconcat 'number-to-string headline-no "-")))
2655 (headline-labels (list headline-label))
2656 (headline-no (org-export-get-headline-number headline info))
2657 (section-no (mapconcat 'number-to-string headline-no "."))
2658 ;; FIXME - end
2660 (pre-blanks (make-string
2661 (org-element-get-property :pre-blank headline) 10)))
2662 (cond
2663 ;; Case 1: This is a footnote section: ignore it.
2664 ((org-element-get-property :footnote-section-p headline) nil)
2665 ;; Case 2. This is a deep sub-tree: export it as a list item.
2666 ;; Also export as items headlines for which no section
2667 ;; format has been found.
2668 ;; ((or (not section-fmt) (org-export-low-level-p headline info)) FIXME
2669 ;; ;; Build the real contents of the sub-tree.
2670 ;; (let ((low-level-body
2671 ;; (concat
2672 ;; ;; If the headline is the first sibling, start a list.
2673 ;; (when (org-export-first-sibling-p headline info)
2674 ;; (format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize)))
2675 ;; ;; Itemize headline
2676 ;; "\\item " full-text "\n" headline-label pre-blanks contents)))
2677 ;; ;; If headline in the last sibling, close the list, before any
2678 ;; ;; blank line. Otherwise, simply return LOW-LEVEL-BODY.
2679 ;; (if (org-export-last-sibling-p headline info)
2680 ;; (replace-regexp-in-string
2681 ;; "[ \t\n]*\\'"
2682 ;; (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
2683 ;; low-level-body)
2684 ;; low-level-body)))
2685 ;; Case 3. Standard headline. Export it as a section.
2687 ;; (format section-fmt full-text
2688 ;; (concat headline-label pre-blanks contents))
2690 (org-e-html-format-outline contents level section-no full-text tags
2691 (car (last headline-labels))
2692 (butlast headline-labels) nil)))))
2695 ;;;; Horizontal Rule
2697 (defun org-e-html-horizontal-rule (horizontal-rule contents info)
2698 "Transcode an HORIZONTAL-RULE object from Org to HTML.
2699 CONTENTS is nil. INFO is a plist holding contextual information."
2700 (let ((attr (mapconcat #'identity
2701 (org-element-get-property :attr_html horizontal-rule)
2702 " ")))
2703 (org-e-html--wrap-label horizontal-rule
2704 (org-e-html-format-horizontal-line))))
2707 ;;;; Inline Babel Call
2709 ;; Inline Babel Calls are ignored.
2712 ;;;; Inline Src Block
2714 (defun org-e-html-inline-src-block (inline-src-block contents info)
2715 "Transcode an INLINE-SRC-BLOCK element from Org to HTML.
2716 CONTENTS holds the contents of the item. INFO is a plist holding
2717 contextual information."
2718 (let* ((org-lang (org-element-get-property :language inline-src-block))
2719 (code (org-element-get-property :value inline-src-block))
2720 (separator (org-e-html--find-verb-separator code)))
2721 (error "FIXME")))
2724 ;;;; Inlinetask
2726 (defun org-e-html-format-section (text class &optional id)
2727 (let ((extra (concat (when id (format " id=\"%s\"" id)))))
2728 (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
2730 (defun org-e-html-inlinetask (inlinetask contents info)
2731 "Transcode an INLINETASK element from Org to HTML.
2732 CONTENTS holds the contents of the block. INFO is a plist
2733 holding contextual information."
2734 (let ((title (org-export-secondary-string
2735 (org-element-get-property :title inlinetask) 'e-html info))
2736 (todo (and (plist-get info :with-todo-keywords)
2737 (let ((todo (org-element-get-property
2738 :todo-keyword inlinetask)))
2739 (and todo
2740 (org-export-secondary-string todo 'e-html info)))))
2741 (todo-type (org-element-get-property :todo-type inlinetask))
2742 (tags (and (plist-get info :with-tags)
2743 (org-element-get-property :tags inlinetask)))
2744 (priority (and (plist-get info :with-priority)
2745 (org-element-get-property :priority inlinetask))))
2746 ;; If `org-e-html-format-inlinetask-function' is provided, call it
2747 ;; with appropriate arguments.
2748 (if (functionp org-e-html-format-inlinetask-function)
2749 (funcall org-e-html-format-inlinetask-function
2750 todo todo-type priority title tags contents)
2751 ;; Otherwise, use a default template.
2752 (org-e-html--wrap-label
2753 inlinetask
2754 (let ((full-title
2755 (concat
2756 (when todo (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
2757 (when priority (format "\\framebox{\\#%c} " priority))
2758 title
2759 (when tags (format "\\hfill{}\\textsc{%s}" tags)))))
2760 (format (concat "\\begin{center}\n"
2761 "\\fbox{\n"
2762 "\\begin{minipage}[c]{.6\\textwidth}\n"
2763 "%s\n\n"
2764 "\\rule[.8em]{\\textwidth}{2pt}\n\n"
2765 "%s"
2766 "\\end{minipage}\n"
2767 "}\n"
2768 "\\end{center}")
2769 full-title contents))))))
2772 ;;;; Item
2774 (defun org-e-html-format-list-item (contents type &optional arg headline)
2775 (setq headline nil) ; FIXME
2776 (concat
2777 (case type
2778 (ordered
2779 (let* ((counter arg)
2780 (extra (if counter (format " value=\"%s\"" counter) "")))
2781 (format "<li%s>" extra)))
2782 (unordered
2783 (let* ((id arg)
2784 (extra (if id (format " id=\"%s\"" id) "")))
2785 (concat
2786 (format "<li%s>" extra)
2787 (when headline (concat headline "<br/>")))))
2788 (descriptive
2789 (let* ((desc-tag (or arg "(no term)")))
2790 (concat (format "<dt> %s </dt>" desc-tag) "<dd>"))))
2791 contents
2792 (case type
2793 (ordered "</li>")
2794 (unordered "</li>")
2795 (descriptive "</dd>"))))
2797 (defun org-e-html-item (item contents info)
2798 "Transcode an ITEM element from Org to HTML.
2799 CONTENTS holds the contents of the item. INFO is a plist holding
2800 contextual information."
2801 ;; Grab `:level' from plain-list properties, which is always the
2802 ;; first element above current item.
2803 (let* ((plain-list (car (org-export-get-genealogy item info)))
2804 (type (org-element-get-property :type plain-list))
2805 (level (org-element-get-property
2806 :level (car (plist-get info :genealogy))))
2807 (counter (let ((count (org-element-get-property :counter item)))
2808 (and count
2809 (< level 4)
2810 (format "\\setcounter{enum%s}{%s}\n"
2811 (nth level '("i" "ii" "iii" "iv"))
2812 (1- count)))))
2813 (checkbox (let ((checkbox (org-element-get-property :checkbox item)))
2814 (cond ((eq checkbox 'on) "$\\boxtimes$ ")
2815 ((eq checkbox 'off) "$\\Box$ ")
2816 ((eq checkbox 'trans) "$\\boxminus$ "))))
2817 (tag (let ((tag (org-element-get-property :tag item)))
2818 (and tag
2819 (format "[%s]" (org-export-secondary-string
2820 tag 'e-html info))))))
2821 ;; (concat counter "\\item" tag " " checkbox contents)
2823 (org-e-html-format-list-item contents type nil)))
2826 ;;;; Keyword
2828 (defun org-e-html-keyword (keyword contents info)
2829 "Transcode a KEYWORD element from Org to HTML.
2830 CONTENTS is nil. INFO is a plist holding contextual information."
2831 (let ((key (downcase (org-element-get-property :key keyword)))
2832 (value (org-element-get-property :value keyword)))
2833 (cond
2834 ((string= key "latex") value)
2835 ((string= key "index") (format "\\index{%s}" value))
2836 ((string= key "target")
2837 (format "\\label{%s}" (org-export-solidify-link-text value)))
2838 ((string= key "toc")
2839 (let ((value (downcase value)))
2840 (cond
2841 ((string-match "\\<headlines\\>" value)
2842 (let ((depth (or (and (string-match "[0-9]+" value)
2843 (string-to-number (match-string 0 value)))
2844 (plist-get info :with-toc))))
2845 (concat
2846 (when (wholenump depth)
2847 (format "\\setcounter{tocdepth}{%s}\n" depth))
2848 "\\tableofcontents")))
2849 ((string= "tables" value) "\\listoftables")
2850 ((string= "figures" value) "\\listoffigures")
2851 ((string= "listings" value)
2852 (cond
2853 ;; At the moment, src blocks with a caption are wrapped
2854 ;; into a figure environment.
2855 (t "\\listoffigures")))))))))
2858 ;;;; Latex Environment
2860 (defun org-e-html-format-latex (latex-frag processing-type)
2861 (let* ((cache-relpath
2862 (concat "ltxpng/" (file-name-sans-extension
2863 (file-name-nondirectory (buffer-file-name)))))
2864 (cache-dir (file-name-directory (buffer-file-name )))
2865 (display-msg "Creating LaTeX Image..."))
2867 (with-temp-buffer
2868 (insert latex-frag)
2869 (org-format-latex cache-relpath cache-dir nil display-msg
2870 nil nil processing-type)
2871 (buffer-string))))
2873 (defun org-e-html-latex-environment (latex-environment contents info)
2874 "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
2875 CONTENTS is nil. INFO is a plist holding contextual information."
2876 (org-e-html--wrap-label
2877 latex-environment
2878 (let ((latex-frag
2879 (org-remove-indentation
2880 (org-element-get-property :value latex-environment)))
2881 (processing-type (plist-get info :LaTeX-fragments)))
2882 (cond
2883 ((member processing-type '(t mathjax))
2884 (org-e-html-format-latex latex-frag 'mathjax))
2885 ((equal processing-type 'dvipng)
2886 (let* ((formula-link (org-e-html-format-latex
2887 latex-frag processing-type)))
2888 (when (and formula-link
2889 (string-match "file:\\([^]]*\\)" formula-link))
2890 (org-e-html-format-inline-image (match-string 1 formula-link)))))
2892 latex-frag)))))
2895 ;;;; Latex Fragment
2897 (defun org-e-html-latex-fragment (latex-fragment contents info)
2898 "Transcode a LATEX-FRAGMENT object from Org to HTML.
2899 CONTENTS is nil. INFO is a plist holding contextual information."
2900 ;; (org-element-get-property :value latex-fragment)
2901 (let* ((latex-frag (org-element-get-property :value latex-fragment)))
2902 (cond
2903 ((string-match "\\\\ref{\\([^{}\n]+\\)}" latex-frag)
2904 (let* ((label (match-string 1 latex-frag))
2905 (href (and label (org-export-solidify-link-text label)))
2906 (text (if (string-match "\\`[a-z]\\{1,10\\}:\\(.+\\)" label)
2907 (substring label (match-beginning 1))
2908 label)))
2909 (org-e-html-format-internal-link text href)))
2910 (t (let ((processing-type (plist-get info :LaTeX-fragments)))
2911 (cond
2912 ((member processing-type '(t mathjax))
2913 (org-e-html-format-latex latex-frag 'mathjax))
2914 ((equal processing-type 'dvipng)
2915 (let* ((formula-link (org-e-html-format-latex
2916 latex-frag processing-type)))
2917 (when (and formula-link
2918 (string-match "file:\\([^]]*\\)" formula-link))
2919 (org-e-html-format-inline-image
2920 (match-string 1 formula-link)))))
2921 (t latex-frag)))))))
2924 ;;;; Line Break
2926 (defun org-e-html-line-break (line-break contents info)
2927 "Transcode a LINE-BREAK object from Org to HTML.
2928 CONTENTS is nil. INFO is a plist holding contextual information."
2929 "<br/>")
2932 ;;;; Link
2934 (defun org-e-html-link--inline-image (link info)
2935 "Return HTML code for an inline image.
2936 LINK is the link pointing to the inline image. INFO is a plist
2937 used as a communication channel."
2938 (let* ((parent (org-export-get-parent-paragraph link info))
2939 (path (let ((raw-path (org-element-get-property :path link)))
2940 (if (not (file-name-absolute-p raw-path)) raw-path
2941 (expand-file-name raw-path))))
2942 (caption (org-e-html--caption/label-string
2943 (org-element-get-property :caption parent)
2944 (org-element-get-property :name parent)
2945 info))
2946 (label (org-element-get-property :name parent))
2947 ;; Retrieve latex attributes from the element around.
2948 (attr (let ((raw-attr
2949 (mapconcat #'identity
2950 (org-element-get-property :attr_html parent)
2951 " ")))
2952 (unless (string= raw-attr "") raw-attr))))
2953 ;; Now clear ATTR from any special keyword and set a default
2954 ;; value if nothing is left.
2955 (setq attr (if (not attr) "" (org-trim attr)))
2956 ;; Return proper string, depending on DISPOSITION.
2957 (let ((href (and label (org-export-solidify-link-text label))))
2958 (org-e-html-format-inline-image path caption href attr))))
2960 (defun org-e-html-link (link desc info)
2961 "Transcode a LINK object from Org to HTML.
2963 DESC is the description part of the link, or the empty string.
2964 INFO is a plist holding contextual information. See
2965 `org-export-data'."
2966 (let* ((type (org-element-get-property :type link))
2967 (raw-path (org-element-get-property :path link))
2968 ;; Ensure DESC really exists, or set it to nil.
2969 (desc (and (not (string= desc "")) desc))
2970 (imagep (org-export-inline-image-p
2971 link org-e-html-inline-image-rules))
2972 (path (cond
2973 ((member type '("http" "https" "ftp" "mailto"))
2974 (concat type ":" raw-path))
2975 ((string= type "file")
2976 (when (string-match "\\(.+\\)::.+" raw-path)
2977 (setq raw-path (match-string 1 raw-path)))
2978 (if (file-name-absolute-p raw-path)
2979 (concat "file://" (expand-file-name raw-path))
2980 ;; TODO: Not implemented yet. Concat also:
2981 ;; (org-export-directory :HTML info)
2982 (concat "file://" raw-path)))
2983 (t raw-path)))
2984 protocol)
2985 (cond
2986 ;; Image file.
2987 (imagep (org-e-html-link--inline-image link info))
2988 ;; Target or radioed target: replace link with the normalized
2989 ;; custom-id/target name.
2990 ((member type '("target" "radio"))
2991 (org-e-html-format-internal-link
2992 (or desc (org-export-secondary-string path 'e-html info))
2993 (org-export-solidify-link-text path)))
2994 ;; Links pointing to an headline: Find destination and build
2995 ;; appropriate referencing commanding.
2996 ((member type '("custom-id" "fuzzy" "id"))
2997 (let ((destination (if (string= type "fuzzy")
2998 (org-export-resolve-fuzzy-link link info)
2999 (org-export-resolve-id-link link info))))
3000 ;; Fuzzy link points to a target. Do as above.
3001 (case (car destination)
3002 (target
3003 (org-e-html-format-internal-link
3004 (or desc
3005 (org-export-secondary-string
3006 (org-element-get-property :raw-link link)
3007 'e-html info))
3008 (org-export-solidify-link-text
3009 (org-element-get-property :raw-value destination))))
3010 ;; Fuzzy link points to an headline. If headlines are
3011 ;; numbered and the link has no description, display
3012 ;; headline's number. Otherwise, display description or
3013 ;; headline's title.
3014 (headline
3015 (let ((label
3016 (format "sec-%s"
3017 (mapconcat
3018 'number-to-string
3019 (org-export-get-headline-number destination info)
3020 "-"))))
3021 (if (and (plist-get info :section-numbers) (not desc))
3022 (format "\\ref{%s}" label)
3023 (org-e-html-format-internal-link
3024 (or desc
3025 (org-export-secondary-string
3026 (org-element-get-property :title destination)
3027 'e-html info)) label))))
3028 ;; Fuzzy link points nowhere.
3029 (otherwise
3030 (org-e-html-format-fontify
3031 (or desc
3032 (org-export-secondary-string
3033 (org-element-get-property :raw-link link)
3034 'e-html info)) 'emphasis)))))
3035 ;; Coderef: replace link with the reference name or the
3036 ;; equivalent line number.
3037 ((string= type "coderef")
3038 (format (org-export-get-coderef-format path (or desc ""))
3039 (org-export-resolve-coderef path info)))
3040 ;; Link type is handled by a special function.
3041 ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
3042 (funcall protocol (org-link-unescape path) desc 'html))
3043 ;; External link with a description part.
3044 ((and path desc) (org-e-html-format-link desc path))
3045 ;; External link without a description part.
3046 (path (org-e-html-format-link path path))
3047 ;; No path, only description. Try to do something useful.
3048 (t (org-e-html-format-fontify desc 'emphasis)))))
3051 ;;;; Babel Call
3053 ;; Babel Calls are ignored.
3056 ;;;; Macro
3058 (defun org-e-html-macro (macro contents info)
3059 "Transcode a MACRO element from Org to HTML.
3060 CONTENTS is nil. INFO is a plist holding contextual information."
3061 ;; Use available tools.
3062 (org-export-expand-macro macro info))
3065 ;;;; Paragraph
3067 (defun org-e-html-paragraph (paragraph contents info)
3068 "Transcode a PARAGRAPH element from Org to HTML.
3069 CONTENTS is the contents of the paragraph, as a string. INFO is
3070 the plist used as a communication channel."
3071 (let* ((style nil) ; FIXME
3072 (class (cdr (assoc style '((footnote . "footnote")
3073 (verse . nil)))))
3074 (extra (if class (format " class=\"%s\"" class) ""))
3075 (parent (car (org-export-get-genealogy paragraph info))))
3076 (cond
3077 ;; is this the first paragraph in a list item
3080 ;; (plain-list (car (org-export-get-genealogy item info)))
3081 ;; (type (org-element-get-property :type plain-list))
3083 ((and (equal parent 'item)
3084 (= (org-element-get-property :begin paragraph)
3085 (plist-get (plist-get info :parent-properties)
3086 :contents-begin)))
3087 contents)
3089 (concat (format "<p%s> " extra) contents "</p>")))))
3092 ;;;; Plain List
3094 (defun org-e-html-plain-list (plain-list contents info)
3095 "Transcode a PLAIN-LIST element from Org to HTML.
3096 CONTENTS is the contents of the list. INFO is a plist holding
3097 contextual information."
3098 (let* ((type (org-element-get-property :type plain-list))
3099 (paralist-types '("inparaenum" "asparaenum" "inparaitem" "asparaitem"
3100 "inparadesc" "asparadesc"))
3101 (paralist-regexp (concat
3102 "\\("
3103 (mapconcat 'identity paralist-types "\\|")
3104 "\\)"))
3105 (attr (mapconcat #'identity
3106 (org-element-get-property :attr_html plain-list)
3107 " "))
3108 (latex-type (cond
3109 ((and attr
3110 (string-match
3111 (format "\\<%s\\>" paralist-regexp) attr))
3112 (match-string 1 attr))
3113 ((eq type 'ordered) "enumerate")
3114 ((eq type 'unordered) "itemize")
3115 ((eq type 'descriptive) "description")))
3116 arg1 ;; FIXME
3118 (org-e-html--wrap-label
3119 plain-list
3120 ;; (format "\\begin{%s}%s\n%s\\end{%s}"
3121 ;; latex-type
3122 ;; ;; Once special environment, if any, has been removed, the
3123 ;; ;; rest of the attributes will be optional arguments.
3124 ;; ;; They will be put inside square brackets if necessary.
3125 ;; (let ((opt (replace-regexp-in-string
3126 ;; (format " *%s *" paralist-regexp) "" attr)))
3127 ;; (cond ((string= opt "") "")
3128 ;; ((string-match "\\`\\[[^][]+\\]\\'" opt) opt)
3129 ;; (t (format "[%s]" opt))))
3130 ;; contents
3131 ;; latex-type)
3133 (format "%s\n%s%s"
3134 (case type
3135 (ordered
3136 (format "<ol%s>" (if arg1
3137 (format " start=\"%d\"" arg1)
3138 "")))
3139 (unordered "<ul>")
3140 (descriptive "<dl>"))
3141 contents
3142 (case type
3143 (ordered "</ol>")
3144 (unordered "</ul>")
3145 (descriptive "</dl>")))
3151 ;;;; Plain Text
3153 (defun org-e-html-convert-special-strings (string)
3154 "Convert special characters in STRING to HTML."
3155 (let ((all org-e-html-special-string-regexps)
3156 e a re rpl start)
3157 (while (setq a (pop all))
3158 (setq re (car a) rpl (cdr a) start 0)
3159 (while (string-match re string start)
3160 (setq string (replace-match rpl t nil string))))
3161 string))
3163 (defun org-e-html-encode-plain-text (s)
3164 "Convert plain text characters to HTML equivalent.
3165 Possible conversions are set in `org-export-html-protect-char-alist'."
3166 (let ((cl org-e-html-protect-char-alist) c)
3167 (while (setq c (pop cl))
3168 (let ((start 0))
3169 (while (string-match (car c) s start)
3170 (setq s (replace-match (cdr c) t t s)
3171 start (1+ (match-beginning 0))))))
3174 (defun org-e-html-plain-text (text info)
3175 "Transcode a TEXT string from Org to HTML.
3176 TEXT is the string to transcode. INFO is a plist holding
3177 contextual information."
3178 (setq text (org-e-html-encode-plain-text text))
3179 ;; Protect %, #, &, $, ~, ^, _, { and }.
3180 ;; (while (string-match "\\([^\\]\\|^\\)\\([%$#&{}~^_]\\)" text)
3181 ;; (setq text
3182 ;; (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
3183 ;; Protect \
3184 ;; (setq text (replace-regexp-in-string
3185 ;; "\\(?:[^\\]\\|^\\)\\(\\\\\\)\\(?:[^%$#&{}~^_\\]\\|$\\)"
3186 ;; "$\\backslash$" text nil t 1))
3187 ;; HTML into \HTML{} and TeX into \TeX{}.
3188 ;; (let ((case-fold-search nil)
3189 ;; (start 0))
3190 ;; (while (string-match "\\<\\(\\(?:La\\)?TeX\\)\\>" text start)
3191 ;; (setq text (replace-match
3192 ;; (format "\\%s{}" (match-string 1 text)) nil t text)
3193 ;; start (match-end 0))))
3194 ;; Handle quotation marks
3195 ;; (setq text (org-e-html--quotation-marks text info))
3196 ;; Convert special strings.
3197 ;; (when (plist-get info :with-special-strings)
3198 ;; (while (string-match (regexp-quote "...") text)
3199 ;; (setq text (replace-match "\\ldots{}" nil t text))))
3200 (when (plist-get info :with-special-strings)
3201 (setq text (org-e-html-convert-special-strings text)))
3202 ;; Handle break preservation if required.
3203 (when (plist-get info :preserve-breaks)
3204 (setq text (replace-regexp-in-string "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
3205 text)))
3206 ;; Return value.
3207 text)
3210 ;;;; Property Drawer
3212 (defun org-e-html-property-drawer (property-drawer contents info)
3213 "Transcode a PROPERTY-DRAWER element from Org to HTML.
3214 CONTENTS is nil. INFO is a plist holding contextual
3215 information."
3216 ;; The property drawer isn't exported but we want separating blank
3217 ;; lines nonetheless.
3221 ;;;; Quote Block
3223 (defun org-e-html-quote-block (quote-block contents info)
3224 "Transcode a QUOTE-BLOCK element from Org to HTML.
3225 CONTENTS holds the contents of the block. INFO is a plist
3226 holding contextual information."
3227 (org-e-html--wrap-label
3228 quote-block (format "<blockquote>\n%s</blockquote>" contents)))
3231 ;;;; Quote Section
3233 (defun org-e-html-quote-section (quote-section contents info)
3234 "Transcode a QUOTE-SECTION element from Org to HTML.
3235 CONTENTS is nil. INFO is a plist holding contextual information."
3236 (let ((value (org-remove-indentation
3237 (org-element-get-property :value quote-section))))
3238 (when value (format "<pre>\n%s</pre>" value))))
3241 ;;;; Section
3243 (defun org-e-html-section (section contents info)
3244 "Transcode a SECTION element from Org to HTML.
3245 CONTENTS holds the contents of the section. INFO is a plist
3246 holding contextual information."
3247 contents)
3250 ;;;; Radio Target
3252 (defun org-e-html-radio-target (radio-target text info)
3253 "Transcode a RADIO-TARGET object from Org to HTML.
3254 TEXT is the text of the target. INFO is a plist holding
3255 contextual information."
3256 (org-e-html-format-anchor
3257 text (org-export-solidify-link-text
3258 (org-element-get-property :raw-value radio-target))))
3261 ;;;; Special Block
3263 (defun org-e-html-special-block (special-block contents info)
3264 "Transcode a SPECIAL-BLOCK element from Org to HTML.
3265 CONTENTS holds the contents of the block. INFO is a plist
3266 holding contextual information."
3267 (let ((type (downcase (org-element-get-property :type special-block))))
3268 (org-e-html--wrap-label
3269 special-block
3270 (format "\\begin{%s}\n%s\\end{%s}" type contents type))))
3273 ;;;; Src Block
3275 (defun org-e-html-src-block (src-block contents info)
3276 "Transcode a SRC-BLOCK element from Org to HTML.
3277 CONTENTS holds the contents of the item. INFO is a plist holding
3278 contextual information."
3279 (let* ((lang (org-element-get-property :language src-block))
3280 (code (org-export-handle-code src-block info))
3281 (caption (org-element-get-property :caption src-block))
3282 (label (org-element-get-property :name src-block)))
3283 ;; FIXME: Handle caption
3285 ;; caption-str (when caption)
3286 ;; (main (org-export-secondary-string (car caption) 'e-html info))
3287 ;; (secondary (org-export-secondary-string (cdr caption) 'e-html info))
3288 ;; (caption-str (org-e-html--caption/label-string caption label info))
3289 (org-e-html-format-source-code-or-example lang code)))
3292 ;;;; Statistics Cookie
3294 (defun org-e-html-statistics-cookie (statistics-cookie contents info)
3295 "Transcode a STATISTICS-COOKIE object from Org to HTML.
3296 CONTENTS is nil. INFO is a plist holding contextual information."
3297 (org-element-get-property :value statistics-cookie))
3300 ;;;; Subscript
3302 (defun org-e-html-subscript (subscript contents info)
3303 "Transcode a SUBSCRIPT object from Org to HTML.
3304 CONTENTS is the contents of the object. INFO is a plist holding
3305 contextual information."
3306 ;; (format (if (= (length contents) 1) "$_%s$" "$_{\\mathrm{%s}}$") contents)
3307 (org-e-html-format-fontify contents 'subscript))
3310 ;;;; Superscript
3312 (defun org-e-html-superscript (superscript contents info)
3313 "Transcode a SUPERSCRIPT object from Org to HTML.
3314 CONTENTS is the contents of the object. INFO is a plist holding
3315 contextual information."
3316 ;; (format (if (= (length contents) 1) "$^%s$" "$^{\\mathrm{%s}}$") contents)
3317 (org-e-html-format-fontify contents 'superscript))
3320 ;;;; Table
3322 (defun org-e-html-table--format-string (table table-info info)
3323 "Return an appropriate format string for TABLE.
3325 TABLE-INFO is the plist containing format info about the table,
3326 as returned by `org-export-table-format-info'. INFO is a plist
3327 used as a communication channel.
3329 The format string leaves one placeholder for the body of the
3330 table."
3331 (let* ((label (org-element-get-property :name table))
3332 (caption (org-e-html--caption/label-string
3333 (org-element-get-property :caption table) label info))
3334 (attr (mapconcat 'identity
3335 (org-element-get-property :attr_html table)
3336 " "))
3337 ;; Determine alignment string.
3338 (alignment (org-e-html-table--align-string attr table-info))
3339 ;; Determine environment for the table: longtable, tabular...
3340 (table-env (cond
3341 ((not attr) org-e-html-default-table-environment)
3342 ((string-match "\\<longtable\\>" attr) "longtable")
3343 ((string-match "\\<tabular.?\\>" attr)
3344 (org-match-string-no-properties 0 attr))
3345 (t org-e-html-default-table-environment)))
3346 ;; If table is a float, determine environment: table or table*.
3347 (float-env (cond
3348 ((string= "longtable" table-env) nil)
3349 ((and attr
3350 (or (string-match (regexp-quote "table*") attr)
3351 (string-match "\\<multicolumn\\>" attr)))
3352 "table*")
3353 ((or (not (string= caption "")) label) "table")))
3354 ;; Extract others display options.
3355 (width (and attr (string-match "\\<width=\\(\\S-+\\)" attr)
3356 (org-match-string-no-properties 1 attr)))
3357 (placement
3358 (if (and attr (string-match "\\<placement=\\(\\S-+\\)" attr))
3359 (org-match-string-no-properties 1 attr)
3360 (format "[%s]" org-e-html-default-figure-position))))
3361 ;; Prepare the final format string for the table.
3362 (cond
3363 ;; Longtable.
3364 ((string= "longtable" table-env)
3365 (format
3366 "\\begin{longtable}{%s}\n%s\n%%s\n%s\\end{longtable}"
3367 alignment
3368 (if (or (not org-e-html-table-caption-above) (string= "" caption)) ""
3369 (concat (org-trim caption) "\\\\"))
3370 (if (or org-e-html-table-caption-above (string= "" caption)) ""
3371 (concat (org-trim caption) "\\\\\n"))))
3372 ;; Others.
3373 (t (concat (when float-env
3374 (concat
3375 (format "\\begin{%s}%s\n" float-env placement)
3376 (if org-e-html-table-caption-above caption "")))
3377 (when org-e-html-tables-centered "\\begin{center}\n")
3378 (format "\\begin{%s}%s{%s}\n%%s\n\\end{%s}"
3379 table-env
3380 (if width (format "{%s}" width) "") alignment table-env)
3381 (when org-e-html-tables-centered "\n\\end{center}")
3382 (when float-env
3383 (concat (if org-e-html-table-caption-above "" caption)
3384 (format "\n\\end{%s}" float-env))))))))
3386 (defun org-e-html-table--align-string (attr table-info)
3387 "Return an appropriate HTML alignment string.
3388 ATTR is a string containing table's HTML specific attributes.
3389 TABLE-INFO is the plist containing format info about the table,
3390 as returned by `org-export-table-format-info'."
3391 (or (and attr
3392 (string-match "\\<align=\\(\\S-+\\)" attr)
3393 (match-string 1 attr))
3394 (let* ((align (copy-sequence (plist-get table-info :alignment)))
3395 (colgroups (copy-sequence (plist-get table-info :column-groups)))
3396 (cols (length align))
3397 (separators (make-vector (1+ cols) "")))
3398 ;; Ignore the first column if it's special.
3399 (when (plist-get table-info :special-column-p)
3400 (aset align 0 "") (aset colgroups 0 nil))
3401 (let ((col 0))
3402 (mapc (lambda (el)
3403 (let ((gr (aref colgroups col)))
3404 (when (memq gr '(start start-end))
3405 (aset separators col "|"))
3406 (when (memq gr '(end start-end))
3407 (aset separators (1+ col) "|")))
3408 (incf col))
3409 align))
3410 ;; Build the HTML specific alignment string.
3411 (loop for al across align
3412 for sep across separators
3413 concat (concat sep al) into output
3414 finally return (concat output (aref separators cols))))))
3417 ;; tables
3419 (defun org-e-html-begin-table (caption label attributes)
3420 (let* ((html-table-tag (or (plist-get info :html-table-tag) ; FIXME
3421 org-e-html-table-tag))
3422 (html-table-tag
3423 (org-export-splice-attributes html-table-tag attributes)))
3424 (when label
3425 (setq html-table-tag
3426 (org-export-splice-attributes
3427 html-table-tag
3428 (format "id=\"%s\"" (org-solidify-link-text label)))))
3429 (concat "\n" html-table-tag
3430 (format "\n<caption>%s</caption>" (or caption "")))))
3432 (defun org-e-html-end-table ()
3433 (when org-lparse-table-is-styled
3434 ;; column groups
3435 ;; (unless (car org-table-colgroup-info)
3436 ;; (setq org-table-colgroup-info
3437 ;; (cons :start (cdr org-table-colgroup-info))))
3439 ;; column alignment
3440 (let ((c -1))
3441 ;; (mapc
3442 ;; (lambda (x)
3443 ;; (incf c)
3444 ;; (setf (aref org-lparse-table-colalign-vector c)
3445 ;; (or (aref org-lparse-table-colalign-vector c)
3446 ;; (if (> (/ (float x) (1+ org-lparse-table-rownum))
3447 ;; org-table-number-fraction)
3448 ;; "right" "left"))))
3449 ;; org-lparse-table-num-numeric-items-per-column)
3452 ;; html specific stuff starts here
3453 ;; (org-e-html-end-table)
3455 "</table>\n")
3457 (defun org-e-html-format-table-cell (text r c horiz-span)
3458 (let ((cell-style-cookie
3459 (if org-e-html-table-align-individual-fields
3460 (format (if (and (boundp 'org-e-html-format-table-no-css)
3461 org-e-html-format-table-no-css)
3462 " align=\"%s\"" " class=\"%s\"")
3463 (or (aref (plist-get table-info :alignment) c) "left")) ""))) ;; FIXME
3464 (cond
3465 (org-lparse-table-cur-rowgrp-is-hdr
3466 (concat
3467 (format (car org-export-table-header-tags) "col" cell-style-cookie)
3468 text (cdr org-export-table-header-tags)))
3469 ((and (= c 0) org-e-html-table-use-header-tags-for-first-column)
3470 (concat
3471 (format (car org-export-table-header-tags) "row" cell-style-cookie)
3472 text (cdr org-export-table-header-tags)))
3474 (concat
3475 (format (car org-export-table-data-tags) cell-style-cookie)
3476 text (cdr org-export-table-data-tags))))))
3478 (defun org-e-html-format-table-row (row)
3479 (concat (eval (car org-export-table-row-tags)) row
3480 (eval (cdr org-export-table-row-tags))))
3482 (defun org-e-html-table-row (fields &optional text-for-empty-fields)
3483 (if org-lparse-table-ncols
3484 ;; second and subsequent rows of the table
3485 ;; (when (and org-lparse-list-table-p
3486 ;; (> (length fields) org-lparse-table-ncols))
3487 ;; (error "Table row has %d columns but header row claims %d columns"
3488 ;; (length fields) org-lparse-table-ncols))
3489 ;; first row of the table
3490 (setq org-lparse-table-ncols (length fields))
3491 ;; (when org-lparse-table-is-styled
3492 ;; (setq org-lparse-table-num-numeric-items-per-column
3493 ;; (make-vector org-lparse-table-ncols 0)))
3495 (incf org-lparse-table-rownum)
3496 (let ((i -1))
3497 (org-e-html-format-table-row
3498 (mapconcat
3499 (lambda (x)
3500 (when (and (string= x "") text-for-empty-fields)
3501 (setq x text-for-empty-fields))
3502 (incf i)
3503 (let (col-cookie horiz-span)
3504 (when org-lparse-table-is-styled
3505 ;; (when (and (< i org-lparse-table-ncols)
3506 ;; (string-match org-table-number-regexp x))
3507 ;; (incf (aref org-lparse-table-num-numeric-items-per-column i)))
3508 (setq col-cookie (cdr (assoc (1+ i) org-lparse-table-colalign-info))
3509 horiz-span (nth 1 col-cookie)))
3510 (org-e-html-format-table-cell
3511 x org-lparse-table-rownum i (or horiz-span 0))))
3512 fields "\n"))))
3514 (defun org-e-html-end-table-rowgroup ()
3515 (when org-lparse-table-rowgrp-open
3516 (setq org-lparse-table-rowgrp-open nil)
3517 (if org-lparse-table-cur-rowgrp-is-hdr "</thead>" "</tbody>")))
3519 (defun org-e-html-begin-table-rowgroup (&optional is-header-row)
3520 (concat
3521 (when org-lparse-table-rowgrp-open
3522 (org-e-html-end-table-rowgroup))
3523 (progn
3524 (setq org-lparse-table-rowgrp-open t)
3525 (setq org-lparse-table-cur-rowgrp-is-hdr is-header-row)
3526 (if is-header-row "<thead>" "<tbody>"))))
3528 (defun org-e-html-table-preamble ()
3529 (let ((colgroup-vector (plist-get table-info :column-groups)) ;; FIXME
3530 c gr colgropen preamble)
3531 (unless (aref colgroup-vector 0)
3532 (setf (aref colgroup-vector 0) 'start))
3533 (dotimes (c columns-number preamble)
3534 (setq gr (aref colgroup-vector c))
3535 (setq preamble
3536 (concat
3537 preamble
3538 (when (memq gr '(start start-end))
3539 (prog1 (if colgropen "</colgroup>\n<colgroup>" "\n<colgroup>")
3540 (setq colgropen t)))
3541 (let* ((colalign-vector (plist-get table-info :alignment)) ;; FIXME
3542 (align (cdr (assoc (aref colalign-vector c)
3543 '(("l" . "left")
3544 ("r" . "right")
3545 ("c" . "center")))))
3546 (alignspec (if (and (boundp 'org-e-html-format-table-no-css)
3547 org-e-html-format-table-no-css)
3548 " align=\"%s\"" " class=\"%s\""))
3549 (extra (format alignspec align)))
3550 (format "<col%s />" extra))
3551 (when (memq gr '(end start-end))
3552 (setq colgropen nil)
3553 "</colgroup>"))))
3554 (concat preamble (if colgropen "</colgroup>"))))
3556 (defun org-e-html-list-table (lines &optional splice
3557 caption label attributes head
3558 org-lparse-table-colalign-info)
3559 (or (featurep 'org-table) ; required for
3560 (require 'org-table)) ; `org-table-number-regexp'
3561 (let* ((org-lparse-table-rownum -1)
3562 (org-lparse-table-ncols (length (plist-get info :alignment)))
3563 i (cnt 0)
3564 tbopen fields line
3565 org-lparse-table-cur-rowgrp-is-hdr
3566 org-lparse-table-rowgrp-open
3567 ;; org-lparse-table-num-numeric-items-per-column
3568 org-lparse-table-colalign-vector n
3569 org-lparse-table-rowgrp-info
3570 (org-lparse-table-style 'org-table)
3571 org-lparse-table-is-styled)
3572 (cond
3573 (splice
3574 (setq org-lparse-table-is-styled nil)
3575 (mapconcat 'org-e-html-table-row lines "\n"))
3577 (setq org-lparse-table-is-styled t)
3579 (concat
3580 (org-e-html-begin-table caption label attributes)
3581 (org-e-html-table-preamble)
3582 (progn (push (cons (1+ org-lparse-table-rownum) :start)
3583 org-lparse-table-rowgrp-info)
3584 (org-e-html-begin-table-rowgroup head))
3586 (mapconcat
3587 (lambda (line)
3588 (cond
3589 ((equal line :hrule)
3590 (push (cons (1+ org-lparse-table-rownum) :start)
3591 org-lparse-table-rowgrp-info)
3592 (org-e-html-begin-table-rowgroup))
3594 (org-e-html-table-row line))))
3595 lines "\n")
3597 (org-e-html-end-table-rowgroup)
3598 (org-e-html-end-table))))))
3600 (defun org-e-html-org-table-to-list-table (lines &optional splice)
3601 "Convert org-table to list-table.
3602 LINES is a list of the form (ROW1 ROW2 ROW3 ...) where each
3603 element is a `string' representing a single row of org-table.
3604 Thus each ROW has vertical separators \"|\" separating the table
3605 fields. A ROW could also be a row-group separator of the form
3606 \"|---...|\". Return a list of the form (ROW1 ROW2 ROW3
3607 ...). ROW could either be symbol `:hrule' or a list of the
3608 form (FIELD1 FIELD2 FIELD3 ...) as appropriate."
3609 (let (line lines-1)
3610 (cond
3611 (splice
3612 (while (setq line (pop lines))
3613 (unless (string-match "^[ \t]*|-" line)
3614 (push (org-split-string line "[ \t]*|[ \t]*") lines-1))))
3616 (while (setq line (pop lines))
3617 (cond
3618 ((string-match "^[ \t]*|-" line)
3619 (when lines
3620 (push :hrule lines-1)))
3622 (push (org-split-string line "[ \t]*|[ \t]*") lines-1))))))
3623 (nreverse lines-1)))
3625 (defun org-e-html-table (table contents info)
3626 "Transcode a TABLE element from Org to HTML.
3627 CONTENTS is nil. INFO is a plist holding contextual information."
3628 (let* (
3629 ;; FIXME
3630 ;; see `org-e-html-table--format-string'
3631 (label (org-element-get-property :name table))
3632 (caption (org-e-html--caption/label-string
3633 (org-element-get-property :caption table) label info))
3634 ;; FIXME
3636 (attr (mapconcat #'identity
3637 (org-element-get-property :attr_html table)
3638 " "))
3639 (raw-table (org-element-get-property :raw-table table)))
3640 (cond
3641 ;; Case 1: verbatim table.
3642 ((or org-e-html-tables-verbatim
3643 (and attr (string-match "\\<verbatim\\>" attr)))
3644 (format "\\begin{verbatim}\n%s\n\\end{verbatim}"
3645 (org-export-clean-table
3646 raw-table
3647 (plist-get (org-export-table-format-info raw-table)
3648 :special-column-p))))
3649 ;; Case 2: table.el table. Convert it using appropriate tools.
3650 ((eq (org-element-get-property :type table) 'table.el)
3651 (require 'table)
3652 ;; Ensure "*org-export-table*" buffer is empty.
3653 (with-current-buffer (get-buffer-create "*org-export-table*")
3654 (erase-buffer))
3655 (let ((output (with-temp-buffer
3656 (insert raw-table)
3657 (goto-char 1)
3658 (re-search-forward "^[ \t]*|[^|]" nil t)
3659 (table-generate-source 'html "*org-export-table*")
3660 (with-current-buffer "*org-export-table*"
3661 (org-trim (buffer-string))))))
3662 (kill-buffer (get-buffer "*org-export-table*"))
3663 ;; Remove left out comments.
3664 (while (string-match "^%.*\n" output)
3665 (setq output (replace-match "" t t output)))
3666 ;; When the "rmlines" attribute is provided, remove all hlines
3667 ;; but the the one separating heading from the table body.
3668 (when (and attr (string-match "\\<rmlines\\>" attr))
3669 (let ((n 0) (pos 0))
3670 (while (and (< (length output) pos)
3671 (setq pos (string-match "^\\\\hline\n?" output pos)))
3672 (incf n)
3673 (unless (= n 2)
3674 (setq output (replace-match "" nil nil output))))))
3675 ;; (if (not org-e-html-tables-centered) output
3676 ;; (format "\\begin{center}\n%s\n\\end{center}" output))
3677 output))
3678 ;; Case 3: Standard table.
3680 (let* ((table-info (org-export-table-format-info raw-table))
3681 (columns-number (length (plist-get table-info :alignment)))
3682 (longtablep (and attr (string-match "\\<longtable\\>" attr)))
3683 (booktabsp
3684 (or (and attr (string-match "\\<booktabs=\\(yes\\|t\\)\\>" attr))
3685 org-e-html-tables-booktabs))
3686 ;; CLEAN-TABLE is a table turned into a list, much like
3687 ;; `org-table-to-lisp', with special column and
3688 ;; formatting cookies removed, and cells already
3689 ;; transcoded.
3690 (lines (org-split-string
3691 (org-export-clean-table
3692 raw-table (plist-get table-info :special-column-p)) "\n"))
3694 ;; (clean-table
3695 ;; (mapcar
3696 ;; (lambda (row)
3697 ;; (if (string-match org-table-hline-regexp row) 'hline
3698 ;; (mapcar
3699 ;; (lambda (cell)
3700 ;; (org-export-secondary-string
3701 ;; (org-element-parse-secondary-string
3702 ;; cell
3703 ;; (cdr (assq 'table org-element-string-restrictions)))
3704 ;; 'e-html info))
3705 ;; (org-split-string row "[ \t]*|[ \t]*"))))
3707 ;; lines))
3713 (let ((splice nil) head)
3714 (setq lines (org-e-html-org-table-to-list-table lines splice))
3715 (org-e-html-list-table lines splice caption label attr head nil))
3716 ;; If BOOKTABSP is non-nil, remove any rule at the beginning
3717 ;; and the end of the table, since booktabs' special rules
3718 ;; will be inserted instead.
3719 ;; (when booktabsp
3720 ;; (when (eq (car clean-table) 'hline)
3721 ;; (setq clean-table (cdr clean-table)))
3722 ;; (when (eq (car (last clean-table)) 'hline)
3723 ;; (setq clean-table (butlast clean-table))))
3724 ;; Convert ROWS to send them to `orgtbl-to-latex'. In
3725 ;; particular, send each cell to
3726 ;; `org-element-parse-secondary-string' to expand any Org
3727 ;; object within. Eventually, flesh the format string out
3728 ;; with the table.
3729 ;; (format
3730 ;; (org-e-html-table--format-string table table-info info)
3731 ;; (orgtbl-to-latex
3732 ;; clean-table
3733 ;; ;; Parameters passed to `orgtbl-to-latex'.
3734 ;; `(:tstart ,(and booktabsp "\\toprule")
3735 ;; :tend ,(and booktabsp "\\bottomrule")
3736 ;; :hline ,(if booktabsp "\\midrule" "\\hline")
3737 ;; ;; Longtable environment requires specific header
3738 ;; ;; lines end string.
3739 ;; :hlend ,(and longtablep
3740 ;; (format "\\\\
3741 ;; %s
3742 ;; \\endhead
3743 ;; %s\\multicolumn{%d}{r}{Continued on next page}\\\\
3744 ;; \\endfoot
3745 ;; \\endlastfoot"
3746 ;; (if booktabsp "\\midrule" "\\hline")
3747 ;; (if booktabsp "\\midrule" "\\hline")
3748 ;; columns-number)))))
3749 )))))
3752 ;;;; Target
3754 (defun org-e-html-target (target text info)
3755 "Transcode a TARGET object from Org to HTML.
3756 TEXT is the text of the target. INFO is a plist holding
3757 contextual information."
3758 (org-e-html-format-anchor
3759 text (org-export-solidify-link-text
3760 (org-element-get-property :raw-value target))))
3763 ;;;; Time-stamp
3765 (defun org-e-html-time-stamp (time-stamp contents info)
3766 "Transcode a TIME-STAMP object from Org to HTML.
3767 CONTENTS is nil. INFO is a plist holding contextual
3768 information."
3769 ;; (let ((value (org-element-get-property :value time-stamp))
3770 ;; (type (org-element-get-property :type time-stamp))
3771 ;; (appt-type (org-element-get-property :appt-type time-stamp)))
3772 ;; (concat (cond ((eq appt-type 'scheduled)
3773 ;; (format "\\textbf{\\textsc{%s}} " org-scheduled-string))
3774 ;; ((eq appt-type 'deadline)
3775 ;; (format "\\textbf{\\textsc{%s}} " org-deadline-string))
3776 ;; ((eq appt-type 'closed)
3777 ;; (format "\\textbf{\\textsc{%s}} " org-closed-string)))
3778 ;; (cond ((memq type '(active active-range))
3779 ;; (format org-e-html-active-timestamp-format value))
3780 ;; ((memq type '(inactive inactive-range))
3781 ;; (format org-e-html-inactive-timestamp-format value))
3782 ;; (t
3783 ;; (format org-e-html-diary-timestamp-format value)))))
3784 (let ((value (org-element-get-property :value time-stamp))
3785 (type (org-element-get-property :type time-stamp))
3786 (appt-type (org-element-get-property :appt-type time-stamp)))
3787 (org-e-html-format-fontify
3788 (concat
3789 (org-e-html-format-fontify
3790 (cond ((eq appt-type 'scheduled) org-scheduled-string)
3791 ((eq appt-type 'deadline) org-deadline-string)
3792 ((eq appt-type 'closed) org-closed-string)) "timestamp-kwd")
3793 ;; FIXME: (org-translate-time value)
3794 (org-e-html-format-fontify value "timestamp"))
3795 "timestamp-wrapper")))
3798 ;;;; Verbatim
3800 (defun org-e-html-verbatim (verbatim contents info)
3801 "Transcode a VERBATIM object from Org to HTML.
3802 CONTENTS is nil. INFO is a plist used as a communication
3803 channel."
3804 (org-e-html-emphasis
3805 verbatim (org-element-get-property :value verbatim) info))
3808 ;;;; Verse Block
3810 (defun org-e-html-verse-block (verse-block contents info)
3811 "Transcode a VERSE-BLOCK element from Org to HTML.
3812 CONTENTS is nil. INFO is a plist holding contextual information."
3813 ;; Replace each newline character with line break. Also replace
3814 ;; each blank line with a line break.
3815 (setq contents (replace-regexp-in-string
3816 "^ *\\\\\\\\$" "<br/>\n"
3817 (replace-regexp-in-string
3818 "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n"
3819 (org-remove-indentation
3820 (org-export-secondary-string
3821 (org-element-get-property :value verse-block)
3822 'e-html info)))))
3824 ;; Replace each white space at beginning of a line with a
3825 ;; non-breaking space.
3826 (while (string-match "^[ \t]+" contents)
3827 (let ((new-str (format "&nbsp;"
3828 (length (match-string 0 contents)))))
3829 (setq contents (replace-match new-str nil t contents))))
3831 (org-e-html--wrap-label
3832 verse-block (format "<p class=\"verse\">\n%s</p>" contents)))
3836 ;;; Interactive functions
3838 (defun org-e-html-export-to-html
3839 (&optional subtreep visible-only body-only ext-plist pub-dir)
3840 "Export current buffer to a HTML file.
3842 If narrowing is active in the current buffer, only export its
3843 narrowed part.
3845 If a region is active, export that region.
3847 When optional argument SUBTREEP is non-nil, export the sub-tree
3848 at point, extracting information from the headline properties
3849 first.
3851 When optional argument VISIBLE-ONLY is non-nil, don't export
3852 contents of hidden elements.
3854 When optional argument BODY-ONLY is non-nil, only write code
3855 between \"\\begin{document}\" and \"\\end{document}\".
3857 EXT-PLIST, when provided, is a property list with external
3858 parameters overriding Org default settings, but still inferior to
3859 file-local settings.
3861 When optional argument PUB-DIR is set, use it as the publishing
3862 directory.
3864 Return output file's name."
3865 (interactive)
3867 (setq org-e-html-footnotes-alist nil)
3869 ;; FIXME
3870 (with-current-buffer (get-buffer-create "*debug*")
3871 (erase-buffer))
3873 (let ((outfile (org-export-output-file-name ".html" subtreep pub-dir)))
3874 (org-export-to-file
3875 'e-html outfile subtreep visible-only body-only ext-plist)))
3877 (provide 'org-e-html)
3878 ;;; org-e-html.el ends here