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