org-e-html: Small refactoring
[org-mode.git] / contrib / lisp / org-e-html.el
blobce71769ae42e022f5721b15b8aa58f9e81d0cee0
1 ;;; org-e-html.el --- HTML Back-End For Org Export Engine
3 ;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
5 ;; Author: Jambunathan K <kjambunathan 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 ;;; Code:
35 ;;; org-e-html.el
36 ;;; Dependencies
38 (require 'org-export)
39 (require 'org-e-publish)
40 (require 'format-spec)
41 (eval-when-compile (require 'cl) (require 'table))
45 ;;; Function Declarations
47 (declare-function org-id-find-id-file "org-id" (id))
48 (declare-function htmlize-region "ext:htmlize" (beg end))
49 (declare-function org-pop-to-buffer-same-window
50 "org-compat" (&optional buffer-or-name norecord label))
53 ;;; Define Back-End
55 (org-export-define-backend e-html
56 ((bold . org-e-html-bold)
57 (center-block . org-e-html-center-block)
58 (clock . org-e-html-clock)
59 (code . org-e-html-code)
60 (drawer . org-e-html-drawer)
61 (dynamic-block . org-e-html-dynamic-block)
62 (entity . org-e-html-entity)
63 (example-block . org-e-html-example-block)
64 (export-block . org-e-html-export-block)
65 (export-snippet . org-e-html-export-snippet)
66 (fixed-width . org-e-html-fixed-width)
67 (footnote-definition . org-e-html-footnote-definition)
68 (footnote-reference . org-e-html-footnote-reference)
69 (headline . org-e-html-headline)
70 (horizontal-rule . org-e-html-horizontal-rule)
71 (inline-src-block . org-e-html-inline-src-block)
72 (inlinetask . org-e-html-inlinetask)
73 (italic . org-e-html-italic)
74 (item . org-e-html-item)
75 (keyword . org-e-html-keyword)
76 (latex-environment . org-e-html-latex-environment)
77 (latex-fragment . org-e-html-latex-fragment)
78 (line-break . org-e-html-line-break)
79 (link . org-e-html-link)
80 (paragraph . org-e-html-paragraph)
81 (plain-list . org-e-html-plain-list)
82 (plain-text . org-e-html-plain-text)
83 (planning . org-e-html-planning)
84 (property-drawer . org-e-html-property-drawer)
85 (quote-block . org-e-html-quote-block)
86 (quote-section . org-e-html-quote-section)
87 (radio-target . org-e-html-radio-target)
88 (section . org-e-html-section)
89 (special-block . org-e-html-special-block)
90 (src-block . org-e-html-src-block)
91 (statistics-cookie . org-e-html-statistics-cookie)
92 (strike-through . org-e-html-strike-through)
93 (subscript . org-e-html-subscript)
94 (superscript . org-e-html-superscript)
95 (table . org-e-html-table)
96 (table-cell . org-e-html-table-cell)
97 (table-row . org-e-html-table-row)
98 (target . org-e-html-target)
99 (template . org-e-html-template)
100 (timestamp . org-e-html-timestamp)
101 (underline . org-e-html-underline)
102 (verbatim . org-e-html-verbatim)
103 (verse-block . org-e-html-verse-block))
104 :export-block "HTML"
105 :filters-alist ((:filter-final-output . org-e-html-final-function))
106 :menu-entry
107 (?h "Export to HTML"
108 ((?H "To temporary buffer" org-e-html-export-as-html)
109 (?h "To file" org-e-html-export-to-html)
110 (?o "To file and open"
111 (lambda (s v b) (org-open-file (org-e-html-export-to-html s v b))))))
112 :options-alist
113 ;; FIXME: Prefix KEYWORD and OPTION with "HTML_". Prefix
114 ;; corresponding properties with `:html-". If such a renaming is
115 ;; taken up, some changes will be required in `org-jsinfo.el',
116 ;; I think. So defer renaming for now.
117 ((:agenda-style nil nil org-agenda-export-html-style)
118 (:creator "CREATOR" nil org-e-html-creator-string)
119 (:convert-org-links nil nil org-e-html-link-org-files-as-html)
120 (:inline-images nil nil org-e-html-inline-images)
121 (:link-home "LINK_HOME" nil org-e-html-link-home)
122 (:link-up "LINK_UP" nil org-e-html-link-up)
123 (:style nil nil org-e-html-style)
124 (:style-extra "STYLE" nil org-e-html-style-extra newline)
125 (:style-include-default nil nil org-e-html-style-include-default)
126 (:style-include-scripts nil nil org-e-html-style-include-scripts)
127 (:html-extension nil nil org-e-html-extension)
128 (:html-postamble nil "html-postamble" org-e-html-postamble)
129 (:html-preamble nil "html-preamble" org-e-html-preamble)
130 (:html-table-tag nil nil org-e-html-table-tag)
131 (:xml-declaration nil nil org-e-html-xml-declaration)
132 (:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments)
133 (:mathjax "MATHJAX" nil "" space)))
137 ;;; Internal Variables
139 (defvar org-e-html-format-table-no-css)
140 (defvar htmlize-buffer-places) ; from htmlize.el
141 (defvar body-only) ; dynamically scoped into this.
143 (defconst org-e-html-special-string-regexps
144 '(("\\\\-" . "&shy;")
145 ("---\\([^-]\\)" . "&mdash;\\1")
146 ("--\\([^-]\\)" . "&ndash;\\1")
147 ("\\.\\.\\." . "&hellip;"))
148 "Regular expressions for special string conversion.")
150 (defconst org-e-html-scripts
151 "<script type=\"text/javascript\">
153 @licstart The following is the entire license notice for the
154 JavaScript code in this tag.
156 Copyright (C) 2012 Free Software Foundation, Inc.
158 The JavaScript code in this tag is free software: you can
159 redistribute it and/or modify it under the terms of the GNU
160 General Public License (GNU GPL) as published by the Free Software
161 Foundation, either version 3 of the License, or (at your option)
162 any later version. The code is distributed WITHOUT ANY WARRANTY;
163 without even the implied warranty of MERCHANTABILITY or FITNESS
164 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
166 As additional permission under GNU GPL version 3 section 7, you
167 may distribute non-source (e.g., minimized or compacted) forms of
168 that code without the copy of the GNU GPL normally required by
169 section 4, provided you include this license notice and a URL
170 through which recipients can access the Corresponding Source.
173 @licend The above is the entire license notice
174 for the JavaScript code in this tag.
176 <!--/*--><![CDATA[/*><!--*/
177 function CodeHighlightOn(elem, id)
179 var target = document.getElementById(id);
180 if(null != target) {
181 elem.cacheClassElem = elem.className;
182 elem.cacheClassTarget = target.className;
183 target.className = \"code-highlighted\";
184 elem.className = \"code-highlighted\";
187 function CodeHighlightOff(elem, id)
189 var target = document.getElementById(id);
190 if(elem.cacheClassElem)
191 elem.className = elem.cacheClassElem;
192 if(elem.cacheClassTarget)
193 target.className = elem.cacheClassTarget;
195 /*]]>*///-->
196 </script>"
197 "Basic JavaScript that is needed by HTML files produced by Org mode.")
199 (defconst org-e-html-style-default
200 "<style type=\"text/css\">
201 <!--/*--><![CDATA[/*><!--*/
202 html { font-family: Times, serif; font-size: 12pt; }
203 .title { text-align: center; }
204 .todo { color: red; }
205 .done { color: green; }
206 .tag { background-color: #add8e6; font-weight:normal }
207 .target { }
208 .timestamp { color: #bebebe; }
209 .timestamp-kwd { color: #5f9ea0; }
210 .right {margin-left:auto; margin-right:0px; text-align:right;}
211 .left {margin-left:0px; margin-right:auto; text-align:left;}
212 .center {margin-left:auto; margin-right:auto; text-align:center;}
213 p.verse { margin-left: 3% }
214 pre {
215 border: 1pt solid #AEBDCC;
216 background-color: #F3F5F7;
217 padding: 5pt;
218 font-family: courier, monospace;
219 font-size: 90%;
220 overflow:auto;
222 table { border-collapse: collapse; }
223 td, th { vertical-align: top; }
224 th.right { text-align:center; }
225 th.left { text-align:center; }
226 th.center { text-align:center; }
227 td.right { text-align:right; }
228 td.left { text-align:left; }
229 td.center { text-align:center; }
230 dt { font-weight: bold; }
231 div.figure { padding: 0.5em; }
232 div.figure p { text-align: center; }
233 div.inlinetask {
234 padding:10px;
235 border:2px solid gray;
236 margin:10px;
237 background: #ffffcc;
239 textarea { overflow-x: auto; }
240 .linenr { font-size:smaller }
241 .code-highlighted {background-color:#ffff00;}
242 .org-info-js_info-navigation { border-style:none; }
243 #org-info-js_console-label { font-size:10px; font-weight:bold;
244 white-space:nowrap; }
245 .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
246 font-weight:bold; }
247 /*]]>*/-->
248 </style>"
249 "The default style specification for exported HTML files.
250 Please use the variables `org-e-html-style' and
251 `org-e-html-style-extra' to add to this style. If you wish to not
252 have the default style included, customize the variable
253 `org-e-html-style-include-default'.")
257 ;;; User Configuration Variables
259 (defgroup org-export-e-html nil
260 "Options for exporting Org mode files to HTML."
261 :tag "Org Export HTML"
262 :group 'org-export)
264 (defgroup org-export-e-htmlize nil
265 "Options for processing examples with htmlize.el."
266 :tag "Org Export Htmlize"
267 :group 'org-export-e-html)
270 ;;;; Bold etc
272 (defcustom org-e-html-text-markup-alist
273 '((bold . "<b>%s</b>")
274 (code . "<code>%s</code>")
275 (italic . "<i>%s</i>")
276 (strike-through . "<del>%s</del>")
277 (underline . "<span style=\"text-decoration:underline;\">%s</span>")
278 (verbatim . "<code>%s</code>"))
279 "Alist of HTML expressions to convert text markup
281 The key must be a symbol among `bold', `code', `italic',
282 `strike-through', `underline' and `verbatim'. The value is
283 a formatting string to wrap fontified text with.
285 If no association can be found for a given markup, text will be
286 returned as-is."
287 :group 'org-export-e-html
288 :type '(alist :key-type (symbol :tag "Markup type")
289 :value-type (string :tag "Format string"))
290 :options '(bold code italic strike-through underline verbatim))
293 ;;;; Debugging
295 (defcustom org-e-html-pretty-output nil
296 "Enable this to generate pretty HTML."
297 :group 'org-export-e-html
298 :type 'boolean)
301 ;;;; Drawers
303 (defcustom org-e-html-format-drawer-function nil
304 "Function called to format a drawer in HTML code.
306 The function must accept two parameters:
307 NAME the drawer name, like \"LOGBOOK\"
308 CONTENTS the contents of the drawer.
310 The function should return the string to be exported.
312 For example, the variable could be set to the following function
313 in order to mimic default behaviour:
315 \(defun org-e-html-format-drawer-default \(name contents\)
316 \"Format a drawer element for HTML export.\"
317 contents\)"
318 :group 'org-export-e-html
319 :type 'function)
322 ;;;; Footnotes
324 (defcustom org-e-html-footnotes-section "<div id=\"footnotes\">
325 <h2 class=\"footnotes\">%s: </h2>
326 <div id=\"text-footnotes\">
328 </div>
329 </div>"
330 "Format for the footnotes section.
331 Should contain a two instances of %s. The first will be replaced with the
332 language-specific word for \"Footnotes\", the second one will be replaced
333 by the footnotes themselves."
334 :group 'org-export-e-html
335 :type 'string)
337 (defcustom org-e-html-footnote-format "<sup>%s</sup>"
338 "The format for the footnote reference.
339 %s will be replaced by the footnote reference itself."
340 :group 'org-export-e-html
341 :type 'string)
343 (defcustom org-e-html-footnote-separator "<sup>, </sup>"
344 "Text used to separate footnotes."
345 :group 'org-export-e-html
346 :type 'string)
349 ;;;; Headline
351 (defcustom org-e-html-toplevel-hlevel 2
352 "The <H> level for level 1 headings in HTML export.
353 This is also important for the classes that will be wrapped around headlines
354 and outline structure. If this variable is 1, the top-level headlines will
355 be <h1>, and the corresponding classes will be outline-1, section-number-1,
356 and outline-text-1. If this is 2, all of these will get a 2 instead.
357 The default for this variable is 2, because we use <h1> for formatting the
358 document title."
359 :group 'org-export-e-html
360 :type 'integer)
362 (defcustom org-e-html-format-headline-function nil
363 "Function to format headline text.
365 This function will be called with 5 arguments:
366 TODO the todo keyword (string or nil).
367 TODO-TYPE the type of todo (symbol: `todo', `done', nil)
368 PRIORITY the priority of the headline (integer or nil)
369 TEXT the main headline text (string).
370 TAGS the tags (string or nil).
372 The function result will be used in the section format string.
374 As an example, one could set the variable to the following, in
375 order to reproduce the default set-up:
377 \(defun org-e-html-format-headline \(todo todo-type priority text tags)
378 \"Default format function for an headline.\"
379 \(concat \(when todo
380 \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo))
381 \(when priority
382 \(format \"\\\\framebox{\\\\#%c} \" priority))
383 text
384 \(when tags (format \"\\\\hfill{}\\\\textsc{%s}\" tags))))"
385 :group 'org-export-e-html
386 :type 'function)
389 ;;;; HTML-specific
391 (defcustom org-e-html-allow-name-attribute-in-anchors t
392 "When nil, do not set \"name\" attribute in anchors.
393 By default, anchors are formatted with both \"id\" and \"name\"
394 attributes, when appropriate."
395 :group 'org-export-e-html
396 :type 'boolean)
399 ;;;; Inlinetasks
401 (defcustom org-e-html-format-inlinetask-function nil
402 "Function called to format an inlinetask in HTML code.
404 The function must accept six parameters:
405 TODO the todo keyword, as a string
406 TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
407 PRIORITY the inlinetask priority, as a string
408 NAME the inlinetask name, as a string.
409 TAGS the inlinetask tags, as a list of strings.
410 CONTENTS the contents of the inlinetask, as a string.
412 The function should return the string to be exported.
414 For example, the variable could be set to the following function
415 in order to mimic default behaviour:
417 \(defun org-e-html-format-inlinetask \(todo type priority name tags contents\)
418 \"Format an inline task element for HTML export.\"
419 \(let \(\(full-title
420 \(concat
421 \(when todo
422 \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo))
423 \(when priority (format \"\\\\framebox{\\\\#%c} \" priority))
424 title
425 \(when tags (format \"\\\\hfill{}\\\\textsc{%s}\" tags)))))
426 \(format (concat \"\\\\begin{center}\\n\"
427 \"\\\\fbox{\\n\"
428 \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
429 \"%s\\n\\n\"
430 \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
431 \"%s\"
432 \"\\\\end{minipage}}\"
433 \"\\\\end{center}\")
434 full-title contents))"
435 :group 'org-export-e-html
436 :type 'function)
439 ;;;; Links :: Generic
441 (defcustom org-e-html-link-org-files-as-html t
442 "Non-nil means make file links to `file.org' point to `file.html'.
443 When org-mode is exporting an org-mode file to HTML, links to
444 non-html files are directly put into a href tag in HTML.
445 However, links to other Org-mode files (recognized by the
446 extension `.org.) should become links to the corresponding html
447 file, assuming that the linked org-mode file will also be
448 converted to HTML.
449 When nil, the links still point to the plain `.org' file."
450 :group 'org-export-e-html
451 :type 'boolean)
454 ;;;; Links :: Inline images
456 (defcustom org-e-html-inline-images 'maybe
457 "Non-nil means inline images into exported HTML pages.
458 This is done using an <img> tag. When nil, an anchor with href is used to
459 link to the image. If this option is `maybe', then images in links with
460 an empty description will be inlined, while images with a description will
461 be linked only."
462 :group 'org-export-e-html
463 :type '(choice (const :tag "Never" nil)
464 (const :tag "Always" t)
465 (const :tag "When there is no description" maybe)))
467 (defcustom org-e-html-inline-image-rules
468 '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
469 ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
470 ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
471 "Rules characterizing image files that can be inlined into HTML.
473 A rule consists in an association whose key is the type of link
474 to consider, and value is a regexp that will be matched against
475 link's path.
477 Note that, by default, the image extension *actually* allowed
478 depend on the way the HTML file is processed. When used with
479 pdflatex, pdf, jpg and png images are OK. When processing
480 through dvi to Postscript, only ps and eps are allowed. The
481 default we use here encompasses both."
482 :group 'org-export-e-html
483 :type '(alist :key-type (string :tag "Type")
484 :value-type (regexp :tag "Path")))
487 ;;;; Plain Text
489 (defcustom org-e-html-protect-char-alist
490 '(("&" . "&amp;")
491 ("<" . "&lt;")
492 (">" . "&gt;"))
493 "Alist of characters to be converted by `org-e-html-protect'."
494 :group 'org-export-e-html
495 :type '(repeat (cons (string :tag "Character")
496 (string :tag "HTML equivalent"))))
499 ;;;; Src Block
501 (defcustom org-export-e-htmlize-output-type 'inline-css
502 "Output type to be used by htmlize when formatting code snippets.
503 Choices are `css', to export the CSS selectors only, or `inline-css', to
504 export the CSS attribute values inline in the HTML. We use as default
505 `inline-css', in order to make the resulting HTML self-containing.
507 However, this will fail when using Emacs in batch mode for export, because
508 then no rich font definitions are in place. It will also not be good if
509 people with different Emacs setup contribute HTML files to a website,
510 because the fonts will represent the individual setups. In these cases,
511 it is much better to let Org/Htmlize assign classes only, and to use
512 a style file to define the look of these classes.
513 To get a start for your css file, start Emacs session and make sure that
514 all the faces you are interested in are defined, for example by loading files
515 in all modes you want. Then, use the command
516 \\[org-export-e-htmlize-generate-css] to extract class definitions."
517 :group 'org-export-e-htmlize
518 :type '(choice (const css) (const inline-css)))
520 (defcustom org-export-e-htmlize-css-font-prefix "org-"
521 "The prefix for CSS class names for htmlize font specifications."
522 :group 'org-export-e-htmlize
523 :type 'string)
525 (defcustom org-export-e-htmlized-org-css-url nil
526 "URL pointing to a CSS file defining text colors for htmlized Emacs buffers.
527 Normally when creating an htmlized version of an Org buffer, htmlize will
528 create CSS to define the font colors. However, this does not work when
529 converting in batch mode, and it also can look bad if different people
530 with different fontification setup work on the same website.
531 When this variable is non-nil, creating an htmlized version of an Org buffer
532 using `org-export-as-org' will remove the internal CSS section and replace it
533 with a link to this URL."
534 :group 'org-export-e-htmlize
535 :type '(choice
536 (const :tag "Keep internal css" nil)
537 (string :tag "URL or local href")))
540 ;;;; Table
542 (defcustom org-e-html-table-tag
543 "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">"
544 "The HTML tag that is used to start a table.
545 This must be a <table> tag, but you may change the options like
546 borders and spacing."
547 :group 'org-export-e-html
548 :type 'string)
550 (defcustom org-e-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>")
551 "The opening tag for table header fields.
552 This is customizable so that alignment options can be specified.
553 The first %s will be filled with the scope of the field, either row or col.
554 The second %s will be replaced by a style entry to align the field.
555 See also the variable `org-e-html-table-use-header-tags-for-first-column'.
556 See also the variable `org-e-html-table-align-individual-fields'."
557 :group 'org-export-tables ; FIXME: change group?
558 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
560 (defcustom org-e-html-table-data-tags '("<td%s>" . "</td>")
561 "The opening tag for table data fields.
562 This is customizable so that alignment options can be specified.
563 The first %s will be filled with the scope of the field, either row or col.
564 The second %s will be replaced by a style entry to align the field.
565 See also the variable `org-e-html-table-align-individual-fields'."
566 :group 'org-export-tables
567 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
569 (defcustom org-e-html-table-row-tags '("<tr>" . "</tr>")
570 "The opening tag for table data fields.
571 This is customizable so that alignment options can be specified.
572 Instead of strings, these can be Lisp forms that will be evaluated
573 for each row in order to construct the table row tags. During evaluation,
574 the variable `head' will be true when this is a header line, nil when this
575 is a body line. And the variable `nline' will contain the line number,
576 starting from 1 in the first header line. For example
578 (setq org-e-html-table-row-tags
579 (cons '(if head
580 \"<tr>\"
581 (if (= (mod nline 2) 1)
582 \"<tr class=\\\"tr-odd\\\">\"
583 \"<tr class=\\\"tr-even\\\">\"))
584 \"</tr>\"))
586 will give even lines the class \"tr-even\" and odd lines the class \"tr-odd\"."
587 :group 'org-export-tables
588 :type '(cons
589 (choice :tag "Opening tag"
590 (string :tag "Specify")
591 (sexp))
592 (choice :tag "Closing tag"
593 (string :tag "Specify")
594 (sexp))))
596 (defcustom org-e-html-table-align-individual-fields t
597 "Non-nil means attach style attributes for alignment to each table field.
598 When nil, alignment will only be specified in the column tags, but this
599 is ignored by some browsers (like Firefox, Safari). Opera does it right
600 though."
601 :group 'org-export-tables
602 :type 'boolean)
604 (defcustom org-e-html-table-use-header-tags-for-first-column nil
605 "Non-nil means format column one in tables with header tags.
606 When nil, also column one will use data tags."
607 :group 'org-export-tables
608 :type 'boolean)
610 (defcustom org-e-html-table-caption-above t
611 "When non-nil, place caption string at the beginning of the table.
612 Otherwise, place it near the end."
613 :group 'org-export-e-html
614 :type 'boolean)
617 ;;;; Tags
619 (defcustom org-e-html-tag-class-prefix ""
620 "Prefix to class names for TODO keywords.
621 Each tag gets a class given by the tag itself, with this prefix.
622 The default prefix is empty because it is nice to just use the keyword
623 as a class name. But if you get into conflicts with other, existing
624 CSS classes, then this prefix can be very useful."
625 :group 'org-export-e-html
626 :type 'string)
629 ;;;; Template :: Generic
631 (defcustom org-e-html-extension "html"
632 "The extension for exported HTML files."
633 :group 'org-export-e-html
634 :type 'string)
636 (defcustom org-e-html-xml-declaration
637 '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>")
638 ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>"))
639 "The extension for exported HTML files.
640 %s will be replaced with the charset of the exported file.
641 This may be a string, or an alist with export extensions
642 and corresponding declarations."
643 :group 'org-export-e-html
644 :type '(choice
645 (string :tag "Single declaration")
646 (repeat :tag "Dependent on extension"
647 (cons (string :tag "Extension")
648 (string :tag "Declaration")))))
650 (defcustom org-e-html-coding-system 'utf-8
651 "Coding system for HTML export.
652 Use utf-8 as the default value."
653 :group 'org-export-e-html
654 :type 'coding-system)
656 (defcustom org-e-html-divs '("preamble" "content" "postamble")
657 "The name of the main divs for HTML export.
658 This is a list of three strings, the first one for the preamble
659 DIV, the second one for the content DIV and the third one for the
660 postamble DIV."
661 :group 'org-export-e-html
662 :type '(list
663 (string :tag " Div for the preamble:")
664 (string :tag " Div for the content:")
665 (string :tag "Div for the postamble:")))
668 ;;;; Template :: Mathjax
670 (defcustom org-e-html-mathjax-options
671 '((path "http://orgmode.org/mathjax/MathJax.js")
672 (scale "100")
673 (align "center")
674 (indent "2em")
675 (mathml nil))
676 "Options for MathJax setup.
678 path The path where to find MathJax
679 scale Scaling for the HTML-CSS backend, usually between 100 and 133
680 align How to align display math: left, center, or right
681 indent If align is not center, how far from the left/right side?
682 mathml Should a MathML player be used if available?
683 This is faster and reduces bandwidth use, but currently
684 sometimes has lower spacing quality. Therefore, the default is
685 nil. When browsers get better, this switch can be flipped.
687 You can also customize this for each buffer, using something like
689 #+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\""
690 :group 'org-export-e-html
691 :type '(list :greedy t
692 (list :tag "path (the path from where to load MathJax.js)"
693 (const :format " " path) (string))
694 (list :tag "scale (scaling for the displayed math)"
695 (const :format " " scale) (string))
696 (list :tag "align (alignment of displayed equations)"
697 (const :format " " align) (string))
698 (list :tag "indent (indentation with left or right alignment)"
699 (const :format " " indent) (string))
700 (list :tag "mathml (should MathML display be used is possible)"
701 (const :format " " mathml) (boolean))))
703 (defcustom org-e-html-mathjax-template
704 "<script type=\"text/javascript\" src=\"%PATH\">
705 <!--/*--><![CDATA[/*><!--*/
706 MathJax.Hub.Config({
707 // Only one of the two following lines, depending on user settings
708 // First allows browser-native MathML display, second forces HTML/CSS
709 :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"],
710 :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"],
711 extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\",
712 \"TeX/noUndefined.js\"],
713 tex2jax: {
714 inlineMath: [ [\"\\\\(\",\"\\\\)\"] ],
715 displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ],
716 skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"],
717 ignoreClass: \"tex2jax_ignore\",
718 processEscapes: false,
719 processEnvironments: true,
720 preview: \"TeX\"
722 showProcessingMessages: true,
723 displayAlign: \"%ALIGN\",
724 displayIndent: \"%INDENT\",
726 \"HTML-CSS\": {
727 scale: %SCALE,
728 availableFonts: [\"STIX\",\"TeX\"],
729 preferredFont: \"TeX\",
730 webFont: \"TeX\",
731 imageFont: \"TeX\",
732 showMathMenu: true,
734 MMLorHTML: {
735 prefer: {
736 MSIE: \"MML\",
737 Firefox: \"MML\",
738 Opera: \"HTML\",
739 other: \"HTML\"
743 /*]]>*///-->
744 </script>"
745 "The MathJax setup for XHTML files."
746 :group 'org-export-e-html
747 :type 'string)
750 ;;;; Template :: Postamble
752 (defcustom org-e-html-postamble 'auto
753 "Non-nil means insert a postamble in HTML export.
755 When `t', insert a string as defined by the formatting string in
756 `org-e-html-postamble-format'. When set to a string, this
757 string overrides `org-e-html-postamble-format'. When set to
758 'auto, discard `org-e-html-postamble-format' and honor
759 `org-export-author/email/creator-info' variables. When set to a
760 function, apply this function and insert the returned string.
761 The function takes the property list of export options as its
762 only argument.
764 Setting :html-postamble in publishing projects will take
765 precedence over this variable."
766 :group 'org-export-e-html
767 :type '(choice (const :tag "No postamble" nil)
768 (const :tag "Auto preamble" 'auto)
769 (const :tag "Default formatting string" t)
770 (string :tag "Custom formatting string")
771 (function :tag "Function (must return a string)")))
773 (defcustom org-e-html-postamble-format
774 '(("en" "<p class=\"author\">Author: %a (%e)</p>
775 <p class=\"date\">Date: %d</p>
776 <p class=\"creator\">Generated by %c</p>
777 <p class=\"xhtml-validation\">%v</p>"))
778 "Alist of languages and format strings for the HTML postamble.
780 The first element of each list is the language code, as used for
781 the #+LANGUAGE keyword.
783 The second element of each list is a format string to format the
784 postamble itself. This format string can contain these elements:
786 %a stands for the author's name.
787 %e stands for the author's email.
788 %d stands for the date.
789 %c will be replaced by information about Org/Emacs versions.
790 %v will be replaced by `org-e-html-validation-link'.
792 If you need to use a \"%\" character, you need to escape it
793 like that: \"%%\"."
794 :group 'org-export-e-html
795 :type '(alist :key-type (string :tag "Language")
796 :value-type (string :tag "Format string")))
798 (defcustom org-e-html-validation-link
799 "<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>"
800 "Link to HTML validation service."
801 :group 'org-export-e-html
802 :type 'string)
804 (defcustom org-e-html-creator-string
805 (format "Generated by <a href=\"http://orgmode.org\">Org</a> mode %s in <a href=\"http://www.gnu.org/software/emacs/\">Emacs</a> %s."
806 (if (fboundp 'org-version) (org-version) "(Unknown)")
807 emacs-version)
808 "String to insert at the end of the HTML document."
809 :group 'org-export-e-html
810 :type '(string :tag "Creator string"))
813 ;;;; Template :: Preamble
815 (defcustom org-e-html-preamble t
816 "Non-nil means insert a preamble in HTML export.
818 When `t', insert a string as defined by one of the formatting
819 strings in `org-e-html-preamble-format'. When set to a
820 string, this string overrides `org-e-html-preamble-format'.
821 When set to a function, apply this function and insert the
822 returned string. The function takes the property list of export
823 options as its only argument.
825 Setting :html-preamble in publishing projects will take
826 precedence over this variable."
827 :group 'org-export-e-html
828 :type '(choice (const :tag "No preamble" nil)
829 (const :tag "Default preamble" t)
830 (string :tag "Custom formatting string")
831 (function :tag "Function (must return a string)")))
833 (defcustom org-e-html-preamble-format '(("en" ""))
834 "Alist of languages and format strings for the HTML preamble.
836 The first element of each list is the language code, as used for
837 the #+LANGUAGE keyword.
839 The second element of each list is a format string to format the
840 preamble itself. This format string can contain these elements:
842 %t stands for the title.
843 %a stands for the author's name.
844 %e stands for the author's email.
845 %d stands for the date.
847 If you need to use a \"%\" character, you need to escape it
848 like that: \"%%\"."
849 :group 'org-export-e-html
850 :type '(alist :key-type (string :tag "Language")
851 :value-type (string :tag "Format string")))
853 (defcustom org-e-html-link-up ""
854 "Where should the \"UP\" link of exported HTML pages lead?"
855 :group 'org-export-e-html
856 :type '(string :tag "File or URL"))
858 (defcustom org-e-html-link-home ""
859 "Where should the \"HOME\" link of exported HTML pages lead?"
860 :group 'org-export-e-html
861 :type '(string :tag "File or URL"))
863 (defcustom org-e-html-home/up-format
864 "<div id=\"org-div-home-and-up\" style=\"text-align:right;font-size:70%%;white-space:nowrap;\">
865 <a accesskey=\"h\" href=\"%s\"> UP </a>
867 <a accesskey=\"H\" href=\"%s\"> HOME </a>
868 </div>"
869 "Snippet used to insert the HOME and UP links.
870 This is a format string, the first %s will receive the UP link,
871 the second the HOME link. If both `org-e-html-link-up' and
872 `org-e-html-link-home' are empty, the entire snippet will be
873 ignored."
874 :group 'org-export-e-html
875 :type 'string)
878 ;;;; Template :: Scripts
880 (defcustom org-e-html-style-include-scripts t
881 "Non-nil means include the JavaScript snippets in exported HTML files.
882 The actual script is defined in `org-e-html-scripts' and should
883 not be modified."
884 :group 'org-export-e-html
885 :type 'boolean)
888 ;;;; Template :: Styles
890 (defcustom org-e-html-style-include-default t
891 "Non-nil means include the default style in exported HTML files.
892 The actual style is defined in `org-e-html-style-default' and should
893 not be modified. Use the variables `org-e-html-style' to add
894 your own style information."
895 :group 'org-export-e-html
896 :type 'boolean)
897 ;;;###autoload
898 (put 'org-e-html-style-include-default 'safe-local-variable 'booleanp)
900 (defcustom org-e-html-style ""
901 "Org-wide style definitions for exported HTML files.
903 This variable needs to contain the full HTML structure to provide a style,
904 including the surrounding HTML tags. If you set the value of this variable,
905 you should consider to include definitions for the following classes:
906 title, todo, done, timestamp, timestamp-kwd, tag, target.
908 For example, a valid value would be:
910 <style type=\"text/css\">
911 <![CDATA[
912 p { font-weight: normal; color: gray; }
913 h1 { color: black; }
914 .title { text-align: center; }
915 .todo, .timestamp-kwd { color: red; }
916 .done { color: green; }
918 </style>
920 If you'd like to refer to an external style file, use something like
922 <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
924 As the value of this option simply gets inserted into the HTML <head> header,
925 you can \"misuse\" it to add arbitrary text to the header.
926 See also the variable `org-e-html-style-extra'."
927 :group 'org-export-e-html
928 :type 'string)
929 ;;;###autoload
930 (put 'org-e-html-style 'safe-local-variable 'stringp)
932 (defcustom org-e-html-style-extra ""
933 "Additional style information for HTML export.
934 The value of this variable is inserted into the HTML buffer right after
935 the value of `org-e-html-style'. Use this variable for per-file
936 settings of style information, and do not forget to surround the style
937 settings with <style>...</style> tags."
938 :group 'org-export-e-html
939 :type 'string)
940 ;;;###autoload
941 (put 'org-e-html-style-extra 'safe-local-variable 'stringp)
944 ;;;; Todos
946 (defcustom org-e-html-todo-kwd-class-prefix ""
947 "Prefix to class names for TODO keywords.
948 Each TODO keyword gets a class given by the keyword itself, with this prefix.
949 The default prefix is empty because it is nice to just use the keyword
950 as a class name. But if you get into conflicts with other, existing
951 CSS classes, then this prefix can be very useful."
952 :group 'org-export-e-html
953 :type 'string)
957 ;;; Internal Functions
959 (defun org-e-html-format-inline-image (src &optional
960 caption label attr standalone-p)
961 (let* ((id (if (not label) ""
962 (format " id=\"%s\"" (org-export-solidify-link-text label))))
963 (attr (concat attr
964 (cond
965 ((string-match "\\<alt=" (or attr "")) "")
966 ((string-match "^ltxpng/" src)
967 (format " alt=\"%s\""
968 (org-e-html-encode-plain-text
969 (org-find-text-property-in-string
970 'org-latex-src src))))
971 (t (format " alt=\"%s\""
972 (file-name-nondirectory src)))))))
973 (cond
974 (standalone-p
975 (let ((img (format "<img src=\"%s\" %s/>" src attr)))
976 (format "\n<div%s class=\"figure\">%s%s\n</div>"
977 id (format "\n<p>%s</p>" img)
978 (when caption (format "\n<p>%s</p>" caption)))))
979 (t (format "<img src=\"%s\" %s/>" src (concat attr id))))))
981 (defun org-e-html--textarea-block (element)
982 "Transcode ELEMENT into a textarea block.
983 ELEMENT is either a src block or an example block."
984 (let ((code (car (org-export-unravel-code element)))
985 (attr (org-export-read-attribute :attr_html element)))
986 (format "<p>\n<textarea cols=\"%d\" rows=\"%d\">\n%s</textarea>\n</p>"
987 (or (plist-get attr :width) 80)
988 (or (plist-get attr :height) (org-count-lines code))
989 code)))
992 ;;;; Bibliography
994 (defun org-e-html-bibliography ()
995 "Find bibliography, cut it out and return it."
996 (catch 'exit
997 (let (beg end (cnt 1) bib)
998 (save-excursion
999 (goto-char (point-min))
1000 (when (re-search-forward
1001 "^[ \t]*<div \\(id\\|class\\)=\"bibliography\"" nil t)
1002 (setq beg (match-beginning 0))
1003 (while (re-search-forward "</?div\\>" nil t)
1004 (setq cnt (+ cnt (if (string= (match-string 0) "<div") +1 -1)))
1005 (when (= cnt 0)
1006 (and (looking-at ">") (forward-char 1))
1007 (setq bib (buffer-substring beg (point)))
1008 (delete-region beg (point))
1009 (throw 'exit bib))))
1010 nil))))
1012 ;;;; Table
1014 (defun org-e-html-splice-attributes (tag attributes)
1015 "Read attributes in string ATTRIBUTES, add and replace in HTML tag TAG."
1016 (if (not attributes)
1018 (let (oldatt newatt)
1019 (setq oldatt (org-extract-attributes-from-string tag)
1020 tag (pop oldatt)
1021 newatt (cdr (org-extract-attributes-from-string attributes)))
1022 (while newatt
1023 (setq oldatt (plist-put oldatt (pop newatt) (pop newatt))))
1024 (if (string-match ">" tag)
1025 (setq tag
1026 (replace-match (concat (org-attributes-to-string oldatt) ">")
1027 t t tag)))
1028 tag)))
1030 (defun org-export-splice-style (style extra)
1031 "Splice EXTRA into STYLE, just before \"</style>\"."
1032 (if (and (stringp extra)
1033 (string-match "\\S-" extra)
1034 (string-match "</style>" style))
1035 (concat (substring style 0 (match-beginning 0))
1036 "\n" extra "\n"
1037 (substring style (match-beginning 0)))
1038 style))
1040 (defun org-export-e-htmlize-region-for-paste (beg end)
1041 "Convert the region to HTML, using htmlize.el.
1042 This is much like `htmlize-region-for-paste', only that it uses
1043 the settings define in the org-... variables."
1044 (let* ((htmlize-output-type org-export-e-htmlize-output-type)
1045 (htmlize-css-name-prefix org-export-e-htmlize-css-font-prefix)
1046 (htmlbuf (htmlize-region beg end)))
1047 (unwind-protect
1048 (with-current-buffer htmlbuf
1049 (buffer-substring (plist-get htmlize-buffer-places 'content-start)
1050 (plist-get htmlize-buffer-places 'content-end)))
1051 (kill-buffer htmlbuf))))
1053 ;;;###autoload
1054 (defun org-export-e-htmlize-generate-css ()
1055 "Create the CSS for all font definitions in the current Emacs session.
1056 Use this to create face definitions in your CSS style file that can then
1057 be used by code snippets transformed by htmlize.
1058 This command just produces a buffer that contains class definitions for all
1059 faces used in the current Emacs session. You can copy and paste the ones you
1060 need into your CSS file.
1062 If you then set `org-export-e-htmlize-output-type' to `css', calls to
1063 the function `org-export-e-htmlize-region-for-paste' will produce code
1064 that uses these same face definitions."
1065 (interactive)
1066 (require 'htmlize)
1067 (and (get-buffer "*html*") (kill-buffer "*html*"))
1068 (with-temp-buffer
1069 (let ((fl (face-list))
1070 (htmlize-css-name-prefix "org-")
1071 (htmlize-output-type 'css)
1072 f i)
1073 (while (setq f (pop fl)
1074 i (and f (face-attribute f :inherit)))
1075 (when (and (symbolp f) (or (not i) (not (listp i))))
1076 (insert (org-add-props (copy-sequence "1") nil 'face f))))
1077 (htmlize-region (point-min) (point-max))))
1078 (org-pop-to-buffer-same-window "*html*")
1079 (goto-char (point-min))
1080 (if (re-search-forward "<style" nil t)
1081 (delete-region (point-min) (match-beginning 0)))
1082 (if (re-search-forward "</style>" nil t)
1083 (delete-region (1+ (match-end 0)) (point-max)))
1084 (beginning-of-line 1)
1085 (if (looking-at " +") (replace-match ""))
1086 (goto-char (point-min)))
1088 (defun org-e-html--make-string (n string)
1089 "Build a string by concatenating N times STRING."
1090 (let (out) (dotimes (i n out) (setq out (concat string out)))))
1092 (defun org-e-html-toc-text (toc-entries)
1093 (let* ((prev-level (1- (nth 1 (car toc-entries))))
1094 (start-level prev-level))
1095 (concat
1096 (mapconcat
1097 (lambda (entry)
1098 (let ((headline (nth 0 entry))
1099 (level (nth 1 entry)))
1100 (concat
1101 (let* ((cnt (- level prev-level))
1102 (times (if (> cnt 0) (1- cnt) (- cnt)))
1103 rtn)
1104 (setq prev-level level)
1105 (concat
1106 (org-e-html--make-string
1107 times (cond ((> cnt 0) "\n<ul>\n<li>")
1108 ((< cnt 0) "</li>\n</ul>\n")))
1109 (if (> cnt 0) "\n<ul>\n<li>" "</li>\n<li>")))
1110 headline)))
1111 toc-entries "")
1112 (org-e-html--make-string (- prev-level start-level) "</li>\n</ul>\n"))))
1114 (defun* org-e-html-format-toc-headline
1115 (todo todo-type priority text tags
1116 &key level section-number headline-label &allow-other-keys)
1117 (let ((headline (concat
1118 section-number (and section-number ". ")
1119 text
1120 (and tags "&nbsp;&nbsp;&nbsp;") (org-e-html--tags tags))))
1121 (format "<a href=\"#%s\">%s</a>"
1122 (org-export-solidify-link-text headline-label)
1123 (if (not nil) headline
1124 (format "<span class=\"%s\">%s</span>" todo-type headline)))))
1126 (defun org-e-html-toc (depth info)
1127 (let* ((headlines (org-export-collect-headlines info depth))
1128 (toc-entries
1129 (loop for headline in headlines collect
1130 (list (org-e-html-format-headline--wrap
1131 headline info 'org-e-html-format-toc-headline)
1132 (org-export-get-relative-level headline info)))))
1133 (when toc-entries
1134 (concat
1135 "<div id=\"table-of-contents\">\n"
1136 (format "<h%d>%s</h%d>\n"
1137 org-e-html-toplevel-hlevel
1138 (org-e-html--translate "Table of Contents" info)
1139 org-e-html-toplevel-hlevel)
1140 "<div id=\"text-table-of-contents\">"
1141 (org-e-html-toc-text toc-entries)
1142 "</div>\n"
1143 "</div>\n"))))
1145 (defun org-e-html-fix-class-name (kwd) ; audit callers of this function
1146 "Turn todo keyword into a valid class name.
1147 Replaces invalid characters with \"_\"."
1148 (save-match-data
1149 (while (string-match "[^a-zA-Z0-9_]" kwd)
1150 (setq kwd (replace-match "_" t t kwd))))
1151 kwd)
1153 (defun org-e-html-format-footnote-reference (n def refcnt)
1154 (let ((extra (if (= refcnt 1) "" (format ".%d" refcnt))))
1155 (format org-e-html-footnote-format
1156 (let* ((id (format "fnr.%s%s" n extra))
1157 (href (format " href=\"#fn.%s\"" n))
1158 (attributes (concat " class=\"footref\"" href)))
1159 (org-e-html--anchor id n attributes)))))
1161 (defun org-e-html-format-footnotes-section (section-name definitions)
1162 (if (not definitions) ""
1163 (format org-e-html-footnotes-section section-name definitions)))
1165 (defun org-e-html-format-footnote-definition (fn)
1166 (let ((n (car fn)) (def (cdr fn)))
1167 (format
1168 "<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>\n"
1169 (format org-e-html-footnote-format
1170 (let* ((id (format "fn.%s" n))
1171 (href (format " href=\"#fnr.%s\"" n))
1172 (attributes (concat " class=\"footnum\"" href)))
1173 (org-e-html--anchor id n attributes)))
1174 def)))
1176 (defun org-e-html-footnote-section (info)
1177 (let* ((fn-alist (org-export-collect-footnote-definitions
1178 (plist-get info :parse-tree) info))
1180 (fn-alist
1181 (loop for (n type raw) in fn-alist collect
1182 (cons n (if (eq (org-element-type raw) 'org-data)
1183 (org-trim (org-export-data raw info))
1184 (format "<p>%s</p>"
1185 (org-trim (org-export-data raw info))))))))
1186 (when fn-alist
1187 (org-e-html-format-footnotes-section
1188 (org-e-html--translate "Footnotes" info)
1189 (format
1190 "<table>\n%s\n</table>\n"
1191 (mapconcat 'org-e-html-format-footnote-definition fn-alist "\n"))))))
1195 ;;; Template
1197 (defun org-e-html--build-meta-info (info)
1198 "Return meta tags for exported document.
1199 INFO is a plist used as a communication channel."
1200 (let* ((title (org-export-data (plist-get info :title) info))
1201 (author (and (plist-get info :with-author)
1202 (let ((auth (plist-get info :author)))
1203 (and auth (org-export-data auth info)))))
1204 (date (and (plist-get info :with-date)
1205 (let ((date (plist-get info :date)))
1206 (and date (org-export-data date info)))))
1207 (description (plist-get info :description))
1208 (keywords (plist-get info :keywords)))
1209 (concat
1210 (format "<title>%s</title>\n" title)
1211 (format
1212 "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>"
1213 (or (and org-e-html-coding-system
1214 (fboundp 'coding-system-get)
1215 (coding-system-get org-e-html-coding-system 'mime-charset))
1216 "iso-8859-1"))
1217 (format "<meta name=\"title\" content=\"%s\"/>\n" title)
1218 (format "<meta name=\"generator\" content=\"Org-mode\"/>\n")
1219 (and date (format "<meta name=\"generated\" content=\"%s\"/>\n" date))
1220 (and author (format "<meta name=\"author\" content=\"%s\"/>\n" author))
1221 (and description
1222 (format "<meta name=\"description\" content=\"%s\"/>\n" description))
1223 (and keywords
1224 (format "<meta name=\"keywords\" content=\"%s\"/>\n" keywords)))))
1226 (defun org-e-html--build-style (info)
1227 "Return style information for exported document.
1228 INFO is a plist used as a communication channel."
1229 (org-element-normalize-string
1230 (concat
1231 (when (plist-get info :style-include-default) org-e-html-style-default)
1232 (org-element-normalize-string (plist-get info :style))
1233 (org-element-normalize-string (plist-get info :style-extra))
1234 (when (plist-get info :style-include-scripts) org-e-html-scripts))))
1236 (defun org-e-html--build-mathjax-config (info)
1237 "Insert the user setup into the mathjax template.
1238 INFO is a plist used as a communication channel."
1239 (when (member (plist-get info :LaTeX-fragments) '(mathjax t))
1240 (let ((template org-e-html-mathjax-template)
1241 (options org-e-html-mathjax-options)
1242 (in-buffer (or (plist-get info :mathjax) ""))
1243 name val (yes " ") (no "// ") x)
1244 (mapc
1245 (lambda (e)
1246 (setq name (car e) val (nth 1 e))
1247 (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer)
1248 (setq val (car (read-from-string
1249 (substring in-buffer (match-end 0))))))
1250 (if (not (stringp val)) (setq val (format "%s" val)))
1251 (if (string-match (concat "%" (upcase (symbol-name name))) template)
1252 (setq template (replace-match val t t template))))
1253 options)
1254 (setq val (nth 1 (assq 'mathml options)))
1255 (if (string-match (concat "\\<mathml:") in-buffer)
1256 (setq val (car (read-from-string
1257 (substring in-buffer (match-end 0))))))
1258 ;; Exchange prefixes depending on mathml setting.
1259 (if (not val) (setq x yes yes no no x))
1260 ;; Replace cookies to turn on or off the config/jax lines.
1261 (if (string-match ":MMLYES:" template)
1262 (setq template (replace-match yes t t template)))
1263 (if (string-match ":MMLNO:" template)
1264 (setq template (replace-match no t t template)))
1265 ;; Return the modified template.
1266 (org-element-normalize-string template))))
1268 (defun org-e-html--build-preamble (info)
1269 "Return document preamble as a string, or nil.
1270 INFO is a plist used as a communication channel."
1271 (let ((preamble (plist-get info :html-preamble)))
1272 (when preamble
1273 (let ((preamble-contents
1274 (if (functionp preamble) (funcall preamble info)
1275 (let ((title (org-export-data (plist-get info :title) info))
1276 (date (if (not (plist-get info :with-date)) ""
1277 (org-export-data (plist-get info :date) info)))
1278 (author (if (not (plist-get info :with-author)) ""
1279 (org-export-data (plist-get info :author) info)))
1280 (email (if (not (plist-get info :with-email)) ""
1281 (plist-get info :email))))
1282 (if (stringp preamble)
1283 (format-spec preamble
1284 `((?t . ,title) (?a . ,author)
1285 (?d . ,date) (?e . ,email)))
1286 (format-spec
1287 (or (cadr (assoc (plist-get info :language)
1288 org-e-html-preamble-format))
1289 (cadr (assoc "en" org-e-html-preamble-format)))
1290 `((?t . ,title) (?a . ,author)
1291 (?d . ,date) (?e . ,email))))))))
1292 (when (org-string-nw-p preamble-contents)
1293 (concat (format "<div id=\"%s\">\n" (nth 0 org-e-html-divs))
1294 (org-element-normalize-string preamble-contents)
1295 "</div>\n"))))))
1297 (defun org-e-html--build-postamble (info)
1298 "Return document postamble as a string, or nil.
1299 INFO is a plist used as a communication channel."
1300 (let ((postamble (plist-get info :html-postamble)))
1301 (when postamble
1302 (let ((postamble-contents
1303 (if (functionp postamble) (funcall postamble info)
1304 (let ((date (if (not (plist-get info :with-date)) ""
1305 (org-export-data (plist-get info :date) info)))
1306 (author (let ((author (plist-get info :author)))
1307 (and author (org-export-data author info))))
1308 (email (mapconcat
1309 (lambda (e)
1310 (format "<a href=\"mailto:%s\">%s</a>" e e))
1311 (split-string (plist-get info :email) ",+ *")
1312 ", "))
1313 (html-validation-link (or org-e-html-validation-link ""))
1314 (creator-info (plist-get info :creator)))
1315 (cond ((stringp postamble)
1316 (format-spec postamble
1317 `((?a . ,author) (?e . ,email)
1318 (?d . ,date) (?c . ,creator-info)
1319 (?v . ,html-validation-link))))
1320 ((eq postamble 'auto)
1321 (concat
1322 (when (plist-get info :time-stamp-file)
1323 (format "<p class=\"date\">%s: %s</p>\n"
1324 (org-e-html--translate "Date" info)
1325 date))
1326 (when (and (plist-get info :with-author) author)
1327 (format "<p class=\"author\">%s : %s</p>\n"
1328 (org-e-html--translate "Author" info)
1329 author))
1330 (when (and (plist-get info :with-email) email)
1331 (format "<p class=\"email\">%s </p>\n" email))
1332 (when (plist-get info :with-creator)
1333 (format "<p class=\"creator\">%s</p>\n"
1334 creator-info))
1335 html-validation-link "\n"))
1336 (t (format-spec
1337 (or (cadr (assoc (plist-get info :language)
1338 org-e-html-postamble-format))
1339 (cadr (assoc "en" org-e-html-postamble-format)))
1340 `((?a . ,author) (?e . ,email)
1341 (?d . ,date) (?c . ,creator-info)
1342 (?v . ,html-validation-link)))))))))
1343 (when (org-string-nw-p postamble-contents)
1344 (concat
1345 (format "<div id=\"%s\">\n" (nth 2 org-e-html-divs))
1346 (org-element-normalize-string postamble-contents)
1347 "</div>\n"))))))
1349 (defun org-e-html-template (contents info)
1350 "Return complete document string after HTML conversion.
1351 CONTENTS is the transcoded contents string. INFO is a plist
1352 holding export options."
1353 (concat
1354 (format
1355 (or (and (stringp org-e-html-xml-declaration)
1356 org-e-html-xml-declaration)
1357 (cdr (assoc (plist-get info :html-extension)
1358 org-e-html-xml-declaration))
1359 (cdr (assoc "html" org-e-html-xml-declaration))
1362 (or (and org-e-html-coding-system
1363 (fboundp 'coding-system-get)
1364 (coding-system-get org-e-html-coding-system 'mime-charset))
1365 "iso-8859-1"))
1366 "\n"
1367 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
1368 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
1369 (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">\n"
1370 (plist-get info :language) (plist-get info :language))
1371 "<head>\n"
1372 (org-e-html--build-meta-info info)
1373 (org-e-html--build-style info)
1374 (org-e-html--build-mathjax-config info)
1375 "</head>\n"
1376 "<body>\n"
1377 (let ((link-up (org-trim (plist-get info :link-up)))
1378 (link-home (org-trim (plist-get info :link-home))))
1379 (unless (and (string= link-up "") (string= link-up ""))
1380 (format org-e-html-home/up-format
1381 (or link-up link-home)
1382 (or link-home link-up))))
1383 ;; Preamble.
1384 (org-e-html--build-preamble info)
1385 ;; Begin content.
1386 (format "<div id=\"%s\">\n" (nth 1 org-e-html-divs))
1387 ;; Document title.
1388 (format "<h1 class=\"title\">%s</h1>\n"
1389 (org-export-data (plist-get info :title) info))
1390 ;; Table of contents.
1391 (let ((depth (plist-get info :with-toc)))
1392 (when depth (org-e-html-toc depth info)))
1393 ;; Document contents.
1394 contents
1395 ;; Footnotes section.
1396 (org-e-html-footnote-section info)
1397 ;; Bibliography.
1398 (org-e-html-bibliography)
1399 ;; End content.
1400 "\n</div>"
1401 ;; Postamble.
1402 (org-e-html--build-postamble info)
1403 ;; Closing document.
1404 "</body>\n</html>"))
1406 (defun org-e-html--translate (s info)
1407 "Translate string S according to specified language.
1408 INFO is a plist used as a communication channel."
1409 (org-export-translate s :html info))
1411 ;;;; Anchor
1413 (defun org-e-html--anchor (&optional id desc attributes)
1414 (let* ((name (and org-e-html-allow-name-attribute-in-anchors id))
1415 (attributes (concat (and id (format " id=\"%s\"" id))
1416 (and name (format " name=\"%s\"" name))
1417 attributes)))
1418 (format "<a%s>%s</a>" attributes (or desc ""))))
1420 ;;;; Todo
1422 (defun org-e-html--todo (todo)
1423 (when todo
1424 (format "<span class=\"%s %s%s\">%s</span>"
1425 (if (member todo org-done-keywords) "done" "todo")
1426 org-e-html-todo-kwd-class-prefix (org-e-html-fix-class-name todo)
1427 todo)))
1429 ;;;; Tags
1431 (defun org-e-html--tags (tags)
1432 (when tags
1433 (format "<span class=\"tag\">%s</span>"
1434 (mapconcat
1435 (lambda (tag)
1436 (format "<span class=\"%s\">%s</span>"
1437 (concat org-e-html-tag-class-prefix
1438 (org-e-html-fix-class-name tag))
1439 tag))
1440 tags "&nbsp;"))))
1442 ;;;; Headline
1444 (defun* org-e-html-format-headline
1445 (todo todo-type priority text tags
1446 &key level section-number headline-label &allow-other-keys)
1447 (let ((section-number
1448 (when section-number
1449 (format "<span class=\"section-number-%d\">%s</span> "
1450 level section-number)))
1451 (todo (org-e-html--todo todo))
1452 (tags (org-e-html--tags tags)))
1453 (concat section-number todo (and todo " ") text
1454 (and tags "&nbsp;&nbsp;&nbsp;") tags)))
1456 ;;;; Src Code
1458 (defun org-e-html-fontify-code (code lang)
1459 "Color CODE with htmlize library.
1460 CODE is a string representing the source code to colorize. LANG
1461 is the language used for CODE, as a string, or nil."
1462 (when code
1463 (cond
1464 ;; Case 1: No lang. Possibly an example block.
1465 ((not lang)
1466 ;; Simple transcoding.
1467 (org-e-html-encode-plain-text code))
1468 ;; Case 2: No htmlize or an inferior version of htmlize
1469 ((not (and (require 'htmlize nil t) (fboundp 'htmlize-region-for-paste)))
1470 ;; Emit a warning.
1471 (message "Cannot fontify src block (htmlize.el >= 1.34 required)")
1472 ;; Simple transcoding.
1473 (org-e-html-encode-plain-text code))
1475 ;; Map language
1476 (setq lang (or (assoc-default lang org-src-lang-modes) lang))
1477 (let* ((lang-mode (and lang (intern (format "%s-mode" lang)))))
1478 (cond
1479 ;; Case 1: Language is not associated with any Emacs mode
1480 ((not (functionp lang-mode))
1481 ;; Simple transcoding.
1482 (org-e-html-encode-plain-text code))
1483 ;; Case 2: Default. Fontify code.
1485 ;; htmlize
1486 (setq code (with-temp-buffer
1487 ;; Switch to language-specific mode.
1488 (funcall lang-mode)
1489 (insert code)
1490 ;; Fontify buffer.
1491 (font-lock-fontify-buffer)
1492 ;; Remove formatting on newline characters.
1493 (save-excursion
1494 (let ((beg (point-min))
1495 (end (point-max)))
1496 (goto-char beg)
1497 (while (progn (end-of-line) (< (point) end))
1498 (put-text-property (point) (1+ (point)) 'face nil)
1499 (forward-char 1))))
1500 (org-src-mode)
1501 (set-buffer-modified-p nil)
1502 ;; Htmlize region.
1503 (org-export-e-htmlize-region-for-paste
1504 (point-min) (point-max))))
1505 ;; Strip any encolosing <pre></pre> tags.
1506 (if (string-match "<pre[^>]*>\n*\\([^\000]*\\)</pre>" code)
1507 (match-string 1 code)
1508 code))))))))
1510 (defun org-e-html-do-format-code
1511 (code &optional lang refs retain-labels num-start)
1512 "Format CODE string as source code.
1513 Optional arguments LANG, REFS, RETAIN-LABELS and NUM-START are,
1514 respectively, the language of the source code, as a string, an
1515 alist between line numbers and references (as returned by
1516 `org-export-unravel-code'), a boolean specifying if labels should
1517 appear in the source code, and the number associated to the first
1518 line of code."
1519 (let* ((code-lines (org-split-string code "\n"))
1520 (code-length (length code-lines))
1521 (num-fmt
1522 (and num-start
1523 (format "%%%ds: "
1524 (length (number-to-string (+ code-length num-start))))))
1525 (code (org-e-html-fontify-code code lang)))
1526 (org-export-format-code
1527 code
1528 (lambda (loc line-num ref)
1529 (setq loc
1530 (concat
1531 ;; Add line number, if needed.
1532 (when num-start
1533 (format "<span class=\"linenr\">%s</span>"
1534 (format num-fmt line-num)))
1535 ;; Transcoded src line.
1537 ;; Add label, if needed.
1538 (when (and ref retain-labels) (format " (%s)" ref))))
1539 ;; Mark transcoded line as an anchor, if needed.
1540 (if (not ref) loc
1541 (format "<span id=\"coderef-%s\" class=\"coderef-off\">%s</span>"
1542 ref loc)))
1543 num-start refs)))
1545 (defun org-e-html-format-code (element info)
1546 "Format contents of ELEMENT as source code.
1547 ELEMENT is either an example block or a src block. INFO is
1548 a plist used as a communication channel."
1549 (let* ((lang (org-element-property :language element))
1550 ;; Extract code and references.
1551 (code-info (org-export-unravel-code element))
1552 (code (car code-info))
1553 (refs (cdr code-info))
1554 ;; Does the src block contain labels?
1555 (retain-labels (org-element-property :retain-labels element))
1556 ;; Does it have line numbers?
1557 (num-start (case (org-element-property :number-lines element)
1558 (continued (org-export-get-loc element info))
1559 (new 0))))
1560 (org-e-html-do-format-code code lang refs retain-labels num-start)))
1564 ;;; Transcode Functions
1566 ;;;; Bold
1568 (defun org-e-html-bold (bold contents info)
1569 "Transcode BOLD from Org to HTML.
1570 CONTENTS is the text with bold markup. INFO is a plist holding
1571 contextual information."
1572 (format (or (cdr (assq 'bold org-e-html-text-markup-alist)) "%s")
1573 contents))
1576 ;;;; Center Block
1578 (defun org-e-html-center-block (center-block contents info)
1579 "Transcode a CENTER-BLOCK element from Org to HTML.
1580 CONTENTS holds the contents of the block. INFO is a plist
1581 holding contextual information."
1582 (format "<div style=\"text-align: center\">\n%s</div>" contents))
1585 ;;;; Clock
1587 (defun org-e-html-clock (clock contents info)
1588 "Transcode a CLOCK element from Org to HTML.
1589 CONTENTS is nil. INFO is a plist used as a communication
1590 channel."
1591 (format "<p>
1592 <span class=\"timestamp-wrapper\">
1593 <span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>%s
1594 </span>
1595 </p>"
1596 org-clock-string
1597 (org-translate-time
1598 (org-element-property :raw-value
1599 (org-element-property :value clock)))
1600 (let ((time (org-element-property :duration clock)))
1601 (and time (format " <span class=\"timestamp\">(%s)</span>" time)))))
1604 ;;;; Code
1606 (defun org-e-html-code (code contents info)
1607 "Transcode CODE from Org to HTML.
1608 CONTENTS is nil. INFO is a plist holding contextual
1609 information."
1610 (format (or (cdr (assq 'code org-e-html-text-markup-alist)) "%s")
1611 (org-element-property :value code)))
1614 ;;;; Drawer
1616 (defun org-e-html-drawer (drawer contents info)
1617 "Transcode a DRAWER element from Org to HTML.
1618 CONTENTS holds the contents of the block. INFO is a plist
1619 holding contextual information."
1620 (if (functionp org-e-html-format-drawer-function)
1621 (funcall org-e-html-format-drawer-function
1622 (org-element-property :drawer-name drawer)
1623 contents)
1624 ;; If there's no user defined function: simply
1625 ;; display contents of the drawer.
1626 contents))
1629 ;;;; Dynamic Block
1631 (defun org-e-html-dynamic-block (dynamic-block contents info)
1632 "Transcode a DYNAMIC-BLOCK element from Org to HTML.
1633 CONTENTS holds the contents of the block. INFO is a plist
1634 holding contextual information. See `org-export-data'."
1635 contents)
1638 ;;;; Entity
1640 (defun org-e-html-entity (entity contents info)
1641 "Transcode an ENTITY object from Org to HTML.
1642 CONTENTS are the definition itself. INFO is a plist holding
1643 contextual information."
1644 (org-element-property :html entity))
1647 ;;;; Example Block
1649 (defun org-e-html-example-block (example-block contents info)
1650 "Transcode a EXAMPLE-BLOCK element from Org to HTML.
1651 CONTENTS is nil. INFO is a plist holding contextual
1652 information."
1653 (if (org-export-read-attribute :attr_html example-block :textarea)
1654 (org-e-html--textarea-block example-block)
1655 (format "<pre class=\"example\">\n%s</pre>"
1656 (org-e-html-format-code example-block info))))
1659 ;;;; Export Snippet
1661 (defun org-e-html-export-snippet (export-snippet contents info)
1662 "Transcode a EXPORT-SNIPPET object from Org to HTML.
1663 CONTENTS is nil. INFO is a plist holding contextual
1664 information."
1665 (when (eq (org-export-snippet-backend export-snippet) 'e-html)
1666 (org-element-property :value export-snippet)))
1669 ;;;; Export Block
1671 (defun org-e-html-export-block (export-block contents info)
1672 "Transcode a EXPORT-BLOCK element from Org to HTML.
1673 CONTENTS is nil. INFO is a plist holding contextual information."
1674 (when (string= (org-element-property :type export-block) "HTML")
1675 (org-remove-indentation (org-element-property :value export-block))))
1678 ;;;; Fixed Width
1680 (defun org-e-html-fixed-width (fixed-width contents info)
1681 "Transcode a FIXED-WIDTH element from Org to HTML.
1682 CONTENTS is nil. INFO is a plist holding contextual information."
1683 (format "<pre class=\"example\">\n%s</pre>"
1684 (org-e-html-do-format-code
1685 (org-remove-indentation
1686 (org-element-property :value fixed-width)))))
1689 ;;;; Footnote Reference
1691 (defun org-e-html-footnote-reference (footnote-reference contents info)
1692 "Transcode a FOOTNOTE-REFERENCE element from Org to HTML.
1693 CONTENTS is nil. INFO is a plist holding contextual information."
1694 (concat
1695 ;; Insert separator between two footnotes in a row.
1696 (let ((prev (org-export-get-previous-element footnote-reference info)))
1697 (when (eq (org-element-type prev) 'footnote-reference)
1698 org-e-html-footnote-separator))
1699 (cond
1700 ((not (org-export-footnote-first-reference-p footnote-reference info))
1701 (org-e-html-format-footnote-reference
1702 (org-export-get-footnote-number footnote-reference info)
1703 "IGNORED" 100))
1704 ;; Inline definitions are secondary strings.
1705 ((eq (org-element-property :type footnote-reference) 'inline)
1706 (org-e-html-format-footnote-reference
1707 (org-export-get-footnote-number footnote-reference info)
1708 "IGNORED" 1))
1709 ;; Non-inline footnotes definitions are full Org data.
1710 (t (org-e-html-format-footnote-reference
1711 (org-export-get-footnote-number footnote-reference info)
1712 "IGNORED" 1)))))
1715 ;;;; Headline
1717 (defun org-e-html-format-headline--wrap (headline info
1718 &optional format-function
1719 &rest extra-keys)
1720 "Transcode an HEADLINE element from Org to HTML.
1721 CONTENTS holds the contents of the headline. INFO is a plist
1722 holding contextual information."
1723 (let* ((level (+ (org-export-get-relative-level headline info)
1724 (1- org-e-html-toplevel-hlevel)))
1725 (headline-number (org-export-get-headline-number headline info))
1726 (section-number (and (not (org-export-low-level-p headline info))
1727 (org-export-numbered-headline-p headline info)
1728 (mapconcat 'number-to-string
1729 headline-number ".")))
1730 (todo (and (plist-get info :with-todo-keywords)
1731 (let ((todo (org-element-property :todo-keyword headline)))
1732 (and todo (org-export-data todo info)))))
1733 (todo-type (and todo (org-element-property :todo-type headline)))
1734 (priority (and (plist-get info :with-priority)
1735 (org-element-property :priority headline)))
1736 (text (org-export-data (org-element-property :title headline) info))
1737 (tags (and (plist-get info :with-tags)
1738 (org-export-get-tags headline info)))
1739 (headline-label (or (org-element-property :custom-id headline)
1740 (concat "sec-" (mapconcat 'number-to-string
1741 headline-number "-"))))
1742 (format-function (cond
1743 ((functionp format-function) format-function)
1744 ((functionp org-e-html-format-headline-function)
1745 (function*
1746 (lambda (todo todo-type priority text tags
1747 &allow-other-keys)
1748 (funcall org-e-html-format-headline-function
1749 todo todo-type priority text tags))))
1750 (t 'org-e-html-format-headline))))
1751 (apply format-function
1752 todo todo-type priority text tags
1753 :headline-label headline-label :level level
1754 :section-number section-number extra-keys)))
1756 (defun org-e-html-headline (headline contents info)
1757 "Transcode an HEADLINE element from Org to HTML.
1758 CONTENTS holds the contents of the headline. INFO is a plist
1759 holding contextual information."
1760 ;; Empty contents?
1761 (setq contents (or contents ""))
1762 (let* ((numberedp (org-export-numbered-headline-p headline info))
1763 (level (org-export-get-relative-level headline info))
1764 (text (org-export-data (org-element-property :title headline) info))
1765 (todo (and (plist-get info :with-todo-keywords)
1766 (let ((todo (org-element-property :todo-keyword headline)))
1767 (and todo (org-export-data todo info)))))
1768 (todo-type (and todo (org-element-property :todo-type headline)))
1769 (tags (and (plist-get info :with-tags)
1770 (org-export-get-tags headline info)))
1771 (priority (and (plist-get info :with-priority)
1772 (org-element-property :priority headline)))
1773 (section-number (and (org-export-numbered-headline-p headline info)
1774 (mapconcat 'number-to-string
1775 (org-export-get-headline-number
1776 headline info) ".")))
1777 ;; Create the headline text.
1778 (full-text (org-e-html-format-headline--wrap headline info)))
1779 (cond
1780 ;; Case 1: This is a footnote section: ignore it.
1781 ((org-element-property :footnote-section-p headline) nil)
1782 ;; Case 2. This is a deep sub-tree: export it as a list item.
1783 ;; Also export as items headlines for which no section
1784 ;; format has been found.
1785 ((org-export-low-level-p headline info)
1786 ;; Build the real contents of the sub-tree.
1787 (let* ((type (if numberedp 'ordered 'unordered))
1788 (itemized-body (org-e-html-format-list-item
1789 contents type nil nil full-text)))
1790 (concat
1791 (and (org-export-first-sibling-p headline info)
1792 (org-e-html-begin-plain-list type))
1793 itemized-body
1794 (and (org-export-last-sibling-p headline info)
1795 (org-e-html-end-plain-list type)))))
1796 ;; Case 3. Standard headline. Export it as a section.
1798 (let* ((section-number (mapconcat 'number-to-string
1799 (org-export-get-headline-number
1800 headline info) "-"))
1801 (ids (remove 'nil
1802 (list (org-element-property :custom-id headline)
1803 (concat "sec-" section-number)
1804 (org-element-property :id headline))))
1805 (preferred-id (car ids))
1806 (extra-ids (cdr ids))
1807 (extra-class (org-element-property :html-container-class headline))
1808 (level1 (+ level (1- org-e-html-toplevel-hlevel))))
1809 (format "<div id=\"%s\" class=\"%s\">%s%s</div>\n"
1810 (format "outline-container-%s"
1811 (or (org-element-property :custom-id headline)
1812 section-number))
1813 (concat (format "outline-%d" level1) (and extra-class " ")
1814 extra-class)
1815 (format "\n<h%d id=\"%s\">%s%s</h%d>\n"
1816 level1
1817 preferred-id
1818 (mapconcat
1819 (lambda (x)
1820 (let ((id (org-export-solidify-link-text
1821 (if (org-uuidgen-p x) (concat "ID-" x)
1822 x))))
1823 (org-e-html--anchor id)))
1824 extra-ids "")
1825 full-text
1826 level1)
1827 contents))))))
1830 ;;;; Horizontal Rule
1832 (defun org-e-html-horizontal-rule (horizontal-rule contents info)
1833 "Transcode an HORIZONTAL-RULE object from Org to HTML.
1834 CONTENTS is nil. INFO is a plist holding contextual information."
1835 "<hr/>")
1838 ;;;; Inline Src Block
1840 (defun org-e-html-inline-src-block (inline-src-block contents info)
1841 "Transcode an INLINE-SRC-BLOCK element from Org to HTML.
1842 CONTENTS holds the contents of the item. INFO is a plist holding
1843 contextual information."
1844 (let* ((org-lang (org-element-property :language inline-src-block))
1845 (code (org-element-property :value inline-src-block)))
1846 (error "FIXME")))
1849 ;;;; Inlinetask
1851 (defun org-e-html-format-section (text class &optional id)
1852 (let ((extra (concat (when id (format " id=\"%s\"" id)))))
1853 (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
1855 (defun org-e-html-inlinetask (inlinetask contents info)
1856 "Transcode an INLINETASK element from Org to HTML.
1857 CONTENTS holds the contents of the block. INFO is a plist
1858 holding contextual information."
1859 (cond
1860 ;; If `org-e-html-format-inlinetask-function' is provided, call it
1861 ;; with appropriate arguments.
1862 ((functionp org-e-html-format-inlinetask-function)
1863 (let ((format-function
1864 (function*
1865 (lambda (todo todo-type priority text tags
1866 &key contents &allow-other-keys)
1867 (funcall org-e-html-format-inlinetask-function
1868 todo todo-type priority text tags contents)))))
1869 (org-e-html-format-headline--wrap
1870 inlinetask info format-function :contents contents)))
1871 ;; Otherwise, use a default template.
1872 (t (format "<div class=\"inlinetask\">\n<b>%s</b><br/>\n%s</div>"
1873 (org-e-html-format-headline--wrap inlinetask info)
1874 contents))))
1877 ;;;; Italic
1879 (defun org-e-html-italic (italic contents info)
1880 "Transcode ITALIC from Org to HTML.
1881 CONTENTS is the text with italic markup. INFO is a plist holding
1882 contextual information."
1883 (format (or (cdr (assq 'italic org-e-html-text-markup-alist)) "%s") contents))
1886 ;;;; Item
1888 (defun org-e-html-checkbox (checkbox)
1889 (case checkbox (on "<code>[X]</code>")
1890 (off "<code>[&nbsp;]</code>")
1891 (trans "<code>[-]</code>")
1892 (t "")))
1894 (defun org-e-html-format-list-item (contents type checkbox
1895 &optional term-counter-id
1896 headline)
1897 (let ((checkbox (concat (org-e-html-checkbox checkbox) (and checkbox " "))))
1898 (concat
1899 (case type
1900 (ordered
1901 (let* ((counter term-counter-id)
1902 (extra (if counter (format " value=\"%s\"" counter) "")))
1903 (concat
1904 (format "<li%s>" extra)
1905 (when headline (concat headline "<br/>")))))
1906 (unordered
1907 (let* ((id term-counter-id)
1908 (extra (if id (format " id=\"%s\"" id) "")))
1909 (concat
1910 (format "<li%s>" extra)
1911 (when headline (concat headline "<br/>")))))
1912 (descriptive
1913 (let* ((term term-counter-id))
1914 (setq term (or term "(no term)"))
1915 ;; Check-boxes in descriptive lists are associated to tag.
1916 (concat (format "<dt> %s </dt>"
1917 (concat checkbox term))
1918 "<dd>"))))
1919 (unless (eq type 'descriptive) checkbox)
1920 contents
1921 (case type
1922 (ordered "</li>")
1923 (unordered "</li>")
1924 (descriptive "</dd>")))))
1926 (defun org-e-html-item (item contents info)
1927 "Transcode an ITEM element from Org to HTML.
1928 CONTENTS holds the contents of the item. INFO is a plist holding
1929 contextual information."
1930 (let* ((plain-list (org-export-get-parent item))
1931 (type (org-element-property :type plain-list))
1932 (counter (org-element-property :counter item))
1933 (checkbox (org-element-property :checkbox item))
1934 (tag (let ((tag (org-element-property :tag item)))
1935 (and tag (org-export-data tag info)))))
1936 (org-e-html-format-list-item
1937 contents type checkbox (or tag counter))))
1940 ;;;; Keyword
1942 (defun org-e-html-keyword (keyword contents info)
1943 "Transcode a KEYWORD element from Org to HTML.
1944 CONTENTS is nil. INFO is a plist holding contextual information."
1945 (let ((key (org-element-property :key keyword))
1946 (value (org-element-property :value keyword)))
1947 (cond
1948 ((string= key "HTML") value)
1949 ((string= key "INDEX") (format "\\index{%s}" value))
1950 ;; Invisible targets.
1951 ((string= key "TARGET") nil)
1952 ((string= key "TOC")
1953 (let ((value (downcase value)))
1954 (cond
1955 ((string-match "\\<headlines\\>" value)
1956 (let ((depth (or (and (string-match "[0-9]+" value)
1957 (string-to-number (match-string 0 value)))
1958 (plist-get info :with-toc))))
1959 (org-e-html-toc depth info)))
1960 ((string= "tables" value) "\\listoftables")
1961 ((string= "figures" value) "\\listoffigures")
1962 ((string= "listings" value)
1963 (cond
1964 ;; At the moment, src blocks with a caption are wrapped
1965 ;; into a figure environment.
1966 (t "\\listoffigures")))))))))
1969 ;;;; Latex Environment
1971 (defun org-e-html-format-latex (latex-frag processing-type)
1972 (let* ((cache-relpath
1973 (concat "ltxpng/" (file-name-sans-extension
1974 (file-name-nondirectory (buffer-file-name)))))
1975 (cache-dir (file-name-directory (buffer-file-name )))
1976 (display-msg "Creating LaTeX Image..."))
1978 (with-temp-buffer
1979 (insert latex-frag)
1980 (org-format-latex cache-relpath cache-dir nil display-msg
1981 nil nil processing-type)
1982 (buffer-string))))
1984 (defun org-e-html-latex-environment (latex-environment contents info)
1985 "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
1986 CONTENTS is nil. INFO is a plist holding contextual information."
1987 (let ((processing-type (plist-get info :LaTeX-fragments))
1988 (latex-frag (org-remove-indentation
1989 (org-element-property :value latex-environment)))
1990 (caption (org-export-data
1991 (org-export-get-caption latex-environment) info))
1992 (attr nil) ; FIXME
1993 (label (org-element-property :name latex-environment)))
1994 (cond
1995 ((memq processing-type '(t mathjax))
1996 (org-e-html-format-latex latex-frag 'mathjax))
1997 ((eq processing-type 'dvipng)
1998 (let* ((formula-link (org-e-html-format-latex
1999 latex-frag processing-type)))
2000 (when (and formula-link
2001 (string-match "file:\\([^]]*\\)" formula-link))
2002 (org-e-html-format-inline-image
2003 (match-string 1 formula-link) caption label attr t))))
2004 (t latex-frag))))
2007 ;;;; Latex Fragment
2009 (defun org-e-html-latex-fragment (latex-fragment contents info)
2010 "Transcode a LATEX-FRAGMENT object from Org to HTML.
2011 CONTENTS is nil. INFO is a plist holding contextual information."
2012 (let ((latex-frag (org-element-property :value latex-fragment))
2013 (processing-type (plist-get info :LaTeX-fragments)))
2014 (case processing-type
2015 ((t mathjax)
2016 (org-e-html-format-latex latex-frag 'mathjax))
2017 (dvipng
2018 (let* ((formula-link (org-e-html-format-latex
2019 latex-frag processing-type)))
2020 (when (and formula-link
2021 (string-match "file:\\([^]]*\\)" formula-link))
2022 (org-e-html-format-inline-image
2023 (match-string 1 formula-link)))))
2024 (t latex-frag))))
2027 ;;;; Line Break
2029 (defun org-e-html-line-break (line-break contents info)
2030 "Transcode a LINE-BREAK object from Org to HTML.
2031 CONTENTS is nil. INFO is a plist holding contextual information."
2032 "<br/>\n")
2035 ;;;; Link
2037 (defun org-e-html-link--inline-image (link desc info)
2038 "Return HTML code for an inline image.
2039 LINK is the link pointing to the inline image. INFO is a plist
2040 used as a communication channel."
2041 (let* ((type (org-element-property :type link))
2042 (raw-path (org-element-property :path link))
2043 (path (cond ((member type '("http" "https"))
2044 (concat type ":" raw-path))
2045 ((file-name-absolute-p raw-path)
2046 (expand-file-name raw-path))
2047 (t raw-path)))
2048 (parent (org-export-get-parent-element link))
2049 (caption (org-export-data (org-export-get-caption parent) info))
2050 (label (org-element-property :name parent))
2051 ;; Retrieve latex attributes from the element around.
2052 (attr (let ((raw-attr
2053 (mapconcat #'identity
2054 (org-element-property :attr_html parent)
2055 " ")))
2056 (unless (string= raw-attr "") raw-attr))))
2057 ;; Now clear ATTR from any special keyword and set a default
2058 ;; value if nothing is left.
2059 (setq attr (if (not attr) "" (org-trim attr)))
2060 ;; Return proper string, depending on DISPOSITION.
2061 (org-e-html-format-inline-image
2062 path caption label attr (org-e-html-standalone-image-p link info))))
2064 (defvar org-e-html-standalone-image-predicate)
2065 (defun org-e-html-standalone-image-p (element info &optional predicate)
2066 "Test if ELEMENT is a standalone image for the purpose HTML export.
2067 INFO is a plist holding contextual information.
2069 Return non-nil, if ELEMENT is of type paragraph and it's sole
2070 content, save for whitespaces, is a link that qualifies as an
2071 inline image.
2073 Return non-nil, if ELEMENT is of type link and it's containing
2074 paragraph has no other content save for leading and trailing
2075 whitespaces.
2077 Return nil, otherwise.
2079 Bind `org-e-html-standalone-image-predicate' to constrain
2080 paragraph further. For example, to check for only captioned
2081 standalone images, do the following.
2083 \(setq org-e-html-standalone-image-predicate
2084 \(lambda \(paragraph\)
2085 \(org-element-property :caption paragraph\)\)\)"
2086 (let ((paragraph (case (org-element-type element)
2087 (paragraph element)
2088 (link (and (org-export-inline-image-p
2089 element org-e-html-inline-image-rules)
2090 (org-export-get-parent element)))
2091 (t nil))))
2092 (when (eq (org-element-type paragraph) 'paragraph)
2093 (when (or (not (and (boundp 'org-e-html-standalone-image-predicate)
2094 (functionp org-e-html-standalone-image-predicate)))
2095 (funcall org-e-html-standalone-image-predicate paragraph))
2096 (let ((contents (org-element-contents paragraph)))
2097 (loop for x in contents
2098 with inline-image-count = 0
2099 always (cond
2100 ((eq (org-element-type x) 'plain-text)
2101 (not (org-string-nw-p x)))
2102 ((eq (org-element-type x) 'link)
2103 (when (org-export-inline-image-p
2104 x org-e-html-inline-image-rules)
2105 (= (incf inline-image-count) 1)))
2106 (t nil))))))))
2108 (defun org-e-html-link (link desc info)
2109 "Transcode a LINK object from Org to HTML.
2111 DESC is the description part of the link, or the empty string.
2112 INFO is a plist holding contextual information. See
2113 `org-export-data'."
2114 (let* ((--link-org-files-as-html-maybe
2115 (function
2116 (lambda (raw-path info)
2117 "Treat links to `file.org' as links to `file.html', if needed.
2118 See `org-e-html-link-org-files-as-html'."
2119 (cond
2120 ((and org-e-html-link-org-files-as-html
2121 (string= ".org"
2122 (downcase (file-name-extension raw-path "."))))
2123 (concat (file-name-sans-extension raw-path) "."
2124 (plist-get info :html-extension)))
2125 (t raw-path)))))
2126 (type (org-element-property :type link))
2127 (raw-path (org-element-property :path link))
2128 ;; Ensure DESC really exists, or set it to nil.
2129 (desc (and (not (string= desc "")) desc))
2130 (path (cond
2131 ((member type '("http" "https" "ftp" "mailto"))
2132 (concat type ":" raw-path))
2133 ((string= type "file")
2134 ;; Treat links to ".org" files as ".html", if needed.
2135 (setq raw-path (funcall --link-org-files-as-html-maybe
2136 raw-path info))
2137 ;; If file path is absolute, prepend it with protocol
2138 ;; component - "file://".
2139 (if (not (file-name-absolute-p raw-path)) raw-path
2140 (concat "file://" (expand-file-name raw-path))))
2141 (t raw-path)))
2142 ;; Extract attributes from parent's paragraph.
2143 (attributes
2144 (let ((attr (mapconcat
2145 'identity
2146 (org-element-property
2147 :attr_html (org-export-get-parent-element link))
2148 " ")))
2149 (if attr (concat " " attr) "")))
2150 protocol)
2151 (cond
2152 ;; Image file.
2153 ((and (or (eq t org-e-html-inline-images)
2154 (and org-e-html-inline-images (not desc)))
2155 (org-export-inline-image-p link org-e-html-inline-image-rules))
2156 (org-e-html-link--inline-image link desc info))
2157 ;; Radio target: Transcode target's contents and use them as
2158 ;; link's description.
2159 ((string= type "radio")
2160 (let ((destination (org-export-resolve-radio-link link info)))
2161 (when destination
2162 (format "<a href=\"#%s\"%s>%s</a>"
2163 (org-export-solidify-link-text path)
2164 attributes
2165 (org-export-data (org-element-contents destination) info)))))
2166 ;; Links pointing to an headline: Find destination and build
2167 ;; appropriate referencing command.
2168 ((member type '("custom-id" "fuzzy" "id"))
2169 (let ((destination (if (string= type "fuzzy")
2170 (org-export-resolve-fuzzy-link link info)
2171 (org-export-resolve-id-link link info))))
2172 (case (org-element-type destination)
2173 ;; ID link points to an external file.
2174 (plain-text
2175 (assert (org-uuidgen-p path))
2176 (let ((fragment (concat "ID-" path))
2177 ;; Treat links to ".org" files as ".html", if needed.
2178 (path (funcall --link-org-files-as-html-maybe
2179 destination info)))
2180 (format "<a href=\"%s#%s\"%s>%s</a>"
2181 path fragment attributes (or desc destination))))
2182 ;; Fuzzy link points nowhere.
2183 ((nil)
2184 (format "<i>%s</i>"
2185 (or desc
2186 (org-export-data
2187 (org-element-property :raw-link link) info))))
2188 ;; Fuzzy link points to an invisible target.
2189 (keyword nil)
2190 ;; Link points to an headline.
2191 (headline
2192 (let ((href
2193 ;; What href to use?
2194 (cond
2195 ;; Case 1: Headline is linked via it's CUSTOM_ID
2196 ;; property. Use CUSTOM_ID.
2197 ((string= type "custom-id")
2198 (org-element-property :custom-id destination))
2199 ;; Case 2: Headline is linked via it's ID property
2200 ;; or through other means. Use the default href.
2201 ((member type '("id" "fuzzy"))
2202 (format "sec-%s"
2203 (mapconcat 'number-to-string
2204 (org-export-get-headline-number
2205 destination info) "-")))
2206 (t (error "Shouldn't reach here"))))
2207 ;; What description to use?
2208 (desc
2209 ;; Case 1: Headline is numbered and LINK has no
2210 ;; description or LINK's description matches
2211 ;; headline's title. Display section number.
2212 (if (and (org-export-numbered-headline-p destination info)
2213 (or (not desc)
2214 (string= desc (org-element-property
2215 :raw-value destination))))
2216 (mapconcat 'number-to-string
2217 (org-export-get-headline-number
2218 destination info) ".")
2219 ;; Case 2: Either the headline is un-numbered or
2220 ;; LINK has a custom description. Display LINK's
2221 ;; description or headline's title.
2222 (or desc (org-export-data (org-element-property
2223 :title destination) info)))))
2224 (format "<a href=\"#%s\"%s>%s</a>"
2225 (org-export-solidify-link-text href) attributes desc)))
2226 ;; Fuzzy link points to a target. Do as above.
2228 (let ((path (org-export-solidify-link-text path)) number)
2229 (unless desc
2230 (setq number (cond
2231 ((org-e-html-standalone-image-p destination info)
2232 (org-export-get-ordinal
2233 (assoc 'link (org-element-contents destination))
2234 info 'link 'org-e-html-standalone-image-p))
2235 (t (org-export-get-ordinal destination info))))
2236 (setq desc (when number
2237 (if (atom number) (number-to-string number)
2238 (mapconcat 'number-to-string number ".")))))
2239 (format "<a href=\"#%s\"%s>%s</a>"
2240 path attributes (or desc "FIXME")))))))
2241 ;; Coderef: replace link with the reference name or the
2242 ;; equivalent line number.
2243 ((string= type "coderef")
2244 (let ((fragment (concat "coderef-" path)))
2245 (format "<a href=\"#%s\" %s%s>%s</a>"
2246 fragment
2247 (format (concat "class=\"coderef\""
2248 " onmouseover=\"CodeHighlightOn(this, '%s');\""
2249 " onmouseout=\"CodeHighlightOff(this, '%s');\"")
2250 fragment fragment)
2251 attributes
2252 (format (org-export-get-coderef-format path desc)
2253 (org-export-resolve-coderef path info)))))
2254 ;; Link type is handled by a special function.
2255 ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
2256 (funcall protocol (org-link-unescape path) desc 'html))
2257 ;; External link with a description part.
2258 ((and path desc) (format "<a href=\"%s\"%s>%s</a>" path attributes desc))
2259 ;; External link without a description part.
2260 (path (format "<a href=\"%s\"%s>%s</a>" path attributes path))
2261 ;; No path, only description. Try to do something useful.
2262 (t (format "<i>%s</i>" desc)))))
2265 ;;;; Paragraph
2267 (defun org-e-html-paragraph (paragraph contents info)
2268 "Transcode a PARAGRAPH element from Org to HTML.
2269 CONTENTS is the contents of the paragraph, as a string. INFO is
2270 the plist used as a communication channel."
2271 (let* ((style nil) ; FIXME
2272 (class (cdr (assoc style '((footnote . "footnote")
2273 (verse . nil)))))
2274 (extra (if class (format " class=\"%s\"" class) ""))
2275 (parent (org-export-get-parent paragraph)))
2276 (cond
2277 ((and (eq (org-element-type parent) 'item)
2278 (= (org-element-property :begin paragraph)
2279 (org-element-property :contents-begin parent)))
2280 ;; leading paragraph in a list item have no tags
2281 contents)
2282 ((org-e-html-standalone-image-p paragraph info)
2283 ;; standalone image
2284 contents)
2285 (t (format "<p%s>\n%s</p>" extra contents)))))
2288 ;;;; Plain List
2290 (defun org-e-html-begin-plain-list (type &optional arg1)
2291 (case type
2292 (ordered
2293 (format "<ol%s>" (if arg1 ; FIXME
2294 (format " start=\"%d\"" arg1)
2295 "")))
2296 (unordered "<ul>")
2297 (descriptive "<dl>")))
2299 (defun org-e-html-end-plain-list (type)
2300 (case type
2301 (ordered "</ol>")
2302 (unordered "</ul>")
2303 (descriptive "</dl>")))
2305 (defun org-e-html-plain-list (plain-list contents info)
2306 "Transcode a PLAIN-LIST element from Org to HTML.
2307 CONTENTS is the contents of the list. INFO is a plist holding
2308 contextual information."
2309 (let* (arg1 ;; FIXME
2310 (type (org-element-property :type plain-list)))
2311 (format "%s\n%s%s"
2312 (org-e-html-begin-plain-list type)
2313 contents (org-e-html-end-plain-list type))))
2315 ;;;; Plain Text
2317 (defun org-e-html-convert-special-strings (string)
2318 "Convert special characters in STRING to HTML."
2319 (let ((all org-e-html-special-string-regexps)
2320 e a re rpl start)
2321 (while (setq a (pop all))
2322 (setq re (car a) rpl (cdr a) start 0)
2323 (while (string-match re string start)
2324 (setq string (replace-match rpl t nil string))))
2325 string))
2327 (defun org-e-html-encode-plain-text (text)
2328 "Convert plain text characters to HTML equivalent.
2329 Possible conversions are set in `org-export-html-protect-char-alist'."
2330 (mapc
2331 (lambda (pair)
2332 (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t)))
2333 org-e-html-protect-char-alist)
2334 text)
2336 (defun org-e-html-plain-text (text info)
2337 "Transcode a TEXT string from Org to HTML.
2338 TEXT is the string to transcode. INFO is a plist holding
2339 contextual information."
2340 (let ((output text))
2341 ;; Protect following characters: <, >, &.
2342 (setq output (org-e-html-encode-plain-text output))
2343 ;; Handle smart quotes. Be sure to provide original string since
2344 ;; OUTPUT may have been modified.
2345 (when (plist-get info :with-smart-quotes)
2346 (setq output (org-export-activate-smart-quotes output :html info text)))
2347 ;; Handle special strings.
2348 (when (plist-get info :with-special-strings)
2349 (setq output (org-e-html-convert-special-strings output)))
2350 ;; Handle break preservation if required.
2351 (when (plist-get info :preserve-breaks)
2352 (setq output
2353 (replace-regexp-in-string
2354 "\\(\\\\\\\\\\)?[ \t]*\n" "<br/>\n" output)))
2355 ;; Return value.
2356 output))
2359 ;; Planning
2361 (defun org-e-html-planning (planning contents info)
2362 "Transcode a PLANNING element from Org to HTML.
2363 CONTENTS is nil. INFO is a plist used as a communication
2364 channel."
2365 (let ((span-fmt "<span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>"))
2366 (format
2367 "<p><span class=\"timestamp-wrapper\">%s</span></p>"
2368 (mapconcat
2369 'identity
2370 (delq nil
2371 (list
2372 (let ((closed (org-element-property :closed planning)))
2373 (when closed
2374 (format span-fmt org-closed-string
2375 (org-translate-time
2376 (org-element-property :raw-value closed)))))
2377 (let ((deadline (org-element-property :deadline planning)))
2378 (when deadline
2379 (format span-fmt org-deadline-string
2380 (org-translate-time
2381 (org-element-property :raw-value deadline)))))
2382 (let ((scheduled (org-element-property :scheduled planning)))
2383 (when scheduled
2384 (format span-fmt org-scheduled-string
2385 (org-translate-time
2386 (org-element-property :raw-value scheduled)))))))
2387 " "))))
2390 ;;;; Property Drawer
2392 (defun org-e-html-property-drawer (property-drawer contents info)
2393 "Transcode a PROPERTY-DRAWER element from Org to HTML.
2394 CONTENTS is nil. INFO is a plist holding contextual
2395 information."
2396 ;; The property drawer isn't exported but we want separating blank
2397 ;; lines nonetheless.
2401 ;;;; Quote Block
2403 (defun org-e-html-quote-block (quote-block contents info)
2404 "Transcode a QUOTE-BLOCK element from Org to HTML.
2405 CONTENTS holds the contents of the block. INFO is a plist
2406 holding contextual information."
2407 (format "<blockquote>\n%s</blockquote>" contents))
2410 ;;;; Quote Section
2412 (defun org-e-html-quote-section (quote-section contents info)
2413 "Transcode a QUOTE-SECTION element from Org to HTML.
2414 CONTENTS is nil. INFO is a plist holding contextual information."
2415 (let ((value (org-remove-indentation
2416 (org-element-property :value quote-section))))
2417 (when value (format "<pre>\n%s</pre>" value))))
2420 ;;;; Section
2422 (defun org-e-html-section (section contents info)
2423 "Transcode a SECTION element from Org to HTML.
2424 CONTENTS holds the contents of the section. INFO is a plist
2425 holding contextual information."
2426 (let ((parent (org-export-get-parent-headline section)))
2427 ;; Before first headline: no container, just return CONTENTS.
2428 (if (not parent) contents
2429 ;; Get div's class and id references.
2430 (let* ((class-num (+ (org-export-get-relative-level parent info)
2431 (1- org-e-html-toplevel-hlevel)))
2432 (section-number
2433 (mapconcat
2434 'number-to-string
2435 (org-export-get-headline-number parent info) "-")))
2436 ;; Build return value.
2437 (format "<div class=\"outline-text-%d\" id=\"text-%s\">\n%s</div>"
2438 class-num
2439 (or (org-element-property :custom-id parent) section-number)
2440 contents)))))
2442 ;;;; Radio Target
2444 (defun org-e-html-radio-target (radio-target text info)
2445 "Transcode a RADIO-TARGET object from Org to HTML.
2446 TEXT is the text of the target. INFO is a plist holding
2447 contextual information."
2448 (let ((id (org-export-solidify-link-text
2449 (org-element-property :value radio-target))))
2450 (org-e-html--anchor id text)))
2453 ;;;; Special Block
2455 (defun org-e-html-special-block (special-block contents info)
2456 "Transcode a SPECIAL-BLOCK element from Org to HTML.
2457 CONTENTS holds the contents of the block. INFO is a plist
2458 holding contextual information."
2459 (format "<div class=\"%s\">\n%s\n</div>"
2460 (downcase (org-element-property :type special-block))
2461 contents))
2464 ;;;; Src Block
2466 (defun org-e-html-src-block (src-block contents info)
2467 "Transcode a SRC-BLOCK element from Org to HTML.
2468 CONTENTS holds the contents of the item. INFO is a plist holding
2469 contextual information."
2470 (if (org-export-read-attribute :attr_html src-block :textarea)
2471 (org-e-html--textarea-block src-block)
2472 (let ((lang (org-element-property :language src-block))
2473 (caption (org-export-get-caption src-block))
2474 (code (org-e-html-format-code src-block info)))
2475 (if (not lang) (format "<pre class=\"example\">\n%s</pre>" code)
2476 (format "<div class=\"org-src-container\">\n%s%s\n</div>"
2477 (if (not caption) ""
2478 (format "<label class=\"org-src-name\">%s</label>"
2479 (org-export-data caption info)))
2480 (format "\n<pre class=\"src src-%s\">%s</pre>" lang code))))))
2483 ;;;; Statistics Cookie
2485 (defun org-e-html-statistics-cookie (statistics-cookie contents info)
2486 "Transcode a STATISTICS-COOKIE object from Org to HTML.
2487 CONTENTS is nil. INFO is a plist holding contextual information."
2488 (let ((cookie-value (org-element-property :value statistics-cookie)))
2489 (format "<code>%s</code>" cookie-value)))
2492 ;;;; Strike-Through
2494 (defun org-e-html-strike-through (strike-through contents info)
2495 "Transcode STRIKE-THROUGH from Org to HTML.
2496 CONTENTS is the text with strike-through markup. INFO is a plist
2497 holding contextual information."
2498 (format (or (cdr (assq 'strike-through org-e-html-text-markup-alist)) "%s")
2499 contents))
2502 ;;;; Subscript
2504 (defun org-e-html-subscript (subscript contents info)
2505 "Transcode a SUBSCRIPT object from Org to HTML.
2506 CONTENTS is the contents of the object. INFO is a plist holding
2507 contextual information."
2508 (format "<sub>%s</sub>" contents))
2511 ;;;; Superscript
2513 (defun org-e-html-superscript (superscript contents info)
2514 "Transcode a SUPERSCRIPT object from Org to HTML.
2515 CONTENTS is the contents of the object. INFO is a plist holding
2516 contextual information."
2517 (format "<sup>%s</sup>" contents))
2520 ;;;; Tabel Cell
2522 (defun org-e-html-table-cell (table-cell contents info)
2523 "Transcode a TABLE-CELL element from Org to HTML.
2524 CONTENTS is nil. INFO is a plist used as a communication
2525 channel."
2526 (let* ((table-row (org-export-get-parent table-cell))
2527 (table (org-export-get-parent-table table-cell))
2528 (cell-attrs
2529 (if (not org-e-html-table-align-individual-fields) ""
2530 (format (if (and (boundp 'org-e-html-format-table-no-css)
2531 org-e-html-format-table-no-css)
2532 " align=\"%s\"" " class=\"%s\"")
2533 (org-export-table-cell-alignment table-cell info)))))
2534 (when (or (not contents) (string= "" (org-trim contents)))
2535 (setq contents "&nbsp;"))
2536 (cond
2537 ((and (org-export-table-has-header-p table info)
2538 (= 1 (org-export-table-row-group table-row info)))
2539 (concat "\n" (format (car org-e-html-table-header-tags) "col" cell-attrs)
2540 contents (cdr org-e-html-table-header-tags)))
2541 ((and org-e-html-table-use-header-tags-for-first-column
2542 (zerop (cdr (org-export-table-cell-address table-cell info))))
2543 (concat "\n" (format (car org-e-html-table-header-tags) "row" cell-attrs)
2544 contents (cdr org-e-html-table-header-tags)))
2545 (t (concat "\n" (format (car org-e-html-table-data-tags) cell-attrs)
2546 contents (cdr org-e-html-table-data-tags))))))
2549 ;;;; Table Row
2551 (defun org-e-html-table-row (table-row contents info)
2552 "Transcode a TABLE-ROW element from Org to HTML.
2553 CONTENTS is the contents of the row. INFO is a plist used as a
2554 communication channel."
2555 ;; Rules are ignored since table separators are deduced from
2556 ;; borders of the current row.
2557 (when (eq (org-element-property :type table-row) 'standard)
2558 (let* ((first-rowgroup-p (= 1 (org-export-table-row-group table-row info)))
2559 (rowgroup-tags
2560 (cond
2561 ;; Case 1: Row belongs to second or subsequent rowgroups.
2562 ((not (= 1 (org-export-table-row-group table-row info)))
2563 '("<tbody>" . "\n</tbody>"))
2564 ;; Case 2: Row is from first rowgroup. Table has >=1 rowgroups.
2565 ((org-export-table-has-header-p
2566 (org-export-get-parent-table table-row) info)
2567 '("<thead>" . "\n</thead>"))
2568 ;; Case 2: Row is from first and only row group.
2569 (t '("<tbody>" . "\n</tbody>")))))
2570 (concat
2571 ;; Begin a rowgroup?
2572 (when (org-export-table-row-starts-rowgroup-p table-row info)
2573 (car rowgroup-tags))
2574 ;; Actual table row
2575 (concat "\n" (eval (car org-e-html-table-row-tags))
2576 contents
2577 "\n"
2578 (eval (cdr org-e-html-table-row-tags)))
2579 ;; End a rowgroup?
2580 (when (org-export-table-row-ends-rowgroup-p table-row info)
2581 (cdr rowgroup-tags))))))
2584 ;;;; Table
2586 (defun org-e-html-table-first-row-data-cells (table info)
2587 (let ((table-row
2588 (org-element-map
2589 table 'table-row
2590 (lambda (row)
2591 (unless (eq (org-element-property :type row) 'rule) row))
2592 info 'first-match))
2593 (special-column-p (org-export-table-has-special-column-p table)))
2594 (if (not special-column-p) (org-element-contents table-row)
2595 (cdr (org-element-contents table-row)))))
2597 (defun org-e-html-table--table.el-table (table info)
2598 (when (eq (org-element-property :type table) 'table.el)
2599 (require 'table)
2600 (let ((outbuf (with-current-buffer
2601 (get-buffer-create "*org-export-table*")
2602 (erase-buffer) (current-buffer))))
2603 (with-temp-buffer
2604 (insert (org-element-property :value table))
2605 (goto-char 1)
2606 (re-search-forward "^[ \t]*|[^|]" nil t)
2607 (table-generate-source 'html outbuf))
2608 (with-current-buffer outbuf
2609 (prog1 (org-trim (buffer-string))
2610 (kill-buffer) )))))
2612 (defun org-e-html-table (table contents info)
2613 "Transcode a TABLE element from Org to HTML.
2614 CONTENTS is the contents of the table. INFO is a plist holding
2615 contextual information."
2616 (case (org-element-property :type table)
2617 ;; Case 1: table.el table. Convert it using appropriate tools.
2618 (table.el (org-e-html-table--table.el-table table info))
2619 ;; Case 2: Standard table.
2621 (let* ((label (org-element-property :name table))
2622 (caption (org-export-get-caption table))
2623 (attributes (mapconcat #'identity
2624 (org-element-property :attr_html table)
2625 " "))
2626 (alignspec
2627 (if (and (boundp 'org-e-html-format-table-no-css)
2628 org-e-html-format-table-no-css)
2629 "align=\"%s\"" "class=\"%s\""))
2630 (table-column-specs
2631 (function
2632 (lambda (table info)
2633 (mapconcat
2634 (lambda (table-cell)
2635 (let ((alignment (org-export-table-cell-alignment
2636 table-cell info)))
2637 (concat
2638 ;; Begin a colgroup?
2639 (when (org-export-table-cell-starts-colgroup-p
2640 table-cell info)
2641 "\n<colgroup>")
2642 ;; Add a column. Also specify it's alignment.
2643 (format "\n<col %s/>" (format alignspec alignment))
2644 ;; End a colgroup?
2645 (when (org-export-table-cell-ends-colgroup-p
2646 table-cell info)
2647 "\n</colgroup>"))))
2648 (org-e-html-table-first-row-data-cells table info) "\n"))))
2649 (table-attributes
2650 (let ((table-tag (plist-get info :html-table-tag)))
2651 (concat
2652 (and (string-match "<table\\(.*\\)>" table-tag)
2653 (match-string 1 table-tag))
2654 (and label (format " id=\"%s\""
2655 (org-export-solidify-link-text label)))))))
2656 ;; Remove last blank line.
2657 (setq contents (substring contents 0 -1))
2658 (format "<table%s>\n%s\n%s\n%s\n</table>"
2659 table-attributes
2660 (if (not caption) ""
2661 (format "<caption>%s</caption>"
2662 (org-export-data caption info)))
2663 (funcall table-column-specs table info)
2664 contents)))))
2667 ;;;; Target
2669 (defun org-e-html-target (target contents info)
2670 "Transcode a TARGET object from Org to HTML.
2671 CONTENTS is nil. INFO is a plist holding contextual
2672 information."
2673 (let ((id (org-export-solidify-link-text
2674 (org-element-property :value target))))
2675 (org-e-html--anchor id)))
2678 ;;;; Timestamp
2680 (defun org-e-html-timestamp (timestamp contents info)
2681 "Transcode a TIMESTAMP object from Org to HTML.
2682 CONTENTS is nil. INFO is a plist holding contextual
2683 information."
2684 (let ((value (org-e-html-plain-text
2685 (org-export-translate-timestamp timestamp) info)))
2686 (format "<span class=\"timestamp-wrapper\"><span class=\"timestamp\">%s</span></span>"
2687 (replace-regexp-in-string "--" "&ndash;" value))))
2690 ;;;; Underline
2692 (defun org-e-html-underline (underline contents info)
2693 "Transcode UNDERLINE from Org to HTML.
2694 CONTENTS is the text with underline markup. INFO is a plist
2695 holding contextual information."
2696 (format (or (cdr (assq 'underline org-e-html-text-markup-alist)) "%s")
2697 contents))
2700 ;;;; Verbatim
2702 (defun org-e-html-verbatim (verbatim contents info)
2703 "Transcode VERBATIM from Org to HTML.
2704 CONTENTS is nil. INFO is a plist holding contextual
2705 information."
2706 (format (or (cdr (assq 'verbatim org-e-html-text-markup-alist)) "%s")
2707 (org-element-property :value verbatim)))
2710 ;;;; Verse Block
2712 (defun org-e-html-verse-block (verse-block contents info)
2713 "Transcode a VERSE-BLOCK element from Org to HTML.
2714 CONTENTS is verse block contents. INFO is a plist holding
2715 contextual information."
2716 ;; Replace each newline character with line break. Also replace
2717 ;; each blank line with a line break.
2718 (setq contents (replace-regexp-in-string
2719 "^ *\\\\\\\\$" "<br/>\n"
2720 (replace-regexp-in-string
2721 "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n" contents)))
2722 ;; Replace each white space at beginning of a line with a
2723 ;; non-breaking space.
2724 (while (string-match "^[ \t]+" contents)
2725 (let* ((num-ws (length (match-string 0 contents)))
2726 (ws (let (out) (dotimes (i num-ws out)
2727 (setq out (concat out "&nbsp;"))))))
2728 (setq contents (replace-match ws nil t contents))))
2729 (format "<p class=\"verse\">\n%s</p>" contents))
2733 ;;; Filter Functions
2735 (defun org-e-html-final-function (contents backend info)
2736 (if (not org-e-html-pretty-output) contents
2737 (with-temp-buffer
2738 (html-mode)
2739 (insert contents)
2740 (indent-region (point-min) (point-max))
2741 (buffer-substring-no-properties (point-min) (point-max)))))
2745 ;;; End-user functions
2747 ;;;###autoload
2748 (defun org-e-html-export-as-html
2749 (&optional subtreep visible-only body-only ext-plist)
2750 "Export current buffer to an HTML buffer.
2752 If narrowing is active in the current buffer, only export its
2753 narrowed part.
2755 If a region is active, export that region.
2757 When optional argument SUBTREEP is non-nil, export the sub-tree
2758 at point, extracting information from the headline properties
2759 first.
2761 When optional argument VISIBLE-ONLY is non-nil, don't export
2762 contents of hidden elements.
2764 When optional argument BODY-ONLY is non-nil, only write code
2765 between \"<body>\" and \"</body>\" tags.
2767 EXT-PLIST, when provided, is a property list with external
2768 parameters overriding Org default settings, but still inferior to
2769 file-local settings.
2771 Export is done in a buffer named \"*Org E-HTML Export*\", which
2772 will be displayed when `org-export-show-temporary-export-buffer'
2773 is non-nil."
2774 (interactive)
2775 (let ((outbuf
2776 (org-export-to-buffer
2777 'e-html "*Org E-HTML Export*"
2778 subtreep visible-only body-only ext-plist)))
2779 ;; Set major mode.
2780 (with-current-buffer outbuf (nxml-mode))
2781 (when org-export-show-temporary-export-buffer
2782 (switch-to-buffer-other-window outbuf))))
2784 ;;;###autoload
2785 (defun org-e-html-export-to-html
2786 (&optional subtreep visible-only body-only ext-plist)
2787 "Export current buffer to a HTML file.
2789 If narrowing is active in the current buffer, only export its
2790 narrowed part.
2792 If a region is active, export that region.
2794 When optional argument SUBTREEP is non-nil, export the sub-tree
2795 at point, extracting information from the headline properties
2796 first.
2798 When optional argument VISIBLE-ONLY is non-nil, don't export
2799 contents of hidden elements.
2801 When optional argument BODY-ONLY is non-nil, only write code
2802 between \"<body>\" and \"</body>\" tags.
2804 EXT-PLIST, when provided, is a property list with external
2805 parameters overriding Org default settings, but still inferior to
2806 file-local settings.
2808 Return output file's name."
2809 (interactive)
2810 (let* ((extension (concat "." org-e-html-extension))
2811 (file (org-export-output-file-name extension subtreep))
2812 (org-export-coding-system org-e-html-coding-system))
2813 (org-export-to-file
2814 'e-html file subtreep visible-only body-only ext-plist)))
2816 ;;;###autoload
2817 (defun org-e-html-publish-to-html (plist filename pub-dir)
2818 "Publish an org file to HTML.
2820 FILENAME is the filename of the Org file to be published. PLIST
2821 is the property list for the given project. PUB-DIR is the
2822 publishing directory.
2824 Return output file name."
2825 (org-e-publish-org-to 'e-html filename ".html" plist pub-dir))
2829 ;;; FIXME
2831 ;;;; org-format-table-html
2832 ;;;; org-format-org-table-html
2833 ;;;; org-format-table-table-html
2834 ;;;; org-table-number-fraction
2835 ;;;; org-table-number-regexp
2836 ;;;; org-e-html-table-caption-above
2838 ;;;; org-e-html-with-timestamp
2839 ;;;; org-e-html-html-helper-timestamp
2841 ;;;; org-export-as-html-and-open
2842 ;;;; org-export-as-html-batch
2843 ;;;; org-export-as-html-to-buffer
2844 ;;;; org-replace-region-by-html
2845 ;;;; org-export-region-as-html
2846 ;;;; org-export-as-html
2848 ;;;; (org-export-directory :html opt-plist)
2849 ;;;; (plist-get opt-plist :html-extension)
2850 ;;;; org-e-html-toplevel-hlevel
2851 ;;;; org-e-html-special-string-regexps
2852 ;;;; org-e-html-inline-images
2853 ;;;; org-e-html-inline-image-extensions
2854 ;;;; org-e-html-protect-char-alist
2855 ;;;; org-e-html-table-use-header-tags-for-first-column
2856 ;;;; org-e-html-todo-kwd-class-prefix
2857 ;;;; org-e-html-tag-class-prefix
2858 ;;;; org-e-html-footnote-separator
2860 ;;;; org-export-preferred-target-alist
2861 ;;;; org-export-solidify-link-text
2862 ;;;; class for anchors
2863 ;;;; org-export-with-section-numbers, body-only
2864 ;;;; org-export-mark-todo-in-toc
2866 ;;;; org-e-html-format-org-link
2867 ;;;; (caption (and caption (org-xml-encode-org-text caption)))
2868 ;;;; alt = (file-name-nondirectory path)
2870 ;;;; org-export-time-stamp-file'
2872 (provide 'org-e-html)
2873 ;;; org-e-html.el ends here