ox-html: Fix code typo in 1fd83e048760c38c23d422f649a53d79591ba5c3
[org-mode.git] / lisp / ox-html.el
blob297b1381a59df48563e9133a734ee5de69e078a4
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 (headline info
1828 &optional format-function
1829 &rest extra-keys)
1830 "Transcode a HEADLINE element from Org to HTML.
1831 CONTENTS holds the contents of the headline. INFO is a plist
1832 holding contextual information."
1833 (let* ((level (+ (org-export-get-relative-level headline info)
1834 (1- org-html-toplevel-hlevel)))
1835 (headline-number (org-export-get-headline-number headline info))
1836 (section-number (and (not (org-export-low-level-p headline info))
1837 (org-export-numbered-headline-p headline info)
1838 (mapconcat 'number-to-string
1839 headline-number ".")))
1840 (todo (and (plist-get info :with-todo-keywords)
1841 (let ((todo (org-element-property :todo-keyword headline)))
1842 (and todo (org-export-data todo info)))))
1843 (todo-type (and todo (org-element-property :todo-type headline)))
1844 (priority (and (plist-get info :with-priority)
1845 (org-element-property :priority headline)))
1846 (text (org-export-data (org-element-property :title headline) info))
1847 (tags (and (plist-get info :with-tags)
1848 (org-export-get-tags headline info)))
1849 (headline-label (or (org-element-property :CUSTOM_ID headline)
1850 (concat "sec-" (mapconcat 'number-to-string
1851 headline-number "-"))))
1852 (format-function (cond
1853 ((functionp format-function) format-function)
1854 ((functionp org-html-format-headline-function)
1855 (function*
1856 (lambda (todo todo-type priority text tags
1857 &allow-other-keys)
1858 (funcall org-html-format-headline-function
1859 todo todo-type priority text tags))))
1860 (t 'org-html-format-headline))))
1861 (apply format-function
1862 todo todo-type priority text tags
1863 :headline-label headline-label :level level
1864 :section-number section-number extra-keys)))
1866 (defun org-html-headline (headline contents info)
1867 "Transcode a HEADLINE element from Org to HTML.
1868 CONTENTS holds the contents of the headline. INFO is a plist
1869 holding contextual information."
1870 ;; Empty contents?
1871 (setq contents (or contents ""))
1872 (let* ((numberedp (org-export-numbered-headline-p headline info))
1873 (level (org-export-get-relative-level headline info))
1874 (text (org-export-data (org-element-property :title headline) info))
1875 (todo (and (plist-get info :with-todo-keywords)
1876 (let ((todo (org-element-property :todo-keyword headline)))
1877 (and todo (org-export-data todo info)))))
1878 (todo-type (and todo (org-element-property :todo-type headline)))
1879 (tags (and (plist-get info :with-tags)
1880 (org-export-get-tags headline info)))
1881 (priority (and (plist-get info :with-priority)
1882 (org-element-property :priority headline)))
1883 (section-number (and (org-export-numbered-headline-p headline info)
1884 (mapconcat 'number-to-string
1885 (org-export-get-headline-number
1886 headline info) ".")))
1887 ;; Create the headline text.
1888 (full-text (org-html-format-headline--wrap headline info)))
1889 (cond
1890 ;; Case 1: This is a footnote section: ignore it.
1891 ((org-element-property :footnote-section-p headline) nil)
1892 ;; Case 2. This is a deep sub-tree: export it as a list item.
1893 ;; Also export as items headlines for which no section
1894 ;; format has been found.
1895 ((org-export-low-level-p headline info)
1896 ;; Build the real contents of the sub-tree.
1897 (let* ((type (if numberedp 'ordered 'unordered))
1898 (itemized-body (org-html-format-list-item
1899 contents type nil nil full-text)))
1900 (concat
1901 (and (org-export-first-sibling-p headline info)
1902 (org-html-begin-plain-list type))
1903 itemized-body
1904 (and (org-export-last-sibling-p headline info)
1905 (org-html-end-plain-list type)))))
1906 ;; Case 3. Standard headline. Export it as a section.
1908 (let* ((section-number (mapconcat 'number-to-string
1909 (org-export-get-headline-number
1910 headline info) "-"))
1911 (ids (remove 'nil
1912 (list (org-element-property :CUSTOM_ID headline)
1913 (concat "sec-" section-number)
1914 (org-element-property :ID headline))))
1915 (preferred-id (car ids))
1916 (extra-ids (cdr ids))
1917 (extra-class (org-element-property :html-container-class headline))
1918 (level1 (+ level (1- org-html-toplevel-hlevel))))
1919 (format "<div id=\"%s\" class=\"%s\">%s%s</div>\n"
1920 (format "outline-container-%s"
1921 (or (org-element-property :CUSTOM_ID headline)
1922 section-number))
1923 (concat (format "outline-%d" level1) (and extra-class " ")
1924 extra-class)
1925 (format "\n<h%d id=\"%s\">%s%s</h%d>\n"
1926 level1
1927 preferred-id
1928 (mapconcat
1929 (lambda (x)
1930 (let ((id (org-export-solidify-link-text
1931 (if (org-uuidgen-p x) (concat "ID-" x)
1932 x))))
1933 (org-html--anchor id)))
1934 extra-ids "")
1935 full-text
1936 level1)
1937 contents))))))
1940 ;;;; Horizontal Rule
1942 (defun org-html-horizontal-rule (horizontal-rule contents info)
1943 "Transcode an HORIZONTAL-RULE object from Org to HTML.
1944 CONTENTS is nil. INFO is a plist holding contextual information."
1945 "<hr/>")
1948 ;;;; Inline Src Block
1950 (defun org-html-inline-src-block (inline-src-block contents info)
1951 "Transcode an INLINE-SRC-BLOCK element from Org to HTML.
1952 CONTENTS holds the contents of the item. INFO is a plist holding
1953 contextual information."
1954 (let* ((org-lang (org-element-property :language inline-src-block))
1955 (code (org-element-property :value inline-src-block)))
1956 (error "Cannot export inline src block")))
1959 ;;;; Inlinetask
1961 (defun org-html-format-section (text class &optional id)
1962 (let ((extra (concat (when id (format " id=\"%s\"" id)))))
1963 (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
1965 (defun org-html-inlinetask (inlinetask contents info)
1966 "Transcode an INLINETASK element from Org to HTML.
1967 CONTENTS holds the contents of the block. INFO is a plist
1968 holding contextual information."
1969 (cond
1970 ;; If `org-html-format-inlinetask-function' is provided, call it
1971 ;; with appropriate arguments.
1972 ((functionp org-html-format-inlinetask-function)
1973 (let ((format-function
1974 (function*
1975 (lambda (todo todo-type priority text tags
1976 &key contents &allow-other-keys)
1977 (funcall org-html-format-inlinetask-function
1978 todo todo-type priority text tags contents)))))
1979 (org-html-format-headline--wrap
1980 inlinetask info format-function :contents contents)))
1981 ;; Otherwise, use a default template.
1982 (t (format "<div class=\"inlinetask\">\n<b>%s</b><br/>\n%s</div>"
1983 (org-html-format-headline--wrap inlinetask info)
1984 contents))))
1987 ;;;; Italic
1989 (defun org-html-italic (italic contents info)
1990 "Transcode ITALIC from Org to HTML.
1991 CONTENTS is the text with italic markup. INFO is a plist holding
1992 contextual information."
1993 (format (or (cdr (assq 'italic org-html-text-markup-alist)) "%s") contents))
1996 ;;;; Item
1998 (defun org-html-checkbox (checkbox)
1999 (case checkbox (on "<code>[X]</code>")
2000 (off "<code>[&nbsp;]</code>")
2001 (trans "<code>[-]</code>")
2002 (t "")))
2004 (defun org-html-format-list-item (contents type checkbox
2005 &optional term-counter-id
2006 headline)
2007 (let ((checkbox (concat (org-html-checkbox checkbox) (and checkbox " "))))
2008 (concat
2009 (case type
2010 (ordered
2011 (let* ((counter term-counter-id)
2012 (extra (if counter (format " value=\"%s\"" counter) "")))
2013 (concat
2014 (format "<li%s>" extra)
2015 (when headline (concat headline "<br/>")))))
2016 (unordered
2017 (let* ((id term-counter-id)
2018 (extra (if id (format " id=\"%s\"" id) "")))
2019 (concat
2020 (format "<li%s>" extra)
2021 (when headline (concat headline "<br/>")))))
2022 (descriptive
2023 (let* ((term term-counter-id))
2024 (setq term (or term "(no term)"))
2025 ;; Check-boxes in descriptive lists are associated to tag.
2026 (concat (format "<dt> %s </dt>"
2027 (concat checkbox term))
2028 "<dd>"))))
2029 (unless (eq type 'descriptive) checkbox)
2030 contents
2031 (case type
2032 (ordered "</li>")
2033 (unordered "</li>")
2034 (descriptive "</dd>")))))
2036 (defun org-html-item (item contents info)
2037 "Transcode an ITEM element from Org to HTML.
2038 CONTENTS holds the contents of the item. INFO is a plist holding
2039 contextual information."
2040 (let* ((plain-list (org-export-get-parent item))
2041 (type (org-element-property :type plain-list))
2042 (counter (org-element-property :counter item))
2043 (checkbox (org-element-property :checkbox item))
2044 (tag (let ((tag (org-element-property :tag item)))
2045 (and tag (org-export-data tag info)))))
2046 (org-html-format-list-item
2047 contents type checkbox (or tag counter))))
2050 ;;;; Keyword
2052 (defun org-html-keyword (keyword contents info)
2053 "Transcode a KEYWORD element from Org to HTML.
2054 CONTENTS is nil. INFO is a plist holding contextual information."
2055 (let ((key (org-element-property :key keyword))
2056 (value (org-element-property :value keyword)))
2057 (cond
2058 ((string= key "HTML") value)
2059 ;; Invisible targets.
2060 ((string= key "TARGET") nil)
2061 ((string= key "TOC")
2062 (let ((value (downcase value)))
2063 (cond
2064 ((string-match "\\<headlines\\>" value)
2065 (let ((depth (or (and (string-match "[0-9]+" value)
2066 (string-to-number (match-string 0 value)))
2067 (plist-get info :with-toc))))
2068 (org-html-toc depth info)))
2069 ((string= "listings" value) (org-html-list-of-listings info))
2070 ((string= "tables" value) (org-html-list-of-tables info))))))))
2073 ;;;; Latex Environment
2075 (defun org-html-format-latex (latex-frag processing-type)
2076 "Format LaTeX fragments into HTML."
2077 (let ((cache-relpath "") (cache-dir "") bfn)
2078 (unless (eq processing-type 'mathjax)
2079 (setq bfn (buffer-file-name)
2080 cache-relpath
2081 (concat "ltxpng/"
2082 (file-name-sans-extension
2083 (file-name-nondirectory bfn)))
2084 cache-dir (file-name-directory bfn)))
2085 (with-temp-buffer
2086 (insert latex-frag)
2087 (org-format-latex cache-relpath cache-dir nil "Creating LaTeX Image..."
2088 nil nil processing-type)
2089 (buffer-string))))
2091 (defun org-html-latex-environment (latex-environment contents info)
2092 "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
2093 CONTENTS is nil. INFO is a plist holding contextual information."
2094 (let ((processing-type (plist-get info :with-latex))
2095 (latex-frag (org-remove-indentation
2096 (org-element-property :value latex-environment)))
2097 (caption (org-export-data
2098 (org-export-get-caption latex-environment) info))
2099 (attr nil) ; FIXME
2100 (label (org-element-property :name latex-environment)))
2101 (cond
2102 ((memq processing-type '(t mathjax))
2103 (org-html-format-latex latex-frag 'mathjax))
2104 ((eq processing-type 'dvipng)
2105 (let* ((formula-link (org-html-format-latex
2106 latex-frag processing-type)))
2107 (when (and formula-link
2108 (string-match "file:\\([^]]*\\)" formula-link))
2109 (org-html-format-inline-image
2110 (match-string 1 formula-link) caption label attr t))))
2111 (t latex-frag))))
2114 ;;;; Latex Fragment
2116 (defun org-html-latex-fragment (latex-fragment contents info)
2117 "Transcode a LATEX-FRAGMENT object from Org to HTML.
2118 CONTENTS is nil. INFO is a plist holding contextual information."
2119 (let ((latex-frag (org-element-property :value latex-fragment))
2120 (processing-type (plist-get info :with-latex)))
2121 (case processing-type
2122 ((t mathjax)
2123 (org-html-format-latex latex-frag 'mathjax))
2124 (dvipng
2125 (let* ((formula-link (org-html-format-latex
2126 latex-frag processing-type)))
2127 (when (and formula-link
2128 (string-match "file:\\([^]]*\\)" formula-link))
2129 (org-html-format-inline-image
2130 (match-string 1 formula-link)))))
2131 (t latex-frag))))
2134 ;;;; Line Break
2136 (defun org-html-line-break (line-break contents info)
2137 "Transcode a LINE-BREAK object from Org to HTML.
2138 CONTENTS is nil. INFO is a plist holding contextual information."
2139 "<br/>\n")
2142 ;;;; Link
2144 (defun org-html-link--inline-image (link desc info)
2145 "Return HTML code for an inline image.
2146 LINK is the link pointing to the inline image. INFO is a plist
2147 used as a communication channel."
2148 (let* ((type (org-element-property :type link))
2149 (raw-path (org-element-property :path link))
2150 (path (cond ((member type '("http" "https"))
2151 (concat type ":" raw-path))
2152 ((file-name-absolute-p raw-path)
2153 (expand-file-name raw-path))
2154 (t raw-path)))
2155 (parent (org-export-get-parent-element link))
2156 (caption (org-export-data (org-export-get-caption parent) info))
2157 (label (org-element-property :name parent))
2158 ;; Retrieve latex attributes from the element around.
2159 (attr (let ((raw-attr
2160 (mapconcat #'identity
2161 (org-element-property :attr_html parent)
2162 " ")))
2163 (unless (string= raw-attr "") raw-attr))))
2164 ;; Now clear ATTR from any special keyword and set a default
2165 ;; value if nothing is left.
2166 (setq attr (if (not attr) "" (org-trim attr)))
2167 ;; Return proper string, depending on DISPOSITION.
2168 (org-html-format-inline-image
2169 path caption label attr (org-html-standalone-image-p link info))))
2171 (defvar org-html-standalone-image-predicate)
2172 (defun org-html-standalone-image-p (element info &optional predicate)
2173 "Test if ELEMENT is a standalone image for the purpose HTML export.
2174 INFO is a plist holding contextual information.
2176 Return non-nil, if ELEMENT is of type paragraph and it's sole
2177 content, save for whitespaces, is a link that qualifies as an
2178 inline image.
2180 Return non-nil, if ELEMENT is of type link and it's containing
2181 paragraph has no other content save for leading and trailing
2182 whitespaces.
2184 Return nil, otherwise.
2186 Bind `org-html-standalone-image-predicate' to constrain
2187 paragraph further. For example, to check for only captioned
2188 standalone images, do the following.
2190 \(setq org-html-standalone-image-predicate
2191 \(lambda \(paragraph\)
2192 \(org-element-property :caption paragraph\)\)\)"
2193 (let ((paragraph (case (org-element-type element)
2194 (paragraph element)
2195 (link (and (org-export-inline-image-p
2196 element org-html-inline-image-rules)
2197 (org-export-get-parent element)))
2198 (t nil))))
2199 (when (eq (org-element-type paragraph) 'paragraph)
2200 (when (or (not (and (boundp 'org-html-standalone-image-predicate)
2201 (functionp org-html-standalone-image-predicate)))
2202 (funcall org-html-standalone-image-predicate paragraph))
2203 (let ((contents (org-element-contents paragraph)))
2204 (loop for x in contents
2205 with inline-image-count = 0
2206 always (cond
2207 ((eq (org-element-type x) 'plain-text)
2208 (not (org-string-nw-p x)))
2209 ((eq (org-element-type x) 'link)
2210 (when (org-export-inline-image-p
2211 x org-html-inline-image-rules)
2212 (= (incf inline-image-count) 1)))
2213 (t nil))))))))
2215 (defun org-html-link (link desc info)
2216 "Transcode a LINK object from Org to HTML.
2218 DESC is the description part of the link, or the empty string.
2219 INFO is a plist holding contextual information. See
2220 `org-export-data'."
2221 (let* ((--link-org-files-as-html-maybe
2222 (function
2223 (lambda (raw-path info)
2224 "Treat links to `file.org' as links to `file.html', if needed.
2225 See `org-html-link-org-files-as-html'."
2226 (cond
2227 ((and org-html-link-org-files-as-html
2228 (string= ".org"
2229 (downcase (file-name-extension raw-path "."))))
2230 (concat (file-name-sans-extension raw-path) "."
2231 (plist-get info :html-extension)))
2232 (t raw-path)))))
2233 (type (org-element-property :type link))
2234 (raw-path (org-element-property :path link))
2235 ;; Ensure DESC really exists, or set it to nil.
2236 (desc (and (not (string= desc "")) desc))
2237 (path
2238 (cond
2239 ((member type '("http" "https" "ftp" "mailto"))
2240 (concat type ":" raw-path))
2241 ((string= type "file")
2242 ;; Treat links to ".org" files as ".html", if needed.
2243 (setq raw-path
2244 (funcall --link-org-files-as-html-maybe raw-path info))
2245 ;; If file path is absolute, prepend it with protocol
2246 ;; component - "file://".
2247 (when (file-name-absolute-p raw-path)
2248 (setq raw-path
2249 (concat "file://" (expand-file-name raw-path))))
2250 ;; Add search option, if any. A search option can be
2251 ;; relative to a custom-id or a headline title. Any other
2252 ;; option is ignored.
2253 (let ((option (org-element-property :search-option link)))
2254 (cond ((not option) raw-path)
2255 ((eq (aref option 0) ?#) (concat raw-path option))
2256 ;; External fuzzy link: try to resolve it if path
2257 ;; belongs to current project, if any.
2258 ((eq (aref option 0) ?*)
2259 (concat
2260 raw-path
2261 (let ((numbers
2262 (org-publish-resolve-external-fuzzy-link
2263 (org-element-property :path link) option)))
2264 (and numbers (concat "#sec-"
2265 (mapconcat 'number-to-string
2266 numbers "-")))))))))
2267 (t raw-path)))
2268 attributes protocol)
2269 ;; Extract attributes from parent's paragraph.
2270 (and (setq attributes
2271 (mapconcat
2272 'identity
2273 (let ((att (org-element-property
2274 :attr_html (org-export-get-parent-element link))))
2275 (unless (and desc att (string-match (regexp-quote (car att)) desc)) att))
2276 " "))
2277 (setq attributes (concat " " attributes)))
2279 (cond
2280 ;; Image file.
2281 ((and (or (eq t org-html-inline-images)
2282 (and org-html-inline-images (not desc)))
2283 (org-export-inline-image-p link org-html-inline-image-rules))
2284 (org-html-link--inline-image link desc info))
2285 ;; Radio target: Transcode target's contents and use them as
2286 ;; link's description.
2287 ((string= type "radio")
2288 (let ((destination (org-export-resolve-radio-link link info)))
2289 (when destination
2290 (format "<a href=\"#%s\"%s>%s</a>"
2291 (org-export-solidify-link-text path)
2292 attributes
2293 (org-export-data (org-element-contents destination) info)))))
2294 ;; Links pointing to a headline: Find destination and build
2295 ;; appropriate referencing command.
2296 ((member type '("custom-id" "fuzzy" "id"))
2297 (let ((destination (if (string= type "fuzzy")
2298 (org-export-resolve-fuzzy-link link info)
2299 (org-export-resolve-id-link link info))))
2300 (case (org-element-type destination)
2301 ;; ID link points to an external file.
2302 (plain-text
2303 (let ((fragment (concat "ID-" path))
2304 ;; Treat links to ".org" files as ".html", if needed.
2305 (path (funcall --link-org-files-as-html-maybe
2306 destination info)))
2307 (format "<a href=\"%s#%s\"%s>%s</a>"
2308 path fragment attributes (or desc destination))))
2309 ;; Fuzzy link points nowhere.
2310 ((nil)
2311 (format "<i>%s</i>"
2312 (or desc
2313 (org-export-data
2314 (org-element-property :raw-link link) info))))
2315 ;; Fuzzy link points to an invisible target.
2316 (keyword nil)
2317 ;; Link points to a headline.
2318 (headline
2319 (let ((href
2320 ;; What href to use?
2321 (cond
2322 ;; Case 1: Headline is linked via it's CUSTOM_ID
2323 ;; property. Use CUSTOM_ID.
2324 ((string= type "custom-id")
2325 (org-element-property :CUSTOM_ID destination))
2326 ;; Case 2: Headline is linked via it's ID property
2327 ;; or through other means. Use the default href.
2328 ((member type '("id" "fuzzy"))
2329 (format "sec-%s"
2330 (mapconcat 'number-to-string
2331 (org-export-get-headline-number
2332 destination info) "-")))
2333 (t (error "Shouldn't reach here"))))
2334 ;; What description to use?
2335 (desc
2336 ;; Case 1: Headline is numbered and LINK has no
2337 ;; description or LINK's description matches
2338 ;; headline's title. Display section number.
2339 (if (and (org-export-numbered-headline-p destination info)
2340 (or (not desc)
2341 (string= desc (org-element-property
2342 :raw-value destination))))
2343 (mapconcat 'number-to-string
2344 (org-export-get-headline-number
2345 destination info) ".")
2346 ;; Case 2: Either the headline is un-numbered or
2347 ;; LINK has a custom description. Display LINK's
2348 ;; description or headline's title.
2349 (or desc (org-export-data (org-element-property
2350 :title destination) info)))))
2351 (format "<a href=\"#%s\"%s>%s</a>"
2352 (org-export-solidify-link-text href) attributes desc)))
2353 ;; Fuzzy link points to a target. Do as above.
2355 (let ((path (org-export-solidify-link-text path)) number)
2356 (unless desc
2357 (setq number (cond
2358 ((org-html-standalone-image-p destination info)
2359 (org-export-get-ordinal
2360 (assoc 'link (org-element-contents destination))
2361 info 'link 'org-html-standalone-image-p))
2362 (t (org-export-get-ordinal destination info))))
2363 (setq desc (when number
2364 (if (atom number) (number-to-string number)
2365 (mapconcat 'number-to-string number ".")))))
2366 (format "<a href=\"#%s\"%s>%s</a>"
2367 path attributes (or desc "No description for this link")))))))
2368 ;; Coderef: replace link with the reference name or the
2369 ;; equivalent line number.
2370 ((string= type "coderef")
2371 (let ((fragment (concat "coderef-" path)))
2372 (format "<a href=\"#%s\" %s%s>%s</a>"
2373 fragment
2374 (format (concat "class=\"coderef\""
2375 " onmouseover=\"CodeHighlightOn(this, '%s');\""
2376 " onmouseout=\"CodeHighlightOff(this, '%s');\"")
2377 fragment fragment)
2378 attributes
2379 (format (org-export-get-coderef-format path desc)
2380 (org-export-resolve-coderef path info)))))
2381 ;; Link type is handled by a special function.
2382 ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
2383 (funcall protocol (org-link-unescape path) desc 'html))
2384 ;; External link with a description part.
2385 ((and path desc) (format "<a href=\"%s\"%s>%s</a>" path attributes desc))
2386 ;; External link without a description part.
2387 (path (format "<a href=\"%s\"%s>%s</a>" path attributes path))
2388 ;; No path, only description. Try to do something useful.
2389 (t (format "<i>%s</i>" desc)))))
2392 ;;;; Paragraph
2394 (defun org-html-paragraph (paragraph contents info)
2395 "Transcode a PARAGRAPH element from Org to HTML.
2396 CONTENTS is the contents of the paragraph, as a string. INFO is
2397 the plist used as a communication channel."
2398 (let* ((style nil) ; FIXME
2399 (class (cdr (assoc style '((footnote . "footnote")
2400 (verse . nil)))))
2401 (extra (if class (format " class=\"%s\"" class) ""))
2402 (parent (org-export-get-parent paragraph)))
2403 (cond
2404 ((and (eq (org-element-type parent) 'item)
2405 (= (org-element-property :begin paragraph)
2406 (org-element-property :contents-begin parent)))
2407 ;; leading paragraph in a list item have no tags
2408 contents)
2409 ((org-html-standalone-image-p paragraph info)
2410 ;; standalone image
2411 contents)
2412 (t (format "<p%s>\n%s</p>" extra contents)))))
2415 ;;;; Plain List
2417 ;; FIXME Maybe arg1 is not needed because <li value="20"> already sets
2418 ;; the correct value for the item counter
2419 (defun org-html-begin-plain-list (type &optional arg1)
2420 "Insert the beginning of the HTML list depending on TYPE.
2421 When ARG1 is a string, use it as the start parameter for ordered
2422 lists."
2423 (case type
2424 (ordered
2425 (format "<ol class=\"org-ol\"%s>"
2426 (if arg1 (format " start=\"%d\"" arg1) "")))
2427 (unordered "<ul class=\"org-ul\">")
2428 (descriptive "<dl class=\"org-dl\">")))
2430 (defun org-html-end-plain-list (type)
2431 "Insert the end of the HTML list depending on TYPE."
2432 (case type
2433 (ordered "</ol>")
2434 (unordered "</ul>")
2435 (descriptive "</dl>")))
2437 (defun org-html-plain-list (plain-list contents info)
2438 "Transcode a PLAIN-LIST element from Org to HTML.
2439 CONTENTS is the contents of the list. INFO is a plist holding
2440 contextual information."
2441 (let* (arg1 ;; (assoc :counter (org-element-map plain-list 'item
2442 (type (org-element-property :type plain-list)))
2443 (format "%s\n%s%s"
2444 (org-html-begin-plain-list type)
2445 contents (org-html-end-plain-list type))))
2447 ;;;; Plain Text
2449 (defun org-html-convert-special-strings (string)
2450 "Convert special characters in STRING to HTML."
2451 (let ((all org-html-special-string-regexps)
2452 e a re rpl start)
2453 (while (setq a (pop all))
2454 (setq re (car a) rpl (cdr a) start 0)
2455 (while (string-match re string start)
2456 (setq string (replace-match rpl t nil string))))
2457 string))
2459 (defun org-html-encode-plain-text (text)
2460 "Convert plain text characters to HTML equivalent.
2461 Possible conversions are set in `org-export-html-protect-char-alist'."
2462 (mapc
2463 (lambda (pair)
2464 (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t)))
2465 org-html-protect-char-alist)
2466 text)
2468 (defun org-html-plain-text (text info)
2469 "Transcode a TEXT string from Org to HTML.
2470 TEXT is the string to transcode. INFO is a plist holding
2471 contextual information."
2472 (let ((output text))
2473 ;; Protect following characters: <, >, &.
2474 (setq output (org-html-encode-plain-text output))
2475 ;; Handle smart quotes. Be sure to provide original string since
2476 ;; OUTPUT may have been modified.
2477 (when (plist-get info :with-smart-quotes)
2478 (setq output (org-export-activate-smart-quotes output :html info text)))
2479 ;; Handle special strings.
2480 (when (plist-get info :with-special-strings)
2481 (setq output (org-html-convert-special-strings output)))
2482 ;; Handle break preservation if required.
2483 (when (plist-get info :preserve-breaks)
2484 (setq output
2485 (replace-regexp-in-string
2486 "\\(\\\\\\\\\\)?[ \t]*\n" "<br/>\n" output)))
2487 ;; Return value.
2488 output))
2491 ;; Planning
2493 (defun org-html-planning (planning contents info)
2494 "Transcode a PLANNING element from Org to HTML.
2495 CONTENTS is nil. INFO is a plist used as a communication
2496 channel."
2497 (let ((span-fmt "<span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>"))
2498 (format
2499 "<p><span class=\"timestamp-wrapper\">%s</span></p>"
2500 (mapconcat
2501 'identity
2502 (delq nil
2503 (list
2504 (let ((closed (org-element-property :closed planning)))
2505 (when closed
2506 (format span-fmt org-closed-string
2507 (org-translate-time
2508 (org-element-property :raw-value closed)))))
2509 (let ((deadline (org-element-property :deadline planning)))
2510 (when deadline
2511 (format span-fmt org-deadline-string
2512 (org-translate-time
2513 (org-element-property :raw-value deadline)))))
2514 (let ((scheduled (org-element-property :scheduled planning)))
2515 (when scheduled
2516 (format span-fmt org-scheduled-string
2517 (org-translate-time
2518 (org-element-property :raw-value scheduled)))))))
2519 " "))))
2522 ;;;; Property Drawer
2524 (defun org-html-property-drawer (property-drawer contents info)
2525 "Transcode a PROPERTY-DRAWER element from Org to HTML.
2526 CONTENTS is nil. INFO is a plist holding contextual
2527 information."
2528 ;; The property drawer isn't exported but we want separating blank
2529 ;; lines nonetheless.
2533 ;;;; Quote Block
2535 (defun org-html-quote-block (quote-block contents info)
2536 "Transcode a QUOTE-BLOCK element from Org to HTML.
2537 CONTENTS holds the contents of the block. INFO is a plist
2538 holding contextual information."
2539 (format "<blockquote>\n%s</blockquote>" contents))
2542 ;;;; Quote Section
2544 (defun org-html-quote-section (quote-section contents info)
2545 "Transcode a QUOTE-SECTION element from Org to HTML.
2546 CONTENTS is nil. INFO is a plist holding contextual information."
2547 (let ((value (org-remove-indentation
2548 (org-element-property :value quote-section))))
2549 (when value (format "<pre>\n%s</pre>" value))))
2552 ;;;; Section
2554 (defun org-html-section (section contents info)
2555 "Transcode a SECTION element from Org to HTML.
2556 CONTENTS holds the contents of the section. INFO is a plist
2557 holding contextual information."
2558 (let ((parent (org-export-get-parent-headline section)))
2559 ;; Before first headline: no container, just return CONTENTS.
2560 (if (not parent) contents
2561 ;; Get div's class and id references.
2562 (let* ((class-num (+ (org-export-get-relative-level parent info)
2563 (1- org-html-toplevel-hlevel)))
2564 (section-number
2565 (mapconcat
2566 'number-to-string
2567 (org-export-get-headline-number parent info) "-")))
2568 ;; Build return value.
2569 (format "<div class=\"outline-text-%d\" id=\"text-%s\">\n%s</div>"
2570 class-num
2571 (or (org-element-property :CUSTOM_ID parent) section-number)
2572 contents)))))
2574 ;;;; Radio Target
2576 (defun org-html-radio-target (radio-target text info)
2577 "Transcode a RADIO-TARGET object from Org to HTML.
2578 TEXT is the text of the target. INFO is a plist holding
2579 contextual information."
2580 (let ((id (org-export-solidify-link-text
2581 (org-element-property :value radio-target))))
2582 (org-html--anchor id text)))
2585 ;;;; Special Block
2587 (defun org-html-special-block (special-block contents info)
2588 "Transcode a SPECIAL-BLOCK element from Org to HTML.
2589 CONTENTS holds the contents of the block. INFO is a plist
2590 holding contextual information."
2591 (format "<div class=\"%s\">\n%s\n</div>"
2592 (downcase (org-element-property :type special-block))
2593 contents))
2596 ;;;; Src Block
2598 (defun org-html-src-block (src-block contents info)
2599 "Transcode a SRC-BLOCK element from Org to HTML.
2600 CONTENTS holds the contents of the item. INFO is a plist holding
2601 contextual information."
2602 (if (org-export-read-attribute :attr_html src-block :textarea)
2603 (org-html--textarea-block src-block)
2604 (let ((lang (org-element-property :language src-block))
2605 (caption (org-export-get-caption src-block))
2606 (code (org-html-format-code src-block info))
2607 (label (let ((lbl (org-element-property :name src-block)))
2608 (if (not lbl) ""
2609 (format " id=\"%s\""
2610 (org-export-solidify-link-text lbl))))))
2611 (if (not lang) (format "<pre class=\"example\"%s>\n%s</pre>" label code)
2612 (format
2613 "<div class=\"org-src-container\">\n%s%s\n</div>"
2614 (if (not caption) ""
2615 (format "<label class=\"org-src-name\">%s</label>"
2616 (org-export-data caption info)))
2617 (format "\n<pre class=\"src src-%s\"%s>%s</pre>" lang label code))))))
2620 ;;;; Statistics Cookie
2622 (defun org-html-statistics-cookie (statistics-cookie contents info)
2623 "Transcode a STATISTICS-COOKIE object from Org to HTML.
2624 CONTENTS is nil. INFO is a plist holding contextual information."
2625 (let ((cookie-value (org-element-property :value statistics-cookie)))
2626 (format "<code>%s</code>" cookie-value)))
2629 ;;;; Strike-Through
2631 (defun org-html-strike-through (strike-through contents info)
2632 "Transcode STRIKE-THROUGH from Org to HTML.
2633 CONTENTS is the text with strike-through markup. INFO is a plist
2634 holding contextual information."
2635 (format (or (cdr (assq 'strike-through org-html-text-markup-alist)) "%s")
2636 contents))
2639 ;;;; Subscript
2641 (defun org-html-subscript (subscript contents info)
2642 "Transcode a SUBSCRIPT object from Org to HTML.
2643 CONTENTS is the contents of the object. INFO is a plist holding
2644 contextual information."
2645 (format "<sub>%s</sub>" contents))
2648 ;;;; Superscript
2650 (defun org-html-superscript (superscript contents info)
2651 "Transcode a SUPERSCRIPT object from Org to HTML.
2652 CONTENTS is the contents of the object. INFO is a plist holding
2653 contextual information."
2654 (format "<sup>%s</sup>" contents))
2657 ;;;; Tabel Cell
2659 (defun org-html-table-cell (table-cell contents info)
2660 "Transcode a TABLE-CELL element from Org to HTML.
2661 CONTENTS is nil. INFO is a plist used as a communication
2662 channel."
2663 (let* ((table-row (org-export-get-parent table-cell))
2664 (table (org-export-get-parent-table table-cell))
2665 (cell-attrs
2666 (if (not org-html-table-align-individual-fields) ""
2667 (format (if (and (boundp 'org-html-format-table-no-css)
2668 org-html-format-table-no-css)
2669 " align=\"%s\"" " class=\"%s\"")
2670 (org-export-table-cell-alignment table-cell info)))))
2671 (when (or (not contents) (string= "" (org-trim contents)))
2672 (setq contents "&nbsp;"))
2673 (cond
2674 ((and (org-export-table-has-header-p table info)
2675 (= 1 (org-export-table-row-group table-row info)))
2676 (concat "\n" (format (car org-html-table-header-tags) "col" cell-attrs)
2677 contents (cdr org-html-table-header-tags)))
2678 ((and org-html-table-use-header-tags-for-first-column
2679 (zerop (cdr (org-export-table-cell-address table-cell info))))
2680 (concat "\n" (format (car org-html-table-header-tags) "row" cell-attrs)
2681 contents (cdr org-html-table-header-tags)))
2682 (t (concat "\n" (format (car org-html-table-data-tags) cell-attrs)
2683 contents (cdr org-html-table-data-tags))))))
2686 ;;;; Table Row
2688 (defun org-html-table-row (table-row contents info)
2689 "Transcode a TABLE-ROW element from Org to HTML.
2690 CONTENTS is the contents of the row. INFO is a plist used as a
2691 communication channel."
2692 ;; Rules are ignored since table separators are deduced from
2693 ;; borders of the current row.
2694 (when (eq (org-element-property :type table-row) 'standard)
2695 (let* ((first-rowgroup-p (= 1 (org-export-table-row-group table-row info)))
2696 (rowgroup-tags
2697 (cond
2698 ;; Case 1: Row belongs to second or subsequent rowgroups.
2699 ((not (= 1 (org-export-table-row-group table-row info)))
2700 '("<tbody>" . "\n</tbody>"))
2701 ;; Case 2: Row is from first rowgroup. Table has >=1 rowgroups.
2702 ((org-export-table-has-header-p
2703 (org-export-get-parent-table table-row) info)
2704 '("<thead>" . "\n</thead>"))
2705 ;; Case 2: Row is from first and only row group.
2706 (t '("<tbody>" . "\n</tbody>")))))
2707 (concat
2708 ;; Begin a rowgroup?
2709 (when (org-export-table-row-starts-rowgroup-p table-row info)
2710 (car rowgroup-tags))
2711 ;; Actual table row
2712 (concat "\n" (eval (car org-html-table-row-tags))
2713 contents
2714 "\n"
2715 (eval (cdr org-html-table-row-tags)))
2716 ;; End a rowgroup?
2717 (when (org-export-table-row-ends-rowgroup-p table-row info)
2718 (cdr rowgroup-tags))))))
2721 ;;;; Table
2723 (defun org-html-table-first-row-data-cells (table info)
2724 (let ((table-row
2725 (org-element-map table 'table-row
2726 (lambda (row)
2727 (unless (eq (org-element-property :type row) 'rule) row))
2728 info 'first-match))
2729 (special-column-p (org-export-table-has-special-column-p table)))
2730 (if (not special-column-p) (org-element-contents table-row)
2731 (cdr (org-element-contents table-row)))))
2733 (defun org-html-table--table.el-table (table info)
2734 (when (eq (org-element-property :type table) 'table.el)
2735 (require 'table)
2736 (let ((outbuf (with-current-buffer
2737 (get-buffer-create "*org-export-table*")
2738 (erase-buffer) (current-buffer))))
2739 (with-temp-buffer
2740 (insert (org-element-property :value table))
2741 (goto-char 1)
2742 (re-search-forward "^[ \t]*|[^|]" nil t)
2743 (table-generate-source 'html outbuf))
2744 (with-current-buffer outbuf
2745 (prog1 (org-trim (buffer-string))
2746 (kill-buffer) )))))
2748 (defun org-html-table (table contents info)
2749 "Transcode a TABLE element from Org to HTML.
2750 CONTENTS is the contents of the table. INFO is a plist holding
2751 contextual information."
2752 (case (org-element-property :type table)
2753 ;; Case 1: table.el table. Convert it using appropriate tools.
2754 (table.el (org-html-table--table.el-table table info))
2755 ;; Case 2: Standard table.
2757 (let* ((label (org-element-property :name table))
2758 (caption (org-export-get-caption table))
2759 (attributes (mapconcat #'identity
2760 (org-element-property :attr_html table)
2761 " "))
2762 (alignspec
2763 (if (and (boundp 'org-html-format-table-no-css)
2764 org-html-format-table-no-css)
2765 "align=\"%s\"" "class=\"%s\""))
2766 (table-column-specs
2767 (function
2768 (lambda (table info)
2769 (mapconcat
2770 (lambda (table-cell)
2771 (let ((alignment (org-export-table-cell-alignment
2772 table-cell info)))
2773 (concat
2774 ;; Begin a colgroup?
2775 (when (org-export-table-cell-starts-colgroup-p
2776 table-cell info)
2777 "\n<colgroup>")
2778 ;; Add a column. Also specify it's alignment.
2779 (format "\n<col %s/>" (format alignspec alignment))
2780 ;; End a colgroup?
2781 (when (org-export-table-cell-ends-colgroup-p
2782 table-cell info)
2783 "\n</colgroup>"))))
2784 (org-html-table-first-row-data-cells table info) "\n"))))
2785 (table-attributes
2786 (let ((table-tag (plist-get info :html-table-tag)))
2787 (concat
2788 (and (string-match "<table\\(.*\\)>" table-tag)
2789 (match-string 1 table-tag))
2790 (and label (format " id=\"%s\""
2791 (org-export-solidify-link-text label)))
2792 (unless (string= attributes "")
2793 (concat " " attributes))))))
2794 ;; Remove last blank line.
2795 (setq contents (substring contents 0 -1))
2796 (format "<table%s>\n%s\n%s\n%s\n</table>"
2797 table-attributes
2798 (if (not caption) ""
2799 (format "<caption>%s</caption>"
2800 (org-export-data caption info)))
2801 (funcall table-column-specs table info)
2802 contents)))))
2805 ;;;; Target
2807 (defun org-html-target (target contents info)
2808 "Transcode a TARGET object from Org to HTML.
2809 CONTENTS is nil. INFO is a plist holding contextual
2810 information."
2811 (let ((id (org-export-solidify-link-text
2812 (org-element-property :value target))))
2813 (org-html--anchor id)))
2816 ;;;; Timestamp
2818 (defun org-html-timestamp (timestamp contents info)
2819 "Transcode a TIMESTAMP object from Org to HTML.
2820 CONTENTS is nil. INFO is a plist holding contextual
2821 information."
2822 (let ((value (org-html-plain-text
2823 (org-timestamp-translate timestamp) info)))
2824 (format "<span class=\"timestamp-wrapper\"><span class=\"timestamp\">%s</span></span>"
2825 (replace-regexp-in-string "--" "&ndash;" value))))
2828 ;;;; Underline
2830 (defun org-html-underline (underline contents info)
2831 "Transcode UNDERLINE from Org to HTML.
2832 CONTENTS is the text with underline markup. INFO is a plist
2833 holding contextual information."
2834 (format (or (cdr (assq 'underline org-html-text-markup-alist)) "%s")
2835 contents))
2838 ;;;; Verbatim
2840 (defun org-html-verbatim (verbatim contents info)
2841 "Transcode VERBATIM from Org to HTML.
2842 CONTENTS is nil. INFO is a plist holding contextual
2843 information."
2844 (format (or (cdr (assq 'verbatim org-html-text-markup-alist)) "%s")
2845 (org-element-property :value verbatim)))
2848 ;;;; Verse Block
2850 (defun org-html-verse-block (verse-block contents info)
2851 "Transcode a VERSE-BLOCK element from Org to HTML.
2852 CONTENTS is verse block contents. INFO is a plist holding
2853 contextual information."
2854 ;; Replace each newline character with line break. Also replace
2855 ;; each blank line with a line break.
2856 (setq contents (replace-regexp-in-string
2857 "^ *\\\\\\\\$" "<br/>\n"
2858 (replace-regexp-in-string
2859 "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n" contents)))
2860 ;; Replace each white space at beginning of a line with a
2861 ;; non-breaking space.
2862 (while (string-match "^[ \t]+" contents)
2863 (let* ((num-ws (length (match-string 0 contents)))
2864 (ws (let (out) (dotimes (i num-ws out)
2865 (setq out (concat out "&nbsp;"))))))
2866 (setq contents (replace-match ws nil t contents))))
2867 (format "<p class=\"verse\">\n%s</p>" contents))
2871 ;;; Filter Functions
2873 (defun org-html-final-function (contents backend info)
2874 (if (not org-html-pretty-output) contents
2875 (with-temp-buffer
2876 (html-mode)
2877 (insert contents)
2878 (indent-region (point-min) (point-max))
2879 (buffer-substring-no-properties (point-min) (point-max)))))
2883 ;;; End-user functions
2885 ;;;###autoload
2886 (defun org-html-export-as-html
2887 (&optional async subtreep visible-only body-only ext-plist)
2888 "Export current buffer to an HTML buffer.
2890 If narrowing is active in the current buffer, only export its
2891 narrowed part.
2893 If a region is active, export that region.
2895 A non-nil optional argument ASYNC means the process should happen
2896 asynchronously. The resulting buffer should be accessible
2897 through the `org-export-stack' interface.
2899 When optional argument SUBTREEP is non-nil, export the sub-tree
2900 at point, extracting information from the headline properties
2901 first.
2903 When optional argument VISIBLE-ONLY is non-nil, don't export
2904 contents of hidden elements.
2906 When optional argument BODY-ONLY is non-nil, only write code
2907 between \"<body>\" and \"</body>\" tags.
2909 EXT-PLIST, when provided, is a property list with external
2910 parameters overriding Org default settings, but still inferior to
2911 file-local settings.
2913 Export is done in a buffer named \"*Org HTML Export*\", which
2914 will be displayed when `org-export-show-temporary-export-buffer'
2915 is non-nil."
2916 (interactive)
2917 (if async
2918 (org-export-async-start
2919 (lambda (output)
2920 (with-current-buffer (get-buffer-create "*Org HTML Export*")
2921 (erase-buffer)
2922 (insert output)
2923 (goto-char (point-min))
2924 (funcall org-html-display-buffer-mode)
2925 (org-export-add-to-stack (current-buffer) 'html)))
2926 `(org-export-as 'html ,subtreep ,visible-only ,body-only ',ext-plist))
2927 (let ((outbuf (org-export-to-buffer
2928 'html "*Org HTML Export*"
2929 subtreep visible-only body-only ext-plist)))
2930 ;; Set major mode.
2931 (with-current-buffer outbuf (funcall org-html-display-buffer-mode))
2932 (when org-export-show-temporary-export-buffer
2933 (switch-to-buffer-other-window outbuf)))))
2935 ;;;###autoload
2936 (defun org-html-export-to-html
2937 (&optional async subtreep visible-only body-only ext-plist)
2938 "Export current buffer to a HTML file.
2940 If narrowing is active in the current buffer, only export its
2941 narrowed part.
2943 If a region is active, export that region.
2945 A non-nil optional argument ASYNC means the process should happen
2946 asynchronously. The resulting file should be accessible through
2947 the `org-export-stack' interface.
2949 When optional argument SUBTREEP is non-nil, export the sub-tree
2950 at point, extracting information from the headline properties
2951 first.
2953 When optional argument VISIBLE-ONLY is non-nil, don't export
2954 contents of hidden elements.
2956 When optional argument BODY-ONLY is non-nil, only write code
2957 between \"<body>\" and \"</body>\" tags.
2959 EXT-PLIST, when provided, is a property list with external
2960 parameters overriding Org default settings, but still inferior to
2961 file-local settings.
2963 Return output file's name."
2964 (interactive)
2965 (let* ((extension (concat "." org-html-extension))
2966 (file (org-export-output-file-name extension subtreep))
2967 (org-export-coding-system org-html-coding-system))
2968 (if async
2969 (org-export-async-start
2970 (lambda (f) (org-export-add-to-stack f 'html))
2971 (let ((org-export-coding-system org-html-coding-system))
2972 `(expand-file-name
2973 (org-export-to-file
2974 'html ,file ,subtreep ,visible-only ,body-only ',ext-plist))))
2975 (let ((org-export-coding-system org-html-coding-system))
2976 (org-export-to-file
2977 'html file subtreep visible-only body-only ext-plist)))))
2979 ;;;###autoload
2980 (defun org-html-publish-to-html (plist filename pub-dir)
2981 "Publish an org file to HTML.
2983 FILENAME is the filename of the Org file to be published. PLIST
2984 is the property list for the given project. PUB-DIR is the
2985 publishing directory.
2987 Return output file name."
2988 (org-publish-org-to 'html filename ".html" plist pub-dir))
2992 ;;; FIXME
2994 ;;;; org-format-table-html
2995 ;;;; org-format-org-table-html
2996 ;;;; org-format-table-table-html
2997 ;;;; org-table-number-fraction
2998 ;;;; org-table-number-regexp
2999 ;;;; org-html-table-caption-above
3000 ;;;; org-html-with-timestamp
3001 ;;;; org-html-html-helper-timestamp
3002 ;;;; org-html-inline-image-extensions
3003 ;;;; org-export-preferred-target-alist
3004 ;;;; class for anchors
3005 ;;;; org-export-with-section-numbers, body-only
3006 ;;;; org-export-mark-todo-in-toc
3007 ;;;; org-html-format-org-link
3008 ;;;; (caption (and caption (org-xml-encode-org-text caption)))
3009 ;;;; alt = (file-name-nondirectory path)
3011 (provide 'ox-html)
3013 ;; Local variables:
3014 ;; generated-autoload-file: "org-loaddefs.el"
3015 ;; End:
3017 ;;; ox-html.el ends here