ox-html.el (org-html-headline): Fix typo
[org-mode.git] / lisp / ox-html.el
blob72743f516579ee6ea79aef573e28cc101609cc30
1 ;;; ox-html.el --- HTML Back-End for Org Export Engine
3 ;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
5 ;; Author: Jambunathan K <kjambunathan at gmail dot com>
6 ;; Keywords: outlines, hypermedia, calendar, wp
8 ;; GNU Emacs 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 ;; GNU Emacs 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 GNU Emacs. 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-x org-export-as-html
29 ;; in an Org mode buffer. See ox.el for more details on how this
30 ;; exporter works.
32 ;;; Code:
34 ;;; Dependencies
36 (require 'ox)
37 (require 'ox-publish)
38 (require 'format-spec)
39 (eval-when-compile (require 'cl) (require 'table))
43 ;;; Function Declarations
45 (declare-function org-id-find-id-file "org-id" (id))
46 (declare-function htmlize-region "ext:htmlize" (beg end))
47 (declare-function org-pop-to-buffer-same-window
48 "org-compat" (&optional buffer-or-name norecord label))
51 ;;; Define Back-End
53 (org-export-define-backend html
54 ((bold . org-html-bold)
55 (center-block . org-html-center-block)
56 (clock . org-html-clock)
57 (code . org-html-code)
58 (drawer . org-html-drawer)
59 (dynamic-block . org-html-dynamic-block)
60 (entity . org-html-entity)
61 (example-block . org-html-example-block)
62 (export-block . org-html-export-block)
63 (export-snippet . org-html-export-snippet)
64 (fixed-width . org-html-fixed-width)
65 (footnote-definition . org-html-footnote-definition)
66 (footnote-reference . org-html-footnote-reference)
67 (headline . org-html-headline)
68 (horizontal-rule . org-html-horizontal-rule)
69 (inline-src-block . org-html-inline-src-block)
70 (inlinetask . org-html-inlinetask)
71 (inner-template . org-html-inner-template)
72 (italic . org-html-italic)
73 (item . org-html-item)
74 (keyword . org-html-keyword)
75 (latex-environment . org-html-latex-environment)
76 (latex-fragment . org-html-latex-fragment)
77 (line-break . org-html-line-break)
78 (link . org-html-link)
79 (paragraph . org-html-paragraph)
80 (plain-list . org-html-plain-list)
81 (plain-text . org-html-plain-text)
82 (planning . org-html-planning)
83 (property-drawer . org-html-property-drawer)
84 (quote-block . org-html-quote-block)
85 (quote-section . org-html-quote-section)
86 (radio-target . org-html-radio-target)
87 (section . org-html-section)
88 (special-block . org-html-special-block)
89 (src-block . org-html-src-block)
90 (statistics-cookie . org-html-statistics-cookie)
91 (strike-through . org-html-strike-through)
92 (subscript . org-html-subscript)
93 (superscript . org-html-superscript)
94 (table . org-html-table)
95 (table-cell . org-html-table-cell)
96 (table-row . org-html-table-row)
97 (target . org-html-target)
98 (template . org-html-template)
99 (timestamp . org-html-timestamp)
100 (underline . org-html-underline)
101 (verbatim . org-html-verbatim)
102 (verse-block . org-html-verse-block))
103 :export-block "HTML"
104 :filters-alist ((:filter-final-output . org-html-final-function))
105 :menu-entry
106 (?h "Export to HTML"
107 ((?H "As HTML buffer" org-html-export-as-html)
108 (?h "As HTML file" org-html-export-to-html)
109 (?o "As HTML file and open"
110 (lambda (a s v b)
111 (if a (org-html-export-to-html t s v b)
112 (org-open-file (org-html-export-to-html nil s v b)))))))
113 :options-alist
114 ((:html-extension nil nil org-html-extension)
115 (:html-link-home "HTML_LINK_HOME" nil org-html-link-home)
116 (:html-link-up "HTML_LINK_UP" nil org-html-link-up)
117 (:html-mathjax "HTML_MATHJAX" nil "" space)
118 (:html-postamble nil "html-postamble" org-html-postamble)
119 (:html-preamble nil "html-preamble" org-html-preamble)
120 (:html-style nil nil org-html-style)
121 (:html-style-extra "HTML_STYLE" nil org-html-style-extra newline)
122 (:html-style-include-default nil nil org-html-style-include-default)
123 (:html-style-include-scripts nil nil org-html-style-include-scripts)
124 (:html-table-tag nil nil org-html-table-tag)
125 ;; Redefine regular options.
126 (:creator "CREATOR" nil org-html-creator-string)
127 (:with-latex nil "tex" org-html-with-latex)
128 ;; Leave room for "ox-infojs.el" extension.
129 (:infojs-opt "INFOJS_OPT" nil nil)))
133 ;;; Internal Variables
135 (defvar org-html-format-table-no-css)
136 (defvar htmlize-buffer-places) ; from htmlize.el
138 (defconst org-html-special-string-regexps
139 '(("\\\\-" . "&shy;")
140 ("---\\([^-]\\)" . "&mdash;\\1")
141 ("--\\([^-]\\)" . "&ndash;\\1")
142 ("\\.\\.\\." . "&hellip;"))
143 "Regular expressions for special string conversion.")
145 (defconst org-html-scripts
146 "<script type=\"text/javascript\">
148 @licstart The following is the entire license notice for the
149 JavaScript code in this tag.
151 Copyright (C) 2012 Free Software Foundation, Inc.
153 The JavaScript code in this tag is free software: you can
154 redistribute it and/or modify it under the terms of the GNU
155 General Public License (GNU GPL) as published by the Free Software
156 Foundation, either version 3 of the License, or (at your option)
157 any later version. The code is distributed WITHOUT ANY WARRANTY;
158 without even the implied warranty of MERCHANTABILITY or FITNESS
159 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
161 As additional permission under GNU GPL version 3 section 7, you
162 may distribute non-source (e.g., minimized or compacted) forms of
163 that code without the copy of the GNU GPL normally required by
164 section 4, provided you include this license notice and a URL
165 through which recipients can access the Corresponding Source.
168 @licend The above is the entire license notice
169 for the JavaScript code in this tag.
171 <!--/*--><![CDATA[/*><!--*/
172 function CodeHighlightOn(elem, id)
174 var target = document.getElementById(id);
175 if(null != target) {
176 elem.cacheClassElem = elem.className;
177 elem.cacheClassTarget = target.className;
178 target.className = \"code-highlighted\";
179 elem.className = \"code-highlighted\";
182 function CodeHighlightOff(elem, id)
184 var target = document.getElementById(id);
185 if(elem.cacheClassElem)
186 elem.className = elem.cacheClassElem;
187 if(elem.cacheClassTarget)
188 target.className = elem.cacheClassTarget;
190 /*]]>*///-->
191 </script>"
192 "Basic JavaScript that is needed by HTML files produced by Org mode.")
194 (defconst org-html-style-default
195 "<style type=\"text/css\">
196 <!--/*--><![CDATA[/*><!--*/
197 html { font-family: Times, serif; font-size: 12pt; }
198 .title { text-align: center; }
199 .todo { color: red; }
200 .done { color: green; }
201 .tag { background-color: #add8e6; font-weight:normal }
202 .target { }
203 .timestamp { color: #bebebe; }
204 .timestamp-kwd { color: #5f9ea0; }
205 .right {margin-left:auto; margin-right:0px; text-align:right;}
206 .left {margin-left:0px; margin-right:auto; text-align:left;}
207 .center {margin-left:auto; margin-right:auto; text-align:center;}
208 p.verse { margin-left: 3% }
209 pre {
210 border: 1pt solid #AEBDCC;
211 background-color: #F3F5F7;
212 padding: 5pt;
213 font-family: courier, monospace;
214 font-size: 90%;
215 overflow:auto;
217 table { border-collapse: collapse; }
218 td, th { vertical-align: top; }
219 th.right { text-align:center; }
220 th.left { text-align:center; }
221 th.center { text-align:center; }
222 td.right { text-align:right; }
223 td.left { text-align:left; }
224 td.center { text-align:center; }
225 dt { font-weight: bold; }
226 div.figure { padding: 0.5em; }
227 div.figure p { text-align: center; }
228 div.inlinetask {
229 padding:10px;
230 border:2px solid gray;
231 margin:10px;
232 background: #ffffcc;
234 textarea { overflow-x: auto; }
235 .linenr { font-size:smaller }
236 .code-highlighted {background-color:#ffff00;}
237 .org-info-js_info-navigation { border-style:none; }
238 #org-info-js_console-label { font-size:10px; font-weight:bold;
239 white-space:nowrap; }
240 .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
241 font-weight:bold; }
242 /*]]>*/-->
243 </style>"
244 "The default style specification for exported HTML files.
245 Please use the variables `org-html-style' and
246 `org-html-style-extra' to add to this style. If you wish to not
247 have the default style included, customize the variable
248 `org-html-style-include-default'.")
252 ;;; User Configuration Variables
254 (defgroup org-export-html nil
255 "Options for exporting Org mode files to HTML."
256 :tag "Org Export HTML"
257 :group 'org-export)
260 ;;;; Bold etc
262 (defcustom org-html-text-markup-alist
263 '((bold . "<b>%s</b>")
264 (code . "<code>%s</code>")
265 (italic . "<i>%s</i>")
266 (strike-through . "<del>%s</del>")
267 (underline . "<span style=\"text-decoration:underline;\">%s</span>")
268 (verbatim . "<code>%s</code>"))
269 "Alist of HTML expressions to convert text markup
271 The key must be a symbol among `bold', `code', `italic',
272 `strike-through', `underline' and `verbatim'. The value is
273 a formatting string to wrap fontified text with.
275 If no association can be found for a given markup, text will be
276 returned as-is."
277 :group 'org-export-html
278 :type '(alist :key-type (symbol :tag "Markup type")
279 :value-type (string :tag "Format string"))
280 :options '(bold code italic strike-through underline verbatim))
283 ;;;; Debugging
285 (defcustom org-html-pretty-output nil
286 "Enable this to generate pretty HTML."
287 :group 'org-export-html
288 :type 'boolean)
291 ;;;; Drawers
293 (defcustom org-html-format-drawer-function nil
294 "Function called to format a drawer in HTML code.
296 The function must accept two parameters:
297 NAME the drawer name, like \"LOGBOOK\"
298 CONTENTS the contents of the drawer.
300 The function should return the string to be exported.
302 For example, the variable could be set to the following function
303 in order to mimic default behaviour:
305 \(defun org-html-format-drawer-default \(name contents\)
306 \"Format a drawer element for HTML export.\"
307 contents\)"
308 :group 'org-export-html
309 :type 'function)
312 ;;;; Footnotes
314 (defcustom org-html-footnotes-section "<div id=\"footnotes\">
315 <h2 class=\"footnotes\">%s: </h2>
316 <div id=\"text-footnotes\">
318 </div>
319 </div>"
320 "Format for the footnotes section.
321 Should contain a two instances of %s. The first will be replaced with the
322 language-specific word for \"Footnotes\", the second one will be replaced
323 by the footnotes themselves."
324 :group 'org-export-html
325 :type 'string)
327 (defcustom org-html-footnote-format "<sup>%s</sup>"
328 "The format for the footnote reference.
329 %s will be replaced by the footnote reference itself."
330 :group 'org-export-html
331 :type 'string)
333 (defcustom org-html-footnote-separator "<sup>, </sup>"
334 "Text used to separate footnotes."
335 :group 'org-export-html
336 :type 'string)
339 ;;;; Headline
341 (defcustom org-html-toplevel-hlevel 2
342 "The <H> level for level 1 headings in HTML export.
343 This is also important for the classes that will be wrapped around headlines
344 and outline structure. If this variable is 1, the top-level headlines will
345 be <h1>, and the corresponding classes will be outline-1, section-number-1,
346 and outline-text-1. If this is 2, all of these will get a 2 instead.
347 The default for this variable is 2, because we use <h1> for formatting the
348 document title."
349 :group 'org-export-html
350 :type 'integer)
352 (defcustom org-html-format-headline-function nil
353 "Function to format headline text.
355 This function will be called with 5 arguments:
356 TODO the todo keyword (string or nil).
357 TODO-TYPE the type of todo (symbol: `todo', `done', nil)
358 PRIORITY the priority of the headline (integer or nil)
359 TEXT the main headline text (string).
360 TAGS the tags (string or nil).
362 The function result will be used in the section format string."
363 :group 'org-export-html
364 :type 'function)
367 ;;;; HTML-specific
369 (defcustom org-html-allow-name-attribute-in-anchors t
370 "When nil, do not set \"name\" attribute in anchors.
371 By default, anchors are formatted with both \"id\" and \"name\"
372 attributes, when appropriate."
373 :group 'org-export-html
374 :type 'boolean)
377 ;;;; Inlinetasks
379 (defcustom org-html-format-inlinetask-function nil
380 "Function called to format an inlinetask in HTML code.
382 The function must accept six parameters:
383 TODO the todo keyword, as a string
384 TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
385 PRIORITY the inlinetask priority, as a string
386 NAME the inlinetask name, as a string.
387 TAGS the inlinetask tags, as a list of strings.
388 CONTENTS the contents of the inlinetask, as a string.
390 The function should return the string to be exported.
392 For example, the variable could be set to the following function
393 in order to mimic default behaviour:
395 \(defun org-html-format-inlinetask \(todo type priority name tags contents\)
396 \"Format an inline task element for HTML export.\"
397 \(let \(\(full-title
398 \(concat
399 \(when todo
400 \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo))
401 \(when priority (format \"\\\\framebox{\\\\#%c} \" priority))
402 title
403 \(when tags (format \"\\\\hfill{}\\\\textsc{%s}\" tags)))))
404 \(format (concat \"\\\\begin{center}\\n\"
405 \"\\\\fbox{\\n\"
406 \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
407 \"%s\\n\\n\"
408 \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
409 \"%s\"
410 \"\\\\end{minipage}}\"
411 \"\\\\end{center}\")
412 full-title contents))"
413 :group 'org-export-html
414 :type 'function)
417 ;;;; LaTeX
419 (defcustom org-html-with-latex org-export-with-latex
420 "Non-nil means process LaTeX math snippets.
422 When set, the exporter will process LaTeX environments and
423 fragments.
425 This option can also be set with the +OPTIONS line,
426 e.g. \"tex:mathjax\". Allowed values are:
428 nil Ignore math snippets.
429 `verbatim' Keep everything in verbatim
430 `dvipng' Process the LaTeX fragments to images. This will also
431 include processing of non-math environments.
432 `imagemagick' Convert the LaTeX fragments to pdf files and use
433 imagemagick to convert pdf files to png files.
434 `mathjax' Do MathJax preprocessing and arrange for MathJax.js to
435 be loaded.
436 t Synonym for `mathjax'."
437 :group 'org-export-html
438 :type '(choice
439 (const :tag "Do not process math in any way" nil)
440 (const :tag "Use dvipng to make images" dvipng)
441 (const :tag "Use imagemagick to make images" imagemagick)
442 (const :tag "Use MathJax to display math" mathjax)
443 (const :tag "Leave math verbatim" verbatim)))
446 ;;;; Links :: Generic
448 (defcustom org-html-link-org-files-as-html t
449 "Non-nil means make file links to `file.org' point to `file.html'.
450 When org-mode is exporting an org-mode file to HTML, links to
451 non-html files are directly put into a href tag in HTML.
452 However, links to other Org-mode files (recognized by the
453 extension `.org.) should become links to the corresponding html
454 file, assuming that the linked org-mode file will also be
455 converted to HTML.
456 When nil, the links still point to the plain `.org' file."
457 :group 'org-export-html
458 :type 'boolean)
461 ;;;; Links :: Inline images
463 (defcustom org-html-inline-images 'maybe
464 "Non-nil means inline images into exported HTML pages.
465 This is done using an <img> tag. When nil, an anchor with href is used to
466 link to the image. If this option is `maybe', then images in links with
467 an empty description will be inlined, while images with a description will
468 be linked only."
469 :group 'org-export-html
470 :type '(choice (const :tag "Never" nil)
471 (const :tag "Always" t)
472 (const :tag "When there is no description" maybe)))
474 (defcustom org-html-inline-image-rules
475 '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
476 ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
477 ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
478 "Rules characterizing image files that can be inlined into HTML.
480 A rule consists in an association whose key is the type of link
481 to consider, and value is a regexp that will be matched against
482 link's path.
484 Note that, by default, the image extension *actually* allowed
485 depend on the way the HTML file is processed. When used with
486 pdflatex, pdf, jpg and png images are OK. When processing
487 through dvi to Postscript, only ps and eps are allowed. The
488 default we use here encompasses both."
489 :group 'org-export-html
490 :type '(alist :key-type (string :tag "Type")
491 :value-type (regexp :tag "Path")))
494 ;;;; Plain Text
496 (defcustom org-html-protect-char-alist
497 '(("&" . "&amp;")
498 ("<" . "&lt;")
499 (">" . "&gt;"))
500 "Alist of characters to be converted by `org-html-protect'."
501 :group 'org-export-html
502 :type '(repeat (cons (string :tag "Character")
503 (string :tag "HTML equivalent"))))
506 ;;;; Src Block
508 (defcustom org-html-htmlize-output-type 'inline-css
509 "Output type to be used by htmlize when formatting code snippets.
510 Choices are `css', to export the CSS selectors only, or `inline-css', to
511 export the CSS attribute values inline in the HTML. We use as default
512 `inline-css', in order to make the resulting HTML self-containing.
514 However, this will fail when using Emacs in batch mode for export, because
515 then no rich font definitions are in place. It will also not be good if
516 people with different Emacs setup contribute HTML files to a website,
517 because the fonts will represent the individual setups. In these cases,
518 it is much better to let Org/Htmlize assign classes only, and to use
519 a style file to define the look of these classes.
520 To get a start for your css file, start Emacs session and make sure that
521 all the faces you are interested in are defined, for example by loading files
522 in all modes you want. Then, use the command
523 \\[org-html-htmlize-generate-css] to extract class definitions."
524 :group 'org-export-html
525 :type '(choice (const css) (const inline-css)))
527 (defcustom org-html-htmlize-font-prefix "org-"
528 "The prefix for CSS class names for htmlize font specifications."
529 :group 'org-export-html
530 :type 'string)
532 (defcustom org-html-htmlized-org-css-url nil
533 "URL pointing to a CSS file defining text colors for htmlized Emacs buffers.
534 Normally when creating an htmlized version of an Org buffer, htmlize will
535 create CSS to define the font colors. However, this does not work when
536 converting in batch mode, and it also can look bad if different people
537 with different fontification setup work on the same website.
538 When this variable is non-nil, creating an htmlized version of an Org buffer
539 using `org-export-as-org' will remove the internal CSS section and replace it
540 with a link to this URL."
541 :group 'org-export-html
542 :type '(choice
543 (const :tag "Keep internal css" nil)
544 (string :tag "URL or local href")))
547 ;;;; Table
549 (defcustom org-html-table-tag
550 "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">"
551 "The HTML tag that is used to start a table.
552 This must be a <table> tag, but you may change the options like
553 borders and spacing."
554 :group 'org-export-html
555 :type 'string)
557 (defcustom org-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>")
558 "The opening tag for table header fields.
559 This is customizable so that alignment options can be specified.
560 The first %s will be filled with the scope of the field, either row or col.
561 The second %s will be replaced by a style entry to align the field.
562 See also the variable `org-html-table-use-header-tags-for-first-column'.
563 See also the variable `org-html-table-align-individual-fields'."
564 :group 'org-export-html
565 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
567 (defcustom org-html-table-data-tags '("<td%s>" . "</td>")
568 "The opening tag for table data fields.
569 This is customizable so that alignment options can be specified.
570 The first %s will be filled with the scope of the field, either row or col.
571 The second %s will be replaced by a style entry to align the field.
572 See also the variable `org-html-table-align-individual-fields'."
573 :group 'org-export-html
574 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
576 (defcustom org-html-table-row-tags '("<tr>" . "</tr>")
577 "The opening tag for table data fields.
578 This is customizable so that alignment options can be specified.
579 Instead of strings, these can be Lisp forms that will be evaluated
580 for each row in order to construct the table row tags. During evaluation,
581 the variable `head' will be true when this is a header line, nil when this
582 is a body line. And the variable `nline' will contain the line number,
583 starting from 1 in the first header line. For example
585 (setq org-html-table-row-tags
586 (cons '(if head
587 \"<tr>\"
588 (if (= (mod nline 2) 1)
589 \"<tr class=\\\"tr-odd\\\">\"
590 \"<tr class=\\\"tr-even\\\">\"))
591 \"</tr>\"))
593 will give even lines the class \"tr-even\" and odd lines the class \"tr-odd\"."
594 :group 'org-export-html
595 :type '(cons
596 (choice :tag "Opening tag"
597 (string :tag "Specify")
598 (sexp))
599 (choice :tag "Closing tag"
600 (string :tag "Specify")
601 (sexp))))
603 (defcustom org-html-table-align-individual-fields t
604 "Non-nil means attach style attributes for alignment to each table field.
605 When nil, alignment will only be specified in the column tags, but this
606 is ignored by some browsers (like Firefox, Safari). Opera does it right
607 though."
608 :group 'org-export-html
609 :type 'boolean)
611 (defcustom org-html-table-use-header-tags-for-first-column nil
612 "Non-nil means format column one in tables with header tags.
613 When nil, also column one will use data tags."
614 :group 'org-export-html
615 :type 'boolean)
617 (defcustom org-html-table-caption-above t
618 "When non-nil, place caption string at the beginning of the table.
619 Otherwise, place it near the end."
620 :group 'org-export-html
621 :type 'boolean)
624 ;;;; Tags
626 (defcustom org-html-tag-class-prefix ""
627 "Prefix to class names for TODO keywords.
628 Each tag gets a class given by the tag itself, with this prefix.
629 The default prefix is empty because it is nice to just use the keyword
630 as a class name. But if you get into conflicts with other, existing
631 CSS classes, then this prefix can be very useful."
632 :group 'org-export-html
633 :type 'string)
636 ;;;; Template :: Generic
638 (defcustom org-html-extension "html"
639 "The extension for exported HTML files."
640 :group 'org-export-html
641 :type 'string)
643 (defcustom org-html-xml-declaration
644 '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>")
645 ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>"))
646 "The extension for exported HTML files.
647 %s will be replaced with the charset of the exported file.
648 This may be a string, or an alist with export extensions
649 and corresponding declarations."
650 :group 'org-export-html
651 :type '(choice
652 (string :tag "Single declaration")
653 (repeat :tag "Dependent on extension"
654 (cons (string :tag "Extension")
655 (string :tag "Declaration")))))
657 (defcustom org-html-coding-system 'utf-8
658 "Coding system for HTML export.
659 Use utf-8 as the default value."
660 :group 'org-export-html
661 :type 'coding-system)
663 (defcustom org-html-divs '("preamble" "content" "postamble")
664 "The name of the main divs for HTML export.
665 This is a list of three strings, the first one for the preamble
666 DIV, the second one for the content DIV and the third one for the
667 postamble DIV."
668 :group 'org-export-html
669 :type '(list
670 (string :tag " Div for the preamble:")
671 (string :tag " Div for the content:")
672 (string :tag "Div for the postamble:")))
675 ;;;; Template :: Mathjax
677 (defcustom org-html-mathjax-options
678 '((path "http://orgmode.org/mathjax/MathJax.js")
679 (scale "100")
680 (align "center")
681 (indent "2em")
682 (mathml nil))
683 "Options for MathJax setup.
685 path The path where to find MathJax
686 scale Scaling for the HTML-CSS backend, usually between 100 and 133
687 align How to align display math: left, center, or right
688 indent If align is not center, how far from the left/right side?
689 mathml Should a MathML player be used if available?
690 This is faster and reduces bandwidth use, but currently
691 sometimes has lower spacing quality. Therefore, the default is
692 nil. When browsers get better, this switch can be flipped.
694 You can also customize this for each buffer, using something like
696 #+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\""
697 :group 'org-export-html
698 :type '(list :greedy t
699 (list :tag "path (the path from where to load MathJax.js)"
700 (const :format " " path) (string))
701 (list :tag "scale (scaling for the displayed math)"
702 (const :format " " scale) (string))
703 (list :tag "align (alignment of displayed equations)"
704 (const :format " " align) (string))
705 (list :tag "indent (indentation with left or right alignment)"
706 (const :format " " indent) (string))
707 (list :tag "mathml (should MathML display be used is possible)"
708 (const :format " " mathml) (boolean))))
710 (defcustom org-html-mathjax-template
711 "<script type=\"text/javascript\" src=\"%PATH\">
712 <!--/*--><![CDATA[/*><!--*/
713 MathJax.Hub.Config({
714 // Only one of the two following lines, depending on user settings
715 // First allows browser-native MathML display, second forces HTML/CSS
716 :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"],
717 :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"],
718 extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\",
719 \"TeX/noUndefined.js\"],
720 tex2jax: {
721 inlineMath: [ [\"\\\\(\",\"\\\\)\"] ],
722 displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ],
723 skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"],
724 ignoreClass: \"tex2jax_ignore\",
725 processEscapes: false,
726 processEnvironments: true,
727 preview: \"TeX\"
729 showProcessingMessages: true,
730 displayAlign: \"%ALIGN\",
731 displayIndent: \"%INDENT\",
733 \"HTML-CSS\": {
734 scale: %SCALE,
735 availableFonts: [\"STIX\",\"TeX\"],
736 preferredFont: \"TeX\",
737 webFont: \"TeX\",
738 imageFont: \"TeX\",
739 showMathMenu: true,
741 MMLorHTML: {
742 prefer: {
743 MSIE: \"MML\",
744 Firefox: \"MML\",
745 Opera: \"HTML\",
746 other: \"HTML\"
750 /*]]>*///-->
751 </script>"
752 "The MathJax setup for XHTML files."
753 :group 'org-export-html
754 :type 'string)
757 ;;;; Template :: Postamble
759 (defcustom org-html-postamble 'auto
760 "Non-nil means insert a postamble in HTML export.
762 When `t', insert a string as defined by the formatting string in
763 `org-html-postamble-format'. When set to a string, this
764 string overrides `org-html-postamble-format'. When set to
765 'auto, discard `org-html-postamble-format' and honor
766 `org-export-author/email/creator-info' variables. When set to a
767 function, apply this function and insert the returned string.
768 The function takes the property list of export options as its
769 only argument.
771 Setting :html-postamble in publishing projects will take
772 precedence over this variable."
773 :group 'org-export-html
774 :type '(choice (const :tag "No postamble" nil)
775 (const :tag "Auto preamble" 'auto)
776 (const :tag "Default formatting string" t)
777 (string :tag "Custom formatting string")
778 (function :tag "Function (must return a string)")))
780 (defcustom org-html-postamble-format
781 '(("en" "<p class=\"author\">Author: %a (%e)</p>
782 <p class=\"date\">Date: %d</p>
783 <p class=\"creator\">Generated by %c</p>
784 <p class=\"xhtml-validation\">%v</p>"))
785 "Alist of languages and format strings for the HTML postamble.
787 The first element of each list is the language code, as used for
788 the #+LANGUAGE keyword.
790 The second element of each list is a format string to format the
791 postamble itself. This format string can contain these elements:
793 %a stands for the author's name.
794 %e stands for the author's email.
795 %d stands for the date.
796 %c will be replaced by information about Org/Emacs versions.
797 %v will be replaced by `org-html-validation-link'.
799 If you need to use a \"%\" character, you need to escape it
800 like that: \"%%\"."
801 :group 'org-export-html
802 :type '(alist :key-type (string :tag "Language")
803 :value-type (string :tag "Format string")))
805 (defcustom org-html-validation-link
806 "<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>"
807 "Link to HTML validation service."
808 :group 'org-export-html
809 :type 'string)
811 (defcustom org-html-creator-string
812 (format "Generated by <a href=\"http://orgmode.org\">Org</a> mode %s in <a href=\"http://www.gnu.org/software/emacs/\">Emacs</a> %s."
813 (if (fboundp 'org-version) (org-version) "(Unknown)")
814 emacs-version)
815 "String to insert at the end of the HTML document."
816 :group 'org-export-html
817 :type '(string :tag "Creator string"))
820 ;;;; Template :: Preamble
822 (defcustom org-html-preamble t
823 "Non-nil means insert a preamble in HTML export.
825 When `t', insert a string as defined by one of the formatting
826 strings in `org-html-preamble-format'. When set to a
827 string, this string overrides `org-html-preamble-format'.
828 When set to a function, apply this function and insert the
829 returned string. The function takes the property list of export
830 options as its only argument.
832 Setting :html-preamble in publishing projects will take
833 precedence over this variable."
834 :group 'org-export-html
835 :type '(choice (const :tag "No preamble" nil)
836 (const :tag "Default preamble" t)
837 (string :tag "Custom formatting string")
838 (function :tag "Function (must return a string)")))
840 (defcustom org-html-preamble-format '(("en" ""))
841 "Alist of languages and format strings for the HTML preamble.
843 The first element of each list is the language code, as used for
844 the #+LANGUAGE keyword.
846 The second element of each list is a format string to format the
847 preamble itself. This format string can contain these elements:
849 %t stands for the title.
850 %a stands for the author's name.
851 %e stands for the author's email.
852 %d stands for the date.
854 If you need to use a \"%\" character, you need to escape it
855 like that: \"%%\"."
856 :group 'org-export-html
857 :type '(alist :key-type (string :tag "Language")
858 :value-type (string :tag "Format string")))
860 (defcustom org-html-link-up ""
861 "Where should the \"UP\" link of exported HTML pages lead?"
862 :group 'org-export-html
863 :type '(string :tag "File or URL"))
865 (defcustom org-html-link-home ""
866 "Where should the \"HOME\" link of exported HTML pages lead?"
867 :group 'org-export-html
868 :type '(string :tag "File or URL"))
870 (defcustom org-html-home/up-format
871 "<div id=\"org-div-home-and-up\" style=\"text-align:right;font-size:70%%;white-space:nowrap;\">
872 <a accesskey=\"h\" href=\"%s\"> UP </a>
874 <a accesskey=\"H\" href=\"%s\"> HOME </a>
875 </div>"
876 "Snippet used to insert the HOME and UP links.
877 This is a format string, the first %s will receive the UP link,
878 the second the HOME link. If both `org-html-link-up' and
879 `org-html-link-home' are empty, the entire snippet will be
880 ignored."
881 :group 'org-export-html
882 :type 'string)
885 ;;;; Template :: Scripts
887 (defcustom org-html-style-include-scripts t
888 "Non-nil means include the JavaScript snippets in exported HTML files.
889 The actual script is defined in `org-html-scripts' and should
890 not be modified."
891 :group 'org-export-html
892 :type 'boolean)
895 ;;;; Template :: Styles
897 (defcustom org-html-style-include-default t
898 "Non-nil means include the default style in exported HTML files.
899 The actual style is defined in `org-html-style-default' and should
900 not be modified. Use the variables `org-html-style' to add
901 your own style information."
902 :group 'org-export-html
903 :type 'boolean)
904 ;;;###autoload
905 (put 'org-html-style-include-default 'safe-local-variable 'booleanp)
907 (defcustom org-html-style ""
908 "Org-wide style definitions for exported HTML files.
910 This variable needs to contain the full HTML structure to provide a style,
911 including the surrounding HTML tags. If you set the value of this variable,
912 you should consider to include definitions for the following classes:
913 title, todo, done, timestamp, timestamp-kwd, tag, target.
915 For example, a valid value would be:
917 <style type=\"text/css\">
918 <![CDATA[
919 p { font-weight: normal; color: gray; }
920 h1 { color: black; }
921 .title { text-align: center; }
922 .todo, .timestamp-kwd { color: red; }
923 .done { color: green; }
925 </style>
927 If you'd like to refer to an external style file, use something like
929 <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
931 As the value of this option simply gets inserted into the HTML <head> header,
932 you can \"misuse\" it to add arbitrary text to the header.
933 See also the variable `org-html-style-extra'."
934 :group 'org-export-html
935 :type 'string)
936 ;;;###autoload
937 (put 'org-html-style 'safe-local-variable 'stringp)
939 (defcustom org-html-style-extra ""
940 "Additional style information for HTML export.
941 The value of this variable is inserted into the HTML buffer right after
942 the value of `org-html-style'. Use this variable for per-file
943 settings of style information, and do not forget to surround the style
944 settings with <style>...</style> tags."
945 :group 'org-export-html
946 :type 'string)
947 ;;;###autoload
948 (put 'org-html-style-extra 'safe-local-variable 'stringp)
951 ;;;; Todos
953 (defcustom org-html-todo-kwd-class-prefix ""
954 "Prefix to class names for TODO keywords.
955 Each TODO keyword gets a class given by the keyword itself, with this prefix.
956 The default prefix is empty because it is nice to just use the keyword
957 as a class name. But if you get into conflicts with other, existing
958 CSS classes, then this prefix can be very useful."
959 :group 'org-export-html
960 :type 'string)
962 (defcustom org-html-display-buffer-mode 'html-mode
963 "Default mode when visiting the HTML output."
964 :group 'org-export-html
965 :version "24.3"
966 :type '(choice (function 'html-mode)
967 (function 'nxml-mode)
968 (function :tag "Other mode")))
972 ;;; Internal Functions
974 (defun org-html-format-inline-image (src &optional
975 caption label attr standalone-p)
976 (let* ((id (if (not label) ""
977 (format " id=\"%s\"" (org-export-solidify-link-text label))))
978 (attr (concat attr
979 (cond
980 ((string-match "\\<alt=" (or attr "")) "")
981 ((string-match "^ltxpng/" src)
982 (format " alt=\"%s\""
983 (org-html-encode-plain-text
984 (org-find-text-property-in-string
985 'org-latex-src src))))
986 (t (format " alt=\"%s\""
987 (file-name-nondirectory src)))))))
988 (cond
989 (standalone-p
990 (let ((img (format "<img src=\"%s\" %s/>" src attr)))
991 (format "\n<div%s class=\"figure\">%s%s\n</div>"
992 id (format "\n<p>%s</p>" img)
993 (when caption (format "\n<p>%s</p>" caption)))))
994 (t (format "<img src=\"%s\" %s/>" src (concat attr id))))))
996 (defun org-html--textarea-block (element)
997 "Transcode ELEMENT into a textarea block.
998 ELEMENT is either a src block or an example block."
999 (let ((code (car (org-export-unravel-code element)))
1000 (attr (org-export-read-attribute :attr_html element)))
1001 (format "<p>\n<textarea cols=\"%d\" rows=\"%d\">\n%s</textarea>\n</p>"
1002 (or (plist-get attr :width) 80)
1003 (or (plist-get attr :height) (org-count-lines code))
1004 code)))
1007 ;;;; Bibliography
1009 (defun org-html-bibliography ()
1010 "Find bibliography, cut it out and return it."
1011 (catch 'exit
1012 (let (beg end (cnt 1) bib)
1013 (save-excursion
1014 (goto-char (point-min))
1015 (when (re-search-forward
1016 "^[ \t]*<div \\(id\\|class\\)=\"bibliography\"" nil t)
1017 (setq beg (match-beginning 0))
1018 (while (re-search-forward "</?div\\>" nil t)
1019 (setq cnt (+ cnt (if (string= (match-string 0) "<div") +1 -1)))
1020 (when (= cnt 0)
1021 (and (looking-at ">") (forward-char 1))
1022 (setq bib (buffer-substring beg (point)))
1023 (delete-region beg (point))
1024 (throw 'exit bib))))
1025 nil))))
1027 ;;;; Table
1029 (defun org-html-splice-attributes (tag attributes)
1030 "Read attributes in string ATTRIBUTES, add and replace in HTML tag TAG."
1031 (if (not attributes)
1033 (let (oldatt newatt)
1034 (setq oldatt (org-extract-attributes-from-string tag)
1035 tag (pop oldatt)
1036 newatt (cdr (org-extract-attributes-from-string attributes)))
1037 (while newatt
1038 (setq oldatt (plist-put oldatt (pop newatt) (pop newatt))))
1039 (if (string-match ">" tag)
1040 (setq tag
1041 (replace-match (concat (org-attributes-to-string oldatt) ">")
1042 t t tag)))
1043 tag)))
1045 (defun org-export-splice-style (style extra)
1046 "Splice EXTRA into STYLE, just before \"</style>\"."
1047 (if (and (stringp extra)
1048 (string-match "\\S-" extra)
1049 (string-match "</style>" style))
1050 (concat (substring style 0 (match-beginning 0))
1051 "\n" extra "\n"
1052 (substring style (match-beginning 0)))
1053 style))
1055 (defun org-html-htmlize-region-for-paste (beg end)
1056 "Convert the region to HTML, using htmlize.el.
1057 This is much like `htmlize-region-for-paste', only that it uses
1058 the settings define in the org-... variables."
1059 (let* ((htmlize-output-type org-html-htmlize-output-type)
1060 (htmlize-css-name-prefix org-html-htmlize-font-prefix)
1061 (htmlbuf (htmlize-region beg end)))
1062 (unwind-protect
1063 (with-current-buffer htmlbuf
1064 (buffer-substring (plist-get htmlize-buffer-places 'content-start)
1065 (plist-get htmlize-buffer-places 'content-end)))
1066 (kill-buffer htmlbuf))))
1068 ;;;###autoload
1069 (defun org-html-htmlize-generate-css ()
1070 "Create the CSS for all font definitions in the current Emacs session.
1071 Use this to create face definitions in your CSS style file that can then
1072 be used by code snippets transformed by htmlize.
1073 This command just produces a buffer that contains class definitions for all
1074 faces used in the current Emacs session. You can copy and paste the ones you
1075 need into your CSS file.
1077 If you then set `org-html-htmlize-output-type' to `css', calls
1078 to the function `org-html-htmlize-region-for-paste' will
1079 produce code that uses these same face definitions."
1080 (interactive)
1081 (require 'htmlize)
1082 (and (get-buffer "*html*") (kill-buffer "*html*"))
1083 (with-temp-buffer
1084 (let ((fl (face-list))
1085 (htmlize-css-name-prefix "org-")
1086 (htmlize-output-type 'css)
1087 f i)
1088 (while (setq f (pop fl)
1089 i (and f (face-attribute f :inherit)))
1090 (when (and (symbolp f) (or (not i) (not (listp i))))
1091 (insert (org-add-props (copy-sequence "1") nil 'face f))))
1092 (htmlize-region (point-min) (point-max))))
1093 (org-pop-to-buffer-same-window "*html*")
1094 (goto-char (point-min))
1095 (if (re-search-forward "<style" nil t)
1096 (delete-region (point-min) (match-beginning 0)))
1097 (if (re-search-forward "</style>" nil t)
1098 (delete-region (1+ (match-end 0)) (point-max)))
1099 (beginning-of-line 1)
1100 (if (looking-at " +") (replace-match ""))
1101 (goto-char (point-min)))
1103 (defun org-html--make-string (n string)
1104 "Build a string by concatenating N times STRING."
1105 (let (out) (dotimes (i n out) (setq out (concat string out)))))
1107 (defun org-html-fix-class-name (kwd) ; audit callers of this function
1108 "Turn todo keyword into a valid class name.
1109 Replaces invalid characters with \"_\"."
1110 (save-match-data
1111 (while (string-match "[^a-zA-Z0-9_]" kwd)
1112 (setq kwd (replace-match "_" t t kwd))))
1113 kwd)
1115 (defun org-html-format-footnote-reference (n def refcnt)
1116 (let ((extra (if (= refcnt 1) "" (format ".%d" refcnt))))
1117 (format org-html-footnote-format
1118 (let* ((id (format "fnr.%s%s" n extra))
1119 (href (format " href=\"#fn.%s\"" n))
1120 (attributes (concat " class=\"footref\"" href)))
1121 (org-html--anchor id n attributes)))))
1123 (defun org-html-format-footnotes-section (section-name definitions)
1124 (if (not definitions) ""
1125 (format org-html-footnotes-section section-name definitions)))
1127 (defun org-html-format-footnote-definition (fn)
1128 (let ((n (car fn)) (def (cdr fn)))
1129 (format
1130 "<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>\n"
1131 (format org-html-footnote-format
1132 (let* ((id (format "fn.%s" n))
1133 (href (format " href=\"#fnr.%s\"" n))
1134 (attributes (concat " class=\"footnum\"" href)))
1135 (org-html--anchor id n attributes)))
1136 def)))
1138 (defun org-html-footnote-section (info)
1139 (let* ((fn-alist (org-export-collect-footnote-definitions
1140 (plist-get info :parse-tree) info))
1142 (fn-alist
1143 (loop for (n type raw) in fn-alist collect
1144 (cons n (if (eq (org-element-type raw) 'org-data)
1145 (org-trim (org-export-data raw info))
1146 (format "<p>%s</p>"
1147 (org-trim (org-export-data raw info))))))))
1148 (when fn-alist
1149 (org-html-format-footnotes-section
1150 (org-html--translate "Footnotes" info)
1151 (format
1152 "<table>\n%s\n</table>\n"
1153 (mapconcat 'org-html-format-footnote-definition fn-alist "\n"))))))
1157 ;;; Template
1159 (defun org-html--build-meta-info (info)
1160 "Return meta tags for exported document.
1161 INFO is a plist used as a communication channel."
1162 (let* ((title (org-export-data (plist-get info :title) info))
1163 (author (and (plist-get info :with-author)
1164 (let ((auth (plist-get info :author)))
1165 (and auth (org-export-data auth info)))))
1166 (date (and (plist-get info :with-date)
1167 (let ((date (plist-get info :date)))
1168 (and date (org-export-data date info)))))
1169 (description (plist-get info :description))
1170 (keywords (plist-get info :keywords)))
1171 (concat
1172 (format "<title>%s</title>\n" title)
1173 (format
1174 "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>\n"
1175 (or (and org-html-coding-system
1176 (fboundp 'coding-system-get)
1177 (coding-system-get org-html-coding-system 'mime-charset))
1178 "iso-8859-1"))
1179 (format "<meta name=\"title\" content=\"%s\"/>\n" title)
1180 (format "<meta name=\"generator\" content=\"Org-mode\"/>\n")
1181 (and date (format "<meta name=\"generated\" content=\"%s\"/>\n" date))
1182 (and author (format "<meta name=\"author\" content=\"%s\"/>\n" author))
1183 (and description
1184 (format "<meta name=\"description\" content=\"%s\"/>\n" description))
1185 (and keywords
1186 (format "<meta name=\"keywords\" content=\"%s\"/>\n" keywords)))))
1188 (defun org-html--build-style (info)
1189 "Return style information for exported document.
1190 INFO is a plist used as a communication channel."
1191 (org-element-normalize-string
1192 (concat
1193 (when (plist-get info :html-style-include-default) org-html-style-default)
1194 (org-element-normalize-string (plist-get info :html-style))
1195 (org-element-normalize-string (plist-get info :html-style-extra))
1196 (when (plist-get info :html-style-include-scripts) org-html-scripts))))
1198 (defun org-html--build-mathjax-config (info)
1199 "Insert the user setup into the mathjax template.
1200 INFO is a plist used as a communication channel."
1201 (when (and (memq (plist-get info :with-latex) '(mathjax t))
1202 (org-element-map (plist-get info :parse-tree)
1203 '(latex-fragment latex-environment) 'identity info t))
1204 (let ((template org-html-mathjax-template)
1205 (options org-html-mathjax-options)
1206 (in-buffer (or (plist-get info :html-mathjax) ""))
1207 name val (yes " ") (no "// ") x)
1208 (mapc
1209 (lambda (e)
1210 (setq name (car e) val (nth 1 e))
1211 (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer)
1212 (setq val (car (read-from-string
1213 (substring in-buffer (match-end 0))))))
1214 (if (not (stringp val)) (setq val (format "%s" val)))
1215 (if (string-match (concat "%" (upcase (symbol-name name))) template)
1216 (setq template (replace-match val t t template))))
1217 options)
1218 (setq val (nth 1 (assq 'mathml options)))
1219 (if (string-match (concat "\\<mathml:") in-buffer)
1220 (setq val (car (read-from-string
1221 (substring in-buffer (match-end 0))))))
1222 ;; Exchange prefixes depending on mathml setting.
1223 (if (not val) (setq x yes yes no no x))
1224 ;; Replace cookies to turn on or off the config/jax lines.
1225 (if (string-match ":MMLYES:" template)
1226 (setq template (replace-match yes t t template)))
1227 (if (string-match ":MMLNO:" template)
1228 (setq template (replace-match no t t template)))
1229 ;; Return the modified template.
1230 (org-element-normalize-string template))))
1232 (defun org-html--build-preamble (info)
1233 "Return document preamble as a string, or nil.
1234 INFO is a plist used as a communication channel."
1235 (let ((preamble (plist-get info :html-preamble)))
1236 (when preamble
1237 (let ((preamble-contents
1238 (if (functionp preamble) (funcall preamble info)
1239 (let ((title (org-export-data (plist-get info :title) info))
1240 (date (if (not (plist-get info :with-date)) ""
1241 (org-export-data (plist-get info :date) info)))
1242 (author (if (not (plist-get info :with-author)) ""
1243 (org-export-data (plist-get info :author) info)))
1244 (email (if (not (plist-get info :with-email)) ""
1245 (plist-get info :email))))
1246 (if (stringp preamble)
1247 (format-spec preamble
1248 `((?t . ,title) (?a . ,author)
1249 (?d . ,date) (?e . ,email)))
1250 (format-spec
1251 (or (cadr (assoc (plist-get info :language)
1252 org-html-preamble-format))
1253 (cadr (assoc "en" org-html-preamble-format)))
1254 `((?t . ,title) (?a . ,author)
1255 (?d . ,date) (?e . ,email))))))))
1256 (when (org-string-nw-p preamble-contents)
1257 (concat (format "<div id=\"%s\">\n" (nth 0 org-html-divs))
1258 (org-element-normalize-string preamble-contents)
1259 "</div>\n"))))))
1261 (defun org-html--build-postamble (info)
1262 "Return document postamble as a string, or nil.
1263 INFO is a plist used as a communication channel."
1264 (let ((postamble (plist-get info :html-postamble)))
1265 (when postamble
1266 (let ((postamble-contents
1267 (if (functionp postamble) (funcall postamble info)
1268 (let ((date (if (not (plist-get info :with-date)) ""
1269 (org-export-data (plist-get info :date) info)))
1270 (author (let ((author (plist-get info :author)))
1271 (and author (org-export-data author info))))
1272 (email (mapconcat
1273 (lambda (e)
1274 (format "<a href=\"mailto:%s\">%s</a>" e e))
1275 (split-string (plist-get info :email) ",+ *")
1276 ", "))
1277 (html-validation-link (or org-html-validation-link ""))
1278 (creator-info (plist-get info :creator)))
1279 (cond ((stringp postamble)
1280 (format-spec postamble
1281 `((?a . ,author) (?e . ,email)
1282 (?d . ,date) (?c . ,creator-info)
1283 (?v . ,html-validation-link))))
1284 ((eq postamble 'auto)
1285 (concat
1286 (when (plist-get info :time-stamp-file)
1287 (format "<p class=\"date\">%s: %s</p>\n"
1288 (org-html--translate "Date" info)
1289 date))
1290 (when (and (plist-get info :with-author) author)
1291 (format "<p class=\"author\">%s : %s</p>\n"
1292 (org-html--translate "Author" info)
1293 author))
1294 (when (and (plist-get info :with-email) email)
1295 (format "<p class=\"email\">%s </p>\n" email))
1296 (when (plist-get info :with-creator)
1297 (format "<p class=\"creator\">%s</p>\n"
1298 creator-info))
1299 html-validation-link "\n"))
1300 (t (format-spec
1301 (or (cadr (assoc (plist-get info :language)
1302 org-html-postamble-format))
1303 (cadr (assoc "en" org-html-postamble-format)))
1304 `((?a . ,author) (?e . ,email)
1305 (?d . ,date) (?c . ,creator-info)
1306 (?v . ,html-validation-link)))))))))
1307 (when (org-string-nw-p postamble-contents)
1308 (concat
1309 (format "<div id=\"%s\">\n" (nth 2 org-html-divs))
1310 (org-element-normalize-string postamble-contents)
1311 "</div>\n"))))))
1313 (defun org-html-inner-template (contents info)
1314 "Return body of document string after HTML conversion.
1315 CONTENTS is the transcoded contents string. INFO is a plist
1316 holding export options."
1317 (concat
1318 (format "<div id=\"%s\">\n" (nth 1 org-html-divs))
1319 ;; Document title.
1320 (format "<h1 class=\"title\">%s</h1>\n"
1321 (org-export-data (plist-get info :title) info))
1322 ;; Table of contents.
1323 (let ((depth (plist-get info :with-toc)))
1324 (when depth (org-html-toc depth info)))
1325 ;; Document contents.
1326 contents
1327 ;; Footnotes section.
1328 (org-html-footnote-section info)
1329 ;; Bibliography.
1330 (org-html-bibliography)
1331 "\n</div>"))
1333 (defun org-html-template (contents info)
1334 "Return complete document string after HTML conversion.
1335 CONTENTS is the transcoded contents string. INFO is a plist
1336 holding export options."
1337 (concat
1338 (format
1339 (or (and (stringp org-html-xml-declaration)
1340 org-html-xml-declaration)
1341 (cdr (assoc (plist-get info :html-extension)
1342 org-html-xml-declaration))
1343 (cdr (assoc "html" org-html-xml-declaration))
1346 (or (and org-html-coding-system
1347 (fboundp 'coding-system-get)
1348 (coding-system-get org-html-coding-system 'mime-charset))
1349 "iso-8859-1"))
1350 "\n"
1351 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
1352 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
1353 (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">\n"
1354 (plist-get info :language) (plist-get info :language))
1355 "<head>\n"
1356 (org-html--build-meta-info info)
1357 (org-html--build-style info)
1358 (org-html--build-mathjax-config info)
1359 "</head>\n"
1360 "<body>\n"
1361 (let ((link-up (org-trim (plist-get info :html-link-up)))
1362 (link-home (org-trim (plist-get info :html-link-home))))
1363 (unless (and (string= link-up "") (string= link-up ""))
1364 (format org-html-home/up-format
1365 (or link-up link-home)
1366 (or link-home link-up))))
1367 ;; Preamble.
1368 (org-html--build-preamble info)
1369 ;; Document contents.
1370 contents
1371 ;; Postamble.
1372 (org-html--build-postamble info)
1373 ;; Closing document.
1374 "</body>\n</html>"))
1376 (defun org-html--translate (s info)
1377 "Translate string S according to specified language.
1378 INFO is a plist used as a communication channel."
1379 (org-export-translate s :html info))
1381 ;;;; Anchor
1383 (defun org-html--anchor (&optional id desc attributes)
1384 (let* ((name (and org-html-allow-name-attribute-in-anchors id))
1385 (attributes (concat (and id (format " id=\"%s\"" id))
1386 (and name (format " name=\"%s\"" name))
1387 attributes)))
1388 (format "<a%s>%s</a>" attributes (or desc ""))))
1390 ;;;; Todo
1392 (defun org-html--todo (todo)
1393 (when todo
1394 (format "<span class=\"%s %s%s\">%s</span>"
1395 (if (member todo org-done-keywords) "done" "todo")
1396 org-html-todo-kwd-class-prefix (org-html-fix-class-name todo)
1397 todo)))
1399 ;;;; Tags
1401 (defun org-html--tags (tags)
1402 (when tags
1403 (format "<span class=\"tag\">%s</span>"
1404 (mapconcat
1405 (lambda (tag)
1406 (format "<span class=\"%s\">%s</span>"
1407 (concat org-html-tag-class-prefix
1408 (org-html-fix-class-name tag))
1409 tag))
1410 tags "&nbsp;"))))
1412 ;;;; Headline
1414 (defun* org-html-format-headline
1415 (todo todo-type priority text tags
1416 &key level section-number headline-label &allow-other-keys)
1417 (let ((section-number
1418 (when section-number
1419 (format "<span class=\"section-number-%d\">%s</span> "
1420 level section-number)))
1421 (todo (org-html--todo todo))
1422 (tags (org-html--tags tags)))
1423 (concat section-number todo (and todo " ") text
1424 (and tags "&nbsp;&nbsp;&nbsp;") tags)))
1426 ;;;; Src Code
1428 (defun org-html-fontify-code (code lang)
1429 "Color CODE with htmlize library.
1430 CODE is a string representing the source code to colorize. LANG
1431 is the language used for CODE, as a string, or nil."
1432 (when code
1433 (cond
1434 ;; Case 1: No lang. Possibly an example block.
1435 ((not lang)
1436 ;; Simple transcoding.
1437 (org-html-encode-plain-text code))
1438 ;; Case 2: No htmlize or an inferior version of htmlize
1439 ((not (and (require 'htmlize nil t) (fboundp 'htmlize-region-for-paste)))
1440 ;; Emit a warning.
1441 (message "Cannot fontify src block (htmlize.el >= 1.34 required)")
1442 ;; Simple transcoding.
1443 (org-html-encode-plain-text code))
1445 ;; Map language
1446 (setq lang (or (assoc-default lang org-src-lang-modes) lang))
1447 (let* ((lang-mode (and lang (intern (format "%s-mode" lang)))))
1448 (cond
1449 ;; Case 1: Language is not associated with any Emacs mode
1450 ((not (functionp lang-mode))
1451 ;; Simple transcoding.
1452 (org-html-encode-plain-text code))
1453 ;; Case 2: Default. Fontify code.
1455 ;; htmlize
1456 (setq code (with-temp-buffer
1457 ;; Switch to language-specific mode.
1458 (funcall lang-mode)
1459 (insert code)
1460 ;; Fontify buffer.
1461 (font-lock-fontify-buffer)
1462 ;; Remove formatting on newline characters.
1463 (save-excursion
1464 (let ((beg (point-min))
1465 (end (point-max)))
1466 (goto-char beg)
1467 (while (progn (end-of-line) (< (point) end))
1468 (put-text-property (point) (1+ (point)) 'face nil)
1469 (forward-char 1))))
1470 (org-src-mode)
1471 (set-buffer-modified-p nil)
1472 ;; Htmlize region.
1473 (org-html-htmlize-region-for-paste
1474 (point-min) (point-max))))
1475 ;; Strip any encolosing <pre></pre> tags.
1476 (if (string-match "<pre[^>]*>\n*\\([^\000]*\\)</pre>" code)
1477 (match-string 1 code)
1478 code))))))))
1480 (defun org-html-do-format-code
1481 (code &optional lang refs retain-labels num-start)
1482 "Format CODE string as source code.
1483 Optional arguments LANG, REFS, RETAIN-LABELS and NUM-START are,
1484 respectively, the language of the source code, as a string, an
1485 alist between line numbers and references (as returned by
1486 `org-export-unravel-code'), a boolean specifying if labels should
1487 appear in the source code, and the number associated to the first
1488 line of code."
1489 (let* ((code-lines (org-split-string code "\n"))
1490 (code-length (length code-lines))
1491 (num-fmt
1492 (and num-start
1493 (format "%%%ds: "
1494 (length (number-to-string (+ code-length num-start))))))
1495 (code (org-html-fontify-code code lang)))
1496 (org-export-format-code
1497 code
1498 (lambda (loc line-num ref)
1499 (setq loc
1500 (concat
1501 ;; Add line number, if needed.
1502 (when num-start
1503 (format "<span class=\"linenr\">%s</span>"
1504 (format num-fmt line-num)))
1505 ;; Transcoded src line.
1507 ;; Add label, if needed.
1508 (when (and ref retain-labels) (format " (%s)" ref))))
1509 ;; Mark transcoded line as an anchor, if needed.
1510 (if (not ref) loc
1511 (format "<span id=\"coderef-%s\" class=\"coderef-off\">%s</span>"
1512 ref loc)))
1513 num-start refs)))
1515 (defun org-html-format-code (element info)
1516 "Format contents of ELEMENT as source code.
1517 ELEMENT is either an example block or a src block. INFO is
1518 a plist used as a communication channel."
1519 (let* ((lang (org-element-property :language element))
1520 ;; Extract code and references.
1521 (code-info (org-export-unravel-code element))
1522 (code (car code-info))
1523 (refs (cdr code-info))
1524 ;; Does the src block contain labels?
1525 (retain-labels (org-element-property :retain-labels element))
1526 ;; Does it have line numbers?
1527 (num-start (case (org-element-property :number-lines element)
1528 (continued (org-export-get-loc element info))
1529 (new 0))))
1530 (org-html-do-format-code code lang refs retain-labels num-start)))
1534 ;;; Tables of Contents
1536 (defun org-html-toc (depth info)
1537 "Build a table of contents.
1538 DEPTH is an integer specifying the depth of the table. INFO is
1539 a plist used as a communication channel. Return the table of
1540 contents as a string, or nil if it is empty."
1541 (let ((toc-entries
1542 (mapcar (lambda (headline)
1543 (cons (org-html--format-toc-headline headline info)
1544 (org-export-get-relative-level headline info)))
1545 (org-export-collect-headlines info depth))))
1546 (when toc-entries
1547 (concat "<div id=\"table-of-contents\">\n"
1548 (format "<h%d>%s</h%d>\n"
1549 org-html-toplevel-hlevel
1550 (org-html--translate "Table of Contents" info)
1551 org-html-toplevel-hlevel)
1552 "<div id=\"text-table-of-contents\">"
1553 (org-html--toc-text toc-entries)
1554 "</div>\n"
1555 "</div>\n"))))
1557 (defun org-html--toc-text (toc-entries)
1558 "Return innards of a table of contents, as a string.
1559 TOC-ENTRIES is an alist where key is an entry title, as a string,
1560 and value is its relative level, as an integer."
1561 (let* ((prev-level (1- (cdar toc-entries)))
1562 (start-level prev-level))
1563 (concat
1564 (mapconcat
1565 (lambda (entry)
1566 (let ((headline (car entry))
1567 (level (cdr entry)))
1568 (concat
1569 (let* ((cnt (- level prev-level))
1570 (times (if (> cnt 0) (1- cnt) (- cnt)))
1571 rtn)
1572 (setq prev-level level)
1573 (concat
1574 (org-html--make-string
1575 times (cond ((> cnt 0) "\n<ul>\n<li>")
1576 ((< cnt 0) "</li>\n</ul>\n")))
1577 (if (> cnt 0) "\n<ul>\n<li>" "</li>\n<li>")))
1578 headline)))
1579 toc-entries "")
1580 (org-html--make-string (- prev-level start-level) "</li>\n</ul>\n"))))
1582 (defun org-html--format-toc-headline (headline info)
1583 "Return an appropriate table of contents entry for HEADLINE.
1584 INFO is a plist used as a communication channel."
1585 (let* ((headline-number (org-export-get-headline-number headline info))
1586 (section-number
1587 (and (not (org-export-low-level-p headline info))
1588 (org-export-numbered-headline-p headline info)
1589 (concat (mapconcat 'number-to-string headline-number ".") ". ")))
1590 (tags (and (eq (plist-get info :with-tags) t)
1591 (org-export-get-tags headline info))))
1592 (format "<a href=\"#%s\">%s</a>"
1593 ;; Label.
1594 (org-export-solidify-link-text
1595 (or (org-element-property :CUSTOM_ID headline)
1596 (concat "sec-" (mapconcat 'number-to-string
1597 headline-number "-"))))
1598 ;; Body.
1599 (concat section-number
1600 (org-export-data
1601 (org-export-get-optional-title headline info) info)
1602 (and tags "&nbsp;&nbsp;&nbsp;") (org-html--tags tags)))))
1604 (defun org-html-list-of-listings (info)
1605 "Build a list of listings.
1606 INFO is a plist used as a communication channel. Return the list
1607 of listings as a string, or nil if it is empty."
1608 (let ((lol-entries (org-export-collect-listings info)))
1609 (when lol-entries
1610 (concat "<div id=\"list-of-listings\">\n"
1611 (format "<h%d>%s</h%d>\n"
1612 org-html-toplevel-hlevel
1613 (org-html--translate "List of Listings" info)
1614 org-html-toplevel-hlevel)
1615 "<div id=\"text-list-of-listings\">\n<ul>\n"
1616 (let ((count 0)
1617 (initial-fmt (org-html--translate "Listing %d:" info)))
1618 (mapconcat
1619 (lambda (entry)
1620 (let ((label (org-element-property :name entry))
1621 (title (org-trim
1622 (org-export-data
1623 (or (org-export-get-caption entry t)
1624 (org-export-get-caption entry))
1625 info))))
1626 (concat
1627 "<li>"
1628 (if (not label)
1629 (concat (format initial-fmt (incf count)) " " title)
1630 (format "<a href=\"#%s\">%s %s</a>"
1631 (org-export-solidify-link-text label)
1632 (format initial-fmt (incf count))
1633 title))
1634 "</li>")))
1635 lol-entries "\n"))
1636 "\n</ul>\n</div>\n</div>"))))
1638 (defun org-html-list-of-tables (info)
1639 "Build a list of tables.
1640 INFO is a plist used as a communication channel. Return the list
1641 of tables as a string, or nil if it is empty."
1642 (let ((lol-entries (org-export-collect-tables info)))
1643 (when lol-entries
1644 (concat "<div id=\"list-of-tables\">\n"
1645 (format "<h%d>%s</h%d>\n"
1646 org-html-toplevel-hlevel
1647 (org-html--translate "List of Tables" info)
1648 org-html-toplevel-hlevel)
1649 "<div id=\"text-list-of-tables\">\n<ul>\n"
1650 (let ((count 0)
1651 (initial-fmt (org-html--translate "Table %d:" info)))
1652 (mapconcat
1653 (lambda (entry)
1654 (let ((label (org-element-property :name entry))
1655 (title (org-trim
1656 (org-export-data
1657 (or (org-export-get-caption entry t)
1658 (org-export-get-caption entry))
1659 info))))
1660 (concat
1661 "<li>"
1662 (if (not label)
1663 (concat (format initial-fmt (incf count)) " " title)
1664 (format "<a href=\"#%s\">%s %s</a>"
1665 (org-export-solidify-link-text label)
1666 (format initial-fmt (incf count))
1667 title))
1668 "</li>")))
1669 lol-entries "\n"))
1670 "\n</ul>\n</div>\n</div>"))))
1674 ;;; Transcode Functions
1676 ;;;; Bold
1678 (defun org-html-bold (bold contents info)
1679 "Transcode BOLD from Org to HTML.
1680 CONTENTS is the text with bold markup. INFO is a plist holding
1681 contextual information."
1682 (format (or (cdr (assq 'bold org-html-text-markup-alist)) "%s")
1683 contents))
1686 ;;;; Center Block
1688 (defun org-html-center-block (center-block contents info)
1689 "Transcode a CENTER-BLOCK element from Org to HTML.
1690 CONTENTS holds the contents of the block. INFO is a plist
1691 holding contextual information."
1692 (format "<div style=\"text-align: center\">\n%s</div>" contents))
1695 ;;;; Clock
1697 (defun org-html-clock (clock contents info)
1698 "Transcode a CLOCK element from Org to HTML.
1699 CONTENTS is nil. INFO is a plist used as a communication
1700 channel."
1701 (format "<p>
1702 <span class=\"timestamp-wrapper\">
1703 <span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>%s
1704 </span>
1705 </p>"
1706 org-clock-string
1707 (org-translate-time
1708 (org-element-property :raw-value
1709 (org-element-property :value clock)))
1710 (let ((time (org-element-property :duration clock)))
1711 (and time (format " <span class=\"timestamp\">(%s)</span>" time)))))
1714 ;;;; Code
1716 (defun org-html-code (code contents info)
1717 "Transcode CODE from Org to HTML.
1718 CONTENTS is nil. INFO is a plist holding contextual
1719 information."
1720 (format (or (cdr (assq 'code org-html-text-markup-alist)) "%s")
1721 (org-element-property :value code)))
1724 ;;;; Drawer
1726 (defun org-html-drawer (drawer contents info)
1727 "Transcode a DRAWER element from Org to HTML.
1728 CONTENTS holds the contents of the block. INFO is a plist
1729 holding contextual information."
1730 (if (functionp org-html-format-drawer-function)
1731 (funcall org-html-format-drawer-function
1732 (org-element-property :drawer-name drawer)
1733 contents)
1734 ;; If there's no user defined function: simply
1735 ;; display contents of the drawer.
1736 contents))
1739 ;;;; Dynamic Block
1741 (defun org-html-dynamic-block (dynamic-block contents info)
1742 "Transcode a DYNAMIC-BLOCK element from Org to HTML.
1743 CONTENTS holds the contents of the block. INFO is a plist
1744 holding contextual information. See `org-export-data'."
1745 contents)
1748 ;;;; Entity
1750 (defun org-html-entity (entity contents info)
1751 "Transcode an ENTITY object from Org to HTML.
1752 CONTENTS are the definition itself. INFO is a plist holding
1753 contextual information."
1754 (org-element-property :html entity))
1757 ;;;; Example Block
1759 (defun org-html-example-block (example-block contents info)
1760 "Transcode a EXAMPLE-BLOCK element from Org to HTML.
1761 CONTENTS is nil. INFO is a plist holding contextual
1762 information."
1763 (if (org-export-read-attribute :attr_html example-block :textarea)
1764 (org-html--textarea-block example-block)
1765 (format "<pre class=\"example\">\n%s</pre>"
1766 (org-html-format-code example-block info))))
1769 ;;;; Export Snippet
1771 (defun org-html-export-snippet (export-snippet contents info)
1772 "Transcode a EXPORT-SNIPPET object from Org to HTML.
1773 CONTENTS is nil. INFO is a plist holding contextual
1774 information."
1775 (when (eq (org-export-snippet-backend export-snippet) 'html)
1776 (org-element-property :value export-snippet)))
1779 ;;;; Export Block
1781 (defun org-html-export-block (export-block contents info)
1782 "Transcode a EXPORT-BLOCK element from Org to HTML.
1783 CONTENTS is nil. INFO is a plist holding contextual information."
1784 (when (string= (org-element-property :type export-block) "HTML")
1785 (org-remove-indentation (org-element-property :value export-block))))
1788 ;;;; Fixed Width
1790 (defun org-html-fixed-width (fixed-width contents info)
1791 "Transcode a FIXED-WIDTH element from Org to HTML.
1792 CONTENTS is nil. INFO is a plist holding contextual information."
1793 (format "<pre class=\"example\">\n%s</pre>"
1794 (org-html-do-format-code
1795 (org-remove-indentation
1796 (org-element-property :value fixed-width)))))
1799 ;;;; Footnote Reference
1801 (defun org-html-footnote-reference (footnote-reference contents info)
1802 "Transcode a FOOTNOTE-REFERENCE element from Org to HTML.
1803 CONTENTS is nil. INFO is a plist holding contextual information."
1804 (concat
1805 ;; Insert separator between two footnotes in a row.
1806 (let ((prev (org-export-get-previous-element footnote-reference info)))
1807 (when (eq (org-element-type prev) 'footnote-reference)
1808 org-html-footnote-separator))
1809 (cond
1810 ((not (org-export-footnote-first-reference-p footnote-reference info))
1811 (org-html-format-footnote-reference
1812 (org-export-get-footnote-number footnote-reference info)
1813 "IGNORED" 100))
1814 ;; Inline definitions are secondary strings.
1815 ((eq (org-element-property :type footnote-reference) 'inline)
1816 (org-html-format-footnote-reference
1817 (org-export-get-footnote-number footnote-reference info)
1818 "IGNORED" 1))
1819 ;; Non-inline footnotes definitions are full Org data.
1820 (t (org-html-format-footnote-reference
1821 (org-export-get-footnote-number footnote-reference info)
1822 "IGNORED" 1)))))
1825 ;;;; Headline
1827 (defun org-html-format-headline--wrap
1828 (headline info &optional format-function &rest extra-keys)
1829 "Transcode a HEADLINE element from Org to HTML.
1830 CONTENTS holds the contents of the headline. INFO is a plist
1831 holding contextual information."
1832 (let* ((level (+ (org-export-get-relative-level headline info)
1833 (1- org-html-toplevel-hlevel)))
1834 (headline-number (org-export-get-headline-number headline info))
1835 (section-number (and (not (org-export-low-level-p headline info))
1836 (org-export-numbered-headline-p headline info)
1837 (mapconcat 'number-to-string
1838 headline-number ".")))
1839 (todo (and (plist-get info :with-todo-keywords)
1840 (let ((todo (org-element-property :todo-keyword headline)))
1841 (and todo (org-export-data todo info)))))
1842 (todo-type (and todo (org-element-property :todo-type headline)))
1843 (priority (and (plist-get info :with-priority)
1844 (org-element-property :priority headline)))
1845 (text (org-export-data (org-element-property :title headline) info))
1846 (tags (and (plist-get info :with-tags)
1847 (org-export-get-tags headline info)))
1848 (headline-label (or (org-element-property :CUSTOM_ID headline)
1849 (concat "sec-" (mapconcat 'number-to-string
1850 headline-number "-"))))
1851 (format-function (cond
1852 ((functionp format-function) format-function)
1853 ((functionp org-html-format-headline-function)
1854 (function*
1855 (lambda (todo todo-type priority text tags
1856 &allow-other-keys)
1857 (funcall org-html-format-headline-function
1858 todo todo-type priority text tags))))
1859 (t 'org-html-format-headline))))
1860 (apply format-function
1861 todo todo-type priority text tags
1862 :headline-label headline-label :level level
1863 :section-number section-number extra-keys)))
1865 (defun org-html-headline (headline contents info)
1866 "Transcode a HEADLINE element from Org to HTML.
1867 CONTENTS holds the contents of the headline. INFO is a plist
1868 holding contextual information."
1869 ;; Empty contents?
1870 (setq contents (or contents ""))
1871 (let* ((numberedp (org-export-numbered-headline-p headline info))
1872 (level (org-export-get-relative-level headline info))
1873 (text (org-export-data (org-element-property :title headline) info))
1874 (todo (and (plist-get info :with-todo-keywords)
1875 (let ((todo (org-element-property :todo-keyword headline)))
1876 (and todo (org-export-data todo info)))))
1877 (todo-type (and todo (org-element-property :todo-type headline)))
1878 (tags (and (plist-get info :with-tags)
1879 (org-export-get-tags headline info)))
1880 (priority (and (plist-get info :with-priority)
1881 (org-element-property :priority headline)))
1882 (section-number (and (org-export-numbered-headline-p headline info)
1883 (mapconcat 'number-to-string
1884 (org-export-get-headline-number
1885 headline info) ".")))
1886 ;; Create the headline text.
1887 (full-text (org-html-format-headline--wrap headline info)))
1888 (cond
1889 ;; Case 1: This is a footnote section: ignore it.
1890 ((org-element-property :footnote-section-p headline) nil)
1891 ;; Case 2. This is a deep sub-tree: export it as a list item.
1892 ;; Also export as items headlines for which no section
1893 ;; format has been found.
1894 ((org-export-low-level-p headline info)
1895 ;; Build the real contents of the sub-tree.
1896 (let* ((type (if numberedp 'ordered 'unordered))
1897 (itemized-body (org-html-format-list-item
1898 contents type nil nil full-text)))
1899 (concat
1900 (and (org-export-first-sibling-p headline info)
1901 (org-html-begin-plain-list type))
1902 itemized-body
1903 (and (org-export-last-sibling-p headline info)
1904 (org-html-end-plain-list type)))))
1905 ;; Case 3. Standard headline. Export it as a section.
1907 (let* ((section-number (mapconcat 'number-to-string
1908 (org-export-get-headline-number
1909 headline info) "-"))
1910 (ids (remove 'nil
1911 (list (org-element-property :CUSTOM_ID headline)
1912 (concat "sec-" section-number)
1913 (org-element-property :ID headline))))
1914 (preferred-id (car ids))
1915 (extra-ids (cdr ids))
1916 (extra-class (org-element-property :HTML_CONTAINER_CLASS headline))
1917 (level1 (+ level (1- org-html-toplevel-hlevel))))
1918 (format "<div id=\"%s\" class=\"%s\">%s%s</div>\n"
1919 (format "outline-container-%s"
1920 (or (org-element-property :CUSTOM_ID headline)
1921 section-number))
1922 (concat (format "outline-%d" level1) (and extra-class " ")
1923 extra-class)
1924 (format "\n<h%d id=\"%s\">%s%s</h%d>\n"
1925 level1
1926 preferred-id
1927 (mapconcat
1928 (lambda (x)
1929 (let ((id (org-export-solidify-link-text
1930 (if (org-uuidgen-p x) (concat "ID-" x)
1931 x))))
1932 (org-html--anchor id)))
1933 extra-ids "")
1934 full-text
1935 level1)
1936 contents))))))
1939 ;;;; Horizontal Rule
1941 (defun org-html-horizontal-rule (horizontal-rule contents info)
1942 "Transcode an HORIZONTAL-RULE object from Org to HTML.
1943 CONTENTS is nil. INFO is a plist holding contextual information."
1944 "<hr/>")
1947 ;;;; Inline Src Block
1949 (defun org-html-inline-src-block (inline-src-block contents info)
1950 "Transcode an INLINE-SRC-BLOCK element from Org to HTML.
1951 CONTENTS holds the contents of the item. INFO is a plist holding
1952 contextual information."
1953 (let* ((org-lang (org-element-property :language inline-src-block))
1954 (code (org-element-property :value inline-src-block)))
1955 (error "Cannot export inline src block")))
1958 ;;;; Inlinetask
1960 (defun org-html-format-section (text class &optional id)
1961 (let ((extra (concat (when id (format " id=\"%s\"" id)))))
1962 (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
1964 (defun org-html-inlinetask (inlinetask contents info)
1965 "Transcode an INLINETASK element from Org to HTML.
1966 CONTENTS holds the contents of the block. INFO is a plist
1967 holding contextual information."
1968 (cond
1969 ;; If `org-html-format-inlinetask-function' is provided, call it
1970 ;; with appropriate arguments.
1971 ((functionp org-html-format-inlinetask-function)
1972 (let ((format-function
1973 (function*
1974 (lambda (todo todo-type priority text tags
1975 &key contents &allow-other-keys)
1976 (funcall org-html-format-inlinetask-function
1977 todo todo-type priority text tags contents)))))
1978 (org-html-format-headline--wrap
1979 inlinetask info format-function :contents contents)))
1980 ;; Otherwise, use a default template.
1981 (t (format "<div class=\"inlinetask\">\n<b>%s</b><br/>\n%s</div>"
1982 (org-html-format-headline--wrap inlinetask info)
1983 contents))))
1986 ;;;; Italic
1988 (defun org-html-italic (italic contents info)
1989 "Transcode ITALIC from Org to HTML.
1990 CONTENTS is the text with italic markup. INFO is a plist holding
1991 contextual information."
1992 (format (or (cdr (assq 'italic org-html-text-markup-alist)) "%s") contents))
1995 ;;;; Item
1997 (defun org-html-checkbox (checkbox)
1998 (case checkbox (on "<code>[X]</code>")
1999 (off "<code>[&nbsp;]</code>")
2000 (trans "<code>[-]</code>")
2001 (t "")))
2003 (defun org-html-format-list-item (contents type checkbox
2004 &optional term-counter-id
2005 headline)
2006 (let ((checkbox (concat (org-html-checkbox checkbox) (and checkbox " "))))
2007 (concat
2008 (case type
2009 (ordered
2010 (let* ((counter term-counter-id)
2011 (extra (if counter (format " value=\"%s\"" counter) "")))
2012 (concat
2013 (format "<li%s>" extra)
2014 (when headline (concat headline "<br/>")))))
2015 (unordered
2016 (let* ((id term-counter-id)
2017 (extra (if id (format " id=\"%s\"" id) "")))
2018 (concat
2019 (format "<li%s>" extra)
2020 (when headline (concat headline "<br/>")))))
2021 (descriptive
2022 (let* ((term term-counter-id))
2023 (setq term (or term "(no term)"))
2024 ;; Check-boxes in descriptive lists are associated to tag.
2025 (concat (format "<dt> %s </dt>"
2026 (concat checkbox term))
2027 "<dd>"))))
2028 (unless (eq type 'descriptive) checkbox)
2029 contents
2030 (case type
2031 (ordered "</li>")
2032 (unordered "</li>")
2033 (descriptive "</dd>")))))
2035 (defun org-html-item (item contents info)
2036 "Transcode an ITEM element from Org to HTML.
2037 CONTENTS holds the contents of the item. INFO is a plist holding
2038 contextual information."
2039 (let* ((plain-list (org-export-get-parent item))
2040 (type (org-element-property :type plain-list))
2041 (counter (org-element-property :counter item))
2042 (checkbox (org-element-property :checkbox item))
2043 (tag (let ((tag (org-element-property :tag item)))
2044 (and tag (org-export-data tag info)))))
2045 (org-html-format-list-item
2046 contents type checkbox (or tag counter))))
2049 ;;;; Keyword
2051 (defun org-html-keyword (keyword contents info)
2052 "Transcode a KEYWORD element from Org to HTML.
2053 CONTENTS is nil. INFO is a plist holding contextual information."
2054 (let ((key (org-element-property :key keyword))
2055 (value (org-element-property :value keyword)))
2056 (cond
2057 ((string= key "HTML") value)
2058 ;; Invisible targets.
2059 ((string= key "TARGET") nil)
2060 ((string= key "TOC")
2061 (let ((value (downcase value)))
2062 (cond
2063 ((string-match "\\<headlines\\>" value)
2064 (let ((depth (or (and (string-match "[0-9]+" value)
2065 (string-to-number (match-string 0 value)))
2066 (plist-get info :with-toc))))
2067 (org-html-toc depth info)))
2068 ((string= "listings" value) (org-html-list-of-listings info))
2069 ((string= "tables" value) (org-html-list-of-tables info))))))))
2072 ;;;; Latex Environment
2074 (defun org-html-format-latex (latex-frag processing-type)
2075 "Format LaTeX fragments into HTML."
2076 (let ((cache-relpath "") (cache-dir "") bfn)
2077 (unless (eq processing-type 'mathjax)
2078 (setq bfn (buffer-file-name)
2079 cache-relpath
2080 (concat "ltxpng/"
2081 (file-name-sans-extension
2082 (file-name-nondirectory bfn)))
2083 cache-dir (file-name-directory bfn)))
2084 (with-temp-buffer
2085 (insert latex-frag)
2086 (org-format-latex cache-relpath cache-dir nil "Creating LaTeX Image..."
2087 nil nil processing-type)
2088 (buffer-string))))
2090 (defun org-html-latex-environment (latex-environment contents info)
2091 "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
2092 CONTENTS is nil. INFO is a plist holding contextual information."
2093 (let ((processing-type (plist-get info :with-latex))
2094 (latex-frag (org-remove-indentation
2095 (org-element-property :value latex-environment)))
2096 (caption (org-export-data
2097 (org-export-get-caption latex-environment) info))
2098 (attr nil) ; FIXME
2099 (label (org-element-property :name latex-environment)))
2100 (cond
2101 ((memq processing-type '(t mathjax))
2102 (org-html-format-latex latex-frag 'mathjax))
2103 ((eq processing-type 'dvipng)
2104 (let* ((formula-link (org-html-format-latex
2105 latex-frag processing-type)))
2106 (when (and formula-link
2107 (string-match "file:\\([^]]*\\)" formula-link))
2108 (org-html-format-inline-image
2109 (match-string 1 formula-link) caption label attr t))))
2110 (t latex-frag))))
2113 ;;;; Latex Fragment
2115 (defun org-html-latex-fragment (latex-fragment contents info)
2116 "Transcode a LATEX-FRAGMENT object from Org to HTML.
2117 CONTENTS is nil. INFO is a plist holding contextual information."
2118 (let ((latex-frag (org-element-property :value latex-fragment))
2119 (processing-type (plist-get info :with-latex)))
2120 (case processing-type
2121 ((t mathjax)
2122 (org-html-format-latex latex-frag 'mathjax))
2123 (dvipng
2124 (let* ((formula-link (org-html-format-latex
2125 latex-frag processing-type)))
2126 (when (and formula-link
2127 (string-match "file:\\([^]]*\\)" formula-link))
2128 (org-html-format-inline-image
2129 (match-string 1 formula-link)))))
2130 (t latex-frag))))
2133 ;;;; Line Break
2135 (defun org-html-line-break (line-break contents info)
2136 "Transcode a LINE-BREAK object from Org to HTML.
2137 CONTENTS is nil. INFO is a plist holding contextual information."
2138 "<br/>\n")
2141 ;;;; Link
2143 (defun org-html-link--inline-image (link desc info)
2144 "Return HTML code for an inline image.
2145 LINK is the link pointing to the inline image. INFO is a plist
2146 used as a communication channel."
2147 (let* ((type (org-element-property :type link))
2148 (raw-path (org-element-property :path link))
2149 (path (cond ((member type '("http" "https"))
2150 (concat type ":" raw-path))
2151 ((file-name-absolute-p raw-path)
2152 (expand-file-name raw-path))
2153 (t raw-path)))
2154 (parent (org-export-get-parent-element link))
2155 (caption (org-export-data (org-export-get-caption parent) info))
2156 (label (org-element-property :name parent))
2157 ;; Retrieve latex attributes from the element around.
2158 (attr (let ((raw-attr
2159 (mapconcat #'identity
2160 (org-element-property :attr_html parent)
2161 " ")))
2162 (unless (string= raw-attr "") raw-attr))))
2163 ;; Now clear ATTR from any special keyword and set a default
2164 ;; value if nothing is left.
2165 (setq attr (if (not attr) "" (org-trim attr)))
2166 ;; Return proper string, depending on DISPOSITION.
2167 (org-html-format-inline-image
2168 path caption label attr (org-html-standalone-image-p link info))))
2170 (defvar org-html-standalone-image-predicate)
2171 (defun org-html-standalone-image-p (element info &optional predicate)
2172 "Test if ELEMENT is a standalone image for the purpose HTML export.
2173 INFO is a plist holding contextual information.
2175 Return non-nil, if ELEMENT is of type paragraph and it's sole
2176 content, save for whitespaces, is a link that qualifies as an
2177 inline image.
2179 Return non-nil, if ELEMENT is of type link and it's containing
2180 paragraph has no other content save for leading and trailing
2181 whitespaces.
2183 Return nil, otherwise.
2185 Bind `org-html-standalone-image-predicate' to constrain
2186 paragraph further. For example, to check for only captioned
2187 standalone images, do the following.
2189 \(setq org-html-standalone-image-predicate
2190 \(lambda \(paragraph\)
2191 \(org-element-property :caption paragraph\)\)\)"
2192 (let ((paragraph (case (org-element-type element)
2193 (paragraph element)
2194 (link (and (org-export-inline-image-p
2195 element org-html-inline-image-rules)
2196 (org-export-get-parent element)))
2197 (t nil))))
2198 (when (eq (org-element-type paragraph) 'paragraph)
2199 (when (or (not (and (boundp 'org-html-standalone-image-predicate)
2200 (functionp org-html-standalone-image-predicate)))
2201 (funcall org-html-standalone-image-predicate paragraph))
2202 (let ((contents (org-element-contents paragraph)))
2203 (loop for x in contents
2204 with inline-image-count = 0
2205 always (cond
2206 ((eq (org-element-type x) 'plain-text)
2207 (not (org-string-nw-p x)))
2208 ((eq (org-element-type x) 'link)
2209 (when (org-export-inline-image-p
2210 x org-html-inline-image-rules)
2211 (= (incf inline-image-count) 1)))
2212 (t nil))))))))
2214 (defun org-html-link (link desc info)
2215 "Transcode a LINK object from Org to HTML.
2217 DESC is the description part of the link, or the empty string.
2218 INFO is a plist holding contextual information. See
2219 `org-export-data'."
2220 (let* ((--link-org-files-as-html-maybe
2221 (function
2222 (lambda (raw-path info)
2223 "Treat links to `file.org' as links to `file.html', if needed.
2224 See `org-html-link-org-files-as-html'."
2225 (cond
2226 ((and org-html-link-org-files-as-html
2227 (string= ".org"
2228 (downcase (file-name-extension raw-path "."))))
2229 (concat (file-name-sans-extension raw-path) "."
2230 (plist-get info :html-extension)))
2231 (t raw-path)))))
2232 (type (org-element-property :type link))
2233 (raw-path (org-element-property :path link))
2234 ;; Ensure DESC really exists, or set it to nil.
2235 (desc (and (not (string= desc "")) desc))
2236 (path
2237 (cond
2238 ((member type '("http" "https" "ftp" "mailto"))
2239 (concat type ":" raw-path))
2240 ((string= type "file")
2241 ;; Treat links to ".org" files as ".html", if needed.
2242 (setq raw-path
2243 (funcall --link-org-files-as-html-maybe raw-path info))
2244 ;; If file path is absolute, prepend it with protocol
2245 ;; component - "file://".
2246 (when (file-name-absolute-p raw-path)
2247 (setq raw-path
2248 (concat "file://" (expand-file-name raw-path))))
2249 ;; Add search option, if any. A search option can be
2250 ;; relative to a custom-id or a headline title. Any other
2251 ;; option is ignored.
2252 (let ((option (org-element-property :search-option link)))
2253 (cond ((not option) raw-path)
2254 ((eq (aref option 0) ?#) (concat raw-path option))
2255 ;; External fuzzy link: try to resolve it if path
2256 ;; belongs to current project, if any.
2257 ((eq (aref option 0) ?*)
2258 (concat
2259 raw-path
2260 (let ((numbers
2261 (org-publish-resolve-external-fuzzy-link
2262 (org-element-property :path link) option)))
2263 (and numbers (concat "#sec-"
2264 (mapconcat 'number-to-string
2265 numbers "-")))))))))
2266 (t raw-path)))
2267 attributes protocol)
2268 ;; Extract attributes from parent's paragraph.
2269 (and (setq attributes
2270 (mapconcat
2271 'identity
2272 (let ((att (org-element-property
2273 :attr_html (org-export-get-parent-element link))))
2274 (unless (and desc att (string-match (regexp-quote (car att)) desc)) att))
2275 " "))
2276 (setq attributes (concat " " attributes)))
2278 (cond
2279 ;; Image file.
2280 ((and (or (eq t org-html-inline-images)
2281 (and org-html-inline-images (not desc)))
2282 (org-export-inline-image-p link org-html-inline-image-rules))
2283 (org-html-link--inline-image link desc info))
2284 ;; Radio target: Transcode target's contents and use them as
2285 ;; link's description.
2286 ((string= type "radio")
2287 (let ((destination (org-export-resolve-radio-link link info)))
2288 (when destination
2289 (format "<a href=\"#%s\"%s>%s</a>"
2290 (org-export-solidify-link-text path)
2291 attributes
2292 (org-export-data (org-element-contents destination) info)))))
2293 ;; Links pointing to a headline: Find destination and build
2294 ;; appropriate referencing command.
2295 ((member type '("custom-id" "fuzzy" "id"))
2296 (let ((destination (if (string= type "fuzzy")
2297 (org-export-resolve-fuzzy-link link info)
2298 (org-export-resolve-id-link link info))))
2299 (case (org-element-type destination)
2300 ;; ID link points to an external file.
2301 (plain-text
2302 (let ((fragment (concat "ID-" path))
2303 ;; Treat links to ".org" files as ".html", if needed.
2304 (path (funcall --link-org-files-as-html-maybe
2305 destination info)))
2306 (format "<a href=\"%s#%s\"%s>%s</a>"
2307 path fragment attributes (or desc destination))))
2308 ;; Fuzzy link points nowhere.
2309 ((nil)
2310 (format "<i>%s</i>"
2311 (or desc
2312 (org-export-data
2313 (org-element-property :raw-link link) info))))
2314 ;; Fuzzy link points to an invisible target.
2315 (keyword nil)
2316 ;; Link points to a headline.
2317 (headline
2318 (let ((href
2319 ;; What href to use?
2320 (cond
2321 ;; Case 1: Headline is linked via it's CUSTOM_ID
2322 ;; property. Use CUSTOM_ID.
2323 ((string= type "custom-id")
2324 (org-element-property :CUSTOM_ID destination))
2325 ;; Case 2: Headline is linked via it's ID property
2326 ;; or through other means. Use the default href.
2327 ((member type '("id" "fuzzy"))
2328 (format "sec-%s"
2329 (mapconcat 'number-to-string
2330 (org-export-get-headline-number
2331 destination info) "-")))
2332 (t (error "Shouldn't reach here"))))
2333 ;; What description to use?
2334 (desc
2335 ;; Case 1: Headline is numbered and LINK has no
2336 ;; description or LINK's description matches
2337 ;; headline's title. Display section number.
2338 (if (and (org-export-numbered-headline-p destination info)
2339 (or (not desc)
2340 (string= desc (org-element-property
2341 :raw-value destination))))
2342 (mapconcat 'number-to-string
2343 (org-export-get-headline-number
2344 destination info) ".")
2345 ;; Case 2: Either the headline is un-numbered or
2346 ;; LINK has a custom description. Display LINK's
2347 ;; description or headline's title.
2348 (or desc (org-export-data (org-element-property
2349 :title destination) info)))))
2350 (format "<a href=\"#%s\"%s>%s</a>"
2351 (org-export-solidify-link-text href) attributes desc)))
2352 ;; Fuzzy link points to a target. Do as above.
2354 (let ((path (org-export-solidify-link-text path)) number)
2355 (unless desc
2356 (setq number (cond
2357 ((org-html-standalone-image-p destination info)
2358 (org-export-get-ordinal
2359 (assoc 'link (org-element-contents destination))
2360 info 'link 'org-html-standalone-image-p))
2361 (t (org-export-get-ordinal destination info))))
2362 (setq desc (when number
2363 (if (atom number) (number-to-string number)
2364 (mapconcat 'number-to-string number ".")))))
2365 (format "<a href=\"#%s\"%s>%s</a>"
2366 path attributes (or desc "No description for this link")))))))
2367 ;; Coderef: replace link with the reference name or the
2368 ;; equivalent line number.
2369 ((string= type "coderef")
2370 (let ((fragment (concat "coderef-" path)))
2371 (format "<a href=\"#%s\" %s%s>%s</a>"
2372 fragment
2373 (format (concat "class=\"coderef\""
2374 " onmouseover=\"CodeHighlightOn(this, '%s');\""
2375 " onmouseout=\"CodeHighlightOff(this, '%s');\"")
2376 fragment fragment)
2377 attributes
2378 (format (org-export-get-coderef-format path desc)
2379 (org-export-resolve-coderef path info)))))
2380 ;; Link type is handled by a special function.
2381 ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
2382 (funcall protocol (org-link-unescape path) desc 'html))
2383 ;; External link with a description part.
2384 ((and path desc) (format "<a href=\"%s\"%s>%s</a>" path attributes desc))
2385 ;; External link without a description part.
2386 (path (format "<a href=\"%s\"%s>%s</a>" path attributes path))
2387 ;; No path, only description. Try to do something useful.
2388 (t (format "<i>%s</i>" desc)))))
2391 ;;;; Paragraph
2393 (defun org-html-paragraph (paragraph contents info)
2394 "Transcode a PARAGRAPH element from Org to HTML.
2395 CONTENTS is the contents of the paragraph, as a string. INFO is
2396 the plist used as a communication channel."
2397 (let* ((style nil) ; FIXME
2398 (class (cdr (assoc style '((footnote . "footnote")
2399 (verse . nil)))))
2400 (extra (if class (format " class=\"%s\"" class) ""))
2401 (parent (org-export-get-parent paragraph)))
2402 (cond
2403 ((and (eq (org-element-type parent) 'item)
2404 (= (org-element-property :begin paragraph)
2405 (org-element-property :contents-begin parent)))
2406 ;; leading paragraph in a list item have no tags
2407 contents)
2408 ((org-html-standalone-image-p paragraph info)
2409 ;; standalone image
2410 contents)
2411 (t (format "<p%s>\n%s</p>" extra contents)))))
2414 ;;;; Plain List
2416 ;; FIXME Maybe arg1 is not needed because <li value="20"> already sets
2417 ;; the correct value for the item counter
2418 (defun org-html-begin-plain-list (type &optional arg1)
2419 "Insert the beginning of the HTML list depending on TYPE.
2420 When ARG1 is a string, use it as the start parameter for ordered
2421 lists."
2422 (case type
2423 (ordered
2424 (format "<ol class=\"org-ol\"%s>"
2425 (if arg1 (format " start=\"%d\"" arg1) "")))
2426 (unordered "<ul class=\"org-ul\">")
2427 (descriptive "<dl class=\"org-dl\">")))
2429 (defun org-html-end-plain-list (type)
2430 "Insert the end of the HTML list depending on TYPE."
2431 (case type
2432 (ordered "</ol>")
2433 (unordered "</ul>")
2434 (descriptive "</dl>")))
2436 (defun org-html-plain-list (plain-list contents info)
2437 "Transcode a PLAIN-LIST element from Org to HTML.
2438 CONTENTS is the contents of the list. INFO is a plist holding
2439 contextual information."
2440 (let* (arg1 ;; (assoc :counter (org-element-map plain-list 'item
2441 (type (org-element-property :type plain-list)))
2442 (format "%s\n%s%s"
2443 (org-html-begin-plain-list type)
2444 contents (org-html-end-plain-list type))))
2446 ;;;; Plain Text
2448 (defun org-html-convert-special-strings (string)
2449 "Convert special characters in STRING to HTML."
2450 (let ((all org-html-special-string-regexps)
2451 e a re rpl start)
2452 (while (setq a (pop all))
2453 (setq re (car a) rpl (cdr a) start 0)
2454 (while (string-match re string start)
2455 (setq string (replace-match rpl t nil string))))
2456 string))
2458 (defun org-html-encode-plain-text (text)
2459 "Convert plain text characters to HTML equivalent.
2460 Possible conversions are set in `org-export-html-protect-char-alist'."
2461 (mapc
2462 (lambda (pair)
2463 (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t)))
2464 org-html-protect-char-alist)
2465 text)
2467 (defun org-html-plain-text (text info)
2468 "Transcode a TEXT string from Org to HTML.
2469 TEXT is the string to transcode. INFO is a plist holding
2470 contextual information."
2471 (let ((output text))
2472 ;; Protect following characters: <, >, &.
2473 (setq output (org-html-encode-plain-text output))
2474 ;; Handle smart quotes. Be sure to provide original string since
2475 ;; OUTPUT may have been modified.
2476 (when (plist-get info :with-smart-quotes)
2477 (setq output (org-export-activate-smart-quotes output :html info text)))
2478 ;; Handle special strings.
2479 (when (plist-get info :with-special-strings)
2480 (setq output (org-html-convert-special-strings output)))
2481 ;; Handle break preservation if required.
2482 (when (plist-get info :preserve-breaks)
2483 (setq output
2484 (replace-regexp-in-string
2485 "\\(\\\\\\\\\\)?[ \t]*\n" "<br/>\n" output)))
2486 ;; Return value.
2487 output))
2490 ;; Planning
2492 (defun org-html-planning (planning contents info)
2493 "Transcode a PLANNING element from Org to HTML.
2494 CONTENTS is nil. INFO is a plist used as a communication
2495 channel."
2496 (let ((span-fmt "<span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>"))
2497 (format
2498 "<p><span class=\"timestamp-wrapper\">%s</span></p>"
2499 (mapconcat
2500 'identity
2501 (delq nil
2502 (list
2503 (let ((closed (org-element-property :closed planning)))
2504 (when closed
2505 (format span-fmt org-closed-string
2506 (org-translate-time
2507 (org-element-property :raw-value closed)))))
2508 (let ((deadline (org-element-property :deadline planning)))
2509 (when deadline
2510 (format span-fmt org-deadline-string
2511 (org-translate-time
2512 (org-element-property :raw-value deadline)))))
2513 (let ((scheduled (org-element-property :scheduled planning)))
2514 (when scheduled
2515 (format span-fmt org-scheduled-string
2516 (org-translate-time
2517 (org-element-property :raw-value scheduled)))))))
2518 " "))))
2521 ;;;; Property Drawer
2523 (defun org-html-property-drawer (property-drawer contents info)
2524 "Transcode a PROPERTY-DRAWER element from Org to HTML.
2525 CONTENTS is nil. INFO is a plist holding contextual
2526 information."
2527 ;; The property drawer isn't exported but we want separating blank
2528 ;; lines nonetheless.
2532 ;;;; Quote Block
2534 (defun org-html-quote-block (quote-block contents info)
2535 "Transcode a QUOTE-BLOCK element from Org to HTML.
2536 CONTENTS holds the contents of the block. INFO is a plist
2537 holding contextual information."
2538 (format "<blockquote>\n%s</blockquote>" contents))
2541 ;;;; Quote Section
2543 (defun org-html-quote-section (quote-section contents info)
2544 "Transcode a QUOTE-SECTION element from Org to HTML.
2545 CONTENTS is nil. INFO is a plist holding contextual information."
2546 (let ((value (org-remove-indentation
2547 (org-element-property :value quote-section))))
2548 (when value (format "<pre>\n%s</pre>" value))))
2551 ;;;; Section
2553 (defun org-html-section (section contents info)
2554 "Transcode a SECTION element from Org to HTML.
2555 CONTENTS holds the contents of the section. INFO is a plist
2556 holding contextual information."
2557 (let ((parent (org-export-get-parent-headline section)))
2558 ;; Before first headline: no container, just return CONTENTS.
2559 (if (not parent) contents
2560 ;; Get div's class and id references.
2561 (let* ((class-num (+ (org-export-get-relative-level parent info)
2562 (1- org-html-toplevel-hlevel)))
2563 (section-number
2564 (mapconcat
2565 'number-to-string
2566 (org-export-get-headline-number parent info) "-")))
2567 ;; Build return value.
2568 (format "<div class=\"outline-text-%d\" id=\"text-%s\">\n%s</div>"
2569 class-num
2570 (or (org-element-property :CUSTOM_ID parent) section-number)
2571 contents)))))
2573 ;;;; Radio Target
2575 (defun org-html-radio-target (radio-target text info)
2576 "Transcode a RADIO-TARGET object from Org to HTML.
2577 TEXT is the text of the target. INFO is a plist holding
2578 contextual information."
2579 (let ((id (org-export-solidify-link-text
2580 (org-element-property :value radio-target))))
2581 (org-html--anchor id text)))
2584 ;;;; Special Block
2586 (defun org-html-special-block (special-block contents info)
2587 "Transcode a SPECIAL-BLOCK element from Org to HTML.
2588 CONTENTS holds the contents of the block. INFO is a plist
2589 holding contextual information."
2590 (format "<div class=\"%s\">\n%s\n</div>"
2591 (downcase (org-element-property :type special-block))
2592 contents))
2595 ;;;; Src Block
2597 (defun org-html-src-block (src-block contents info)
2598 "Transcode a SRC-BLOCK element from Org to HTML.
2599 CONTENTS holds the contents of the item. INFO is a plist holding
2600 contextual information."
2601 (if (org-export-read-attribute :attr_html src-block :textarea)
2602 (org-html--textarea-block src-block)
2603 (let ((lang (org-element-property :language src-block))
2604 (caption (org-export-get-caption src-block))
2605 (code (org-html-format-code src-block info))
2606 (label (let ((lbl (org-element-property :name src-block)))
2607 (if (not lbl) ""
2608 (format " id=\"%s\""
2609 (org-export-solidify-link-text lbl))))))
2610 (if (not lang) (format "<pre class=\"example\"%s>\n%s</pre>" label code)
2611 (format
2612 "<div class=\"org-src-container\">\n%s%s\n</div>"
2613 (if (not caption) ""
2614 (format "<label class=\"org-src-name\">%s</label>"
2615 (org-export-data caption info)))
2616 (format "\n<pre class=\"src src-%s\"%s>%s</pre>" lang label code))))))
2619 ;;;; Statistics Cookie
2621 (defun org-html-statistics-cookie (statistics-cookie contents info)
2622 "Transcode a STATISTICS-COOKIE object from Org to HTML.
2623 CONTENTS is nil. INFO is a plist holding contextual information."
2624 (let ((cookie-value (org-element-property :value statistics-cookie)))
2625 (format "<code>%s</code>" cookie-value)))
2628 ;;;; Strike-Through
2630 (defun org-html-strike-through (strike-through contents info)
2631 "Transcode STRIKE-THROUGH from Org to HTML.
2632 CONTENTS is the text with strike-through markup. INFO is a plist
2633 holding contextual information."
2634 (format (or (cdr (assq 'strike-through org-html-text-markup-alist)) "%s")
2635 contents))
2638 ;;;; Subscript
2640 (defun org-html-subscript (subscript contents info)
2641 "Transcode a SUBSCRIPT object from Org to HTML.
2642 CONTENTS is the contents of the object. INFO is a plist holding
2643 contextual information."
2644 (format "<sub>%s</sub>" contents))
2647 ;;;; Superscript
2649 (defun org-html-superscript (superscript contents info)
2650 "Transcode a SUPERSCRIPT object from Org to HTML.
2651 CONTENTS is the contents of the object. INFO is a plist holding
2652 contextual information."
2653 (format "<sup>%s</sup>" contents))
2656 ;;;; Tabel Cell
2658 (defun org-html-table-cell (table-cell contents info)
2659 "Transcode a TABLE-CELL element from Org to HTML.
2660 CONTENTS is nil. INFO is a plist used as a communication
2661 channel."
2662 (let* ((table-row (org-export-get-parent table-cell))
2663 (table (org-export-get-parent-table table-cell))
2664 (cell-attrs
2665 (if (not org-html-table-align-individual-fields) ""
2666 (format (if (and (boundp 'org-html-format-table-no-css)
2667 org-html-format-table-no-css)
2668 " align=\"%s\"" " class=\"%s\"")
2669 (org-export-table-cell-alignment table-cell info)))))
2670 (when (or (not contents) (string= "" (org-trim contents)))
2671 (setq contents "&nbsp;"))
2672 (cond
2673 ((and (org-export-table-has-header-p table info)
2674 (= 1 (org-export-table-row-group table-row info)))
2675 (concat "\n" (format (car org-html-table-header-tags) "col" cell-attrs)
2676 contents (cdr org-html-table-header-tags)))
2677 ((and org-html-table-use-header-tags-for-first-column
2678 (zerop (cdr (org-export-table-cell-address table-cell info))))
2679 (concat "\n" (format (car org-html-table-header-tags) "row" cell-attrs)
2680 contents (cdr org-html-table-header-tags)))
2681 (t (concat "\n" (format (car org-html-table-data-tags) cell-attrs)
2682 contents (cdr org-html-table-data-tags))))))
2685 ;;;; Table Row
2687 (defun org-html-table-row (table-row contents info)
2688 "Transcode a TABLE-ROW element from Org to HTML.
2689 CONTENTS is the contents of the row. INFO is a plist used as a
2690 communication channel."
2691 ;; Rules are ignored since table separators are deduced from
2692 ;; borders of the current row.
2693 (when (eq (org-element-property :type table-row) 'standard)
2694 (let* ((first-rowgroup-p (= 1 (org-export-table-row-group table-row info)))
2695 (rowgroup-tags
2696 (cond
2697 ;; Case 1: Row belongs to second or subsequent rowgroups.
2698 ((not (= 1 (org-export-table-row-group table-row info)))
2699 '("<tbody>" . "\n</tbody>"))
2700 ;; Case 2: Row is from first rowgroup. Table has >=1 rowgroups.
2701 ((org-export-table-has-header-p
2702 (org-export-get-parent-table table-row) info)
2703 '("<thead>" . "\n</thead>"))
2704 ;; Case 2: Row is from first and only row group.
2705 (t '("<tbody>" . "\n</tbody>")))))
2706 (concat
2707 ;; Begin a rowgroup?
2708 (when (org-export-table-row-starts-rowgroup-p table-row info)
2709 (car rowgroup-tags))
2710 ;; Actual table row
2711 (concat "\n" (eval (car org-html-table-row-tags))
2712 contents
2713 "\n"
2714 (eval (cdr org-html-table-row-tags)))
2715 ;; End a rowgroup?
2716 (when (org-export-table-row-ends-rowgroup-p table-row info)
2717 (cdr rowgroup-tags))))))
2720 ;;;; Table
2722 (defun org-html-table-first-row-data-cells (table info)
2723 (let ((table-row
2724 (org-element-map table 'table-row
2725 (lambda (row)
2726 (unless (eq (org-element-property :type row) 'rule) row))
2727 info 'first-match))
2728 (special-column-p (org-export-table-has-special-column-p table)))
2729 (if (not special-column-p) (org-element-contents table-row)
2730 (cdr (org-element-contents table-row)))))
2732 (defun org-html-table--table.el-table (table info)
2733 (when (eq (org-element-property :type table) 'table.el)
2734 (require 'table)
2735 (let ((outbuf (with-current-buffer
2736 (get-buffer-create "*org-export-table*")
2737 (erase-buffer) (current-buffer))))
2738 (with-temp-buffer
2739 (insert (org-element-property :value table))
2740 (goto-char 1)
2741 (re-search-forward "^[ \t]*|[^|]" nil t)
2742 (table-generate-source 'html outbuf))
2743 (with-current-buffer outbuf
2744 (prog1 (org-trim (buffer-string))
2745 (kill-buffer) )))))
2747 (defun org-html-table (table contents info)
2748 "Transcode a TABLE element from Org to HTML.
2749 CONTENTS is the contents of the table. INFO is a plist holding
2750 contextual information."
2751 (case (org-element-property :type table)
2752 ;; Case 1: table.el table. Convert it using appropriate tools.
2753 (table.el (org-html-table--table.el-table table info))
2754 ;; Case 2: Standard table.
2756 (let* ((label (org-element-property :name table))
2757 (caption (org-export-get-caption table))
2758 (attributes (mapconcat #'identity
2759 (org-element-property :attr_html table)
2760 " "))
2761 (alignspec
2762 (if (and (boundp 'org-html-format-table-no-css)
2763 org-html-format-table-no-css)
2764 "align=\"%s\"" "class=\"%s\""))
2765 (table-column-specs
2766 (function
2767 (lambda (table info)
2768 (mapconcat
2769 (lambda (table-cell)
2770 (let ((alignment (org-export-table-cell-alignment
2771 table-cell info)))
2772 (concat
2773 ;; Begin a colgroup?
2774 (when (org-export-table-cell-starts-colgroup-p
2775 table-cell info)
2776 "\n<colgroup>")
2777 ;; Add a column. Also specify it's alignment.
2778 (format "\n<col %s/>" (format alignspec alignment))
2779 ;; End a colgroup?
2780 (when (org-export-table-cell-ends-colgroup-p
2781 table-cell info)
2782 "\n</colgroup>"))))
2783 (org-html-table-first-row-data-cells table info) "\n"))))
2784 (table-attributes
2785 (let ((table-tag (plist-get info :html-table-tag)))
2786 (concat
2787 (and (string-match "<table\\(.*\\)>" table-tag)
2788 (match-string 1 table-tag))
2789 (and label (format " id=\"%s\""
2790 (org-export-solidify-link-text label)))
2791 (unless (string= attributes "")
2792 (concat " " attributes))))))
2793 ;; Remove last blank line.
2794 (setq contents (substring contents 0 -1))
2795 (format "<table%s>\n%s\n%s\n%s\n</table>"
2796 table-attributes
2797 (if (not caption) ""
2798 (format "<caption>%s</caption>"
2799 (org-export-data caption info)))
2800 (funcall table-column-specs table info)
2801 contents)))))
2804 ;;;; Target
2806 (defun org-html-target (target contents info)
2807 "Transcode a TARGET object from Org to HTML.
2808 CONTENTS is nil. INFO is a plist holding contextual
2809 information."
2810 (let ((id (org-export-solidify-link-text
2811 (org-element-property :value target))))
2812 (org-html--anchor id)))
2815 ;;;; Timestamp
2817 (defun org-html-timestamp (timestamp contents info)
2818 "Transcode a TIMESTAMP object from Org to HTML.
2819 CONTENTS is nil. INFO is a plist holding contextual
2820 information."
2821 (let ((value (org-html-plain-text
2822 (org-timestamp-translate timestamp) info)))
2823 (format "<span class=\"timestamp-wrapper\"><span class=\"timestamp\">%s</span></span>"
2824 (replace-regexp-in-string "--" "&ndash;" value))))
2827 ;;;; Underline
2829 (defun org-html-underline (underline contents info)
2830 "Transcode UNDERLINE from Org to HTML.
2831 CONTENTS is the text with underline markup. INFO is a plist
2832 holding contextual information."
2833 (format (or (cdr (assq 'underline org-html-text-markup-alist)) "%s")
2834 contents))
2837 ;;;; Verbatim
2839 (defun org-html-verbatim (verbatim contents info)
2840 "Transcode VERBATIM from Org to HTML.
2841 CONTENTS is nil. INFO is a plist holding contextual
2842 information."
2843 (format (or (cdr (assq 'verbatim org-html-text-markup-alist)) "%s")
2844 (org-element-property :value verbatim)))
2847 ;;;; Verse Block
2849 (defun org-html-verse-block (verse-block contents info)
2850 "Transcode a VERSE-BLOCK element from Org to HTML.
2851 CONTENTS is verse block contents. INFO is a plist holding
2852 contextual information."
2853 ;; Replace each newline character with line break. Also replace
2854 ;; each blank line with a line break.
2855 (setq contents (replace-regexp-in-string
2856 "^ *\\\\\\\\$" "<br/>\n"
2857 (replace-regexp-in-string
2858 "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n" contents)))
2859 ;; Replace each white space at beginning of a line with a
2860 ;; non-breaking space.
2861 (while (string-match "^[ \t]+" contents)
2862 (let* ((num-ws (length (match-string 0 contents)))
2863 (ws (let (out) (dotimes (i num-ws out)
2864 (setq out (concat out "&nbsp;"))))))
2865 (setq contents (replace-match ws nil t contents))))
2866 (format "<p class=\"verse\">\n%s</p>" contents))
2870 ;;; Filter Functions
2872 (defun org-html-final-function (contents backend info)
2873 (if (not org-html-pretty-output) contents
2874 (with-temp-buffer
2875 (html-mode)
2876 (insert contents)
2877 (indent-region (point-min) (point-max))
2878 (buffer-substring-no-properties (point-min) (point-max)))))
2882 ;;; End-user functions
2884 ;;;###autoload
2885 (defun org-html-export-as-html
2886 (&optional async subtreep visible-only body-only ext-plist)
2887 "Export current buffer to an HTML buffer.
2889 If narrowing is active in the current buffer, only export its
2890 narrowed part.
2892 If a region is active, export that region.
2894 A non-nil optional argument ASYNC means the process should happen
2895 asynchronously. The resulting buffer should be accessible
2896 through the `org-export-stack' interface.
2898 When optional argument SUBTREEP is non-nil, export the sub-tree
2899 at point, extracting information from the headline properties
2900 first.
2902 When optional argument VISIBLE-ONLY is non-nil, don't export
2903 contents of hidden elements.
2905 When optional argument BODY-ONLY is non-nil, only write code
2906 between \"<body>\" and \"</body>\" tags.
2908 EXT-PLIST, when provided, is a property list with external
2909 parameters overriding Org default settings, but still inferior to
2910 file-local settings.
2912 Export is done in a buffer named \"*Org HTML Export*\", which
2913 will be displayed when `org-export-show-temporary-export-buffer'
2914 is non-nil."
2915 (interactive)
2916 (if async
2917 (org-export-async-start
2918 (lambda (output)
2919 (with-current-buffer (get-buffer-create "*Org HTML Export*")
2920 (erase-buffer)
2921 (insert output)
2922 (goto-char (point-min))
2923 (funcall org-html-display-buffer-mode)
2924 (org-export-add-to-stack (current-buffer) 'html)))
2925 `(org-export-as 'html ,subtreep ,visible-only ,body-only ',ext-plist))
2926 (let ((outbuf (org-export-to-buffer
2927 'html "*Org HTML Export*"
2928 subtreep visible-only body-only ext-plist)))
2929 ;; Set major mode.
2930 (with-current-buffer outbuf (funcall org-html-display-buffer-mode))
2931 (when org-export-show-temporary-export-buffer
2932 (switch-to-buffer-other-window outbuf)))))
2934 ;;;###autoload
2935 (defun org-html-export-to-html
2936 (&optional async subtreep visible-only body-only ext-plist)
2937 "Export current buffer to a HTML file.
2939 If narrowing is active in the current buffer, only export its
2940 narrowed part.
2942 If a region is active, export that region.
2944 A non-nil optional argument ASYNC means the process should happen
2945 asynchronously. The resulting file should be accessible through
2946 the `org-export-stack' interface.
2948 When optional argument SUBTREEP is non-nil, export the sub-tree
2949 at point, extracting information from the headline properties
2950 first.
2952 When optional argument VISIBLE-ONLY is non-nil, don't export
2953 contents of hidden elements.
2955 When optional argument BODY-ONLY is non-nil, only write code
2956 between \"<body>\" and \"</body>\" tags.
2958 EXT-PLIST, when provided, is a property list with external
2959 parameters overriding Org default settings, but still inferior to
2960 file-local settings.
2962 Return output file's name."
2963 (interactive)
2964 (let* ((extension (concat "." org-html-extension))
2965 (file (org-export-output-file-name extension subtreep))
2966 (org-export-coding-system org-html-coding-system))
2967 (if async
2968 (org-export-async-start
2969 (lambda (f) (org-export-add-to-stack f 'html))
2970 (let ((org-export-coding-system org-html-coding-system))
2971 `(expand-file-name
2972 (org-export-to-file
2973 'html ,file ,subtreep ,visible-only ,body-only ',ext-plist))))
2974 (let ((org-export-coding-system org-html-coding-system))
2975 (org-export-to-file
2976 'html file subtreep visible-only body-only ext-plist)))))
2978 ;;;###autoload
2979 (defun org-html-publish-to-html (plist filename pub-dir)
2980 "Publish an org file to HTML.
2982 FILENAME is the filename of the Org file to be published. PLIST
2983 is the property list for the given project. PUB-DIR is the
2984 publishing directory.
2986 Return output file name."
2987 (org-publish-org-to 'html filename ".html" plist pub-dir))
2991 ;;; FIXME
2993 ;;;; org-format-table-html
2994 ;;;; org-format-org-table-html
2995 ;;;; org-format-table-table-html
2996 ;;;; org-table-number-fraction
2997 ;;;; org-table-number-regexp
2998 ;;;; org-html-table-caption-above
2999 ;;;; org-html-with-timestamp
3000 ;;;; org-html-html-helper-timestamp
3001 ;;;; org-html-inline-image-extensions
3002 ;;;; org-export-preferred-target-alist
3003 ;;;; class for anchors
3004 ;;;; org-export-with-section-numbers, body-only
3005 ;;;; org-export-mark-todo-in-toc
3006 ;;;; org-html-format-org-link
3007 ;;;; (caption (and caption (org-xml-encode-org-text caption)))
3008 ;;;; alt = (file-name-nondirectory path)
3010 (provide 'ox-html)
3012 ;; Local variables:
3013 ;; generated-autoload-file: "org-loaddefs.el"
3014 ;; End:
3016 ;;; ox-html.el ends here