ox-html.el (153293B)
1 ;;; ox-html.el --- HTML Back-End for Org Export Engine -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2011-2023 Free Software Foundation, Inc. 4 5 ;; Author: Carsten Dominik <carsten.dominik@gmail.com> 6 ;; Jambunathan K <kjambunathan at gmail dot com> 7 ;; Maintainer: TEC <orgmode@tec.tecosaur.net> 8 ;; Keywords: outlines, hypermedia, calendar, wp 9 10 ;; This file is part of GNU Emacs. 11 12 ;; GNU Emacs is free software: you can redistribute it and/or modify 13 ;; it under the terms of the GNU General Public License as published by 14 ;; the Free Software Foundation, either version 3 of the License, or 15 ;; (at your option) any later version. 16 17 ;; GNU Emacs is distributed in the hope that it will be useful, 18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 ;; GNU General Public License for more details. 21 22 ;; You should have received a copy of the GNU General Public License 23 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 24 25 ;;; Commentary: 26 27 ;; This library implements a HTML back-end for Org generic exporter. 28 ;; See Org manual for more information. 29 30 ;;; Code: 31 32 ;;; Dependencies 33 34 (require 'org-macs) 35 (org-assert-version) 36 37 (require 'cl-lib) 38 (require 'format-spec) 39 (require 'ox) 40 (require 'ox-publish) 41 (require 'table) 42 43 44 ;;; Function Declarations 45 46 (declare-function org-id-find-id-file "org-id" (id)) 47 (declare-function htmlize-region "ext:htmlize" (beg end)) 48 (declare-function mm-url-decode-entities "mm-url" ()) 49 (declare-function org-at-heading-p "org" (&optional _)) 50 (declare-function org-back-to-heading "org" (&optional invisible-ok)) 51 (declare-function org-next-visible-heading "org" (arg)) 52 53 (defvar htmlize-css-name-prefix) 54 (defvar htmlize-output-type) 55 (defvar htmlize-output-type) 56 (defvar htmlize-css-name-prefix) 57 58 ;;; Define Back-End 59 60 (org-export-define-backend 'html 61 '((bold . org-html-bold) 62 (center-block . org-html-center-block) 63 (clock . org-html-clock) 64 (code . org-html-code) 65 (drawer . org-html-drawer) 66 (dynamic-block . org-html-dynamic-block) 67 (entity . org-html-entity) 68 (example-block . org-html-example-block) 69 (export-block . org-html-export-block) 70 (export-snippet . org-html-export-snippet) 71 (fixed-width . org-html-fixed-width) 72 (footnote-reference . org-html-footnote-reference) 73 (headline . org-html-headline) 74 (horizontal-rule . org-html-horizontal-rule) 75 (inline-src-block . org-html-inline-src-block) 76 (inlinetask . org-html-inlinetask) 77 (inner-template . org-html-inner-template) 78 (italic . org-html-italic) 79 (item . org-html-item) 80 (keyword . org-html-keyword) 81 (latex-environment . org-html-latex-environment) 82 (latex-fragment . org-html-latex-fragment) 83 (line-break . org-html-line-break) 84 (link . org-html-link) 85 (node-property . org-html-node-property) 86 (paragraph . org-html-paragraph) 87 (plain-list . org-html-plain-list) 88 (plain-text . org-html-plain-text) 89 (planning . org-html-planning) 90 (property-drawer . org-html-property-drawer) 91 (quote-block . org-html-quote-block) 92 (radio-target . org-html-radio-target) 93 (section . org-html-section) 94 (special-block . org-html-special-block) 95 (src-block . org-html-src-block) 96 (statistics-cookie . org-html-statistics-cookie) 97 (strike-through . org-html-strike-through) 98 (subscript . org-html-subscript) 99 (superscript . org-html-superscript) 100 (table . org-html-table) 101 (table-cell . org-html-table-cell) 102 (table-row . org-html-table-row) 103 (target . org-html-target) 104 (template . org-html-template) 105 (timestamp . org-html-timestamp) 106 (underline . org-html-underline) 107 (verbatim . org-html-verbatim) 108 (verse-block . org-html-verse-block)) 109 :filters-alist '((:filter-options . org-html-infojs-install-script) 110 (:filter-parse-tree . org-html-image-link-filter) 111 (:filter-final-output . org-html-final-function)) 112 :menu-entry 113 '(?h "Export to HTML" 114 ((?H "As HTML buffer" org-html-export-as-html) 115 (?h "As HTML file" org-html-export-to-html) 116 (?o "As HTML file and open" 117 (lambda (a s v b) 118 (if a (org-html-export-to-html t s v b) 119 (org-open-file (org-html-export-to-html nil s v b))))))) 120 :options-alist 121 '((:html-doctype "HTML_DOCTYPE" nil org-html-doctype) 122 (:html-container "HTML_CONTAINER" nil org-html-container-element) 123 (:html-content-class "HTML_CONTENT_CLASS" nil org-html-content-class) 124 (:description "DESCRIPTION" nil nil newline) 125 (:keywords "KEYWORDS" nil nil space) 126 (:html-html5-fancy nil "html5-fancy" org-html-html5-fancy) 127 (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) 128 (:html-link-home "HTML_LINK_HOME" nil org-html-link-home) 129 (:html-link-up "HTML_LINK_UP" nil org-html-link-up) 130 (:html-mathjax "HTML_MATHJAX" nil "" space) 131 (:html-equation-reference-format "HTML_EQUATION_REFERENCE_FORMAT" nil org-html-equation-reference-format t) 132 (:html-postamble nil "html-postamble" org-html-postamble) 133 (:html-preamble nil "html-preamble" org-html-preamble) 134 (:html-head "HTML_HEAD" nil org-html-head newline) 135 (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline) 136 (:subtitle "SUBTITLE" nil nil parse) 137 (:html-head-include-default-style 138 nil "html-style" org-html-head-include-default-style) 139 (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts) 140 (:html-allow-name-attribute-in-anchors 141 nil nil org-html-allow-name-attribute-in-anchors) 142 (:html-divs nil nil org-html-divs) 143 (:html-checkbox-type nil nil org-html-checkbox-type) 144 (:html-extension nil nil org-html-extension) 145 (:html-footnote-format nil nil org-html-footnote-format) 146 (:html-footnote-separator nil nil org-html-footnote-separator) 147 (:html-footnotes-section nil nil org-html-footnotes-section) 148 (:html-format-drawer-function nil nil org-html-format-drawer-function) 149 (:html-format-headline-function nil nil org-html-format-headline-function) 150 (:html-format-inlinetask-function 151 nil nil org-html-format-inlinetask-function) 152 (:html-home/up-format nil nil org-html-home/up-format) 153 (:html-indent nil nil org-html-indent) 154 (:html-infojs-options nil nil org-html-infojs-options) 155 (:html-infojs-template nil nil org-html-infojs-template) 156 (:html-inline-image-rules nil nil org-html-inline-image-rules) 157 (:html-link-org-files-as-html nil nil org-html-link-org-files-as-html) 158 (:html-mathjax-options nil nil org-html-mathjax-options) 159 (:html-mathjax-template nil nil org-html-mathjax-template) 160 (:html-metadata-timestamp-format nil nil org-html-metadata-timestamp-format) 161 (:html-postamble-format nil nil org-html-postamble-format) 162 (:html-preamble-format nil nil org-html-preamble-format) 163 (:html-prefer-user-labels nil nil org-html-prefer-user-labels) 164 (:html-self-link-headlines nil nil org-html-self-link-headlines) 165 (:html-table-align-individual-fields 166 nil nil org-html-table-align-individual-fields) 167 (:html-table-caption-above nil nil org-html-table-caption-above) 168 (:html-table-data-tags nil nil org-html-table-data-tags) 169 (:html-table-header-tags nil nil org-html-table-header-tags) 170 (:html-table-use-header-tags-for-first-column 171 nil nil org-html-table-use-header-tags-for-first-column) 172 (:html-tag-class-prefix nil nil org-html-tag-class-prefix) 173 (:html-text-markup-alist nil nil org-html-text-markup-alist) 174 (:html-todo-kwd-class-prefix nil nil org-html-todo-kwd-class-prefix) 175 (:html-toplevel-hlevel nil nil org-html-toplevel-hlevel) 176 (:html-use-infojs nil nil org-html-use-infojs) 177 (:html-validation-link nil nil org-html-validation-link) 178 (:html-viewport nil nil org-html-viewport) 179 (:html-inline-images nil nil org-html-inline-images) 180 (:html-table-attributes nil nil org-html-table-default-attributes) 181 (:html-table-row-open-tag nil nil org-html-table-row-open-tag) 182 (:html-table-row-close-tag nil nil org-html-table-row-close-tag) 183 (:html-xml-declaration nil nil org-html-xml-declaration) 184 (:html-wrap-src-lines nil nil org-html-wrap-src-lines) 185 (:html-klipsify-src nil nil org-html-klipsify-src) 186 (:html-klipse-css nil nil org-html-klipse-css) 187 (:html-klipse-js nil nil org-html-klipse-js) 188 (:html-klipse-selection-script nil nil org-html-klipse-selection-script) 189 (:infojs-opt "INFOJS_OPT" nil nil) 190 ;; Redefine regular options. 191 (:creator "CREATOR" nil org-html-creator-string) 192 (:with-latex nil "tex" org-html-with-latex) 193 ;; Retrieve LaTeX header for fragments. 194 (:latex-header "LATEX_HEADER" nil nil newline))) 195 196 197 ;;; Internal Variables 198 199 (defvar org-html-format-table-no-css) 200 (defvar htmlize-buffer-places) ; from htmlize.el 201 202 (defvar org-html--pre/postamble-class "status" 203 "CSS class used for pre/postamble.") 204 205 (defconst org-html-doctype-alist 206 '(("html4-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" 207 \"http://www.w3.org/TR/html4/strict.dtd\">") 208 ("html4-transitional" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" 209 \"http://www.w3.org/TR/html4/loose.dtd\">") 210 ("html4-frameset" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" 211 \"http://www.w3.org/TR/html4/frameset.dtd\">") 212 213 ("xhtml-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" 214 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">") 215 ("xhtml-transitional" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" 216 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">") 217 ("xhtml-frameset" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" 218 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">") 219 ("xhtml-11" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" 220 \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">") 221 222 ("html5" . "<!DOCTYPE html>") 223 ("xhtml5" . "<!DOCTYPE html>")) 224 "An alist mapping (x)html flavors to specific doctypes.") 225 226 (defconst org-html-html5-elements 227 '("article" "aside" "audio" "canvas" "details" "figcaption" 228 "figure" "footer" "header" "menu" "meter" "nav" "output" 229 "progress" "section" "summary" "video") 230 "New elements in html5. 231 232 For blocks that should contain headlines, use the HTML_CONTAINER 233 property on the headline itself.") 234 235 (defconst org-html-special-string-regexps 236 '(("\\\\-" . "­") ; shy 237 ("---\\([^-]\\)" . "—\\1") ; mdash 238 ("--\\([^-]\\)" . "–\\1") ; ndash 239 ("\\.\\.\\." . "…")) ; hellip 240 "Regular expressions for special string conversion.") 241 242 (defcustom org-html-scripts 243 "<script> 244 // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later 245 function CodeHighlightOn(elem, id) 246 { 247 var target = document.getElementById(id); 248 if(null != target) { 249 elem.classList.add(\"code-highlighted\"); 250 target.classList.add(\"code-highlighted\"); 251 } 252 } 253 function CodeHighlightOff(elem, id) 254 { 255 var target = document.getElementById(id); 256 if(null != target) { 257 elem.classList.remove(\"code-highlighted\"); 258 target.classList.remove(\"code-highlighted\"); 259 } 260 } 261 // @license-end 262 </script>" 263 "Basic JavaScript to allow highlighting references in code blocks." 264 :group 'org-export-html 265 :package-version '(Org . "9.5") 266 :type 'string) 267 268 (defcustom org-html-style-default 269 "<style> 270 #content { max-width: 60em; margin: auto; } 271 .title { text-align: center; 272 margin-bottom: .2em; } 273 .subtitle { text-align: center; 274 font-size: medium; 275 font-weight: bold; 276 margin-top:0; } 277 .todo { font-family: monospace; color: red; } 278 .done { font-family: monospace; color: green; } 279 .priority { font-family: monospace; color: orange; } 280 .tag { background-color: #eee; font-family: monospace; 281 padding: 2px; font-size: 80%; font-weight: normal; } 282 .timestamp { color: #bebebe; } 283 .timestamp-kwd { color: #5f9ea0; } 284 .org-right { margin-left: auto; margin-right: 0px; text-align: right; } 285 .org-left { margin-left: 0px; margin-right: auto; text-align: left; } 286 .org-center { margin-left: auto; margin-right: auto; text-align: center; } 287 .underline { text-decoration: underline; } 288 #postamble p, #preamble p { font-size: 90%; margin: .2em; } 289 p.verse { margin-left: 3%; } 290 pre { 291 border: 1px solid #e6e6e6; 292 border-radius: 3px; 293 background-color: #f2f2f2; 294 padding: 8pt; 295 font-family: monospace; 296 overflow: auto; 297 margin: 1.2em; 298 } 299 pre.src { 300 position: relative; 301 overflow: auto; 302 } 303 pre.src:before { 304 display: none; 305 position: absolute; 306 top: -8px; 307 right: 12px; 308 padding: 3px; 309 color: #555; 310 background-color: #f2f2f299; 311 } 312 pre.src:hover:before { display: inline; margin-top: 14px;} 313 /* Languages per Org manual */ 314 pre.src-asymptote:before { content: 'Asymptote'; } 315 pre.src-awk:before { content: 'Awk'; } 316 pre.src-authinfo::before { content: 'Authinfo'; } 317 pre.src-C:before { content: 'C'; } 318 /* pre.src-C++ doesn't work in CSS */ 319 pre.src-clojure:before { content: 'Clojure'; } 320 pre.src-css:before { content: 'CSS'; } 321 pre.src-D:before { content: 'D'; } 322 pre.src-ditaa:before { content: 'ditaa'; } 323 pre.src-dot:before { content: 'Graphviz'; } 324 pre.src-calc:before { content: 'Emacs Calc'; } 325 pre.src-emacs-lisp:before { content: 'Emacs Lisp'; } 326 pre.src-fortran:before { content: 'Fortran'; } 327 pre.src-gnuplot:before { content: 'gnuplot'; } 328 pre.src-haskell:before { content: 'Haskell'; } 329 pre.src-hledger:before { content: 'hledger'; } 330 pre.src-java:before { content: 'Java'; } 331 pre.src-js:before { content: 'Javascript'; } 332 pre.src-latex:before { content: 'LaTeX'; } 333 pre.src-ledger:before { content: 'Ledger'; } 334 pre.src-lisp:before { content: 'Lisp'; } 335 pre.src-lilypond:before { content: 'Lilypond'; } 336 pre.src-lua:before { content: 'Lua'; } 337 pre.src-matlab:before { content: 'MATLAB'; } 338 pre.src-mscgen:before { content: 'Mscgen'; } 339 pre.src-ocaml:before { content: 'Objective Caml'; } 340 pre.src-octave:before { content: 'Octave'; } 341 pre.src-org:before { content: 'Org mode'; } 342 pre.src-oz:before { content: 'OZ'; } 343 pre.src-plantuml:before { content: 'Plantuml'; } 344 pre.src-processing:before { content: 'Processing.js'; } 345 pre.src-python:before { content: 'Python'; } 346 pre.src-R:before { content: 'R'; } 347 pre.src-ruby:before { content: 'Ruby'; } 348 pre.src-sass:before { content: 'Sass'; } 349 pre.src-scheme:before { content: 'Scheme'; } 350 pre.src-screen:before { content: 'Gnu Screen'; } 351 pre.src-sed:before { content: 'Sed'; } 352 pre.src-sh:before { content: 'shell'; } 353 pre.src-sql:before { content: 'SQL'; } 354 pre.src-sqlite:before { content: 'SQLite'; } 355 /* additional languages in org.el's org-babel-load-languages alist */ 356 pre.src-forth:before { content: 'Forth'; } 357 pre.src-io:before { content: 'IO'; } 358 pre.src-J:before { content: 'J'; } 359 pre.src-makefile:before { content: 'Makefile'; } 360 pre.src-maxima:before { content: 'Maxima'; } 361 pre.src-perl:before { content: 'Perl'; } 362 pre.src-picolisp:before { content: 'Pico Lisp'; } 363 pre.src-scala:before { content: 'Scala'; } 364 pre.src-shell:before { content: 'Shell Script'; } 365 pre.src-ebnf2ps:before { content: 'ebfn2ps'; } 366 /* additional language identifiers per \"defun org-babel-execute\" 367 in ob-*.el */ 368 pre.src-cpp:before { content: 'C++'; } 369 pre.src-abc:before { content: 'ABC'; } 370 pre.src-coq:before { content: 'Coq'; } 371 pre.src-groovy:before { content: 'Groovy'; } 372 /* additional language identifiers from org-babel-shell-names in 373 ob-shell.el: ob-shell is the only babel language using a lambda to put 374 the execution function name together. */ 375 pre.src-bash:before { content: 'bash'; } 376 pre.src-csh:before { content: 'csh'; } 377 pre.src-ash:before { content: 'ash'; } 378 pre.src-dash:before { content: 'dash'; } 379 pre.src-ksh:before { content: 'ksh'; } 380 pre.src-mksh:before { content: 'mksh'; } 381 pre.src-posh:before { content: 'posh'; } 382 /* Additional Emacs modes also supported by the LaTeX listings package */ 383 pre.src-ada:before { content: 'Ada'; } 384 pre.src-asm:before { content: 'Assembler'; } 385 pre.src-caml:before { content: 'Caml'; } 386 pre.src-delphi:before { content: 'Delphi'; } 387 pre.src-html:before { content: 'HTML'; } 388 pre.src-idl:before { content: 'IDL'; } 389 pre.src-mercury:before { content: 'Mercury'; } 390 pre.src-metapost:before { content: 'MetaPost'; } 391 pre.src-modula-2:before { content: 'Modula-2'; } 392 pre.src-pascal:before { content: 'Pascal'; } 393 pre.src-ps:before { content: 'PostScript'; } 394 pre.src-prolog:before { content: 'Prolog'; } 395 pre.src-simula:before { content: 'Simula'; } 396 pre.src-tcl:before { content: 'tcl'; } 397 pre.src-tex:before { content: 'TeX'; } 398 pre.src-plain-tex:before { content: 'Plain TeX'; } 399 pre.src-verilog:before { content: 'Verilog'; } 400 pre.src-vhdl:before { content: 'VHDL'; } 401 pre.src-xml:before { content: 'XML'; } 402 pre.src-nxml:before { content: 'XML'; } 403 /* add a generic configuration mode; LaTeX export needs an additional 404 (add-to-list 'org-latex-listings-langs '(conf \" \")) in .emacs */ 405 pre.src-conf:before { content: 'Configuration File'; } 406 407 table { border-collapse:collapse; } 408 caption.t-above { caption-side: top; } 409 caption.t-bottom { caption-side: bottom; } 410 td, th { vertical-align:top; } 411 th.org-right { text-align: center; } 412 th.org-left { text-align: center; } 413 th.org-center { text-align: center; } 414 td.org-right { text-align: right; } 415 td.org-left { text-align: left; } 416 td.org-center { text-align: center; } 417 dt { font-weight: bold; } 418 .footpara { display: inline; } 419 .footdef { margin-bottom: 1em; } 420 .figure { padding: 1em; } 421 .figure p { text-align: center; } 422 .equation-container { 423 display: table; 424 text-align: center; 425 width: 100%; 426 } 427 .equation { 428 vertical-align: middle; 429 } 430 .equation-label { 431 display: table-cell; 432 text-align: right; 433 vertical-align: middle; 434 } 435 .inlinetask { 436 padding: 10px; 437 border: 2px solid gray; 438 margin: 10px; 439 background: #ffffcc; 440 } 441 #org-div-home-and-up 442 { text-align: right; font-size: 70%; white-space: nowrap; } 443 textarea { overflow-x: auto; } 444 .linenr { font-size: smaller } 445 .code-highlighted { background-color: #ffff00; } 446 .org-info-js_info-navigation { border-style: none; } 447 #org-info-js_console-label 448 { font-size: 10px; font-weight: bold; white-space: nowrap; } 449 .org-info-js_search-highlight 450 { background-color: #ffff00; color: #000000; font-weight: bold; } 451 .org-svg { } 452 </style>" 453 "The default style specification for exported HTML files. 454 You can use `org-html-head' and `org-html-head-extra' to add to 455 this style. If you don't want to include this default style, 456 customize `org-html-head-include-default-style'." 457 :group 'org-export-html 458 :package-version '(Org . "9.5") 459 :type 'string) 460 461 462 ;;; User Configuration Variables 463 464 (defgroup org-export-html nil 465 "Options for exporting Org mode files to HTML." 466 :tag "Org Export HTML" 467 :group 'org-export) 468 469 ;;;; Handle infojs 470 471 (defvar org-html-infojs-opts-table 472 '((path PATH "https://orgmode.org/org-info.js") 473 (view VIEW "info") 474 (toc TOC :with-toc) 475 (ftoc FIXED_TOC "0") 476 (tdepth TOC_DEPTH "max") 477 (sdepth SECTION_DEPTH "max") 478 (mouse MOUSE_HINT "underline") 479 (buttons VIEW_BUTTONS "0") 480 (ltoc LOCAL_TOC "1") 481 (up LINK_UP :html-link-up) 482 (home LINK_HOME :html-link-home)) 483 "JavaScript options, long form for script, default values.") 484 485 (defcustom org-html-use-infojs 'when-configured 486 "Non-nil when Sebastian Rose's Java Script org-info.js should be active. 487 This option can be nil or t to never or always use the script. 488 It can also be the symbol `when-configured', meaning that the 489 script will be linked into the export file if and only if there 490 is a \"#+INFOJS_OPT:\" line in the buffer. See also the variable 491 `org-html-infojs-options'." 492 :group 'org-export-html 493 :version "24.4" 494 :package-version '(Org . "8.0") 495 :type '(choice 496 (const :tag "Never" nil) 497 (const :tag "When configured in buffer" when-configured) 498 (const :tag "Always" t))) 499 500 (defcustom org-html-infojs-options 501 (mapcar (lambda (x) (cons (car x) (nth 2 x))) org-html-infojs-opts-table) 502 "Options settings for the INFOJS JavaScript. 503 Each of the options must have an entry in `org-html-infojs-opts-table'. 504 The value can either be a string that will be passed to the script, or 505 a property. This property is then assumed to be a property that is defined 506 by the Export/Publishing setup of Org. 507 The `sdepth' and `tdepth' parameters can also be set to \"max\", which 508 means to use the maximum value consistent with other options." 509 :group 'org-export-html 510 :version "24.4" 511 :package-version '(Org . "8.0") 512 :type 513 `(set :greedy t :inline t 514 ,@(mapcar 515 (lambda (x) 516 (list 'cons (list 'const (car x)) 517 '(choice 518 (symbol :tag "Publishing/Export property") 519 (string :tag "Value")))) 520 org-html-infojs-opts-table))) 521 522 (defcustom org-html-infojs-template 523 "<script src=\"%SCRIPT_PATH\"> 524 // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later 525 // @license-end 526 </script> 527 528 <script> 529 // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later 530 %MANAGER_OPTIONS 531 org_html_manager.setup(); // activate after the parameters are set 532 // @license-end 533 </script>" 534 "The template for the export style additions when org-info.js is used. 535 Option settings will replace the %MANAGER-OPTIONS cookie." 536 :group 'org-export-html 537 :package-version '(Org . "9.4") 538 :type 'string) 539 540 (defun org-html-infojs-install-script (exp-plist _backend) 541 "Install script in export options when appropriate. 542 EXP-PLIST is a plist containing export options. BACKEND is the 543 export back-end currently used." 544 (unless (or (memq 'body-only (plist-get exp-plist :export-options)) 545 (not (plist-get exp-plist :html-use-infojs)) 546 (and (eq (plist-get exp-plist :html-use-infojs) 'when-configured) 547 (let ((opt (plist-get exp-plist :infojs-opt))) 548 (or (not opt) 549 (string= "" opt) 550 (string-match "\\<view:nil\\>" opt))))) 551 (let* ((template (plist-get exp-plist :html-infojs-template)) 552 (ptoc (plist-get exp-plist :with-toc)) 553 (hlevels (plist-get exp-plist :headline-levels)) 554 (sdepth hlevels) 555 (tdepth (if (integerp ptoc) (min ptoc hlevels) hlevels)) 556 (options (plist-get exp-plist :infojs-opt)) 557 (infojs-opt (plist-get exp-plist :html-infojs-options)) 558 (table org-html-infojs-opts-table) 559 style) 560 (dolist (entry table) 561 (let* ((opt (car entry)) 562 (var (nth 1 entry)) 563 ;; Compute default values for script option OPT from 564 ;; `org-html-infojs-options' variable. 565 (default 566 (let ((default (cdr (assq opt infojs-opt)))) 567 (if (and (symbolp default) (not (memq default '(t nil)))) 568 (plist-get exp-plist default) 569 default))) 570 ;; Value set through INFOJS_OPT keyword has precedence 571 ;; over the default one. 572 (val (if (and options 573 (string-match (format "\\<%s:\\(\\S-+\\)" opt) 574 options)) 575 (match-string 1 options) 576 default))) 577 (pcase opt 578 (`path (setq template 579 (replace-regexp-in-string 580 "%SCRIPT_PATH" val template t t))) 581 (`sdepth (when (integerp (read val)) 582 (setq sdepth (min (read val) sdepth)))) 583 (`tdepth (when (integerp (read val)) 584 (setq tdepth (min (read val) tdepth)))) 585 (_ (setq val 586 (cond 587 ((or (eq val t) (equal val "t")) "1") 588 ((or (eq val nil) (equal val "nil")) "0") 589 ((stringp val) val) 590 (t (format "%s" val)))) 591 (push (cons var val) style))))) 592 ;; Now we set the depth of the *generated* TOC to SDEPTH, 593 ;; because the toc will actually determine the splitting. How 594 ;; much of the toc will actually be displayed is governed by the 595 ;; TDEPTH option. 596 (setq exp-plist (plist-put exp-plist :with-toc sdepth)) 597 ;; The table of contents should not show more sections than we 598 ;; generate. 599 (setq tdepth (min tdepth sdepth)) 600 (push (cons "TOC_DEPTH" tdepth) style) 601 ;; Build style string. 602 (setq style (mapconcat 603 (lambda (x) 604 (format "org_html_manager.set(\"%s\", \"%s\");" 605 (car x) (cdr x))) 606 style "\n")) 607 (when (and style (> (length style) 0)) 608 (and (string-match "%MANAGER_OPTIONS" template) 609 (setq style (replace-match style t t template)) 610 (setq exp-plist 611 (plist-put 612 exp-plist :html-head-extra 613 (concat (or (plist-get exp-plist :html-head-extra) "") 614 "\n" 615 style))))) 616 ;; This script absolutely needs the table of contents, so we 617 ;; change that setting. 618 (unless (plist-get exp-plist :with-toc) 619 (setq exp-plist (plist-put exp-plist :with-toc t))) 620 ;; Return the modified property list. 621 exp-plist))) 622 623 ;;;; Bold, etc. 624 625 (defcustom org-html-text-markup-alist 626 '((bold . "<b>%s</b>") 627 (code . "<code>%s</code>") 628 (italic . "<i>%s</i>") 629 (strike-through . "<del>%s</del>") 630 (underline . "<span class=\"underline\">%s</span>") 631 (verbatim . "<code>%s</code>")) 632 "Alist of HTML expressions to convert text markup. 633 634 The key must be a symbol among `bold', `code', `italic', 635 `strike-through', `underline' and `verbatim'. The value is 636 a formatting string to wrap fontified text with. 637 638 If no association can be found for a given markup, text will be 639 returned as-is." 640 :group 'org-export-html 641 :version "24.4" 642 :package-version '(Org . "8.0") 643 :type '(alist :key-type (symbol :tag "Markup type") 644 :value-type (string :tag "Format string")) 645 :options '(bold code italic strike-through underline verbatim)) 646 647 (defcustom org-html-indent nil 648 "Non-nil means to indent the generated HTML. 649 Warning: non-nil may break indentation of source code blocks." 650 :group 'org-export-html 651 :version "24.4" 652 :package-version '(Org . "8.0") 653 :type 'boolean) 654 655 ;;;; Drawers 656 657 (defcustom org-html-format-drawer-function (lambda (_name contents) contents) 658 "Function called to format a drawer in HTML code. 659 660 The function must accept two parameters: 661 NAME the drawer name, like \"LOGBOOK\" 662 CONTENTS the contents of the drawer. 663 664 The function should return the string to be exported. 665 666 The default value simply returns the value of CONTENTS." 667 :group 'org-export-html 668 :version "24.4" 669 :package-version '(Org . "8.0") 670 :type 'function) 671 672 ;;;; Footnotes 673 674 (defcustom org-html-footnotes-section "<div id=\"footnotes\"> 675 <h2 class=\"footnotes\">%s: </h2> 676 <div id=\"text-footnotes\"> 677 %s 678 </div> 679 </div>" 680 "Format for the footnotes section. 681 Should contain a two instances of %s. The first will be replaced with the 682 language-specific word for \"Footnotes\", the second one will be replaced 683 by the footnotes themselves." 684 :group 'org-export-html 685 :type 'string) 686 687 (defcustom org-html-footnote-format "<sup>%s</sup>" 688 "The format for the footnote reference. 689 %s will be replaced by the footnote reference itself." 690 :group 'org-export-html 691 :type 'string) 692 693 (defcustom org-html-footnote-separator "<sup>, </sup>" 694 "Text used to separate footnotes." 695 :group 'org-export-html 696 :type 'string) 697 698 ;;;; Headline 699 700 (defcustom org-html-toplevel-hlevel 2 701 "The <H> level for level 1 headings in HTML export. 702 This is also important for the classes that will be wrapped around headlines 703 and outline structure. If this variable is 1, the top-level headlines will 704 be <h1>, and the corresponding classes will be outline-1, section-number-1, 705 and outline-text-1. If this is 2, all of these will get a 2 instead. 706 The default for this variable is 2, because we use <h1> for formatting the 707 document title." 708 :group 'org-export-html 709 :type 'integer) 710 711 (defcustom org-html-format-headline-function 712 'org-html-format-headline-default-function 713 "Function to format headline text. 714 715 This function will be called with six arguments: 716 TODO the todo keyword (string or nil). 717 TODO-TYPE the type of todo (symbol: `todo', `done', nil) 718 PRIORITY the priority of the headline (integer or nil) 719 TEXT the main headline text (string). 720 TAGS the tags (string or nil). 721 INFO the export options (plist). 722 723 The function result will be used in the section format string." 724 :group 'org-export-html 725 :version "26.1" 726 :package-version '(Org . "8.3") 727 :type 'function) 728 729 ;;;; HTML-specific 730 731 (defcustom org-html-allow-name-attribute-in-anchors nil 732 "When nil, do not set \"name\" attribute in anchors. 733 By default, when appropriate, anchors are formatted with \"id\" 734 but without \"name\" attribute." 735 :group 'org-export-html 736 :version "24.4" 737 :package-version '(Org . "8.0") 738 :type 'boolean) 739 740 (defcustom org-html-self-link-headlines nil 741 "When non-nil, the headlines contain a hyperlink to themselves." 742 :group 'org-export-html 743 :package-version '(Org . "9.3") 744 :type 'boolean 745 :safe #'booleanp) 746 747 (defcustom org-html-prefer-user-labels nil 748 "When non-nil use user-defined names and ID over internal ones. 749 750 By default, Org generates its own internal ID values during HTML 751 export. This process ensures that these values are unique and 752 valid, but the keys are not available in advance of the export 753 process, and not so readable. 754 755 When this variable is non-nil, Org will use NAME keyword, or the 756 real name of the target to create the ID attribute. 757 758 Independently of this variable, however, CUSTOM_ID are always 759 used as a reference." 760 :group 'org-export-html 761 :package-version '(Org . "9.4") 762 :type 'boolean 763 :safe #'booleanp) 764 765 ;;;; Inlinetasks 766 767 (defcustom org-html-format-inlinetask-function 768 'org-html-format-inlinetask-default-function 769 "Function called to format an inlinetask in HTML code. 770 771 The function must accept seven parameters: 772 TODO the todo keyword, as a string 773 TODO-TYPE the todo type, a symbol among `todo', `done' and nil. 774 PRIORITY the inlinetask priority, as a string 775 NAME the inlinetask name, as a string. 776 TAGS the inlinetask tags, as a list of strings. 777 CONTENTS the contents of the inlinetask, as a string. 778 INFO the export options, as a plist 779 780 The function should return the string to be exported." 781 :group 'org-export-html 782 :version "26.1" 783 :package-version '(Org . "8.3") 784 :type 'function) 785 786 ;;;; LaTeX 787 788 (defcustom org-html-equation-reference-format "\\eqref{%s}" 789 "The MathJax command to use when referencing equations. 790 791 This is a format control string that expects a single string argument 792 specifying the label that is being referenced. The argument is 793 generated automatically on export. 794 795 The default is to wrap equations in parentheses (using \"\\eqref{%s}\)\". 796 797 Most common values are: 798 799 \\eqref{%s} Wrap the equation in parentheses 800 \\ref{%s} Do not wrap the equation in parentheses" 801 :group 'org-export-html 802 :package-version '(Org . "9.4") 803 :type 'string 804 :safe #'stringp) 805 806 (defcustom org-html-with-latex org-export-with-latex 807 "Non-nil means process LaTeX math snippets. 808 809 When set, the exporter will process LaTeX environments and 810 fragments. 811 812 This option can also be set with the +OPTIONS line, 813 e.g. \"tex:mathjax\". Allowed values are: 814 815 nil Ignore math snippets. 816 `verbatim' Keep everything in verbatim 817 `mathjax', t Do MathJax preprocessing and arrange for MathJax.js to 818 be loaded. 819 `html' Use `org-latex-to-html-convert-command' to convert 820 LaTeX fragments to HTML. 821 SYMBOL Any symbol defined in `org-preview-latex-process-alist', 822 e.g., `dvipng'." 823 :group 'org-export-html 824 :version "24.4" 825 :package-version '(Org . "8.0") 826 :type '(choice 827 (const :tag "Do not process math in any way" nil) 828 (const :tag "Leave math verbatim" verbatim) 829 (const :tag "Use MathJax to display math" mathjax) 830 (symbol :tag "Convert to image to display math" :value dvipng))) 831 832 ;;;; Links :: Generic 833 834 (defcustom org-html-link-org-files-as-html t 835 "Non-nil means make file links to \"file.org\" point to \"file.html\". 836 837 When Org mode is exporting an Org file to HTML, links to non-HTML files 838 are directly put into a \"href\" tag in HTML. However, links to other Org files 839 (recognized by the extension \".org\") should become links to the corresponding 840 HTML file, assuming that the linked Org file will also be converted to HTML. 841 842 Links to \"file.org.gpg\" are also converted. 843 844 When nil, the links still point to the plain \".org\" file." 845 :group 'org-export-html 846 :type 'boolean) 847 848 ;;;; Links :: Inline images 849 850 (defcustom org-html-inline-images t 851 "Non-nil means inline images into exported HTML pages. 852 This is done using an <img> tag. When nil, an anchor with href is used to 853 link to the image." 854 :group 'org-export-html 855 :version "24.4" 856 :package-version '(Org . "8.1") 857 :type 'boolean) 858 859 (defcustom org-html-inline-image-rules 860 `(("file" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg" ".webp"))) 861 ("http" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg" ".webp"))) 862 ("https" . ,(regexp-opt '(".jpeg" ".jpg" ".png" ".gif" ".svg" ".webp")))) 863 "Rules characterizing image files that can be inlined into HTML. 864 A rule consists in an association whose key is the type of link 865 to consider, and value is a regexp that will be matched against 866 link's path." 867 :group 'org-export-html 868 :package-version '(Org . "9.5") 869 :type '(alist :key-type (string :tag "Type") 870 :value-type (regexp :tag "Path"))) 871 872 ;;;; Plain Text 873 874 (defvar org-html-protect-char-alist 875 '(("&" . "&") 876 ("<" . "<") 877 (">" . ">")) 878 "Alist of characters to be converted by `org-html-encode-plain-text'.") 879 880 ;;;; Src Block 881 882 (defcustom org-html-htmlize-output-type 'inline-css 883 "Output type to be used by htmlize when formatting code snippets. 884 Choices are `css' to export the CSS selectors only,`inline-css' 885 to export the CSS attribute values inline in the HTML or nil to 886 export plain text. We use as default `inline-css', in order to 887 make the resulting HTML self-containing. 888 889 However, this will fail when using Emacs in batch mode for export, because 890 then no rich font definitions are in place. It will also not be good if 891 people with different Emacs setup contribute HTML files to a website, 892 because the fonts will represent the individual setups. In these cases, 893 it is much better to let Org/Htmlize assign classes only, and to use 894 a style file to define the look of these classes. 895 To get a start for your css file, start Emacs session and make sure that 896 all the faces you are interested in are defined, for example by loading files 897 in all modes you want. Then, use the command 898 `\\[org-html-htmlize-generate-css]' to extract class definitions." 899 :group 'org-export-html 900 :type '(choice (const css) (const inline-css) (const nil)) 901 :safe #'symbolp) 902 903 (defcustom org-html-htmlize-font-prefix "org-" 904 "The prefix for CSS class names for htmlize font specifications." 905 :group 'org-export-html 906 :type 'string) 907 908 (defcustom org-html-wrap-src-lines nil 909 "If non-nil, wrap individual lines of source blocks in \"code\" elements. 910 In this case, add line number in attribute \"data-ox-html-linenr\" when line 911 numbers are enabled." 912 :group 'org-export-html 913 :package-version '(Org . "9.3") 914 :type 'boolean 915 :safe #'booleanp) 916 917 ;;;; Table 918 919 (defcustom org-html-table-default-attributes 920 '(:border "2" :cellspacing "0" :cellpadding "6" :rules "groups" :frame "hsides") 921 "Default attributes and values which will be used in table tags. 922 This is a plist where attributes are symbols, starting with 923 colons, and values are strings. 924 925 When exporting to HTML5, these values will be disregarded." 926 :group 'org-export-html 927 :version "24.4" 928 :package-version '(Org . "8.0") 929 :type '(plist :key-type (symbol :tag "Property") 930 :value-type (string :tag "Value"))) 931 932 (defcustom org-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>") 933 "The opening and ending tags for table header fields. 934 This is customizable so that alignment options can be specified. 935 The first %s will be filled with the scope of the field, either row or col. 936 The second %s will be replaced by a style entry to align the field. 937 See also the variable `org-html-table-use-header-tags-for-first-column'. 938 See also the variable `org-html-table-align-individual-fields'." 939 :group 'org-export-html 940 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) 941 942 (defcustom org-html-table-data-tags '("<td%s>" . "</td>") 943 "The opening and ending tags for table data fields. 944 This is customizable so that alignment options can be specified. 945 The first %s will be filled with the scope of the field, either row or col. 946 The second %s will be replaced by a style entry to align the field. 947 See also the variable `org-html-table-align-individual-fields'." 948 :group 'org-export-html 949 :type '(cons (string :tag "Opening tag") (string :tag "Closing tag"))) 950 951 (defcustom org-html-table-row-open-tag "<tr>" 952 "The opening tag for table rows. 953 This is customizable so that alignment options can be specified. 954 Instead of strings, these can be a Lisp function that will be 955 evaluated for each row in order to construct the table row tags. 956 957 The function will be called with these arguments: 958 959 `number': row number (0 is the first row) 960 `group-number': group number of current row 961 `start-group?': non-nil means the row starts a group 962 `end-group?': non-nil means the row ends a group 963 `top?': non-nil means this is the top row 964 `bottom?': non-nil means this is the bottom row 965 966 For example: 967 968 (setq org-html-table-row-open-tag 969 (lambda (number group-number start-group? end-group-p top? bottom?) 970 (cond (top? \"<tr class=\\\"tr-top\\\">\") 971 (bottom? \"<tr class=\\\"tr-bottom\\\">\") 972 (t (if (= (mod number 2) 1) 973 \"<tr class=\\\"tr-odd\\\">\" 974 \"<tr class=\\\"tr-even\\\">\"))))) 975 976 will use the \"tr-top\" and \"tr-bottom\" classes for the top row 977 and the bottom row, and otherwise alternate between \"tr-odd\" and 978 \"tr-even\" for odd and even rows." 979 :group 'org-export-html 980 :type '(choice :tag "Opening tag" 981 (string :tag "Specify") 982 (function))) 983 984 (defcustom org-html-table-row-close-tag "</tr>" 985 "The closing tag for table rows. 986 This is customizable so that alignment options can be specified. 987 Instead of strings, this can be a Lisp function that will be 988 evaluated for each row in order to construct the table row tags. 989 990 See documentation of `org-html-table-row-open-tag'." 991 :group 'org-export-html 992 :type '(choice :tag "Closing tag" 993 (string :tag "Specify") 994 (function))) 995 996 (defcustom org-html-table-align-individual-fields t 997 "Non-nil means attach style attributes for alignment to each table field. 998 When nil, alignment will only be specified in the column tags, but this 999 is ignored by some browsers (like Firefox, Safari). Opera does it right 1000 though." 1001 :group 'org-export-html 1002 :type 'boolean) 1003 1004 (defcustom org-html-table-use-header-tags-for-first-column nil 1005 "Non-nil means format column one in tables with header tags. 1006 When nil, also column one will use data tags." 1007 :group 'org-export-html 1008 :type 'boolean) 1009 1010 (defcustom org-html-table-caption-above t 1011 "When non-nil, place caption string at the beginning of the table. 1012 Otherwise, place it near the end." 1013 :group 'org-export-html 1014 :type 'boolean) 1015 1016 ;;;; Tags 1017 1018 (defcustom org-html-tag-class-prefix "" 1019 "Prefix to class names for TODO keywords. 1020 Each tag gets a class given by the tag itself, with this prefix. 1021 The default prefix is empty because it is nice to just use the keyword 1022 as a class name. But if you get into conflicts with other, existing 1023 CSS classes, then this prefix can be very useful." 1024 :group 'org-export-html 1025 :type 'string) 1026 1027 ;;;; Template :: Generic 1028 1029 (defcustom org-html-extension "html" 1030 "The extension for exported HTML files." 1031 :group 'org-export-html 1032 :type 'string) 1033 1034 (defcustom org-html-xml-declaration 1035 '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>") 1036 ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>")) 1037 "The extension for exported HTML files. 1038 %s will be replaced with the charset of the exported file. 1039 This may be a string, or an alist with export extensions 1040 and corresponding declarations. 1041 1042 This declaration only applies when exporting to XHTML." 1043 :group 'org-export-html 1044 :type '(choice 1045 (string :tag "Single declaration") 1046 (repeat :tag "Dependent on extension" 1047 (cons (string :tag "Extension") 1048 (string :tag "Declaration"))))) 1049 1050 (defcustom org-html-coding-system 'utf-8 1051 "Coding system for HTML export. 1052 Use utf-8 as the default value." 1053 :group 'org-export-html 1054 :version "24.4" 1055 :package-version '(Org . "8.0") 1056 :type 'coding-system) 1057 1058 (defcustom org-html-doctype "xhtml-strict" 1059 "Document type definition to use for exported HTML files. 1060 Can be set with the in-buffer HTML_DOCTYPE property or for 1061 publishing, with :html-doctype." 1062 :group 'org-export-html 1063 :version "24.4" 1064 :package-version '(Org . "8.0") 1065 :type (append 1066 '(choice) 1067 (mapcar (lambda (x) `(const ,(car x))) org-html-doctype-alist) 1068 '((string :tag "Custom doctype" )))) 1069 1070 (defcustom org-html-html5-fancy nil 1071 "Non-nil means using new HTML5 elements. 1072 This variable is ignored for anything other than HTML5 export." 1073 :group 'org-export-html 1074 :version "24.4" 1075 :package-version '(Org . "8.0") 1076 :type 'boolean) 1077 1078 (defcustom org-html-container-element "div" 1079 "HTML element to use for wrapping top level sections. 1080 Can be set with the in-buffer HTML_CONTAINER property or for 1081 publishing, with :html-container. 1082 1083 Note that changing the default will prevent you from using 1084 org-info.js for your website." 1085 :group 'org-export-html 1086 :version "24.4" 1087 :package-version '(Org . "8.0") 1088 :type 'string) 1089 1090 (defcustom org-html-content-class "content" 1091 "CSS class name to use for the top level content wrapper. 1092 Can be set with the in-buffer HTML_CONTENT_CLASS property or for 1093 publishing, with :html-content-class." 1094 :group 'org-export-html 1095 :version "27.2" 1096 :package-version '(Org . "9.5") 1097 :type 'string) 1098 1099 1100 (defcustom org-html-divs 1101 '((preamble "div" "preamble") 1102 (content "div" "content") 1103 (postamble "div" "postamble")) 1104 "Alist of the three section elements for HTML export. 1105 The car of each entry is one of `preamble', `content' or `postamble'. 1106 The cdrs of each entry are the ELEMENT_TYPE and ID for each 1107 section of the exported document. 1108 1109 Note that changing the default will prevent you from using 1110 org-info.js for your website." 1111 :group 'org-export-html 1112 :version "24.4" 1113 :package-version '(Org . "8.0") 1114 :type '(list :greedy t 1115 (list :tag "Preamble" 1116 (const :format "" preamble) 1117 (string :tag "element") (string :tag " id")) 1118 (list :tag "Content" 1119 (const :format "" content) 1120 (string :tag "element") (string :tag " id")) 1121 (list :tag "Postamble" (const :format "" postamble) 1122 (string :tag " id") (string :tag "element")))) 1123 1124 (defconst org-html-checkbox-types 1125 '((unicode . 1126 ((on . "☑") (off . "☐") (trans . "☐"))) 1127 (ascii . 1128 ((on . "<code>[X]</code>") 1129 (off . "<code>[ ]</code>") 1130 (trans . "<code>[-]</code>"))) 1131 (html . 1132 ((on . "<input type='checkbox' checked='checked' />") 1133 (off . "<input type='checkbox' />") 1134 (trans . "<input type='checkbox' />")))) 1135 "Alist of checkbox types. 1136 The cdr of each entry is an alist list three checkbox types for 1137 HTML export: `on', `off' and `trans'. 1138 1139 The choices are: 1140 `unicode' Unicode characters (HTML entities) 1141 `ascii' ASCII characters 1142 `html' HTML checkboxes 1143 1144 Note that only the ascii characters implement tri-state 1145 checkboxes. The other two use the `off' checkbox for `trans'.") 1146 1147 (defcustom org-html-checkbox-type 'ascii 1148 "The type of checkboxes to use for HTML export. 1149 See `org-html-checkbox-types' for the values used for each 1150 option." 1151 :group 'org-export-html 1152 :version "24.4" 1153 :package-version '(Org . "8.0") 1154 :type '(choice 1155 (const :tag "ASCII characters" ascii) 1156 (const :tag "Unicode characters" unicode) 1157 (const :tag "HTML checkboxes" html))) 1158 1159 (defcustom org-html-metadata-timestamp-format "%Y-%m-%d %a %H:%M" 1160 "Format used for timestamps in preamble, postamble and metadata. 1161 See `format-time-string' for more information on its components." 1162 :group 'org-export-html 1163 :version "24.4" 1164 :package-version '(Org . "8.0") 1165 :type 'string) 1166 1167 ;;;; Template :: Mathjax 1168 1169 (defcustom org-html-mathjax-options 1170 '((path "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js") 1171 (scale 1.0) 1172 (align "center") 1173 (font "mathjax-modern") 1174 (overflow "overflow") 1175 (tags "ams") 1176 (indent "0em") 1177 (multlinewidth "85%") 1178 (tagindent ".8em") 1179 (tagside "right")) 1180 "Options for MathJax setup. 1181 1182 Alist of the following elements. 1183 1184 path The path to MathJax version 3 or later. 1185 scale Scaling with HTML-CSS, MathML and SVG output engines. 1186 align How to align display math: left, center, or right. 1187 font The font to use with HTML-CSS and SVG output. Needs 1188 MathJax version 4+. MathJax 4 provides 11 fonts: 1189 \"mathjax-modern\" Latin-Modern font, default in MathJax 4+ 1190 \"mathjax-asana\" Asana-Math font 1191 \"mathjax-bonum\" Gyre Bonum font 1192 \"mathjax-dejavu\" Gyre DejaVu font 1193 \"mathjax-pagella\" Gyre Pagella font 1194 \"mathjax-schola\" Gyre Schola font 1195 \"mathjax-termes\" Gyre Termes font 1196 \"mathjax-stix2\" STIX2 font 1197 \"mathjax-fira\" Fira and Fira-Math fonts 1198 \"mathjax-euler\" Neo Euler font that extends Latin-Modern 1199 \"mathjax-tex\" The original MathJax TeX font 1200 overflow How to break displayed equations when too large. Needs 1201 MathJax 4 or newer. Supported options include 1202 \"overflow\", \"scale\", \"scroll\", \"truncate\", 1203 \"linebreak\", and \"elide\". 1204 linebreaks Let MathJax perform automatic linebreaks. Valid values 1205 are \"true\" and \"false\". 1206 indent If align is not center, how far from the left/right side? For 1207 example, \"1em\". 1208 multlinewidth The width of the multline environment. 1209 tags How to number equations. Valid values are \"none\", 1210 \"all\" and \"ams\". 1211 tagindent The amount tags are indented. 1212 tagside Which side to show tags/labels on. Valid values are 1213 \"left\" and \"right\" 1214 1215 You can also customize this for some buffer, using something like 1216 1217 #+HTML_MATHJAX: align: left indent: 5em tagside: left 1218 1219 For further information about MathJax options, see the MathJax documentation: 1220 1221 https://docs.mathjax.org/ 1222 1223 To maintain compatibility with pre-9.6 Org that used MathJax 2, 1224 the following conversions take place. 1225 1226 The legacy \"autonumber\" option, with the value \"AMS\", 1227 \"None\", or \"All\", becomes the \"tags\" option set to the 1228 value \"ams\", \"none\", or \"all\", respectively. 1229 1230 Any legacy values of the \"scale\" option, specified as 1231 percentage strings, become converted to unit-interval numbers. 1232 For example, a legacy scale of \"150\" becomes a scale of 1.5. 1233 1234 The legacy \"linebreaks\" option, with the value \"true\" or 1235 \"false\", becomes the \"overflow\" option set to the value 1236 \"linebreak\" or \"overflow\", respectively. 1237 1238 The legacy values of the \"font\" option, namely \"TeX\", 1239 \"STIX-Web\", \"Asana-Math\", \"Neo-Euler\", \"Gyre-Pagella\", 1240 \"Gyre-Termes\", \"Latin-Modern\", become converted to the 1241 corresponding MathJax 4+ font names. 1242 1243 Legacy options and values always take precedence. 1244 " 1245 :group 'org-export-html 1246 :package-version '(Org . "9.6") 1247 :type '(list :greedy t 1248 (list :tag "path (the path from where to load MathJax.js)" 1249 (const :format " " path) (string)) 1250 (list :tag "scale (scaling for the displayed math)" 1251 (const :format " " scale) (float)) 1252 (list :tag "align (alignment of displayed equations)" 1253 (const :format " " align) (string)) 1254 (list :tag "font (used to typeset math)" 1255 (const :format " " font) 1256 (choice (const "mathjax-modern") 1257 (const "mathjax-asana") 1258 (const "mathjax-bonum") 1259 (const "mathjax-dejavu") 1260 (const "mathjax-pagella") 1261 (const "mathjax-schola") 1262 (const "mathjax-termes") 1263 (const "mathjax-stix2") 1264 (const "mathjax-fira") 1265 (const "mathjax-euler") 1266 (const "mathjax-tex"))) 1267 (list :tag "overflow (how to break displayed math)" 1268 (const :format " " overflow) 1269 (choice (const "overflow") 1270 (const "scale") 1271 (const "scroll") 1272 (const "truncate") 1273 (const "linebreak") 1274 (const "elide"))) 1275 (list :tag "tags (whether equations are numbered and how)" 1276 (const :format " " tags) 1277 (choice (const "ams") 1278 (const "none") 1279 (const "all"))) 1280 (list :tag "indent (indentation with left or right alignment)" 1281 (const :format " " indent) (string)) 1282 (list :tag "multlinewidth (width to use for the multline environment)" 1283 (const :format " " multlinewidth) (string)) 1284 (list :tag "tagindent (the indentation of tags from left or right)" 1285 (const :format " " tagindent) (string)) 1286 (list :tag "tagside (location of tags)" 1287 (const :format " " tagside) 1288 (choice (const "left") 1289 (const "right"))))) 1290 1291 (defcustom org-html-mathjax-template 1292 "<script> 1293 window.MathJax = { 1294 tex: { 1295 ams: { 1296 multlineWidth: '%MULTLINEWIDTH' 1297 }, 1298 tags: '%TAGS', 1299 tagSide: '%TAGSIDE', 1300 tagIndent: '%TAGINDENT' 1301 }, 1302 chtml: { 1303 scale: %SCALE, 1304 displayAlign: '%ALIGN', 1305 displayIndent: '%INDENT' 1306 }, 1307 svg: { 1308 scale: %SCALE, 1309 displayAlign: '%ALIGN', 1310 displayIndent: '%INDENT' 1311 }, 1312 output: { 1313 font: '%FONT', 1314 displayOverflow: '%OVERFLOW' 1315 } 1316 }; 1317 </script> 1318 1319 <script 1320 id=\"MathJax-script\" 1321 async 1322 src=\"%PATH\"> 1323 </script>" 1324 "The MathJax template. See also `org-html-mathjax-options'." 1325 :group 'org-export-html 1326 :type 'string) 1327 1328 ;;;; Template :: Postamble 1329 1330 (defcustom org-html-postamble 'auto 1331 "Non-nil means insert a postamble in HTML export. 1332 1333 When set to `auto', check against the 1334 `org-export-with-author/email/creator/date' variables to set the 1335 content of the postamble. When t, insert a string as defined by the 1336 formatting string in `org-html-postamble-format'. When set to a 1337 string, use this formatting string instead (see 1338 `org-html-postamble-format' for an example of such a formatting 1339 string). 1340 1341 When set to a function, apply this function and insert the 1342 returned string. The function takes the property list of export 1343 options as its only argument. 1344 1345 Setting :html-postamble in publishing projects will take 1346 precedence over this variable." 1347 :group 'org-export-html 1348 :type '(choice (const :tag "No postamble" nil) 1349 (const :tag "Auto postamble" auto) 1350 (const :tag "Default formatting string" t) 1351 (string :tag "Custom formatting string") 1352 (function :tag "Function (must return a string)"))) 1353 1354 (defcustom org-html-postamble-format 1355 '(("en" "<p class=\"author\">Author: %a (%e)</p> 1356 <p class=\"date\">Date: %d</p> 1357 <p class=\"creator\">%c</p> 1358 <p class=\"validation\">%v</p>")) 1359 "Alist of languages and format strings for the HTML postamble. 1360 1361 The first element of each list is the language code, as used for 1362 the LANGUAGE keyword. See `org-export-default-language'. 1363 1364 The second element of each list is a format string to format the 1365 postamble itself. This format string can contain these elements: 1366 1367 %t stands for the title. 1368 %s stands for the subtitle. 1369 %a stands for the author's name. 1370 %e stands for the author's email. 1371 %d stands for the date. 1372 %c will be replaced by `org-html-creator-string'. 1373 %v will be replaced by `org-html-validation-link'. 1374 %T will be replaced by the export time. 1375 %C will be replaced by the last modification time. 1376 1377 If you need to use a \"%\" character, you need to escape it 1378 like that: \"%%\"." 1379 :group 'org-export-html 1380 :type '(repeat 1381 (list (string :tag "Language") 1382 (string :tag "Format string")))) 1383 1384 (defcustom org-html-validation-link 1385 "<a href=\"https://validator.w3.org/check?uri=referer\">Validate</a>" 1386 "Link to HTML validation service." 1387 :group 'org-export-html 1388 :package-version '(Org . "9.4") 1389 :type 'string) 1390 1391 (defcustom org-html-creator-string 1392 (format "<a href=\"https://www.gnu.org/software/emacs/\">Emacs</a> %s (<a href=\"https://orgmode.org\">Org</a> mode %s)" 1393 emacs-version 1394 (if (fboundp 'org-version) (org-version) "unknown version")) 1395 "Information about the creator of the HTML document. 1396 This option can also be set on with the CREATOR keyword." 1397 :group 'org-export-html 1398 :version "24.4" 1399 :package-version '(Org . "8.0") 1400 :type '(string :tag "Creator string")) 1401 1402 ;;;; Template :: Preamble 1403 1404 (defcustom org-html-preamble t 1405 "Non-nil means insert a preamble in HTML export. 1406 1407 When t, insert a string as defined by the formatting string in 1408 `org-html-preamble-format'. When set to a string, use this 1409 formatting string instead (see `org-html-postamble-format' for an 1410 example of such a formatting string). 1411 1412 When set to a function, apply this function and insert the 1413 returned string. The function takes the property list of export 1414 options as its only argument. 1415 1416 Setting :html-preamble in publishing projects will take 1417 precedence over this variable." 1418 :group 'org-export-html 1419 :type '(choice (const :tag "No preamble" nil) 1420 (const :tag "Default preamble" t) 1421 (string :tag "Custom formatting string") 1422 (function :tag "Function (must return a string)"))) 1423 1424 (defcustom org-html-preamble-format '(("en" "")) 1425 "Alist of languages and format strings for the HTML preamble. 1426 1427 The first element of each list is the language code, as used for 1428 the LANGUAGE keyword. See `org-export-default-language'. 1429 1430 The second element of each list is a format string to format the 1431 preamble itself. This format string can contain these elements: 1432 1433 %t stands for the title. 1434 %s stands for the subtitle. 1435 %a stands for the author's name. 1436 %e stands for the author's email. 1437 %d stands for the date. 1438 %c will be replaced by `org-html-creator-string'. 1439 %v will be replaced by `org-html-validation-link'. 1440 %T will be replaced by the export time. 1441 %C will be replaced by the last modification time. 1442 1443 If you need to use a \"%\" character, you need to escape it 1444 like that: \"%%\". 1445 1446 See the default value of `org-html-postamble-format' for an 1447 example." 1448 :group 'org-export-html 1449 :type '(repeat 1450 (list (string :tag "Language") 1451 (string :tag "Format string")))) 1452 1453 (defcustom org-html-link-up "" 1454 "Where should the \"UP\" link of exported HTML pages lead?" 1455 :group 'org-export-html 1456 :type '(string :tag "File or URL")) 1457 1458 (defcustom org-html-link-home "" 1459 "Where should the \"HOME\" link of exported HTML pages lead?" 1460 :group 'org-export-html 1461 :type '(string :tag "File or URL")) 1462 1463 (defcustom org-html-link-use-abs-url nil 1464 "Should we prepend relative links with HTML_LINK_HOME?" 1465 :group 'org-export-html 1466 :version "24.4" 1467 :package-version '(Org . "8.1") 1468 :type 'boolean) 1469 1470 (defcustom org-html-home/up-format 1471 "<div id=\"org-div-home-and-up\"> 1472 <a accesskey=\"h\" href=\"%s\"> UP </a> 1473 | 1474 <a accesskey=\"H\" href=\"%s\"> HOME </a> 1475 </div>" 1476 "Snippet used to insert the HOME and UP links. 1477 This is a format string, the first %s will receive the UP link, 1478 the second the HOME link. If both `org-html-link-up' and 1479 `org-html-link-home' are empty, the entire snippet will be 1480 ignored." 1481 :group 'org-export-html 1482 :type 'string) 1483 1484 ;;;; Template :: Scripts 1485 1486 (defcustom org-html-head-include-scripts nil 1487 "Non-nil means include the JavaScript snippets in exported HTML files. 1488 The actual script is defined in `org-html-scripts'." 1489 :group 'org-export-html 1490 :version "24.4" 1491 :package-version '(Org . "8.0") 1492 :type 'boolean) 1493 1494 ;;;; Template :: Styles 1495 1496 (defcustom org-html-meta-tags #'org-html-meta-tags-default 1497 "Form that is used to produce meta tags in the HTML head. 1498 1499 Can be a list where each item is a list of arguments to be passed 1500 to `org-html--build-meta-entry'. Any nil items are ignored. 1501 1502 Also accept a function which gives such a list when called with a 1503 single argument (INFO, a communication plist)." 1504 :group 'org-export-html 1505 :package-version '(Org . "9.5") 1506 :type '(choice 1507 (repeat 1508 (list (string :tag "Meta label") 1509 (string :tag "label value") 1510 (string :tag "Content value"))) 1511 function)) 1512 1513 (defcustom org-html-head-include-default-style t 1514 "Non-nil means include the default style in exported HTML files. 1515 The actual style is defined in `org-html-style-default' and 1516 should not be modified. Use `org-html-head' to use your own 1517 style information." 1518 :group 'org-export-html 1519 :version "24.4" 1520 :package-version '(Org . "8.0") 1521 :type 'boolean) 1522 ;;;###autoload 1523 (put 'org-html-head-include-default-style 'safe-local-variable 'booleanp) 1524 1525 (defcustom org-html-head "" 1526 "Org-wide head definitions for exported HTML files. 1527 1528 This variable can contain the full HTML structure to provide a 1529 style, including the surrounding HTML tags. You can consider 1530 including definitions for the following classes: title, todo, 1531 done, timestamp, timestamp-kwd, tag, target. 1532 1533 For example, a valid value would be: 1534 1535 <style> 1536 p { font-weight: normal; color: gray; } 1537 h1 { color: black; } 1538 .title { text-align: center; } 1539 .todo, .timestamp-kwd { color: red; } 1540 .done { color: green; } 1541 </style> 1542 1543 If you want to refer to an external style, use something like 1544 1545 <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\" /> 1546 1547 As the value of this option simply gets inserted into the HTML 1548 <head> header, you can use it to add any arbitrary text to the 1549 header. 1550 1551 You can set this on a per-file basis using #+HTML_HEAD:, 1552 or for publication projects using the :html-head property." 1553 :group 'org-export-html 1554 :version "24.4" 1555 :package-version '(Org . "8.0") 1556 :type 'string) 1557 ;;;###autoload 1558 (put 'org-html-head 'safe-local-variable 'stringp) 1559 1560 (defcustom org-html-head-extra "" 1561 "More head information to add in the HTML output. 1562 1563 You can set this on a per-file basis using #+HTML_HEAD_EXTRA:, 1564 or for publication projects using the :html-head-extra property." 1565 :group 'org-export-html 1566 :version "24.4" 1567 :package-version '(Org . "8.0") 1568 :type 'string) 1569 ;;;###autoload 1570 (put 'org-html-head-extra 'safe-local-variable 'stringp) 1571 1572 ;;;; Template :: Viewport 1573 1574 (defcustom org-html-viewport '((width "device-width") 1575 (initial-scale "1") 1576 (minimum-scale "") 1577 (maximum-scale "") 1578 (user-scalable "")) 1579 "Viewport options for mobile-optimized sites. 1580 1581 The following values are recognized 1582 1583 width Size of the viewport. 1584 initial-scale Zoom level when the page is first loaded. 1585 minimum-scale Minimum allowed zoom level. 1586 maximum-scale Maximum allowed zoom level. 1587 user-scalable Whether zoom can be changed. 1588 1589 The viewport meta tag is inserted if this variable is non-nil. 1590 1591 See the following site for a reference: 1592 https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag" 1593 :group 'org-export-html 1594 :version "26.1" 1595 :package-version '(Org . "8.3") 1596 :type '(choice (const :tag "Disable" nil) 1597 (list :tag "Enable" 1598 (list :tag "Width of viewport" 1599 (const :format " " width) 1600 (choice (const :tag "unset" "") 1601 (string))) 1602 (list :tag "Initial scale" 1603 (const :format " " initial-scale) 1604 (choice (const :tag "unset" "") 1605 (string))) 1606 (list :tag "Minimum scale/zoom" 1607 (const :format " " minimum-scale) 1608 (choice (const :tag "unset" "") 1609 (string))) 1610 (list :tag "Maximum scale/zoom" 1611 (const :format " " maximum-scale) 1612 (choice (const :tag "unset" "") 1613 (string))) 1614 (list :tag "User scalable/zoomable" 1615 (const :format " " user-scalable) 1616 (choice (const :tag "unset" "") 1617 (const "true") 1618 (const "false")))))) 1619 1620 ;; Handle source code blocks with Klipse 1621 1622 (defcustom org-html-klipsify-src nil 1623 "When non-nil, source code blocks are editable in exported presentation." 1624 :group 'org-export-html 1625 :package-version '(Org . "9.1") 1626 :type 'boolean) 1627 1628 (defcustom org-html-klipse-css 1629 "https://storage.googleapis.com/app.klipse.tech/css/codemirror.css" 1630 "Location of the codemirror CSS file for use with klipse." 1631 :group 'org-export-html 1632 :package-version '(Org . "9.1") 1633 :type 'string) 1634 1635 (defcustom org-html-klipse-js 1636 "https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js" 1637 "Location of the klipse javascript file." 1638 :group 'org-export-html 1639 :type 'string) 1640 1641 (defcustom org-html-klipse-selection-script 1642 "window.klipse_settings = {selector_eval_html: '.src-html', 1643 selector_eval_js: '.src-js', 1644 selector_eval_python_client: '.src-python', 1645 selector_eval_scheme: '.src-scheme', 1646 selector: '.src-clojure', 1647 selector_eval_ruby: '.src-ruby'};" 1648 "Javascript snippet to activate klipse." 1649 :group 'org-export-html 1650 :package-version '(Org . "9.1") 1651 :type 'string) 1652 1653 1654 ;;;; Todos 1655 1656 (defcustom org-html-todo-kwd-class-prefix "" 1657 "Prefix to class names for TODO keywords. 1658 Each TODO keyword gets a class given by the keyword itself, with this prefix. 1659 The default prefix is empty because it is nice to just use the keyword 1660 as a class name. But if you get into conflicts with other, existing 1661 CSS classes, then this prefix can be very useful." 1662 :group 'org-export-html 1663 :type 'string) 1664 1665 1666 ;;; Internal Functions 1667 1668 (defun org-html-xhtml-p (info) 1669 (let ((dt (downcase (plist-get info :html-doctype)))) 1670 (string-match-p "xhtml" dt))) 1671 1672 (defun org-html-html5-p (info) 1673 (let ((dt (downcase (plist-get info :html-doctype)))) 1674 (member dt '("html5" "xhtml5" "<!doctype html>")))) 1675 1676 (defun org-html--html5-fancy-p (info) 1677 "Non-nil when exporting to HTML5 with fancy elements. 1678 INFO is the current state of the export process, as a plist." 1679 (and (plist-get info :html-html5-fancy) 1680 (org-html-html5-p info))) 1681 1682 (defun org-html-close-tag (tag attr info) 1683 "Return close-tag for string TAG. 1684 ATTR specifies additional attributes. INFO is a property list 1685 containing current export state." 1686 (concat "<" tag 1687 (org-string-nw-p (concat " " attr)) 1688 (if (org-html-xhtml-p info) " />" ">"))) 1689 1690 (defun org-html-doctype (info) 1691 "Return correct HTML doctype tag. 1692 INFO is a plist used as a communication channel. Doctype tag is 1693 extracted from `org-html-doctype-alist', or the literal value 1694 of :html-doctype from INFO if :html-doctype is not found in the 1695 alist." 1696 (let ((dt (plist-get info :html-doctype))) 1697 (or (cdr (assoc dt org-html-doctype-alist)) dt))) 1698 1699 (defun org-html--make-attribute-string (attributes) 1700 "Return a list of attributes, as a string. 1701 ATTRIBUTES is a plist where values are either strings or nil. An 1702 attribute with a nil value will be omitted from the result." 1703 (let (output) 1704 (dolist (item attributes (mapconcat 'identity (nreverse output) " ")) 1705 (cond ((null item) (pop output)) 1706 ((symbolp item) (push (substring (symbol-name item) 1) output)) 1707 (t (let ((key (car output)) 1708 (value (replace-regexp-in-string 1709 "\"" """ (org-html-encode-plain-text item)))) 1710 (setcar output (format "%s=\"%s\"" key value)))))))) 1711 1712 (defun org-html--reference (datum info &optional named-only) 1713 "Return an appropriate reference for DATUM. 1714 1715 DATUM is an element or a `target' type object. INFO is the 1716 current export state, as a plist. 1717 1718 When NAMED-ONLY is non-nil and DATUM has no NAME keyword, return 1719 nil. This doesn't apply to headlines, inline tasks, radio 1720 targets and targets." 1721 (let* ((type (org-element-type datum)) 1722 (user-label 1723 (org-element-property 1724 (pcase type 1725 ((or `headline `inlinetask) :CUSTOM_ID) 1726 ((or `radio-target `target) :value) 1727 (_ :name)) 1728 datum))) 1729 (cond 1730 ((and user-label 1731 (or (plist-get info :html-prefer-user-labels) 1732 ;; Used CUSTOM_ID property unconditionally. 1733 (memq type '(headline inlinetask)))) 1734 user-label) 1735 ((and named-only 1736 (not (memq type '(headline inlinetask radio-target target))) 1737 (not user-label)) 1738 nil) 1739 (t 1740 (org-export-get-reference datum info))))) 1741 1742 (defun org-html--wrap-image (contents info &optional caption label) 1743 "Wrap CONTENTS string within an appropriate environment for images. 1744 INFO is a plist used as a communication channel. When optional 1745 arguments CAPTION and LABEL are given, use them for caption and 1746 \"id\" attribute." 1747 (let ((html5-fancy (org-html--html5-fancy-p info))) 1748 (format (if html5-fancy "\n<figure%s>\n%s%s\n</figure>" 1749 "\n<div%s class=\"figure\">\n%s%s\n</div>") 1750 ;; ID. 1751 (if (org-string-nw-p label) (format " id=\"%s\"" label) "") 1752 ;; Contents. 1753 (if html5-fancy contents (format "<p>%s</p>" contents)) 1754 ;; Caption. 1755 (if (not (org-string-nw-p caption)) "" 1756 (format (if html5-fancy "\n<figcaption>%s</figcaption>" 1757 "\n<p>%s</p>") 1758 caption))))) 1759 1760 (defun org-html--format-image (source attributes info) 1761 "Return \"img\" tag with given SOURCE and ATTRIBUTES. 1762 SOURCE is a string specifying the location of the image. 1763 ATTRIBUTES is a plist, as returned by 1764 `org-export-read-attribute'. INFO is a plist used as 1765 a communication channel." 1766 (org-html-close-tag 1767 "img" 1768 (org-html--make-attribute-string 1769 (org-combine-plists 1770 (list :src source 1771 :alt (if (string-match-p 1772 (concat "^" org-preview-latex-image-directory) source) 1773 (org-html-encode-plain-text 1774 (org-find-text-property-in-string 'org-latex-src source)) 1775 (file-name-nondirectory source))) 1776 (if (string= "svg" (file-name-extension source)) 1777 (org-combine-plists '(:class "org-svg") attributes '(:fallback nil)) 1778 attributes))) 1779 info)) 1780 1781 (defun org-html--textarea-block (element) 1782 "Transcode ELEMENT into a textarea block. 1783 ELEMENT is either a source or an example block." 1784 (let* ((code (car (org-export-unravel-code element))) 1785 (attr (org-export-read-attribute :attr_html element))) 1786 (format "<p>\n<textarea cols=\"%s\" rows=\"%s\">\n%s</textarea>\n</p>" 1787 (or (plist-get attr :width) 80) 1788 (or (plist-get attr :height) (org-count-lines code)) 1789 code))) 1790 1791 (defun org-html--has-caption-p (element &optional _info) 1792 "Non-nil when ELEMENT has a caption affiliated keyword. 1793 INFO is a plist used as a communication channel. This function 1794 is meant to be used as a predicate for `org-export-get-ordinal' or 1795 a value to `org-html-standalone-image-predicate'." 1796 (org-element-property :caption element)) 1797 1798 ;;;; Table 1799 1800 (defun org-html-htmlize-region-for-paste (beg end) 1801 "Convert the region between BEG and END to HTML, using htmlize.el. 1802 This is much like `htmlize-region-for-paste', only that it uses 1803 the settings define in the org-... variables." 1804 (let* ((htmlize-output-type org-html-htmlize-output-type) 1805 (htmlize-css-name-prefix org-html-htmlize-font-prefix) 1806 (htmlbuf (htmlize-region beg end))) 1807 (unwind-protect 1808 (with-current-buffer htmlbuf 1809 (buffer-substring (plist-get htmlize-buffer-places 'content-start) 1810 (plist-get htmlize-buffer-places 'content-end))) 1811 (kill-buffer htmlbuf)))) 1812 1813 ;;;###autoload 1814 (defun org-html-htmlize-generate-css () 1815 "Create the CSS for all font definitions in the current Emacs session. 1816 Use this to create face definitions in your CSS style file that can then 1817 be used by code snippets transformed by htmlize. 1818 This command just produces a buffer that contains class definitions for all 1819 faces used in the current Emacs session. You can copy and paste the ones you 1820 need into your CSS file. 1821 1822 If you then set `org-html-htmlize-output-type' to `css', calls 1823 to the function `org-html-htmlize-region-for-paste' will 1824 produce code that uses these same face definitions." 1825 (interactive) 1826 (unless (require 'htmlize nil t) 1827 (error "htmlize library missing. Aborting")) 1828 (and (get-buffer "*html*") (kill-buffer "*html*")) 1829 (with-temp-buffer 1830 (let ((fl (face-list)) 1831 (htmlize-css-name-prefix "org-") 1832 (htmlize-output-type 'css) 1833 f i) 1834 (while (setq f (pop fl) 1835 i (and f (face-attribute f :inherit))) 1836 (when (and (symbolp f) (or (not i) (not (listp i)))) 1837 (insert (org-add-props (copy-sequence "1") nil 'face f)))) 1838 (htmlize-region (point-min) (point-max)))) 1839 (pop-to-buffer-same-window "*html*") 1840 (goto-char (point-min)) 1841 (when (re-search-forward "<style" nil t) 1842 (delete-region (point-min) (match-beginning 0))) 1843 (when (re-search-forward "</style>" nil t) 1844 (delete-region (1+ (match-end 0)) (point-max))) 1845 (beginning-of-line 1) 1846 (when (looking-at " +") (replace-match "")) 1847 (goto-char (point-min))) 1848 1849 (defun org-html--make-string (n string) 1850 "Build a string by concatenating N times STRING." 1851 (let (out) (dotimes (_ n out) (setq out (concat string out))))) 1852 1853 (defun org-html-fix-class-name (kwd) ; audit callers of this function 1854 "Turn todo keyword KWD into a valid class name. 1855 Replaces invalid characters with \"_\"." 1856 (replace-regexp-in-string "[^a-zA-Z0-9_]" "_" kwd nil t)) 1857 1858 (defun org-html-footnote-section (info) 1859 "Format the footnote section. 1860 INFO is a plist used as a communication channel." 1861 (pcase (org-export-collect-footnote-definitions info) 1862 (`nil nil) 1863 (definitions 1864 (format 1865 (plist-get info :html-footnotes-section) 1866 (org-html--translate "Footnotes" info) 1867 (format 1868 "\n%s\n" 1869 (mapconcat 1870 (lambda (definition) 1871 (pcase definition 1872 (`(,n ,_ ,def) 1873 ;; `org-export-collect-footnote-definitions' can return 1874 ;; two kinds of footnote definitions: inline and blocks. 1875 ;; Since this should not make any difference in the HTML 1876 ;; output, we wrap the inline definitions within 1877 ;; a "footpara" class paragraph. 1878 (let ((inline? (not (org-element-map def org-element-all-elements 1879 #'identity nil t))) 1880 (anchor (org-html--anchor 1881 (format "fn.%d" n) 1882 n 1883 (format " class=\"footnum\" href=\"#fnr.%d\" role=\"doc-backlink\"" n) 1884 info)) 1885 (contents (org-trim (org-export-data def info)))) 1886 (format "<div class=\"footdef\">%s %s</div>\n" 1887 (format (plist-get info :html-footnote-format) anchor) 1888 (format "<div class=\"footpara\" role=\"doc-footnote\">%s</div>" 1889 (if (not inline?) contents 1890 (format "<p class=\"footpara\">%s</p>" 1891 contents)))))))) 1892 definitions 1893 "\n")))))) 1894 1895 1896 ;;; Template 1897 1898 (defun org-html-meta-tags-default (info) 1899 "A default value for `org-html-meta-tags'. 1900 1901 Generate a list items, each of which is a list of arguments that can 1902 be passed to `org-html--build-meta-entry', to generate meta tags to be 1903 included in the HTML head. 1904 1905 Use document's plist INFO to derive relevant information for the tags." 1906 (let ((author (and (plist-get info :with-author) 1907 (let ((auth (plist-get info :author))) 1908 ;; Return raw Org syntax. 1909 (and auth (org-element-interpret-data auth)))))) 1910 (list 1911 (when (org-string-nw-p author) 1912 (list "name" "author" author)) 1913 (when (org-string-nw-p (plist-get info :description)) 1914 (list "name" "description" 1915 (plist-get info :description))) 1916 (when (org-string-nw-p (plist-get info :keywords)) 1917 (list "name" "keywords" (plist-get info :keywords))) 1918 '("name" "generator" "Org Mode")))) 1919 1920 (defun org-html--build-meta-entry 1921 (label identity &optional content-format &rest content-formatters) 1922 "Build a meta tag using the provided information. 1923 1924 Construct <meta> tag of form <meta LABEL=\"IDENTITY\" />, or when CONTENT-FORMAT 1925 is present: <meta LABEL=\"IDENTITY\" content=\"{content}\" /> 1926 1927 Here {content} is determined by applying any CONTENT-FORMATTERS to the 1928 CONTENT-FORMAT and encoding the result as plain text." 1929 (concat "<meta " 1930 (format "%s=\"%s" label identity) 1931 (when content-format 1932 (concat "\" content=\"" 1933 (replace-regexp-in-string 1934 "\"" """ 1935 (org-html-encode-plain-text 1936 (if content-formatters 1937 (apply #'format content-format content-formatters) 1938 content-format))))) 1939 "\" />\n")) 1940 1941 (defun org-html--build-meta-info (info) 1942 "Return meta tags for exported document. 1943 INFO is a plist used as a communication channel." 1944 (let* ((title (org-html-plain-text 1945 (org-element-interpret-data (plist-get info :title)) info)) 1946 ;; Set title to an invisible character instead of leaving it 1947 ;; empty, which is invalid. 1948 (title (if (org-string-nw-p title) title "‎")) 1949 (charset (or (and org-html-coding-system 1950 (symbol-name 1951 (coding-system-get org-html-coding-system 1952 'mime-charset))) 1953 "iso-8859-1"))) 1954 (concat 1955 (when (plist-get info :time-stamp-file) 1956 (format-time-string 1957 (concat "<!-- " 1958 (plist-get info :html-metadata-timestamp-format) 1959 " -->\n"))) 1960 1961 (if (org-html-html5-p info) 1962 (org-html--build-meta-entry "charset" charset) 1963 (org-html--build-meta-entry "http-equiv" "Content-Type" 1964 (concat "text/html;charset=" charset))) 1965 1966 (let ((viewport-options 1967 (cl-remove-if-not (lambda (cell) (org-string-nw-p (cadr cell))) 1968 (plist-get info :html-viewport)))) 1969 (if viewport-options 1970 (org-html--build-meta-entry "name" "viewport" 1971 (mapconcat 1972 (lambda (elm) 1973 (format "%s=%s" (car elm) (cadr elm))) 1974 viewport-options ", ")))) 1975 1976 (format "<title>%s</title>\n" title) 1977 1978 (mapconcat 1979 (lambda (args) (apply #'org-html--build-meta-entry args)) 1980 (delq nil (if (functionp org-html-meta-tags) 1981 (funcall org-html-meta-tags info) 1982 org-html-meta-tags)) 1983 "")))) 1984 1985 (defun org-html--build-head (info) 1986 "Return information for the <head>..</head> of the HTML output. 1987 INFO is a plist used as a communication channel." 1988 (org-element-normalize-string 1989 (concat 1990 (when (plist-get info :html-head-include-default-style) 1991 (org-element-normalize-string org-html-style-default)) 1992 (org-element-normalize-string (plist-get info :html-head)) 1993 (org-element-normalize-string (plist-get info :html-head-extra)) 1994 (when (and (plist-get info :html-htmlized-css-url) 1995 (eq org-html-htmlize-output-type 'css)) 1996 (org-html-close-tag "link" 1997 (format "rel=\"stylesheet\" href=\"%s\" type=\"text/css\"" 1998 (plist-get info :html-htmlized-css-url)) 1999 info)) 2000 (when (plist-get info :html-head-include-scripts) org-html-scripts)))) 2001 2002 (defun org-html--build-mathjax-config (info) 2003 "Insert the user setup into the mathjax template. 2004 INFO is a plist used as a communication channel." 2005 (when (and (memq (plist-get info :with-latex) '(mathjax t)) 2006 (org-element-map (plist-get info :parse-tree) 2007 '(latex-fragment latex-environment) #'identity info t nil t)) 2008 (let ((template (plist-get info :html-mathjax-template)) 2009 (options (let ((options (plist-get info :html-mathjax-options))) 2010 ;; If the user customized some legacy option, set 2011 ;; the corresponding new option to nil, so that 2012 ;; the legacy user choice overrides the default. 2013 ;; Otherwise, the user did not set the legacy 2014 ;; option, in which case still set the legacy 2015 ;; option but to no value, so that the code can 2016 ;; find its in-buffer value, if set. 2017 `((,(if (plist-member options 'autonumber) 2018 'tags 'autonumber) 2019 nil) 2020 (,(if (plist-member options 'linebreaks) 2021 'overflow 'linebreaks) 2022 nil) 2023 ,@options))) 2024 (in-buffer (or (plist-get info :html-mathjax) ""))) 2025 (dolist (e options (org-element-normalize-string template)) 2026 (let ((symbol (car e)) 2027 (value (nth 1 e))) 2028 (when (string-match (concat "\\<" (symbol-name symbol) ":") 2029 in-buffer) 2030 (setq value 2031 (car (split-string (substring in-buffer 2032 (match-end 0)))))) 2033 (when value 2034 (pcase symbol 2035 (`font 2036 (when-let 2037 ((value-new 2038 (pcase value 2039 ("TeX" "mathjax-tex") 2040 ("STIX-Web" "mathjax-stix2") 2041 ("Asana-Math" "mathjax-asana") 2042 ("Neo-Euler" "mathjax-euler") 2043 ("Gyre-Pagella" "mathjax-pagella") 2044 ("Gyre-Termes" "mathjax-termes") 2045 ("Latin-Modern" "mathjax-modern")))) 2046 (setq value value-new))) 2047 (`linebreaks 2048 (org-display-warning 2049 "Converting legacy MathJax option: linebreaks") 2050 (setq symbol 'overflow 2051 value (if (string= value "true") 2052 "linebreak" 2053 "overflow"))) 2054 (`scale 2055 (when (stringp value) 2056 (let ((value-maybe (string-to-number value))) 2057 (setq value 2058 (if (= value-maybe 0) 2059 (progn 2060 (org-display-warning 2061 (format "Non-numerical MathJax scale: %s" 2062 value)) 2063 1.0) 2064 value-maybe)))) 2065 (when (>= value 10) 2066 (setq value 2067 (let ((value-new (/ (float value) 100))) 2068 (org-display-warning 2069 (format "Converting legacy MathJax scale: %s to %s" 2070 value 2071 value-new)) 2072 value-new)))) 2073 (`autonumber 2074 (org-display-warning 2075 "Converting legacy MathJax option: autonumber") 2076 (setq symbol 'tags 2077 value (downcase value)))) 2078 (while (string-match (format "\\(%%%s\\)[^A-Z]" 2079 (upcase (symbol-name symbol))) 2080 template) 2081 (setq template 2082 (replace-match (format "%s" value) 2083 t 2084 t template 1))))))))) 2085 2086 (defun org-html-format-spec (info) 2087 "Return format specification for preamble and postamble. 2088 INFO is a plist used as a communication channel." 2089 (let ((timestamp-format (plist-get info :html-metadata-timestamp-format))) 2090 `((?t . ,(org-export-data (plist-get info :title) info)) 2091 (?s . ,(org-export-data (plist-get info :subtitle) info)) 2092 (?d . ,(org-export-data (org-export-get-date info timestamp-format) 2093 info)) 2094 (?T . ,(format-time-string timestamp-format)) 2095 (?a . ,(org-export-data (plist-get info :author) info)) 2096 (?e . ,(mapconcat 2097 (lambda (e) (format "<a href=\"mailto:%s\">%s</a>" e e)) 2098 (split-string (plist-get info :email) ",+ *") 2099 ", ")) 2100 (?c . ,(plist-get info :creator)) 2101 (?C . ,(let ((file (plist-get info :input-file))) 2102 (format-time-string timestamp-format 2103 (and file (file-attribute-modification-time 2104 (file-attributes file)))))) 2105 (?v . ,(or (plist-get info :html-validation-link) ""))))) 2106 2107 (defun org-html--build-pre/postamble (type info) 2108 "Return document preamble or postamble as a string, or nil. 2109 TYPE is either `preamble' or `postamble', INFO is a plist used as a 2110 communication channel." 2111 (let ((section (plist-get info (intern (format ":html-%s" type)))) 2112 (spec (org-html-format-spec info))) 2113 (when section 2114 (let ((section-contents 2115 (if (functionp section) (funcall section info) 2116 (cond 2117 ((stringp section) (format-spec section spec)) 2118 ((and (eq section 'auto) (eq type 'postamble)) 2119 (let ((date (cdr (assq ?d spec))) 2120 (author (cdr (assq ?a spec))) 2121 (email (cdr (assq ?e spec))) 2122 (creator (cdr (assq ?c spec))) 2123 (validation-link (cdr (assq ?v spec)))) 2124 (concat 2125 (and (plist-get info :with-date) 2126 (org-string-nw-p date) 2127 (format "<p class=\"date\">%s: %s</p>\n" 2128 (org-html--translate "Date" info) 2129 date)) 2130 (and (plist-get info :with-author) 2131 (org-string-nw-p author) 2132 (format "<p class=\"author\">%s: %s</p>\n" 2133 (org-html--translate "Author" info) 2134 author)) 2135 (and (plist-get info :with-email) 2136 (org-string-nw-p email) 2137 (format "<p class=\"email\">%s: %s</p>\n" 2138 (org-html--translate "Email" info) 2139 email)) 2140 (and (plist-get info :time-stamp-file) 2141 (format 2142 "<p class=\"date\">%s: %s</p>\n" 2143 (org-html--translate "Created" info) 2144 (format-time-string 2145 (plist-get info :html-metadata-timestamp-format)))) 2146 (and (plist-get info :with-creator) 2147 (org-string-nw-p creator) 2148 (format "<p class=\"creator\">%s</p>\n" creator)) 2149 (and (org-string-nw-p validation-link) 2150 (format "<p class=\"validation\">%s</p>\n" 2151 validation-link))))) 2152 (t 2153 (let ((formats (plist-get info (if (eq type 'preamble) 2154 :html-preamble-format 2155 :html-postamble-format))) 2156 (language (plist-get info :language))) 2157 (format-spec 2158 (cadr (or (assoc-string language formats t) 2159 (assoc-string "en" formats t))) 2160 spec))))))) 2161 (let ((div (assq type (plist-get info :html-divs)))) 2162 (when (org-string-nw-p section-contents) 2163 (concat 2164 (format "<%s id=\"%s\" class=\"%s\">\n" 2165 (nth 1 div) 2166 (nth 2 div) 2167 org-html--pre/postamble-class) 2168 (org-element-normalize-string section-contents) 2169 (format "</%s>\n" (nth 1 div))))))))) 2170 2171 (defun org-html-inner-template (contents info) 2172 "Return body of document string after HTML conversion. 2173 CONTENTS is the transcoded contents string. INFO is a plist 2174 holding export options." 2175 (concat 2176 ;; Table of contents. 2177 (let ((depth (plist-get info :with-toc))) 2178 (when depth (org-html-toc depth info))) 2179 ;; Document contents. 2180 contents 2181 ;; Footnotes section. 2182 (org-html-footnote-section info))) 2183 2184 (defun org-html-template (contents info) 2185 "Return complete document string after HTML conversion. 2186 CONTENTS is the transcoded contents string. INFO is a plist 2187 holding export options." 2188 (concat 2189 (when (and (not (org-html-html5-p info)) (org-html-xhtml-p info)) 2190 (let* ((xml-declaration (plist-get info :html-xml-declaration)) 2191 (decl (or (and (stringp xml-declaration) xml-declaration) 2192 (cdr (assoc (plist-get info :html-extension) 2193 xml-declaration)) 2194 (cdr (assoc "html" xml-declaration)) 2195 ""))) 2196 (when (not (or (not decl) (string= "" decl))) 2197 (format "%s\n" 2198 (format decl 2199 (or (and org-html-coding-system 2200 ;; FIXME: Use Emacs 22 style here, see `coding-system-get'. 2201 (coding-system-get org-html-coding-system 'mime-charset)) 2202 "iso-8859-1")))))) 2203 (org-html-doctype info) 2204 "\n" 2205 (concat "<html" 2206 (cond ((org-html-xhtml-p info) 2207 (format 2208 " xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"" 2209 (plist-get info :language) (plist-get info :language))) 2210 ((org-html-html5-p info) 2211 (format " lang=\"%s\"" (plist-get info :language)))) 2212 ">\n") 2213 "<head>\n" 2214 (org-html--build-meta-info info) 2215 (org-html--build-head info) 2216 (org-html--build-mathjax-config info) 2217 "</head>\n" 2218 "<body>\n" 2219 (let ((link-up (org-trim (plist-get info :html-link-up))) 2220 (link-home (org-trim (plist-get info :html-link-home)))) 2221 (unless (and (string= link-up "") (string= link-home "")) 2222 (format (plist-get info :html-home/up-format) 2223 (or link-up link-home) 2224 (or link-home link-up)))) 2225 ;; Preamble. 2226 (org-html--build-pre/postamble 'preamble info) 2227 ;; Document contents. 2228 (let ((div (assq 'content (plist-get info :html-divs)))) 2229 (format "<%s id=\"%s\" class=\"%s\">\n" 2230 (nth 1 div) 2231 (nth 2 div) 2232 (plist-get info :html-content-class))) 2233 ;; Document title. 2234 (when (plist-get info :with-title) 2235 (let ((title (and (plist-get info :with-title) 2236 (plist-get info :title))) 2237 (subtitle (plist-get info :subtitle)) 2238 (html5-fancy (org-html--html5-fancy-p info))) 2239 (when title 2240 (format 2241 (if html5-fancy 2242 "<header>\n<h1 class=\"title\">%s</h1>\n%s</header>" 2243 "<h1 class=\"title\">%s%s</h1>\n") 2244 (org-export-data title info) 2245 (if subtitle 2246 (format 2247 (if html5-fancy 2248 "<p class=\"subtitle\" role=\"doc-subtitle\">%s</p>\n" 2249 (concat "\n" (org-html-close-tag "br" nil info) "\n" 2250 "<span class=\"subtitle\">%s</span>\n")) 2251 (org-export-data subtitle info)) 2252 ""))))) 2253 contents 2254 (format "</%s>\n" (nth 1 (assq 'content (plist-get info :html-divs)))) 2255 ;; Postamble. 2256 (org-html--build-pre/postamble 'postamble info) 2257 ;; Possibly use the Klipse library live code blocks. 2258 (when (plist-get info :html-klipsify-src) 2259 (concat "<script>" (plist-get info :html-klipse-selection-script) 2260 "</script><script src=\"" 2261 org-html-klipse-js 2262 "\"></script><link rel=\"stylesheet\" type=\"text/css\" href=\"" 2263 org-html-klipse-css "\"/>")) 2264 ;; Closing document. 2265 "</body>\n</html>")) 2266 2267 (defun org-html--translate (s info) 2268 "Translate string S according to specified language. 2269 INFO is a plist used as a communication channel." 2270 (org-export-translate s :html info)) 2271 2272 ;;;; Anchor 2273 2274 (defun org-html--anchor (id desc attributes info) 2275 "Format a HTML anchor." 2276 (let* ((name (and (plist-get info :html-allow-name-attribute-in-anchors) id)) 2277 (attributes (concat (and id (format " id=\"%s\"" id)) 2278 (and name (format " name=\"%s\"" name)) 2279 attributes))) 2280 (format "<a%s>%s</a>" attributes (or desc "")))) 2281 2282 ;;;; Todo 2283 2284 (defun org-html--todo (todo info) 2285 "Format TODO keywords into HTML." 2286 (when todo 2287 (format "<span class=\"%s %s%s\">%s</span>" 2288 (if (member todo org-done-keywords) "done" "todo") 2289 (or (plist-get info :html-todo-kwd-class-prefix) "") 2290 (org-html-fix-class-name todo) 2291 todo))) 2292 2293 ;;;; Priority 2294 2295 (defun org-html--priority (priority _info) 2296 "Format a priority into HTML. 2297 PRIORITY is the character code of the priority or nil. INFO is 2298 a plist containing export options." 2299 (and priority (format "<span class=\"priority\">[%c]</span>" priority))) 2300 2301 ;;;; Tags 2302 2303 (defun org-html--tags (tags info) 2304 "Format TAGS into HTML. 2305 INFO is a plist containing export options." 2306 (when tags 2307 (format "<span class=\"tag\">%s</span>" 2308 (mapconcat 2309 (lambda (tag) 2310 (format "<span class=\"%s\">%s</span>" 2311 (concat (plist-get info :html-tag-class-prefix) 2312 (org-html-fix-class-name tag)) 2313 tag)) 2314 tags " ")))) 2315 2316 ;;;; Src Code 2317 2318 (defun org-html-fontify-code (code lang) 2319 "Color CODE with htmlize library. 2320 CODE is a string representing the source code to colorize. LANG 2321 is the language used for CODE, as a string, or nil." 2322 (when code 2323 (cond 2324 ;; No language. Possibly an example block. 2325 ((not lang) (org-html-encode-plain-text code)) 2326 ;; Plain text explicitly set. 2327 ((not org-html-htmlize-output-type) (org-html-encode-plain-text code)) 2328 ;; No htmlize library or an inferior version of htmlize. 2329 ((not (progn (require 'htmlize nil t) 2330 (fboundp 'htmlize-region-for-paste))) 2331 ;; Emit a warning. 2332 (message "Cannot fontify source block (htmlize.el >= 1.34 required)") 2333 (org-html-encode-plain-text code)) 2334 (t 2335 ;; Map language 2336 (setq lang (or (assoc-default lang org-src-lang-modes) lang)) 2337 (let* ((lang-mode (and lang (intern (format "%s-mode" lang))))) 2338 (cond 2339 ;; Case 1: Language is not associated with any Emacs mode 2340 ((not (functionp lang-mode)) 2341 (org-html-encode-plain-text code)) 2342 ;; Case 2: Default. Fontify code. 2343 (t 2344 ;; htmlize 2345 (setq code 2346 (let ((output-type org-html-htmlize-output-type) 2347 (font-prefix org-html-htmlize-font-prefix) 2348 (inhibit-read-only t)) 2349 (with-temp-buffer 2350 ;; Switch to language-specific mode. 2351 (funcall lang-mode) 2352 (insert code) 2353 ;; Fontify buffer. 2354 (font-lock-ensure) 2355 ;; Remove formatting on newline characters. 2356 (save-excursion 2357 (let ((beg (point-min)) 2358 (end (point-max))) 2359 (goto-char beg) 2360 (while (progn (end-of-line) (< (point) end)) 2361 (put-text-property (point) (1+ (point)) 'face nil) 2362 (forward-char 1)))) 2363 (org-src-mode) 2364 (set-buffer-modified-p nil) 2365 ;; Htmlize region. 2366 (let ((org-html-htmlize-output-type output-type) 2367 (org-html-htmlize-font-prefix font-prefix)) 2368 (org-html-htmlize-region-for-paste 2369 (point-min) (point-max)))))) 2370 ;; Strip any enclosing <pre></pre> tags. 2371 (let* ((beg (and (string-match "\\`<pre[^>]*>\n?" code) (match-end 0))) 2372 (end (and beg (string-match "</pre>\\'" code)))) 2373 (if (and beg end) (substring code beg end) code))))))))) 2374 2375 (defun org-html-do-format-code 2376 (code &optional lang refs retain-labels num-start wrap-lines) 2377 "Format CODE string as source code. 2378 Optional arguments LANG, REFS, RETAIN-LABELS, NUM-START, WRAP-LINES 2379 are, respectively, the language of the source code, as a string, an 2380 alist between line numbers and references (as returned by 2381 `org-export-unravel-code'), a boolean specifying if labels should 2382 appear in the source code, the number associated to the first 2383 line of code, and a boolean specifying if lines of code should be 2384 wrapped in code elements." 2385 (let* ((code-lines (split-string code "\n")) 2386 (code-length (length code-lines)) 2387 (num-fmt 2388 (and num-start 2389 (format "%%%ds: " 2390 (length (number-to-string (+ code-length num-start)))))) 2391 (code (org-html-fontify-code code lang))) 2392 (org-export-format-code 2393 code 2394 (lambda (loc line-num ref) 2395 (setq loc 2396 (concat 2397 ;; Add line number, if needed. 2398 (when num-start 2399 (format "<span class=\"linenr\">%s</span>" 2400 (format num-fmt line-num))) 2401 ;; Transcoded src line. 2402 (if wrap-lines 2403 (format "<code%s>%s</code>" 2404 (if num-start 2405 (format " data-ox-html-linenr=\"%s\"" line-num) 2406 "") 2407 loc) 2408 loc) 2409 ;; Add label, if needed. 2410 (when (and ref retain-labels) (format " (%s)" ref)))) 2411 ;; Mark transcoded line as an anchor, if needed. 2412 (if (not ref) loc 2413 (format "<span id=\"coderef-%s\" class=\"coderef-off\">%s</span>" 2414 ref loc))) 2415 num-start refs))) 2416 2417 (defun org-html-format-code (element info) 2418 "Format contents of ELEMENT as source code. 2419 ELEMENT is either an example or a source block. INFO is a plist 2420 used as a communication channel." 2421 (let* ((lang (org-element-property :language element)) 2422 ;; Extract code and references. 2423 (code-info (org-export-unravel-code element)) 2424 (code (car code-info)) 2425 (refs (cdr code-info)) 2426 ;; Does the source block contain labels? 2427 (retain-labels (org-element-property :retain-labels element)) 2428 ;; Does it have line numbers? 2429 (num-start (org-export-get-loc element info)) 2430 ;; Should lines be wrapped in code elements? 2431 (wrap-lines (plist-get info :html-wrap-src-lines))) 2432 (org-html-do-format-code code lang refs retain-labels num-start wrap-lines))) 2433 2434 2435 ;;; Tables of Contents 2436 2437 (defun org-html-toc (depth info &optional scope) 2438 "Build a table of contents. 2439 DEPTH is an integer specifying the depth of the table. INFO is 2440 a plist used as a communication channel. Optional argument SCOPE 2441 is an element defining the scope of the table. Return the table 2442 of contents as a string, or nil if it is empty." 2443 (let ((toc-entries 2444 (mapcar (lambda (headline) 2445 (cons (org-html--format-toc-headline headline info) 2446 (org-export-get-relative-level headline info))) 2447 (org-export-collect-headlines info depth scope)))) 2448 (when toc-entries 2449 (let ((toc (concat "<div id=\"text-table-of-contents\" role=\"doc-toc\">" 2450 (org-html--toc-text toc-entries) 2451 "</div>\n"))) 2452 (if scope toc 2453 (let ((outer-tag (if (org-html--html5-fancy-p info) 2454 "nav" 2455 "div"))) 2456 (concat (format "<%s id=\"table-of-contents\" role=\"doc-toc\">\n" outer-tag) 2457 (let ((top-level (plist-get info :html-toplevel-hlevel))) 2458 (format "<h%d>%s</h%d>\n" 2459 top-level 2460 (org-html--translate "Table of Contents" info) 2461 top-level)) 2462 toc 2463 (format "</%s>\n" outer-tag)))))))) 2464 2465 (defun org-html--toc-text (toc-entries) 2466 "Return innards of a table of contents, as a string. 2467 TOC-ENTRIES is an alist where key is an entry title, as a string, 2468 and value is its relative level, as an integer." 2469 (let* ((prev-level (1- (cdar toc-entries))) 2470 (start-level prev-level)) 2471 (concat 2472 (mapconcat 2473 (lambda (entry) 2474 (let ((headline (car entry)) 2475 (level (cdr entry))) 2476 (concat 2477 (let* ((cnt (- level prev-level)) 2478 (times (if (> cnt 0) (1- cnt) (- cnt)))) 2479 (setq prev-level level) 2480 (concat 2481 (org-html--make-string 2482 times (cond ((> cnt 0) "\n<ul>\n<li>") 2483 ((< cnt 0) "</li>\n</ul>\n"))) 2484 (if (> cnt 0) "\n<ul>\n<li>" "</li>\n<li>"))) 2485 headline))) 2486 toc-entries "") 2487 (org-html--make-string (- prev-level start-level) "</li>\n</ul>\n")))) 2488 2489 (defun org-html--format-toc-headline (headline info) 2490 "Return an appropriate table of contents entry for HEADLINE. 2491 INFO is a plist used as a communication channel." 2492 (let* ((headline-number (org-export-get-headline-number headline info)) 2493 (todo (and (plist-get info :with-todo-keywords) 2494 (let ((todo (org-element-property :todo-keyword headline))) 2495 (and todo (org-export-data todo info))))) 2496 (todo-type (and todo (org-element-property :todo-type headline))) 2497 (priority (and (plist-get info :with-priority) 2498 (org-element-property :priority headline))) 2499 (text (org-export-data-with-backend 2500 (org-export-get-alt-title headline info) 2501 (org-export-toc-entry-backend 'html) 2502 info)) 2503 (tags (and (eq (plist-get info :with-tags) t) 2504 (org-export-get-tags headline info)))) 2505 (format "<a href=\"#%s\">%s</a>" 2506 ;; Label. 2507 (org-html--reference headline info) 2508 ;; Body. 2509 (concat 2510 (and (not (org-export-low-level-p headline info)) 2511 (org-export-numbered-headline-p headline info) 2512 (concat (mapconcat #'number-to-string headline-number ".") 2513 ". ")) 2514 (apply (plist-get info :html-format-headline-function) 2515 todo todo-type priority text tags :section-number nil))))) 2516 2517 (defun org-html-list-of-listings (info) 2518 "Build a list of listings. 2519 INFO is a plist used as a communication channel. Return the list 2520 of listings as a string, or nil if it is empty." 2521 (let ((lol-entries (org-export-collect-listings info))) 2522 (when lol-entries 2523 (concat "<div id=\"list-of-listings\">\n" 2524 (let ((top-level (plist-get info :html-toplevel-hlevel))) 2525 (format "<h%d>%s</h%d>\n" 2526 top-level 2527 (org-html--translate "List of Listings" info) 2528 top-level)) 2529 "<div id=\"text-list-of-listings\">\n<ul>\n" 2530 (let ((count 0) 2531 (initial-fmt (format "<span class=\"listing-number\">%s</span>" 2532 (org-html--translate "Listing %d:" info)))) 2533 (mapconcat 2534 (lambda (entry) 2535 (let ((label (org-html--reference entry info t)) 2536 (title (org-trim 2537 (org-export-data 2538 (or (org-export-get-caption entry t) 2539 (org-export-get-caption entry)) 2540 info)))) 2541 (concat 2542 "<li>" 2543 (if (not label) 2544 (concat (format initial-fmt (cl-incf count)) 2545 " " 2546 title) 2547 (format "<a href=\"#%s\">%s %s</a>" 2548 label 2549 (format initial-fmt (cl-incf count)) 2550 title)) 2551 "</li>"))) 2552 lol-entries "\n")) 2553 "\n</ul>\n</div>\n</div>")))) 2554 2555 (defun org-html-list-of-tables (info) 2556 "Build a list of tables. 2557 INFO is a plist used as a communication channel. Return the list 2558 of tables as a string, or nil if it is empty." 2559 (let ((lol-entries (org-export-collect-tables info))) 2560 (when lol-entries 2561 (concat "<div id=\"list-of-tables\">\n" 2562 (let ((top-level (plist-get info :html-toplevel-hlevel))) 2563 (format "<h%d>%s</h%d>\n" 2564 top-level 2565 (org-html--translate "List of Tables" info) 2566 top-level)) 2567 "<div id=\"text-list-of-tables\">\n<ul>\n" 2568 (let ((count 0) 2569 (initial-fmt (format "<span class=\"table-number\">%s</span>" 2570 (org-html--translate "Table %d:" info)))) 2571 (mapconcat 2572 (lambda (entry) 2573 (let ((label (org-html--reference entry info t)) 2574 (title (org-trim 2575 (org-export-data 2576 (or (org-export-get-caption entry t) 2577 (org-export-get-caption entry)) 2578 info)))) 2579 (concat 2580 "<li>" 2581 (if (not label) 2582 (concat (format initial-fmt (cl-incf count)) 2583 " " 2584 title) 2585 (format "<a href=\"#%s\">%s %s</a>" 2586 label 2587 (format initial-fmt (cl-incf count)) 2588 title)) 2589 "</li>"))) 2590 lol-entries "\n")) 2591 "\n</ul>\n</div>\n</div>")))) 2592 2593 2594 ;;; Transcode Functions 2595 2596 ;;;; Bold 2597 2598 (defun org-html-bold (_bold contents info) 2599 "Transcode BOLD from Org to HTML. 2600 CONTENTS is the text with bold markup. INFO is a plist holding 2601 contextual information." 2602 (format (or (cdr (assq 'bold (plist-get info :html-text-markup-alist))) "%s") 2603 contents)) 2604 2605 ;;;; Center Block 2606 2607 (defun org-html-center-block (_center-block contents _info) 2608 "Transcode a CENTER-BLOCK element from Org to HTML. 2609 CONTENTS holds the contents of the block. INFO is a plist 2610 holding contextual information." 2611 (format "<div class=\"org-center\">\n%s</div>" contents)) 2612 2613 ;;;; Clock 2614 2615 (defun org-html-clock (clock _contents _info) 2616 "Transcode a CLOCK element from Org to HTML. 2617 CONTENTS is nil. INFO is a plist used as a communication 2618 channel." 2619 (format "<p> 2620 <span class=\"timestamp-wrapper\"> 2621 <span class=\"timestamp-kwd\">%s</span> <span class=\"timestamp\">%s</span>%s 2622 </span> 2623 </p>" 2624 org-clock-string 2625 (org-timestamp-translate (org-element-property :value clock)) 2626 (let ((time (org-element-property :duration clock))) 2627 (and time (format " <span class=\"timestamp\">(%s)</span>" time))))) 2628 2629 ;;;; Code 2630 2631 (defun org-html-code (code _contents info) 2632 "Transcode CODE from Org to HTML. 2633 CONTENTS is nil. INFO is a plist holding contextual 2634 information." 2635 (format (or (cdr (assq 'code (plist-get info :html-text-markup-alist))) "%s") 2636 (org-html-encode-plain-text (org-element-property :value code)))) 2637 2638 ;;;; Drawer 2639 2640 (defun org-html-drawer (drawer contents info) 2641 "Transcode a DRAWER element from Org to HTML. 2642 CONTENTS holds the contents of the block. INFO is a plist 2643 holding contextual information." 2644 (funcall (plist-get info :html-format-drawer-function) 2645 (org-element-property :drawer-name drawer) 2646 contents)) 2647 2648 ;;;; Dynamic Block 2649 2650 (defun org-html-dynamic-block (_dynamic-block contents _info) 2651 "Transcode a DYNAMIC-BLOCK element from Org to HTML. 2652 CONTENTS holds the contents of the block. INFO is a plist 2653 holding contextual information. See `org-export-data'." 2654 contents) 2655 2656 ;;;; Entity 2657 2658 (defun org-html-entity (entity _contents _info) 2659 "Transcode an ENTITY object from Org to HTML. 2660 CONTENTS are the definition itself. INFO is a plist holding 2661 contextual information." 2662 (org-element-property :html entity)) 2663 2664 ;;;; Example Block 2665 2666 (defun org-html-example-block (example-block _contents info) 2667 "Transcode a EXAMPLE-BLOCK element from Org to HTML. 2668 CONTENTS is nil. INFO is a plist holding contextual 2669 information." 2670 (let ((attributes (org-export-read-attribute :attr_html example-block))) 2671 (if (plist-get attributes :textarea) 2672 (org-html--textarea-block example-block) 2673 (format "<pre class=\"example\"%s>\n%s</pre>" 2674 (let* ((reference (org-html--reference example-block info)) 2675 (a (org-html--make-attribute-string 2676 (if (or (not reference) (plist-member attributes :id)) 2677 attributes 2678 (plist-put attributes :id reference))))) 2679 (if (org-string-nw-p a) (concat " " a) "")) 2680 (org-html-format-code example-block info))))) 2681 2682 ;;;; Export Snippet 2683 2684 (defun org-html-export-snippet (export-snippet _contents _info) 2685 "Transcode a EXPORT-SNIPPET object from Org to HTML. 2686 CONTENTS is nil. INFO is a plist holding contextual 2687 information." 2688 (when (eq (org-export-snippet-backend export-snippet) 'html) 2689 (org-element-property :value export-snippet))) 2690 2691 ;;;; Export Block 2692 2693 (defun org-html-export-block (export-block _contents _info) 2694 "Transcode a EXPORT-BLOCK element from Org to HTML. 2695 CONTENTS is nil. INFO is a plist holding contextual information." 2696 (when (string= (org-element-property :type export-block) "HTML") 2697 (org-remove-indentation (org-element-property :value export-block)))) 2698 2699 ;;;; Fixed Width 2700 2701 (defun org-html-fixed-width (fixed-width _contents _info) 2702 "Transcode a FIXED-WIDTH element from Org to HTML. 2703 CONTENTS is nil. INFO is a plist holding contextual information." 2704 (format "<pre class=\"example\">\n%s</pre>" 2705 (org-html-do-format-code 2706 (org-remove-indentation 2707 (org-element-property :value fixed-width))))) 2708 2709 ;;;; Footnote Reference 2710 2711 (defun org-html-footnote-reference (footnote-reference _contents info) 2712 "Transcode a FOOTNOTE-REFERENCE element from Org to HTML. 2713 CONTENTS is nil. INFO is a plist holding contextual information." 2714 (concat 2715 ;; Insert separator between two footnotes in a row. 2716 (let ((prev (org-export-get-previous-element footnote-reference info))) 2717 (when (eq (org-element-type prev) 'footnote-reference) 2718 (plist-get info :html-footnote-separator))) 2719 (let* ((n (org-export-get-footnote-number footnote-reference info)) 2720 (id (format "fnr.%d%s" 2721 n 2722 (if (org-export-footnote-first-reference-p 2723 footnote-reference info) 2724 "" 2725 ".100")))) 2726 (format 2727 (plist-get info :html-footnote-format) 2728 (org-html--anchor 2729 id n (format " class=\"footref\" href=\"#fn.%d\" role=\"doc-backlink\"" n) info))))) 2730 2731 ;;;; Headline 2732 2733 (defun org-html-headline (headline contents info) 2734 "Transcode a HEADLINE element from Org to HTML. 2735 CONTENTS holds the contents of the headline. INFO is a plist 2736 holding contextual information." 2737 (unless (org-element-property :footnote-section-p headline) 2738 (let* ((numberedp (org-export-numbered-headline-p headline info)) 2739 (numbers (org-export-get-headline-number headline info)) 2740 (level (+ (org-export-get-relative-level headline info) 2741 (1- (plist-get info :html-toplevel-hlevel)))) 2742 (todo (and (plist-get info :with-todo-keywords) 2743 (let ((todo (org-element-property :todo-keyword headline))) 2744 (and todo (org-export-data todo info))))) 2745 (todo-type (and todo (org-element-property :todo-type headline))) 2746 (priority (and (plist-get info :with-priority) 2747 (org-element-property :priority headline))) 2748 (text (org-export-data (org-element-property :title headline) info)) 2749 (tags (and (plist-get info :with-tags) 2750 (org-export-get-tags headline info))) 2751 (full-text (funcall (plist-get info :html-format-headline-function) 2752 todo todo-type priority text tags info)) 2753 (contents (or contents "")) 2754 (id (org-html--reference headline info)) 2755 (formatted-text 2756 (if (plist-get info :html-self-link-headlines) 2757 (format "<a href=\"#%s\">%s</a>" id full-text) 2758 full-text))) 2759 (if (org-export-low-level-p headline info) 2760 ;; This is a deep sub-tree: export it as a list item. 2761 (let* ((html-type (if numberedp "ol" "ul"))) 2762 (concat 2763 (and (org-export-first-sibling-p headline info) 2764 (apply #'format "<%s class=\"org-%s\">\n" 2765 (make-list 2 html-type))) 2766 (org-html-format-list-item 2767 contents (if numberedp 'ordered 'unordered) 2768 nil info nil 2769 (concat (org-html--anchor id nil nil info) formatted-text)) "\n" 2770 (and (org-export-last-sibling-p headline info) 2771 (format "</%s>\n" html-type)))) 2772 ;; Standard headline. Export it as a section. 2773 (let ((extra-class 2774 (org-element-property :HTML_CONTAINER_CLASS headline)) 2775 (headline-class 2776 (org-element-property :HTML_HEADLINE_CLASS headline)) 2777 (first-content (car (org-element-contents headline)))) 2778 (format "<%s id=\"%s\" class=\"%s\">%s%s</%s>\n" 2779 (org-html--container headline info) 2780 (format "outline-container-%s" id) 2781 (concat (format "outline-%d" level) 2782 (and extra-class " ") 2783 extra-class) 2784 (format "\n<h%d id=\"%s\"%s>%s</h%d>\n" 2785 level 2786 id 2787 (if (not headline-class) "" 2788 (format " class=\"%s\"" headline-class)) 2789 (concat 2790 (and numberedp 2791 (format 2792 "<span class=\"section-number-%d\">%s</span> " 2793 level 2794 (concat (mapconcat #'number-to-string numbers ".") "."))) 2795 formatted-text) 2796 level) 2797 ;; When there is no section, pretend there is an 2798 ;; empty one to get the correct <div 2799 ;; class="outline-...> which is needed by 2800 ;; `org-info.js'. 2801 (if (eq (org-element-type first-content) 'section) contents 2802 (concat (org-html-section first-content "" info) contents)) 2803 (org-html--container headline info))))))) 2804 2805 (defun org-html-format-headline-default-function 2806 (todo _todo-type priority text tags info) 2807 "Default format function for a headline. 2808 See `org-html-format-headline-function' for details." 2809 (let ((todo (org-html--todo todo info)) 2810 (priority (org-html--priority priority info)) 2811 (tags (org-html--tags tags info))) 2812 (concat todo (and todo " ") 2813 priority (and priority " ") 2814 text 2815 (and tags "   ") tags))) 2816 2817 (defun org-html--container (headline info) 2818 (or (org-element-property :HTML_CONTAINER headline) 2819 (if (= 1 (org-export-get-relative-level headline info)) 2820 (plist-get info :html-container) 2821 "div"))) 2822 2823 ;;;; Horizontal Rule 2824 2825 (defun org-html-horizontal-rule (_horizontal-rule _contents info) 2826 "Transcode an HORIZONTAL-RULE object from Org to HTML. 2827 CONTENTS is nil. INFO is a plist holding contextual information." 2828 (org-html-close-tag "hr" nil info)) 2829 2830 ;;;; Inline Src Block 2831 2832 (defun org-html-inline-src-block (inline-src-block _contents info) 2833 "Transcode an INLINE-SRC-BLOCK element from Org to HTML. 2834 CONTENTS holds the contents of the item. INFO is a plist holding 2835 contextual information." 2836 (let* ((lang (org-element-property :language inline-src-block)) 2837 (code (org-html-fontify-code 2838 (org-element-property :value inline-src-block) 2839 lang)) 2840 (label 2841 (let ((lbl (org-html--reference inline-src-block info t))) 2842 (if (not lbl) "" (format " id=\"%s\"" lbl))))) 2843 (format "<code class=\"src src-%s\"%s>%s</code>" lang label code))) 2844 2845 ;;;; Inlinetask 2846 2847 (defun org-html-inlinetask (inlinetask contents info) 2848 "Transcode an INLINETASK element from Org to HTML. 2849 CONTENTS holds the contents of the block. INFO is a plist 2850 holding contextual information." 2851 (let* ((todo (and (plist-get info :with-todo-keywords) 2852 (let ((todo (org-element-property :todo-keyword inlinetask))) 2853 (and todo (org-export-data todo info))))) 2854 (todo-type (and todo (org-element-property :todo-type inlinetask))) 2855 (priority (and (plist-get info :with-priority) 2856 (org-element-property :priority inlinetask))) 2857 (text (org-export-data (org-element-property :title inlinetask) info)) 2858 (tags (and (plist-get info :with-tags) 2859 (org-export-get-tags inlinetask info)))) 2860 (funcall (plist-get info :html-format-inlinetask-function) 2861 todo todo-type priority text tags contents info))) 2862 2863 (defun org-html-format-inlinetask-default-function 2864 (todo todo-type priority text tags contents info) 2865 "Default format function for inlinetasks. 2866 See `org-html-format-inlinetask-function' for details." 2867 (format "<div class=\"inlinetask\">\n<b>%s</b>%s\n%s</div>" 2868 (org-html-format-headline-default-function 2869 todo todo-type priority text tags info) 2870 (org-html-close-tag "br" nil info) 2871 contents)) 2872 2873 ;;;; Italic 2874 2875 (defun org-html-italic (_italic contents info) 2876 "Transcode ITALIC from Org to HTML. 2877 CONTENTS is the text with italic markup. INFO is a plist holding 2878 contextual information." 2879 (format 2880 (or (cdr (assq 'italic (plist-get info :html-text-markup-alist))) "%s") 2881 contents)) 2882 2883 ;;;; Item 2884 2885 (defun org-html-checkbox (checkbox info) 2886 "Format CHECKBOX into HTML. 2887 INFO is a plist holding contextual information. See 2888 `org-html-checkbox-type' for customization options." 2889 (cdr (assq checkbox 2890 (cdr (assq (plist-get info :html-checkbox-type) 2891 org-html-checkbox-types))))) 2892 2893 (defun org-html-format-list-item (contents type checkbox info 2894 &optional term-counter-id 2895 headline) 2896 "Format a list item into HTML." 2897 (let ((class (if checkbox 2898 (format " class=\"%s\"" 2899 (symbol-name checkbox)) "")) 2900 (checkbox (concat (org-html-checkbox checkbox info) 2901 (and checkbox " "))) 2902 (br (org-html-close-tag "br" nil info)) 2903 (extra-newline (if (and (org-string-nw-p contents) headline) "\n" ""))) 2904 (concat 2905 (pcase type 2906 (`ordered 2907 (let* ((counter term-counter-id) 2908 (extra (if counter (format " value=\"%s\"" counter) ""))) 2909 (concat 2910 (format "<li%s%s>" class extra) 2911 (when headline (concat headline br))))) 2912 (`unordered 2913 (let* ((id term-counter-id) 2914 (extra (if id (format " id=\"%s\"" id) ""))) 2915 (concat 2916 (format "<li%s%s>" class extra) 2917 (when headline (concat headline br))))) 2918 (`descriptive 2919 (let* ((term term-counter-id)) 2920 (setq term (or term "(no term)")) 2921 ;; Check-boxes in descriptive lists are associated to tag. 2922 (concat (format "<dt%s>%s</dt>" 2923 class (concat checkbox term)) 2924 "<dd>")))) 2925 (unless (eq type 'descriptive) checkbox) 2926 extra-newline 2927 (and (org-string-nw-p contents) (org-trim contents)) 2928 extra-newline 2929 (pcase type 2930 (`ordered "</li>") 2931 (`unordered "</li>") 2932 (`descriptive "</dd>"))))) 2933 2934 (defun org-html-item (item contents info) 2935 "Transcode an ITEM element from Org to HTML. 2936 CONTENTS holds the contents of the item. INFO is a plist holding 2937 contextual information." 2938 (let* ((plain-list (org-export-get-parent item)) 2939 (type (org-element-property :type plain-list)) 2940 (counter (org-element-property :counter item)) 2941 (checkbox (org-element-property :checkbox item)) 2942 (tag (let ((tag (org-element-property :tag item))) 2943 (and tag (org-export-data tag info))))) 2944 (org-html-format-list-item 2945 contents type checkbox info (or tag counter)))) 2946 2947 ;;;; Keyword 2948 2949 (defun org-html-keyword (keyword _contents info) 2950 "Transcode a KEYWORD element from Org to HTML. 2951 CONTENTS is nil. INFO is a plist holding contextual information." 2952 (let ((key (org-element-property :key keyword)) 2953 (value (org-element-property :value keyword))) 2954 (cond 2955 ((string= key "HTML") value) 2956 ((string= key "TOC") 2957 (let ((case-fold-search t)) 2958 (cond 2959 ((string-match "\\<headlines\\>" value) 2960 (let ((depth (and (string-match "\\<[0-9]+\\>" value) 2961 (string-to-number (match-string 0 value)))) 2962 (scope 2963 (cond 2964 ((string-match ":target +\\(\".+?\"\\|\\S-+\\)" value) ;link 2965 (org-export-resolve-link 2966 (org-strip-quotes (match-string 1 value)) info)) 2967 ((string-match-p "\\<local\\>" value) keyword)))) ;local 2968 (org-html-toc depth info scope))) 2969 ((string= "listings" value) (org-html-list-of-listings info)) 2970 ((string= "tables" value) (org-html-list-of-tables info)))))))) 2971 2972 ;;;; Latex Environment 2973 2974 (defun org-html-format-latex (latex-frag processing-type info) 2975 "Format a LaTeX fragment LATEX-FRAG into HTML. 2976 PROCESSING-TYPE designates the tool used for conversion. It can 2977 be `mathjax', `verbatim', `html', nil, t or symbols in 2978 `org-preview-latex-process-alist', e.g., `dvipng', `dvisvgm' or 2979 `imagemagick'. See `org-html-with-latex' for more information. 2980 INFO is a plist containing export properties." 2981 (let ((cache-relpath "") (cache-dir "")) 2982 (unless (or (eq processing-type 'mathjax) 2983 (eq processing-type 'html)) 2984 (let ((bfn (or (buffer-file-name) 2985 (make-temp-name 2986 (expand-file-name "latex" temporary-file-directory)))) 2987 (latex-header 2988 (let ((header (plist-get info :latex-header))) 2989 (and header 2990 (concat (mapconcat 2991 (lambda (line) (concat "#+LATEX_HEADER: " line)) 2992 (org-split-string header "\n") 2993 "\n") 2994 "\n"))))) 2995 (setq cache-relpath 2996 (concat (file-name-as-directory org-preview-latex-image-directory) 2997 (file-name-sans-extension 2998 (file-name-nondirectory bfn))) 2999 cache-dir (file-name-directory bfn)) 3000 ;; Re-create LaTeX environment from original buffer in 3001 ;; temporary buffer so that dvipng/imagemagick can properly 3002 ;; turn the fragment into an image. 3003 (setq latex-frag (concat latex-header latex-frag)))) 3004 (org-export-with-buffer-copy 3005 :to-buffer (get-buffer-create " *Org HTML Export LaTeX*") 3006 :drop-visibility t :drop-narrowing t :drop-contents t 3007 (erase-buffer) 3008 (insert latex-frag) 3009 (org-format-latex cache-relpath nil nil cache-dir nil 3010 "Creating LaTeX Image..." nil processing-type) 3011 (buffer-string)))) 3012 3013 (defun org-html--wrap-latex-environment (contents _ &optional caption label) 3014 "Wrap CONTENTS string within appropriate environment for equations. 3015 When optional arguments CAPTION and LABEL are given, use them for 3016 caption and \"id\" attribute." 3017 (format "\n<div%s class=\"equation-container\">\n%s%s\n</div>" 3018 ;; ID. 3019 (if (org-string-nw-p label) (format " id=\"%s\"" label) "") 3020 ;; Contents. 3021 (format "<span class=\"equation\">\n%s\n</span>" contents) 3022 ;; Caption. 3023 (if (not (org-string-nw-p caption)) "" 3024 (format "\n<span class=\"equation-label\">\n%s\n</span>" 3025 caption)))) 3026 3027 (defun org-html--math-environment-p (element &optional _) 3028 "Non-nil when ELEMENT is a LaTeX math environment. 3029 Math environments match the regular expression defined in 3030 `org-latex-math-environments-re'. This function is meant to be 3031 used as a predicate for `org-export-get-ordinal' or a value to 3032 `org-html-standalone-image-predicate'." 3033 (string-match-p org-latex-math-environments-re 3034 (org-element-property :value element))) 3035 3036 (defun org-html--latex-environment-numbered-p (element) 3037 "Non-nil when ELEMENT contains a numbered LaTeX math environment. 3038 Starred and \"displaymath\" environments are not numbered." 3039 (not (string-match-p "\\`[ \t]*\\\\begin{\\(.*\\*\\|displaymath\\)}" 3040 (org-element-property :value element)))) 3041 3042 (defun org-html--unlabel-latex-environment (latex-frag) 3043 "Change environment in LATEX-FRAG string to an unnumbered one. 3044 For instance, change an `equation' environment to `equation*'." 3045 (replace-regexp-in-string 3046 "\\`[ \t]*\\\\begin{\\([^*]+?\\)}" 3047 "\\1*" 3048 (replace-regexp-in-string "^[ \t]*\\\\end{\\([^*]+?\\)}[ \r\t\n]*\\'" 3049 "\\1*" 3050 latex-frag nil nil 1) 3051 nil nil 1)) 3052 3053 (defun org-html-latex-environment (latex-environment _contents info) 3054 "Transcode a LATEX-ENVIRONMENT element from Org to HTML. 3055 CONTENTS is nil. INFO is a plist holding contextual information." 3056 (let ((processing-type (plist-get info :with-latex)) 3057 (latex-frag (org-remove-indentation 3058 (org-element-property :value latex-environment))) 3059 (attributes (org-export-read-attribute :attr_html latex-environment)) 3060 (label (org-html--reference latex-environment info t)) 3061 (caption (and (org-html--latex-environment-numbered-p latex-environment) 3062 (number-to-string 3063 (org-export-get-ordinal 3064 latex-environment info nil 3065 (lambda (l _) 3066 (and (org-html--math-environment-p l) 3067 (org-html--latex-environment-numbered-p l)))))))) 3068 (cond 3069 ((memq processing-type '(t mathjax)) 3070 (org-html-format-latex 3071 (if (org-string-nw-p label) 3072 (replace-regexp-in-string "\\`.*" 3073 (format "\\&\n\\\\label{%s}" label) 3074 latex-frag) 3075 latex-frag) 3076 'mathjax info)) 3077 ((assq processing-type org-preview-latex-process-alist) 3078 (let ((formula-link 3079 (org-html-format-latex 3080 (org-html--unlabel-latex-environment latex-frag) 3081 processing-type info))) 3082 (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) 3083 (let ((source (org-export-file-uri (match-string 1 formula-link)))) 3084 (org-html--wrap-latex-environment 3085 (org-html--format-image source attributes info) 3086 info caption label))))) 3087 (t (org-html--wrap-latex-environment latex-frag info caption label))))) 3088 3089 ;;;; Latex Fragment 3090 3091 (defun org-html-latex-fragment (latex-fragment _contents info) 3092 "Transcode a LATEX-FRAGMENT object from Org to HTML. 3093 CONTENTS is nil. INFO is a plist holding contextual information." 3094 (let ((latex-frag (org-element-property :value latex-fragment)) 3095 (processing-type (plist-get info :with-latex))) 3096 (cond 3097 ((memq processing-type '(t mathjax)) 3098 (org-html-format-latex latex-frag 'mathjax info)) 3099 ((memq processing-type '(t html)) 3100 (org-html-format-latex latex-frag 'html info)) 3101 ((assq processing-type org-preview-latex-process-alist) 3102 (let ((formula-link 3103 (org-html-format-latex latex-frag processing-type info))) 3104 (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) 3105 (let ((source (org-export-file-uri (match-string 1 formula-link)))) 3106 (org-html--format-image source nil info))))) 3107 (t latex-frag)))) 3108 3109 ;;;; Line Break 3110 3111 (defun org-html-line-break (_line-break _contents info) 3112 "Transcode a LINE-BREAK object from Org to HTML. 3113 CONTENTS is nil. INFO is a plist holding contextual information." 3114 (concat (org-html-close-tag "br" nil info) "\n")) 3115 3116 ;;;; Link 3117 3118 (defun org-html-image-link-filter (data _backend info) 3119 (org-export-insert-image-links data info org-html-inline-image-rules)) 3120 3121 (defun org-html-inline-image-p (link info) 3122 "Non-nil when LINK is meant to appear as an image. 3123 INFO is a plist used as a communication channel. LINK is an 3124 inline image when it has no description and targets an image 3125 file (see `org-html-inline-image-rules' for more information), or 3126 if its description is a single link targeting an image file." 3127 (if (not (org-element-contents link)) 3128 (org-export-inline-image-p 3129 link (plist-get info :html-inline-image-rules)) 3130 (not 3131 (let ((link-count 0)) 3132 (org-element-map (org-element-contents link) 3133 (cons 'plain-text org-element-all-objects) 3134 (lambda (obj) 3135 (pcase (org-element-type obj) 3136 (`plain-text (org-string-nw-p obj)) 3137 (`link (if (= link-count 1) t 3138 (cl-incf link-count) 3139 (not (org-export-inline-image-p 3140 obj (plist-get info :html-inline-image-rules))))) 3141 (_ t))) 3142 info t))))) 3143 3144 (defvar org-html-standalone-image-predicate) 3145 (defun org-html-standalone-image-p (element info) 3146 "Non-nil if ELEMENT is a standalone image. 3147 3148 INFO is a plist holding contextual information. 3149 3150 An element or object is a standalone image when 3151 3152 - its type is `paragraph' and its sole content, save for white 3153 spaces, is a link that qualifies as an inline image; 3154 3155 - its type is `link' and its containing paragraph has no other 3156 content save white spaces. 3157 3158 Bind `org-html-standalone-image-predicate' to constrain paragraph 3159 further. For example, to check for only captioned standalone 3160 images, set it to: 3161 3162 (lambda (paragraph) (org-element-property :caption paragraph))" 3163 (let ((paragraph (pcase (org-element-type element) 3164 (`paragraph element) 3165 (`link (org-export-get-parent element))))) 3166 (and (eq (org-element-type paragraph) 'paragraph) 3167 (or (not (and (boundp 'org-html-standalone-image-predicate) 3168 (fboundp org-html-standalone-image-predicate))) 3169 (funcall org-html-standalone-image-predicate paragraph)) 3170 (catch 'exit 3171 (let ((link-count 0)) 3172 (org-element-map (org-element-contents paragraph) 3173 (cons 'plain-text org-element-all-objects) 3174 (lambda (obj) 3175 (when (pcase (org-element-type obj) 3176 (`plain-text (org-string-nw-p obj)) 3177 (`link (or (> (cl-incf link-count) 1) 3178 (not (org-html-inline-image-p obj info)))) 3179 (_ t)) 3180 (throw 'exit nil))) 3181 info nil 'link) 3182 (= link-count 1)))))) 3183 3184 (defun org-html-link (link desc info) 3185 "Transcode a LINK object from Org to HTML. 3186 DESC is the description part of the link, or the empty string. 3187 INFO is a plist holding contextual information. See 3188 `org-export-data'." 3189 (let* ((html-ext (plist-get info :html-extension)) 3190 (dot (when (> (length html-ext) 0) ".")) 3191 (link-org-files-as-html-maybe 3192 (lambda (raw-path info) 3193 ;; Treat links to `file.org' as links to `file.html', if 3194 ;; needed. See `org-html-link-org-files-as-html'. 3195 (save-match-data 3196 (cond 3197 ((and (plist-get info :html-link-org-files-as-html) 3198 (let ((case-fold-search t)) 3199 (string-match "\\(.+\\)\\.org\\(?:\\.gpg\\)?$" raw-path))) 3200 (concat (match-string 1 raw-path) dot html-ext)) 3201 (t raw-path))))) 3202 (type (org-element-property :type link)) 3203 (raw-path (org-element-property :path link)) 3204 ;; Ensure DESC really exists, or set it to nil. 3205 (desc (org-string-nw-p desc)) 3206 (path 3207 (cond 3208 ((member type '("http" "https" "ftp" "mailto" "news")) 3209 (url-encode-url (concat type ":" raw-path))) 3210 ((string= "file" type) 3211 ;; During publishing, turn absolute file names belonging 3212 ;; to base directory into relative file names. Otherwise, 3213 ;; append "file" protocol to absolute file name. 3214 (setq raw-path 3215 (org-export-file-uri 3216 (org-publish-file-relative-name raw-path info))) 3217 ;; Possibly append `:html-link-home' to relative file 3218 ;; name. 3219 (let ((home (and (plist-get info :html-link-home) 3220 (org-trim (plist-get info :html-link-home))))) 3221 (when (and home 3222 (plist-get info :html-link-use-abs-url) 3223 (file-name-absolute-p raw-path)) 3224 (setq raw-path (concat (file-name-as-directory home) raw-path)))) 3225 ;; Maybe turn ".org" into ".html". 3226 (setq raw-path (funcall link-org-files-as-html-maybe raw-path info)) 3227 ;; Add search option, if any. A search option can be 3228 ;; relative to a custom-id, a headline title, a name or 3229 ;; a target. 3230 (let ((option (org-element-property :search-option link))) 3231 (if (not option) raw-path 3232 (let ((path (org-element-property :path link))) 3233 (concat raw-path 3234 "#" 3235 (org-publish-resolve-external-link option path t)))))) 3236 (t raw-path))) 3237 (attributes-plist 3238 (org-combine-plists 3239 ;; Extract attributes from parent's paragraph. HACK: Only 3240 ;; do this for the first link in parent (inner image link 3241 ;; for inline images). This is needed as long as 3242 ;; attributes cannot be set on a per link basis. 3243 (let* ((parent (org-export-get-parent-element link)) 3244 (link (let ((container (org-export-get-parent link))) 3245 (if (and (eq 'link (org-element-type container)) 3246 (org-html-inline-image-p link info)) 3247 container 3248 link)))) 3249 (and (eq link (org-element-map parent 'link #'identity info t)) 3250 (org-export-read-attribute :attr_html parent))) 3251 ;; Also add attributes from link itself. Currently, those 3252 ;; need to be added programmatically before `org-html-link' 3253 ;; is invoked, for example, by backends building upon HTML 3254 ;; export. 3255 (org-export-read-attribute :attr_html link))) 3256 (attributes 3257 (let ((attr (org-html--make-attribute-string attributes-plist))) 3258 (if (org-string-nw-p attr) (concat " " attr) "")))) 3259 (cond 3260 ;; Link type is handled by a special function. 3261 ((org-export-custom-protocol-maybe link desc 'html info)) 3262 ;; Image file. 3263 ((and (plist-get info :html-inline-images) 3264 (org-export-inline-image-p 3265 link (plist-get info :html-inline-image-rules))) 3266 (org-html--format-image path attributes-plist info)) 3267 ;; Radio target: Transcode target's contents and use them as 3268 ;; link's description. 3269 ((string= type "radio") 3270 (let ((destination (org-export-resolve-radio-link link info))) 3271 (if (not destination) desc 3272 (format "<a href=\"#%s\"%s>%s</a>" 3273 (org-export-get-reference destination info) 3274 attributes 3275 desc)))) 3276 ;; Links pointing to a headline: Find destination and build 3277 ;; appropriate referencing command. 3278 ((member type '("custom-id" "fuzzy" "id")) 3279 (let ((destination (if (string= type "fuzzy") 3280 (org-export-resolve-fuzzy-link link info) 3281 (org-export-resolve-id-link link info)))) 3282 (pcase (org-element-type destination) 3283 ;; ID link points to an external file. 3284 (`plain-text 3285 (let ((fragment (concat "ID-" path)) 3286 ;; Treat links to ".org" files as ".html", if needed. 3287 (path (funcall link-org-files-as-html-maybe 3288 destination info))) 3289 (format "<a href=\"%s#%s\"%s>%s</a>" 3290 path fragment attributes (or desc destination)))) 3291 ;; Fuzzy link points nowhere. 3292 (`nil 3293 (format "<i>%s</i>" 3294 (or desc 3295 (org-export-data 3296 (org-element-property :raw-link link) info)))) 3297 ;; Link points to a headline. 3298 (`headline 3299 (let ((href (org-html--reference destination info)) 3300 ;; What description to use? 3301 (desc 3302 ;; Case 1: Headline is numbered and LINK has no 3303 ;; description. Display section number. 3304 (if (and (org-export-numbered-headline-p destination info) 3305 (not desc)) 3306 (mapconcat #'number-to-string 3307 (org-export-get-headline-number 3308 destination info) ".") 3309 ;; Case 2: Either the headline is un-numbered or 3310 ;; LINK has a custom description. Display LINK's 3311 ;; description or headline's title. 3312 (or desc 3313 (org-export-data 3314 (org-element-property :title destination) info))))) 3315 (format "<a href=\"#%s\"%s>%s</a>" href attributes desc))) 3316 ;; Fuzzy link points to a target or an element. 3317 (_ 3318 (if (and destination 3319 (memq (plist-get info :with-latex) '(mathjax t)) 3320 (eq 'latex-environment (org-element-type destination)) 3321 (eq 'math (org-latex--environment-type destination))) 3322 ;; Caption and labels are introduced within LaTeX 3323 ;; environment. Use "ref" or "eqref" macro, depending on user 3324 ;; preference to refer to those in the document. 3325 (format (plist-get info :html-equation-reference-format) 3326 (org-html--reference destination info)) 3327 (let* ((ref (org-html--reference destination info)) 3328 (org-html-standalone-image-predicate 3329 #'org-html--has-caption-p) 3330 (counter-predicate 3331 (if (eq 'latex-environment (org-element-type destination)) 3332 #'org-html--math-environment-p 3333 #'org-html--has-caption-p)) 3334 (number 3335 (cond 3336 (desc nil) 3337 ((org-html-standalone-image-p destination info) 3338 (org-export-get-ordinal 3339 (org-element-map destination 'link #'identity info t) 3340 info '(link) 'org-html-standalone-image-p)) 3341 (t (org-export-get-ordinal 3342 destination info nil counter-predicate)))) 3343 (desc 3344 (cond (desc) 3345 ((not number) "No description for this link") 3346 ((numberp number) (number-to-string number)) 3347 (t (mapconcat #'number-to-string number "."))))) 3348 (format "<a href=\"#%s\"%s>%s</a>" ref attributes desc))))))) 3349 ;; Coderef: replace link with the reference name or the 3350 ;; equivalent line number. 3351 ((string= type "coderef") 3352 (let ((fragment (concat "coderef-" (org-html-encode-plain-text path)))) 3353 (format "<a href=\"#%s\" %s%s>%s</a>" 3354 fragment 3355 (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, \ 3356 '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\"" 3357 fragment fragment) 3358 attributes 3359 (format (org-export-get-coderef-format path desc) 3360 (org-export-resolve-coderef path info))))) 3361 ;; External link with a description part. 3362 ((and path desc) 3363 (format "<a href=\"%s\"%s>%s</a>" 3364 (org-html-encode-plain-text path) 3365 attributes 3366 desc)) 3367 ;; External link without a description part. 3368 (path 3369 (let ((path (org-html-encode-plain-text path))) 3370 (format "<a href=\"%s\"%s>%s</a>" path attributes path))) 3371 ;; No path, only description. Try to do something useful. 3372 (t 3373 (format "<i>%s</i>" desc))))) 3374 3375 ;;;; Node Property 3376 3377 (defun org-html-node-property (node-property _contents _info) 3378 "Transcode a NODE-PROPERTY element from Org to HTML. 3379 CONTENTS is nil. INFO is a plist holding contextual 3380 information." 3381 (format "%s:%s" 3382 (org-element-property :key node-property) 3383 (let ((value (org-element-property :value node-property))) 3384 (if value (concat " " value) "")))) 3385 3386 ;;;; Paragraph 3387 3388 (defun org-html-paragraph (paragraph contents info) 3389 "Transcode a PARAGRAPH element from Org to HTML. 3390 CONTENTS is the contents of the paragraph, as a string. INFO is 3391 the plist used as a communication channel." 3392 (let* ((parent (org-export-get-parent paragraph)) 3393 (parent-type (org-element-type parent)) 3394 (style '((footnote-definition " class=\"footpara\"") 3395 (org-data " class=\"footpara\""))) 3396 (attributes (org-html--make-attribute-string 3397 (org-export-read-attribute :attr_html paragraph))) 3398 (extra (or (cadr (assq parent-type style)) ""))) 3399 (cond 3400 ((and (eq parent-type 'item) 3401 (not (org-export-get-previous-element paragraph info)) 3402 (let ((followers (org-export-get-next-element paragraph info 2))) 3403 (and (not (cdr followers)) 3404 (memq (org-element-type (car followers)) '(nil plain-list))))) 3405 ;; First paragraph in an item has no tag if it is alone or 3406 ;; followed, at most, by a sub-list. 3407 contents) 3408 ((org-html-standalone-image-p paragraph info) 3409 ;; Standalone image. 3410 (let ((caption 3411 (let ((raw (org-export-data 3412 (org-export-get-caption paragraph) info)) 3413 (org-html-standalone-image-predicate 3414 #'org-html--has-caption-p)) 3415 (if (not (org-string-nw-p raw)) raw 3416 (concat "<span class=\"figure-number\">" 3417 (format (org-html--translate "Figure %d:" info) 3418 (org-export-get-ordinal 3419 (org-element-map paragraph 'link 3420 #'identity info t) 3421 info nil #'org-html-standalone-image-p)) 3422 " </span>" 3423 raw)))) 3424 (label (org-html--reference paragraph info))) 3425 (org-html--wrap-image contents info caption label))) 3426 ;; Regular paragraph. 3427 (t (format "<p%s%s>\n%s</p>" 3428 (if (org-string-nw-p attributes) 3429 (concat " " attributes) "") 3430 extra contents))))) 3431 3432 ;;;; Plain List 3433 3434 (defun org-html-plain-list (plain-list contents _info) 3435 "Transcode a PLAIN-LIST element from Org to HTML. 3436 CONTENTS is the contents of the list. INFO is a plist holding 3437 contextual information." 3438 (let* ((type (pcase (org-element-property :type plain-list) 3439 (`ordered "ol") 3440 (`unordered "ul") 3441 (`descriptive "dl") 3442 (other (error "Unknown HTML list type: %s" other)))) 3443 (class (format "org-%s" type)) 3444 (attributes (org-export-read-attribute :attr_html plain-list))) 3445 (format "<%s %s>\n%s</%s>" 3446 type 3447 (org-html--make-attribute-string 3448 (plist-put attributes :class 3449 (org-trim 3450 (mapconcat #'identity 3451 (list class (plist-get attributes :class)) 3452 " ")))) 3453 contents 3454 type))) 3455 3456 ;;;; Plain Text 3457 3458 (defun org-html-convert-special-strings (string) 3459 "Convert special characters in STRING to HTML." 3460 (dolist (a org-html-special-string-regexps string) 3461 (let ((re (car a)) 3462 (rpl (cdr a))) 3463 (setq string (replace-regexp-in-string re rpl string t))))) 3464 3465 (defun org-html-encode-plain-text (text) 3466 "Convert plain text characters from TEXT to HTML equivalent. 3467 Possible conversions are set in `org-html-protect-char-alist'." 3468 (dolist (pair org-html-protect-char-alist text) 3469 (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t)))) 3470 3471 (defun org-html-plain-text (text info) 3472 "Transcode a TEXT string from Org to HTML. 3473 TEXT is the string to transcode. INFO is a plist holding 3474 contextual information." 3475 (let ((output text)) 3476 ;; Protect following characters: <, >, &. 3477 (setq output (org-html-encode-plain-text output)) 3478 ;; Handle smart quotes. Be sure to provide original string since 3479 ;; OUTPUT may have been modified. 3480 (when (plist-get info :with-smart-quotes) 3481 (setq output (org-export-activate-smart-quotes output :html info text))) 3482 ;; Handle special strings. 3483 (when (plist-get info :with-special-strings) 3484 (setq output (org-html-convert-special-strings output))) 3485 ;; Handle break preservation if required. 3486 (when (plist-get info :preserve-breaks) 3487 (setq output 3488 (replace-regexp-in-string 3489 "\\(\\\\\\\\\\)?[ \t]*\n" 3490 (concat (org-html-close-tag "br" nil info) "\n") output))) 3491 ;; Return value. 3492 output)) 3493 3494 3495 ;; Planning 3496 3497 (defun org-html-planning (planning _contents info) 3498 "Transcode a PLANNING element from Org to HTML. 3499 CONTENTS is nil. INFO is a plist used as a communication 3500 channel." 3501 (format 3502 "<p><span class=\"timestamp-wrapper\">%s</span></p>" 3503 (org-trim 3504 (mapconcat 3505 (lambda (pair) 3506 (let ((timestamp (cdr pair))) 3507 (when timestamp 3508 (let ((string (car pair))) 3509 (format "<span class=\"timestamp-kwd\">%s</span> \ 3510 <span class=\"timestamp\">%s</span> " 3511 string 3512 (org-html-plain-text (org-timestamp-translate timestamp) 3513 info)))))) 3514 `((,org-closed-string . ,(org-element-property :closed planning)) 3515 (,org-deadline-string . ,(org-element-property :deadline planning)) 3516 (,org-scheduled-string . ,(org-element-property :scheduled planning))) 3517 "")))) 3518 3519 ;;;; Property Drawer 3520 3521 (defun org-html-property-drawer (_property-drawer contents _info) 3522 "Transcode a PROPERTY-DRAWER element from Org to HTML. 3523 CONTENTS holds the contents of the drawer. INFO is a plist 3524 holding contextual information." 3525 (and (org-string-nw-p contents) 3526 (format "<pre class=\"example\">\n%s</pre>" contents))) 3527 3528 ;;;; Quote Block 3529 3530 (defun org-html-quote-block (quote-block contents info) 3531 "Transcode a QUOTE-BLOCK element from Org to HTML. 3532 CONTENTS holds the contents of the block. INFO is a plist 3533 holding contextual information." 3534 (format "<blockquote%s>\n%s</blockquote>" 3535 (let* ((reference (org-html--reference quote-block info t)) 3536 (attributes (org-export-read-attribute :attr_html quote-block)) 3537 (a (org-html--make-attribute-string 3538 (if (or (not reference) (plist-member attributes :id)) 3539 attributes 3540 (plist-put attributes :id reference))))) 3541 (if (org-string-nw-p a) (concat " " a) "")) 3542 contents)) 3543 3544 ;;;; Section 3545 3546 (defun org-html-section (section contents info) 3547 "Transcode a SECTION element from Org to HTML. 3548 CONTENTS holds the contents of the section. INFO is a plist 3549 holding contextual information." 3550 (let ((parent (org-export-get-parent-headline section))) 3551 ;; Before first headline: no container, just return CONTENTS. 3552 (if (not parent) contents 3553 ;; Get div's class and id references. 3554 (let* ((class-num (+ (org-export-get-relative-level parent info) 3555 (1- (plist-get info :html-toplevel-hlevel)))) 3556 (section-number 3557 (and (org-export-numbered-headline-p parent info) 3558 (mapconcat 3559 #'number-to-string 3560 (org-export-get-headline-number parent info) "-")))) 3561 ;; Build return value. 3562 (format "<div class=\"outline-text-%d\" id=\"text-%s\">\n%s</div>\n" 3563 class-num 3564 (or (org-element-property :CUSTOM_ID parent) 3565 section-number 3566 (org-export-get-reference parent info)) 3567 (or contents "")))))) 3568 3569 ;;;; Radio Target 3570 3571 (defun org-html-radio-target (radio-target text info) 3572 "Transcode a RADIO-TARGET object from Org to HTML. 3573 TEXT is the text of the target. INFO is a plist holding 3574 contextual information." 3575 (let ((ref (org-html--reference radio-target info))) 3576 (org-html--anchor ref text nil info))) 3577 3578 ;;;; Special Block 3579 3580 (defun org-html-special-block (special-block contents info) 3581 "Transcode a SPECIAL-BLOCK element from Org to HTML. 3582 CONTENTS holds the contents of the block. INFO is a plist 3583 holding contextual information." 3584 (let* ((block-type (org-element-property :type special-block)) 3585 (html5-fancy (and (org-html--html5-fancy-p info) 3586 (member block-type org-html-html5-elements))) 3587 (attributes (org-export-read-attribute :attr_html special-block))) 3588 (unless html5-fancy 3589 (let ((class (plist-get attributes :class))) 3590 (setq attributes (plist-put attributes :class 3591 (if class (concat class " " block-type) 3592 block-type))))) 3593 (let* ((contents (or contents "")) 3594 (reference (org-html--reference special-block info)) 3595 (a (org-html--make-attribute-string 3596 (if (or (not reference) (plist-member attributes :id)) 3597 attributes 3598 (plist-put attributes :id reference)))) 3599 (str (if (org-string-nw-p a) (concat " " a) ""))) 3600 (if html5-fancy 3601 (format "<%s%s>\n%s</%s>" block-type str contents block-type) 3602 (format "<div%s>\n%s\n</div>" str contents))))) 3603 3604 ;;;; Src Block 3605 3606 (defun org-html-src-block (src-block _contents info) 3607 "Transcode a SRC-BLOCK element from Org to HTML. 3608 CONTENTS holds the contents of the item. INFO is a plist holding 3609 contextual information." 3610 (if (org-export-read-attribute :attr_html src-block :textarea) 3611 (org-html--textarea-block src-block) 3612 (let* ((lang (org-element-property :language src-block)) 3613 (code (org-html-format-code src-block info)) 3614 (label (let ((lbl (org-html--reference src-block info t))) 3615 (if lbl (format " id=\"%s\"" lbl) ""))) 3616 (klipsify (and (plist-get info :html-klipsify-src) 3617 (member lang '("javascript" "js" 3618 "ruby" "scheme" "clojure" "php" "html"))))) 3619 (if (not lang) (format "<pre class=\"example\"%s>\n%s</pre>" label code) 3620 (format "<div class=\"org-src-container\">\n%s%s\n</div>" 3621 ;; Build caption. 3622 (let ((caption (org-export-get-caption src-block))) 3623 (if (not caption) "" 3624 (let ((listing-number 3625 (format 3626 "<span class=\"listing-number\">%s </span>" 3627 (format 3628 (org-html--translate "Listing %d:" info) 3629 (org-export-get-ordinal 3630 src-block info nil #'org-html--has-caption-p))))) 3631 (format "<label class=\"org-src-name\">%s%s</label>" 3632 listing-number 3633 (org-trim (org-export-data caption info)))))) 3634 ;; Contents. 3635 (if klipsify 3636 (format "<pre><code class=\"src src-%s\"%s%s>%s</code></pre>" 3637 lang 3638 label 3639 (if (string= lang "html") 3640 " data-editor-type=\"html\"" 3641 "") 3642 code) 3643 (format "<pre class=\"src src-%s\"%s>%s</pre>" 3644 lang label code))))))) 3645 3646 ;;;; Statistics Cookie 3647 3648 (defun org-html-statistics-cookie (statistics-cookie _contents _info) 3649 "Transcode a STATISTICS-COOKIE object from Org to HTML. 3650 CONTENTS is nil. INFO is a plist holding contextual information." 3651 (let ((cookie-value (org-element-property :value statistics-cookie))) 3652 (format "<code>%s</code>" cookie-value))) 3653 3654 ;;;; Strike-Through 3655 3656 (defun org-html-strike-through (_strike-through contents info) 3657 "Transcode STRIKE-THROUGH from Org to HTML. 3658 CONTENTS is the text with strike-through markup. INFO is a plist 3659 holding contextual information." 3660 (format 3661 (or (cdr (assq 'strike-through (plist-get info :html-text-markup-alist))) 3662 "%s") 3663 contents)) 3664 3665 ;;;; Subscript 3666 3667 (defun org-html-subscript (_subscript contents _info) 3668 "Transcode a SUBSCRIPT object from Org to HTML. 3669 CONTENTS is the contents of the object. INFO is a plist holding 3670 contextual information." 3671 (format "<sub>%s</sub>" contents)) 3672 3673 ;;;; Superscript 3674 3675 (defun org-html-superscript (_superscript contents _info) 3676 "Transcode a SUPERSCRIPT object from Org to HTML. 3677 CONTENTS is the contents of the object. INFO is a plist holding 3678 contextual information." 3679 (format "<sup>%s</sup>" contents)) 3680 3681 ;;;; Table Cell 3682 3683 (defun org-html-table-cell (table-cell contents info) 3684 "Transcode a TABLE-CELL element from Org to HTML. 3685 CONTENTS is nil. INFO is a plist used as a communication 3686 channel." 3687 (let* ((table-row (org-export-get-parent table-cell)) 3688 (table (org-export-get-parent-table table-cell)) 3689 (cell-attrs 3690 (if (not (plist-get info :html-table-align-individual-fields)) "" 3691 (format (if (and (boundp 'org-html-format-table-no-css) 3692 org-html-format-table-no-css) 3693 " align=\"%s\"" " class=\"org-%s\"") 3694 (org-export-table-cell-alignment table-cell info))))) 3695 (when (or (not contents) (string= "" (org-trim contents))) 3696 (setq contents " ")) 3697 (cond 3698 ((and (org-export-table-has-header-p table info) 3699 (= 1 (org-export-table-row-group table-row info))) 3700 (let ((header-tags (plist-get info :html-table-header-tags))) 3701 (concat "\n" (format (car header-tags) "col" cell-attrs) 3702 contents 3703 (cdr header-tags)))) 3704 ((and (plist-get info :html-table-use-header-tags-for-first-column) 3705 (zerop (cdr (org-export-table-cell-address table-cell info)))) 3706 (let ((header-tags (plist-get info :html-table-header-tags))) 3707 (concat "\n" (format (car header-tags) "row" cell-attrs) 3708 contents 3709 (cdr header-tags)))) 3710 (t (let ((data-tags (plist-get info :html-table-data-tags))) 3711 (concat "\n" (format (car data-tags) cell-attrs) 3712 contents 3713 (cdr data-tags))))))) 3714 3715 ;;;; Table Row 3716 3717 (defun org-html-table-row (table-row contents info) 3718 "Transcode a TABLE-ROW element from Org to HTML. 3719 CONTENTS is the contents of the row. INFO is a plist used as a 3720 communication channel." 3721 ;; Rules are ignored since table separators are deduced from 3722 ;; borders of the current row. 3723 (when (eq (org-element-property :type table-row) 'standard) 3724 (let* ((group (org-export-table-row-group table-row info)) 3725 (number (org-export-table-row-number table-row info)) 3726 (start-group-p 3727 (org-export-table-row-starts-rowgroup-p table-row info)) 3728 (end-group-p 3729 (org-export-table-row-ends-rowgroup-p table-row info)) 3730 (topp (and (equal start-group-p '(top)) 3731 (equal end-group-p '(below top)))) 3732 (bottomp (and (equal start-group-p '(above)) 3733 (equal end-group-p '(bottom above)))) 3734 (row-open-tag 3735 (pcase (plist-get info :html-table-row-open-tag) 3736 ((and accessor (pred functionp)) 3737 (funcall accessor 3738 number group start-group-p end-group-p topp bottomp)) 3739 (accessor accessor))) 3740 (row-close-tag 3741 (pcase (plist-get info :html-table-row-close-tag) 3742 ((and accessor (pred functionp)) 3743 (funcall accessor 3744 number group start-group-p end-group-p topp bottomp)) 3745 (accessor accessor))) 3746 (group-tags 3747 (cond 3748 ;; Row belongs to second or subsequent groups. 3749 ((not (= 1 group)) '("<tbody>" . "\n</tbody>")) 3750 ;; Row is from first group. Table has >=1 groups. 3751 ((org-export-table-has-header-p 3752 (org-export-get-parent-table table-row) info) 3753 '("<thead>" . "\n</thead>")) 3754 ;; Row is from first and only group. 3755 (t '("<tbody>" . "\n</tbody>"))))) 3756 (concat (and start-group-p (car group-tags)) 3757 (concat "\n" 3758 row-open-tag 3759 contents 3760 "\n" 3761 row-close-tag) 3762 (and end-group-p (cdr group-tags)))))) 3763 3764 ;;;; Table 3765 3766 (defun org-html-table-first-row-data-cells (table info) 3767 "Transcode the first row of TABLE. 3768 INFO is a plist used as a communication channel." 3769 (let ((table-row 3770 (org-element-map table 'table-row 3771 (lambda (row) 3772 (unless (eq (org-element-property :type row) 'rule) row)) 3773 info 'first-match)) 3774 (special-column-p (org-export-table-has-special-column-p table))) 3775 (if (not special-column-p) (org-element-contents table-row) 3776 (cdr (org-element-contents table-row))))) 3777 3778 (defun org-html-table--table.el-table (table _info) 3779 "Format table.el tables into HTML. 3780 INFO is a plist used as a communication channel." 3781 (when (eq (org-element-property :type table) 'table.el) 3782 (require 'table) 3783 (let ((outbuf (with-current-buffer 3784 (get-buffer-create "*org-export-table*") 3785 (erase-buffer) (current-buffer)))) 3786 (with-temp-buffer 3787 (insert (org-element-property :value table)) 3788 (goto-char 1) 3789 (re-search-forward "^[ \t]*|[^|]" nil t) 3790 (table-generate-source 'html outbuf)) 3791 (with-current-buffer outbuf 3792 (prog1 (org-trim (buffer-string)) 3793 (kill-buffer) ))))) 3794 3795 (defun org-html-table (table contents info) 3796 "Transcode a TABLE element from Org to HTML. 3797 CONTENTS is the contents of the table. INFO is a plist holding 3798 contextual information." 3799 (if (eq (org-element-property :type table) 'table.el) 3800 ;; "table.el" table. Convert it using appropriate tools. 3801 (org-html-table--table.el-table table info) 3802 ;; Standard table. 3803 (let* ((caption (org-export-get-caption table)) 3804 (number (org-export-get-ordinal 3805 table info nil #'org-html--has-caption-p)) 3806 (attributes 3807 (org-html--make-attribute-string 3808 (org-combine-plists 3809 (list :id (org-html--reference table info t)) 3810 (and (not (org-html-html5-p info)) 3811 (plist-get info :html-table-attributes)) 3812 (org-export-read-attribute :attr_html table)))) 3813 (alignspec 3814 (if (bound-and-true-p org-html-format-table-no-css) 3815 "align=\"%s\"" 3816 "class=\"org-%s\"")) 3817 (table-column-specs 3818 (lambda (table info) 3819 (mapconcat 3820 (lambda (table-cell) 3821 (let ((alignment (org-export-table-cell-alignment 3822 table-cell info))) 3823 (concat 3824 ;; Begin a colgroup? 3825 (when (org-export-table-cell-starts-colgroup-p 3826 table-cell info) 3827 "\n<colgroup>") 3828 ;; Add a column. Also specify its alignment. 3829 (format "\n%s" 3830 (org-html-close-tag 3831 "col" (concat " " (format alignspec alignment)) info)) 3832 ;; End a colgroup? 3833 (when (org-export-table-cell-ends-colgroup-p 3834 table-cell info) 3835 "\n</colgroup>")))) 3836 (org-html-table-first-row-data-cells table info) "\n")))) 3837 (format "<table%s>\n%s\n%s\n%s</table>" 3838 (if (equal attributes "") "" (concat " " attributes)) 3839 (if (not caption) "" 3840 (format (if (plist-get info :html-table-caption-above) 3841 "<caption class=\"t-above\">%s</caption>" 3842 "<caption class=\"t-bottom\">%s</caption>") 3843 (concat 3844 "<span class=\"table-number\">" 3845 (format (org-html--translate "Table %d:" info) number) 3846 "</span> " (org-export-data caption info)))) 3847 (funcall table-column-specs table info) 3848 contents)))) 3849 3850 ;;;; Target 3851 3852 (defun org-html-target (target _contents info) 3853 "Transcode a TARGET object from Org to HTML. 3854 CONTENTS is nil. INFO is a plist holding contextual 3855 information." 3856 (let ((ref (org-html--reference target info))) 3857 (org-html--anchor ref nil nil info))) 3858 3859 ;;;; Timestamp 3860 3861 (defun org-html-timestamp (timestamp _contents info) 3862 "Transcode a TIMESTAMP object from Org to HTML. 3863 CONTENTS is nil. INFO is a plist holding contextual 3864 information." 3865 (let ((value (org-html-plain-text (org-timestamp-translate timestamp) info))) 3866 (format "<span class=\"timestamp-wrapper\"><span class=\"timestamp\">%s</span></span>" 3867 (replace-regexp-in-string "--" "–" value)))) 3868 3869 ;;;; Underline 3870 3871 (defun org-html-underline (_underline contents info) 3872 "Transcode UNDERLINE from Org to HTML. 3873 CONTENTS is the text with underline markup. INFO is a plist 3874 holding contextual information." 3875 (format (or (cdr (assq 'underline (plist-get info :html-text-markup-alist))) 3876 "%s") 3877 contents)) 3878 3879 ;;;; Verbatim 3880 3881 (defun org-html-verbatim (verbatim _contents info) 3882 "Transcode VERBATIM from Org to HTML. 3883 CONTENTS is nil. INFO is a plist holding contextual 3884 information." 3885 (format (or (cdr (assq 'verbatim (plist-get info :html-text-markup-alist))) "%s") 3886 (org-html-encode-plain-text (org-element-property :value verbatim)))) 3887 3888 ;;;; Verse Block 3889 3890 (defun org-html-verse-block (_verse-block contents info) 3891 "Transcode a VERSE-BLOCK element from Org to HTML. 3892 CONTENTS is verse block contents. INFO is a plist holding 3893 contextual information." 3894 (format "<p class=\"verse\">\n%s</p>" 3895 ;; Replace leading white spaces with non-breaking spaces. 3896 (replace-regexp-in-string 3897 "^[ \t]+" (lambda (m) (org-html--make-string (length m) " ")) 3898 ;; Replace each newline character with line break. Also 3899 ;; remove any trailing "br" close-tag so as to avoid 3900 ;; duplicates. 3901 (let* ((br (org-html-close-tag "br" nil info)) 3902 (re (format "\\(?:%s\\)?[ \t]*\n" (regexp-quote br)))) 3903 (replace-regexp-in-string re (concat br "\n") contents))))) 3904 3905 3906 ;;; Filter Functions 3907 3908 (defun org-html-final-function (contents _backend info) 3909 "Filter to indent the HTML and convert HTML entities." 3910 (with-temp-buffer 3911 (insert contents) 3912 (set-auto-mode t) 3913 (when (plist-get info :html-indent) 3914 (indent-region (point-min) (point-max))) 3915 (buffer-substring-no-properties (point-min) (point-max)))) 3916 3917 3918 ;;; End-user functions 3919 3920 ;;;###autoload 3921 (defun org-html-export-as-html 3922 (&optional async subtreep visible-only body-only ext-plist) 3923 "Export current buffer to an HTML buffer. 3924 3925 If narrowing is active in the current buffer, only export its 3926 narrowed part. 3927 3928 If a region is active, export that region. 3929 3930 A non-nil optional argument ASYNC means the process should happen 3931 asynchronously. The resulting buffer should be accessible 3932 through the `org-export-stack' interface. 3933 3934 When optional argument SUBTREEP is non-nil, export the sub-tree 3935 at point, extracting information from the headline properties 3936 first. 3937 3938 When optional argument VISIBLE-ONLY is non-nil, don't export 3939 contents of hidden elements. 3940 3941 When optional argument BODY-ONLY is non-nil, only write code 3942 between \"<body>\" and \"</body>\" tags. 3943 3944 EXT-PLIST, when provided, is a property list with external 3945 parameters overriding Org default settings, but still inferior to 3946 file-local settings. 3947 3948 Export is done in a buffer named \"*Org HTML Export*\", which 3949 will be displayed when `org-export-show-temporary-export-buffer' 3950 is non-nil." 3951 (interactive) 3952 (org-export-to-buffer 'html "*Org HTML Export*" 3953 async subtreep visible-only body-only ext-plist 3954 (lambda () (set-auto-mode t)))) 3955 3956 ;;;###autoload 3957 (defun org-html-convert-region-to-html () 3958 "Assume the current region has Org syntax, and convert it to HTML. 3959 This can be used in any buffer. For example, you can write an 3960 itemized list in Org syntax in an HTML buffer and use this command 3961 to convert it." 3962 (interactive) 3963 (org-export-replace-region-by 'html)) 3964 3965 ;;;###autoload 3966 (defun org-html-export-to-html 3967 (&optional async subtreep visible-only body-only ext-plist) 3968 "Export current buffer to a HTML file. 3969 3970 If narrowing is active in the current buffer, only export its 3971 narrowed part. 3972 3973 If a region is active, export that region. 3974 3975 A non-nil optional argument ASYNC means the process should happen 3976 asynchronously. The resulting file should be accessible through 3977 the `org-export-stack' interface. 3978 3979 When optional argument SUBTREEP is non-nil, export the sub-tree 3980 at point, extracting information from the headline properties 3981 first. 3982 3983 When optional argument VISIBLE-ONLY is non-nil, don't export 3984 contents of hidden elements. 3985 3986 When optional argument BODY-ONLY is non-nil, only write code 3987 between \"<body>\" and \"</body>\" tags. 3988 3989 EXT-PLIST, when provided, is a property list with external 3990 parameters overriding Org default settings, but still inferior to 3991 file-local settings. 3992 3993 Return output file's name." 3994 (interactive) 3995 (let* ((extension (concat 3996 (when (> (length org-html-extension) 0) ".") 3997 (or (plist-get ext-plist :html-extension) 3998 org-html-extension 3999 "html"))) 4000 (file (org-export-output-file-name extension subtreep)) 4001 (org-export-coding-system org-html-coding-system)) 4002 (org-export-to-file 'html file 4003 async subtreep visible-only body-only ext-plist))) 4004 4005 ;;;###autoload 4006 (defun org-html-publish-to-html (plist filename pub-dir) 4007 "Publish an org file to HTML. 4008 4009 FILENAME is the filename of the Org file to be published. PLIST 4010 is the property list for the given project. PUB-DIR is the 4011 publishing directory. 4012 4013 Return output file name." 4014 (org-publish-org-to 'html filename 4015 (concat (when (> (length org-html-extension) 0) ".") 4016 (or (plist-get plist :html-extension) 4017 org-html-extension 4018 "html")) 4019 plist pub-dir)) 4020 4021 4022 (provide 'ox-html) 4023 4024 ;; Local variables: 4025 ;; generated-autoload-file: "org-loaddefs.el" 4026 ;; End: 4027 4028 ;;; ox-html.el ends here