diff options
author | Sébastien Delafond <sdelafond@gmail.com> | 2014-07-13 13:35:29 +0200 |
---|---|---|
committer | Sébastien Delafond <sdelafond@gmail.com> | 2014-07-13 13:35:29 +0200 |
commit | 40ce6b75e6245659a3a14622356e32e7dd1125dd (patch) | |
tree | 7d0051414493a78c84a3dfbec6143883c2ba8341 /lisp/ox-html.el | |
parent | e32a45ed36d6000db4b39171149072d11b77af72 (diff) |
Imported Upstream version 8.2.1
Diffstat (limited to 'lisp/ox-html.el')
-rw-r--r-- | lisp/ox-html.el | 663 |
1 files changed, 406 insertions, 257 deletions
diff --git a/lisp/ox-html.el b/lisp/ox-html.el index 8794882..14b31b2 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -37,7 +37,7 @@ (require 'ox) (require 'ox-publish) (require 'format-spec) -(eval-when-compile (require 'cl) (require 'table)) +(eval-when-compile (require 'cl) (require 'table nil 'noerror)) ;;; Function Declarations @@ -116,6 +116,8 @@ (:html-link-org-as-html nil nil org-html-link-org-files-as-html) (:html-doctype "HTML_DOCTYPE" nil org-html-doctype) (:html-container "HTML_CONTAINER" nil org-html-container-element) + (:html-html5-fancy nil "html5-fancy" org-html-html5-fancy) + (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) (:html-link-home "HTML_LINK_HOME" nil org-html-link-home) (:html-link-up "HTML_LINK_UP" nil org-html-link-up) (:html-mathjax "HTML_MATHJAX" nil "" space) @@ -123,8 +125,8 @@ (:html-preamble nil "html-preamble" org-html-preamble) (:html-head "HTML_HEAD" nil org-html-head newline) (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline) - (:html-head-include-default-style "HTML_INCLUDE_STYLE" nil org-html-head-include-default-style newline) - (:html-head-include-scripts "HTML_INCLUDE_SCRIPTS" nil org-html-head-include-scripts newline) + (:html-head-include-default-style nil "html-style" org-html-head-include-default-style) + (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts) (:html-table-attributes nil nil org-html-table-default-attributes) (:html-table-row-tags nil nil org-html-table-row-tags) (:html-xml-declaration nil nil org-html-xml-declaration) @@ -143,6 +145,38 @@ (defvar org-html--pre/postamble-class "status" "CSS class used for pre/postamble") +(defconst org-html-doctype-alist + '(("html4-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" +\"http://www.w3.org/TR/html4/strict.dtd\">") + ("html4-transitional" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" +\"http://www.w3.org/TR/html4/loose.dtd\">") + ("html4-frameset" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" +\"http://www.w3.org/TR/html4/frameset.dtd\">") + + ("xhtml-strict" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" +\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">") + ("xhtml-transitional" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" +\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">") + ("xhtml-framset" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" +\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">") + ("xhtml-11" . "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" +\"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd\">") + + ("html5" . "<!DOCTYPE html>") + ("xhtml5" . "<!DOCTYPE html>")) + "An alist mapping (x)html flavors to specific doctypes.") + +(defconst org-html-html5-elements + '("article" "aside" "audio" "canvas" "details" "figcaption" + "figure" "footer" "header" "menu" "meter" "nav" "output" + "progress" "section" "video") + "New elements in html5. + +<hgroup> is not included because it's currently impossible to +wrap special blocks around multiple headlines. For other blocks +that should contain headlines, use the HTML_CONTAINER property on +the headline itself.") + (defconst org-html-special-string-regexps '(("\\\\-" . "­") ; shy ("---\\([^-]\\)" . "—\\1") ; mdash @@ -680,16 +714,14 @@ When nil, the links still point to the plain `.org' file." ;;;; Links :: Inline images -(defcustom org-html-inline-images 'maybe +(defcustom org-html-inline-images t "Non-nil means inline images into exported HTML pages. This is done using an <img> tag. When nil, an anchor with href is used to -link to the image. If this option is `maybe', then images in links with -an empty description will be inlined, while images with a description will -be linked only." +link to the image." :group 'org-export-html - :type '(choice (const :tag "Never" nil) - (const :tag "Always" t) - (const :tag "When there is no description" maybe))) + :version "24.4" + :package-version '(Org . "8.1") + :type 'boolean) (defcustom org-html-inline-image-rules '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'") @@ -748,7 +780,9 @@ in all modes you want. Then, use the command '(:border "2" :cellspacing "0" :cellpadding "6" :rules "groups" :frame "hsides") "Default attributes and values which will be used in table tags. This is a plist where attributes are symbols, starting with -colons, and values are strings." +colons, and values are strings. + +When exporting to HTML5, these values will be disregarded." :group 'org-export-html :version "24.4" :package-version '(Org . "8.0") @@ -856,7 +890,9 @@ CSS classes, then this prefix can be very useful." "The extension for exported HTML files. %s will be replaced with the charset of the exported file. This may be a string, or an alist with export extensions -and corresponding declarations." +and corresponding declarations. + +This declaration only applies when exporting to XHTML." :group 'org-export-html :type '(choice (string :tag "Single declaration") @@ -872,8 +908,7 @@ Use utf-8 as the default value." :package-version '(Org . "8.0") :type 'coding-system) -(defcustom org-html-doctype - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" +(defcustom org-html-doctype "xhtml-strict" "Document type definition to use for exported HTML files. Can be set with the in-buffer HTML_DOCTYPE property or for publishing, with :html-doctype." @@ -882,6 +917,20 @@ publishing, with :html-doctype." :package-version '(Org . "8.0") :type 'string) +(defcustom org-html-html5-fancy nil + "Non-nil means using new HTML5 elements. +This variable is ignored for anything other than HTML5 export. + +For compatibility with Internet Explorer, it's probably a good +idea to download some form of the html5shiv (for instance +https://code.google.com/p/html5shiv/) and add it to your +HTML_HEAD_EXTRA, so that your pages don't break for users of IE +versions 8 and below." + :group 'org-export-html + :version "24.4" + :package-version '(Org . "8.0") + :type 'boolean) + (defcustom org-html-container-element "div" "HTML element to use for wrapping top level sections. Can be set with the in-buffer HTML_CONTAINER property or for @@ -962,7 +1011,8 @@ You can also customize this for each buffer, using something like (const :format " " mathml) (boolean)))) (defcustom org-html-mathjax-template - "<script type=\"text/javascript\" src=\"%PATH\"> + "<script type=\"text/javascript\" src=\"%PATH\"></script> +<script type=\"text/javascript\"> <!--/*--><![CDATA[/*><!--*/ MathJax.Hub.Config({ // Only one of the two following lines, depending on user settings @@ -1026,7 +1076,7 @@ Setting :html-postamble in publishing projects will take precedence over this variable." :group 'org-export-html :type '(choice (const :tag "No postamble" nil) - (const :tag "Auto postamble" 'auto) + (const :tag "Auto postamble" auto) (const :tag "Default formatting string" t) (string :tag "Custom formatting string") (function :tag "Function (must return a string)"))) @@ -1035,7 +1085,7 @@ precedence over this variable." '(("en" "<p class=\"author\">Author: %a (%e)</p> <p class=\"date\">Date: %d</p> <p class=\"creator\">%c</p> -<p class=\"xhtml-validation\">%v</p>")) +<p class=\"validation\">%v</p>")) "Alist of languages and format strings for the HTML postamble. The first element of each list is the language code, as used for @@ -1056,11 +1106,12 @@ postamble itself. This format string can contain these elements: If you need to use a \"%\" character, you need to escape it like that: \"%%\"." :group 'org-export-html - :type '(alist :key-type (string :tag "Language") - :value-type (string :tag "Format string"))) + :type '(repeat + (list (string :tag "Language") + (string :tag "Format string")))) (defcustom org-html-validation-link - "<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>" + "<a href=\"http://validator.w3.org/check?uri=referer\">Validate</a>" "Link to HTML validation service." :group 'org-export-html :type 'string) @@ -1120,8 +1171,9 @@ like that: \"%%\". See the default value of `org-html-postamble-format' for an example." :group 'org-export-html - :type '(alist :key-type (string :tag "Language") - :value-type (string :tag "Format string"))) + :type '(repeat + (list (string :tag "Language") + (string :tag "Format string")))) (defcustom org-html-link-up "" "Where should the \"UP\" link of exported HTML pages lead?" @@ -1133,6 +1185,13 @@ example." :group 'org-export-html :type '(string :tag "File or URL")) +(defcustom org-html-link-use-abs-url nil + "Should we prepend relative links with HTML_LINK_HOME?" + :group 'org-export-html + :version "24.4" + :package-version '(Org . "8.1") + :type 'boolean) + (defcustom org-html-home/up-format "<div id=\"org-div-home-and-up\"> <a accesskey=\"h\" href=\"%s\"> UP </a> @@ -1240,6 +1299,26 @@ CSS classes, then this prefix can be very useful." ;;; Internal Functions +(defun org-html-xhtml-p (info) + (let ((dt (downcase (plist-get info :html-doctype)))) + (string-match-p "xhtml" dt))) + +(defun org-html-html5-p (info) + (let ((dt (downcase (plist-get info :html-doctype)))) + (member dt '("html5" "xhtml5" "<!doctype html>")))) + +(defun org-html-close-tag (tag attr info) + (concat "<" tag " " attr + (if (org-html-xhtml-p info) " />" ">"))) + +(defun org-html-doctype (info) + "Return correct html doctype tag from `org-html-doctype-alist', +or the literal value of :html-doctype from INFO if :html-doctype +is not found in the alist. +INFO is a plist used as a communication channel." + (let ((dt (plist-get info :html-doctype))) + (or (cdr (assoc dt org-html-doctype-alist)) dt))) + (defun org-html--make-attribute-string (attributes) "Return a list of attributes, as a string. ATTRIBUTES is a plist where values are either strings or nil. An @@ -1253,32 +1332,43 @@ attributes with a nil value will be omitted from the result." "\"" """ (org-html-encode-plain-text item)))) (setcar output (format "%s=\"%s\"" key value)))))))) -(defun org-html-format-inline-image (src &optional - caption label attr standalone-p) - "Format an inline image from SRC. -CAPTION, LABEL and ATTR are optional arguments providing the -caption, the label and the attribute of the image. -When STANDALONE-P is t, wrap the <img.../> into a <div>...</div>." - (let* ((id (if (not label) "" - (format " id=\"%s\"" (org-export-solidify-link-text label)))) - (attr (concat attr - (cond - ((string-match "\\<alt=" (or attr "")) "") - ((string-match "^ltxpng/" src) - (format " alt=\"%s\"" - (org-html-encode-plain-text - (org-find-text-property-in-string - 'org-latex-src src)))) - (t (format " alt=\"%s\"" - (file-name-nondirectory src))))))) - (cond - (standalone-p - (let ((img (format "<img src=\"%s\" %s/>" src attr))) - (format "\n<div%s class=\"figure\">%s%s\n</div>" - id (format "\n<p>%s</p>" img) - (if (and caption (not (string= caption ""))) - (format "\n<p>%s</p>" caption) "")))) - (t (format "<img src=\"%s\" %s/>" src (concat attr id)))))) +(defun org-html--wrap-image (contents info &optional caption label) + "Wrap CONTENTS string within an appropriate environment for images. +INFO is a plist used as a communication channel. When optional +arguments CAPTION and LABEL are given, use them for caption and +\"id\" attribute." + (let ((html5-fancy (and (org-html-html5-p info) + (plist-get info :html-html5-fancy)))) + (format (if html5-fancy "\n<figure%s>%s%s\n</figure>" + "\n<div%s class=\"figure\">%s%s\n</div>") + ;; ID. + (if (not (org-string-nw-p label)) "" + (format " id=\"%s\"" (org-export-solidify-link-text label))) + ;; Contents. + (format "\n<p>%s</p>" contents) + ;; Caption. + (if (not (org-string-nw-p caption)) "" + (format (if html5-fancy "\n<figcaption>%s</figcaption>" + "\n<p>%s</p>") + caption))))) + +(defun org-html--format-image (source attributes info) + "Return \"img\" tag with given SOURCE and ATTRIBUTES. +SOURCE is a string specifying the location of the image. +ATTRIBUTES is a plist, as returned by +`org-export-read-attribute'. INFO is a plist used as +a communication channel." + (org-html-close-tag + "img" + (org-html--make-attribute-string + (org-combine-plists + (list :src source + :alt (if (string-match-p "^ltxpng/" source) + (org-html-encode-plain-text + (org-find-text-property-in-string 'org-latex-src source)) + (file-name-nondirectory source))) + attributes)) + info)) (defun org-html--textarea-block (element) "Transcode ELEMENT into a textarea block. @@ -1290,6 +1380,13 @@ ELEMENT is either a src block or an example block." (or (plist-get attr :height) (org-count-lines code)) code))) +(defun org-html--has-caption-p (element &optional info) + "Non-nil when ELEMENT has a caption affiliated keyword. +INFO is a plist used as a communication channel. This function +is meant to be used as a predicate for `org-export-get-ordinal' or +a value to `org-html-standalone-image-predicate'." + (org-element-property :caption element)) + ;;;; Table (defun org-html-htmlize-region-for-paste (beg end) @@ -1417,28 +1514,47 @@ INFO is a plist used as a communication channel." (cons 'plain-text org-element-all-objects) 'identity info)))))) (description (plist-get info :description)) - (keywords (plist-get info :keywords))) + (keywords (plist-get info :keywords)) + (charset (or (and org-html-coding-system + (fboundp 'coding-system-get) + (coding-system-get org-html-coding-system + 'mime-charset)) + "iso-8859-1"))) (concat (format "<title>%s</title>\n" title) (when (plist-get info :time-stamp-file) (format-time-string (concat "<!-- " org-html-metadata-timestamp-format " -->\n"))) (format - "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>\n" - (or (and org-html-coding-system - (fboundp 'coding-system-get) - (coding-system-get org-html-coding-system 'mime-charset)) - "iso-8859-1")) - (format "<meta name=\"generator\" content=\"Org-mode\"/>\n") + (if (org-html-html5-p info) + (org-html-close-tag "meta" " charset=\"%s\"" info) + (org-html-close-tag + "meta" " http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"" + info)) + charset) "\n" + (org-html-close-tag "meta" " name=\"generator\" content=\"Org-mode\"" info) + "\n" (and (org-string-nw-p author) - (format "<meta name=\"author\" content=\"%s\"/>\n" - (funcall protect-string author))) + (concat + (org-html-close-tag "meta" + (format " name=\"author\" content=\"%s\"" + (funcall protect-string author)) + info) + "\n")) (and (org-string-nw-p description) - (format "<meta name=\"description\" content=\"%s\"/>\n" - (funcall protect-string description))) + (concat + (org-html-close-tag "meta" + (format " name=\"description\" content=\"%s\"\n" + (funcall protect-string description)) + info) + "\n")) (and (org-string-nw-p keywords) - (format "<meta name=\"keywords\" content=\"%s\"/>\n" - (funcall protect-string keywords)))))) + (concat + (org-html-close-tag "meta" + (format " name=\"keywords\" content=\"%s\"" + (funcall protect-string keywords)) + info) + "\n"))))) (defun org-html--build-head (info) "Return information for the <head>..</head> of the HTML output. @@ -1451,8 +1567,10 @@ INFO is a plist used as a communication channel." (org-element-normalize-string (plist-get info :html-head-extra)) (when (and (plist-get info :html-htmlized-css-url) (eq org-html-htmlize-output-type 'css)) - (format "<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\" />\n" - (plist-get info :html-htmlized-css-url))) + (org-html-close-tag "link" + (format " rel=\"stylesheet\" href=\"%s\" type=\"text/css\"" + (plist-get info :html-htmlized-css-url)) + info)) (when (plist-get info :html-head-include-scripts) org-html-scripts)))) (defun org-html--build-mathjax-config (info) @@ -1549,7 +1667,7 @@ communication channel." (format-time-string org-html-metadata-timestamp-format))) (when (plist-get info :with-creator) (format "<p class=\"creator\">%s</p>\n" creator)) - (format "<p class=\"xhtml-validation\">%s</p>\n" + (format "<p class=\"validation\">%s</p>\n" validation-link)))) (t (format-spec (or (cadr (assoc @@ -1589,23 +1707,29 @@ holding export options." CONTENTS is the transcoded contents string. INFO is a plist holding export options." (concat - (format - (or (and (stringp org-html-xml-declaration) - org-html-xml-declaration) - (cdr (assoc (plist-get info :html-extension) - org-html-xml-declaration)) - (cdr (assoc "html" org-html-xml-declaration)) - - "") - (or (and org-html-coding-system - (fboundp 'coding-system-get) - (coding-system-get org-html-coding-system 'mime-charset)) - "iso-8859-1")) - "\n" - (plist-get info :html-doctype) + (when (and (not (org-html-html5-p info)) (org-html-xhtml-p info)) + (let ((decl (or (and (stringp org-html-xml-declaration) + org-html-xml-declaration) + (cdr (assoc (plist-get info :html-extension) + org-html-xml-declaration)) + (cdr (assoc "html" org-html-xml-declaration)) + + ""))) + (when (not (or (eq nil decl) (string= "" decl))) + (format "%s\n" + (format decl + (or (and org-html-coding-system + (fboundp 'coding-system-get) + (coding-system-get org-html-coding-system 'mime-charset)) + "iso-8859-1")))))) + (org-html-doctype info) "\n" - (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">\n" - (plist-get info :language) (plist-get info :language)) + (concat "<html" + (when (org-html-xhtml-p info) + (format + " xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"" + (plist-get info :language) (plist-get info :language))) + ">\n") "<head>\n" (org-html--build-meta-info info) (org-html--build-head info) @@ -1807,9 +1931,13 @@ contents as a string, or nil if it is empty." (mapcar (lambda (headline) (cons (org-html--format-toc-headline headline info) (org-export-get-relative-level headline info))) - (org-export-collect-headlines info depth)))) + (org-export-collect-headlines info depth))) + (outer-tag (if (and (org-html-html5-p info) + (plist-get info :html-html5-fancy)) + "nav" + "div"))) (when toc-entries - (concat "<div id=\"table-of-contents\">\n" + (concat (format "<%s id=\"table-of-contents\">\n" outer-tag) (format "<h%d>%s</h%d>\n" org-html-toplevel-hlevel (org-html--translate "Table of Contents" info) @@ -1817,7 +1945,7 @@ contents as a string, or nil if it is empty." "<div id=\"text-table-of-contents\">" (org-html--toc-text toc-entries) "</div>\n" - "</div>\n")))) + (format "</%s>\n" outer-tag))))) (defun org-html--toc-text (toc-entries) "Return innards of a table of contents, as a string. @@ -1862,16 +1990,17 @@ INFO is a plist used as a communication channel." headline-number "-")))) ;; Body. (concat section-number - (org-export-data-with-translations + (org-export-data-with-backend (org-export-get-alt-title headline info) - ;; Ignore any footnote-reference, link, - ;; radio-target and target in table of contents. - (append - '((footnote-reference . ignore) - (link . (lambda (link desc i) desc)) - (radio-target . (lambda (radio desc i) desc)) - (target . ignore)) - (org-export-backend-translate-table 'html)) + ;; Create an anonymous back-end that will ignore + ;; any footnote-reference, link, radio-target and + ;; target in table of contents. + (org-export-create-backend + :parent 'html + :transcoders '((footnote-reference . ignore) + (link . (lambda (object c i) c)) + (radio-target . (lambda (object c i) c)) + (target . ignore))) info) (and tags "   ") (org-html--tags tags))))) @@ -1888,7 +2017,8 @@ of listings as a string, or nil if it is empty." org-html-toplevel-hlevel) "<div id=\"text-list-of-listings\">\n<ul>\n" (let ((count 0) - (initial-fmt (org-html--translate "Listing %d:" info))) + (initial-fmt (format "<span class=\"listing-number\">%s</span>" + (org-html--translate "Listing %d:" info)))) (mapconcat (lambda (entry) (let ((label (org-element-property :name entry)) @@ -1922,7 +2052,8 @@ of tables as a string, or nil if it is empty." org-html-toplevel-hlevel) "<div id=\"text-list-of-tables\">\n<ul>\n" (let ((count 0) - (initial-fmt (org-html--translate "Table %d:" info))) + (initial-fmt (format "<span class=\"table-number\">%s</span>" + (org-html--translate "Table %d:" info)))) (mapconcat (lambda (entry) (let ((label (org-element-property :name entry)) @@ -2154,7 +2285,7 @@ holding contextual information." ;; Build the real contents of the sub-tree. (let* ((type (if numberedp 'ordered 'unordered)) (itemized-body (org-html-format-list-item - contents type nil nil full-text))) + contents type nil info nil full-text))) (concat (and (org-export-first-sibling-p headline info) (org-html-begin-plain-list type)) @@ -2214,7 +2345,7 @@ holding contextual information." (defun org-html-horizontal-rule (horizontal-rule contents info) "Transcode an HORIZONTAL-RULE object from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information." - "<hr/>") + (org-html-close-tag "hr" nil info)) ;;;; Inline Src Block @@ -2250,8 +2381,9 @@ holding contextual information." (org-html-format-headline--wrap inlinetask info format-function :contents contents))) ;; Otherwise, use a default template. - (t (format "<div class=\"inlinetask\">\n<b>%s</b><br/>\n%s</div>" + (t (format "<div class=\"inlinetask\">\n<b>%s</b>%s\n%s</div>" (org-html-format-headline--wrap inlinetask info) + (org-html-close-tag "br" nil info) contents)))) ;;;; Italic @@ -2271,11 +2403,12 @@ contextual information." (trans "<code>[-]</code>") (t ""))) -(defun org-html-format-list-item (contents type checkbox +(defun org-html-format-list-item (contents type checkbox info &optional term-counter-id headline) "Format a list item into HTML." - (let ((checkbox (concat (org-html-checkbox checkbox) (and checkbox " ")))) + (let ((checkbox (concat (org-html-checkbox checkbox) (and checkbox " "))) + (br (org-html-close-tag "br" nil info))) (concat (case type (ordered @@ -2283,13 +2416,13 @@ contextual information." (extra (if counter (format " value=\"%s\"" counter) ""))) (concat (format "<li%s>" extra) - (when headline (concat headline "<br/>"))))) + (when headline (concat headline br))))) (unordered (let* ((id term-counter-id) (extra (if id (format " id=\"%s\"" id) ""))) (concat (format "<li%s>" extra) - (when headline (concat headline "<br/>"))))) + (when headline (concat headline br))))) (descriptive (let* ((term term-counter-id)) (setq term (or term "(no term)")) @@ -2315,7 +2448,7 @@ contextual information." (tag (let ((tag (org-element-property :tag item))) (and tag (org-export-data tag info))))) (org-html-format-list-item - contents type checkbox (or tag counter)))) + contents type checkbox info (or tag counter)))) ;;;; Keyword @@ -2363,21 +2496,19 @@ CONTENTS is nil. INFO is a plist holding contextual information." (let ((processing-type (plist-get info :with-latex)) (latex-frag (org-remove-indentation (org-element-property :value latex-environment))) - (caption (org-export-data - (org-export-get-caption latex-environment) info)) - (attr nil) ; FIXME - (label (org-element-property :name latex-environment))) - (cond - ((memq processing-type '(t mathjax)) - (org-html-format-latex latex-frag 'mathjax)) - ((eq processing-type 'dvipng) - (let* ((formula-link (org-html-format-latex - latex-frag processing-type))) - (when (and formula-link - (string-match "file:\\([^]]*\\)" formula-link)) - (org-html-format-inline-image - (match-string 1 formula-link) caption label attr t)))) - (t latex-frag)))) + (attributes (org-export-read-attribute :attr_html latex-environment))) + (case processing-type + ((t mathjax) + (org-html-format-latex latex-frag 'mathjax)) + ((dvipng imagemagick) + (let ((formula-link (org-html-format-latex latex-frag processing-type))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + ;; Do not provide a caption or a name to be consistent with + ;; `mathjax' handling. + (org-html--wrap-image + (org-html--format-image + (match-string 1 formula-link) attributes info) info)))) + (t latex-frag)))) ;;;; Latex Fragment @@ -2389,13 +2520,10 @@ CONTENTS is nil. INFO is a plist holding contextual information." (case processing-type ((t mathjax) (org-html-format-latex latex-frag 'mathjax)) - (dvipng - (let* ((formula-link (org-html-format-latex - latex-frag processing-type))) - (when (and formula-link - (string-match "file:\\([^]]*\\)" formula-link)) - (org-html-format-inline-image - (match-string 1 formula-link))))) + ((dvipng imagemagick) + (let ((formula-link (org-html-format-latex latex-frag processing-type))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (org-html--format-image (match-string 1 formula-link) nil info)))) (t latex-frag)))) ;;;; Line Break @@ -2403,79 +2531,69 @@ CONTENTS is nil. INFO is a plist holding contextual information." (defun org-html-line-break (line-break contents info) "Transcode a LINE-BREAK object from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information." - "<br/>\n") + (concat (org-html-close-tag "br" nil info) "\n")) ;;;; Link -(defun org-html-link--inline-image (link desc info) - "Return HTML code for an inline image. - -LINK is the link pointing to the inline image. INFO is a plist -used as a communication channel. - -Inline images can have these attributes: - -#+ATTR_HTML: :width 100px :height 100px :alt \"Alt description\"." - (let* ((type (org-element-property :type link)) - (raw-path (org-element-property :path link)) - (path (cond ((member type '("http" "https")) - (concat type ":" raw-path)) - ((file-name-absolute-p raw-path) - (expand-file-name raw-path)) - (t raw-path))) - (parent (org-export-get-parent-element link)) - (caption (org-export-data (org-export-get-caption parent) info)) - (label (org-element-property :name parent))) - ;; Return proper string, depending on DISPOSITION. - (org-html-format-inline-image - path caption label - (org-html--make-attribute-string - (org-export-read-attribute :attr_html parent)) - (org-html-standalone-image-p link info)))) +(defun org-html-inline-image-p (link info) + "Non-nil when LINK is meant to appear as an image. +INFO is a plist used as a communication channel. LINK is an +inline image when it has no description and targets an image +file (see `org-html-inline-image-rules' for more information), or +if its description is a single link targeting an image file." + (if (not (org-element-contents link)) + (org-export-inline-image-p link org-html-inline-image-rules) + (not + (let ((link-count 0)) + (org-element-map (org-element-contents link) + (cons 'plain-text org-element-all-objects) + (lambda (obj) + (case (org-element-type obj) + (plain-text (org-string-nw-p obj)) + (link (if (= link-count 1) t + (incf link-count) + (not (org-export-inline-image-p + obj org-html-inline-image-rules)))) + (otherwise t))) + info t))))) (defvar org-html-standalone-image-predicate) -(defun org-html-standalone-image-p (element info &optional predicate) - "Test if ELEMENT is a standalone image for the purpose HTML export. +(defun org-html-standalone-image-p (element info) + "Test if ELEMENT is a standalone image. + INFO is a plist holding contextual information. -Return non-nil, if ELEMENT is of type paragraph and it's sole -content, save for whitespaces, is a link that qualifies as an +Return non-nil, if ELEMENT is of type paragraph and its sole +content, save for white spaces, is a link that qualifies as an inline image. -Return non-nil, if ELEMENT is of type link and it's containing -paragraph has no other content save for leading and trailing -whitespaces. +Return non-nil, if ELEMENT is of type link and its containing +paragraph has no other content save white spaces. Return nil, otherwise. -Bind `org-html-standalone-image-predicate' to constrain -paragraph further. For example, to check for only captioned -standalone images, do the following. +Bind `org-html-standalone-image-predicate' to constrain paragraph +further. For example, to check for only captioned standalone +images, set it to: - \(setq org-html-standalone-image-predicate - \(lambda \(paragraph\) - \(org-element-property :caption paragraph\)\)\)" + \(lambda (paragraph) (org-element-property :caption paragraph))" (let ((paragraph (case (org-element-type element) (paragraph element) - (link (and (org-export-inline-image-p - element org-html-inline-image-rules) - (org-export-get-parent element))) - (t nil)))) - (when (eq (org-element-type paragraph) 'paragraph) - (when (or (not (and (boundp 'org-html-standalone-image-predicate) - (functionp org-html-standalone-image-predicate))) - (funcall org-html-standalone-image-predicate paragraph)) - (let ((contents (org-element-contents paragraph))) - (loop for x in contents - with inline-image-count = 0 - always (cond - ((eq (org-element-type x) 'plain-text) - (not (org-string-nw-p x))) - ((eq (org-element-type x) 'link) - (when (org-export-inline-image-p - x org-html-inline-image-rules) - (= (incf inline-image-count) 1))) - (t nil)))))))) + (link (org-export-get-parent element))))) + (and (eq (org-element-type paragraph) 'paragraph) + (or (not (and (boundp 'org-html-standalone-image-predicate) + (functionp org-html-standalone-image-predicate))) + (funcall org-html-standalone-image-predicate paragraph)) + (not (let ((link-count 0)) + (org-element-map (org-element-contents paragraph) + (cons 'plain-text org-element-all-objects) + (lambda (obj) (case (org-element-type obj) + (plain-text (org-string-nw-p obj)) + (link + (or (> (incf link-count) 1) + (not (org-html-inline-image-p obj info)))) + (otherwise t))) + info 'first-match 'link)))))) (defun org-html-link (link desc info) "Transcode a LINK object from Org to HTML. @@ -2483,7 +2601,10 @@ standalone images, do the following. DESC is the description part of the link, or the empty string. INFO is a plist holding contextual information. See `org-export-data'." - (let* ((link-org-files-as-html-maybe + (let* ((home (when (plist-get info :html-link-home) + (org-trim (plist-get info :html-link-home)))) + (use-abs-url (plist-get info :html-link-use-abs-url)) + (link-org-files-as-html-maybe (function (lambda (raw-path info) "Treat links to `file.org' as links to `file.html', if needed. @@ -2509,9 +2630,12 @@ INFO is a plist holding contextual information. See (funcall link-org-files-as-html-maybe raw-path info)) ;; If file path is absolute, prepend it with protocol ;; component - "file://". - (when (file-name-absolute-p raw-path) - (setq raw-path - (concat "file://" (expand-file-name raw-path)))) + (cond ((file-name-absolute-p raw-path) + (setq raw-path + (concat "file://" (expand-file-name + raw-path)))) + ((and home use-abs-url) + (setq raw-path (concat (file-name-as-directory home) raw-path)))) ;; Add search option, if any. A search option can be ;; relative to a custom-id or a headline title. Any other ;; option is ignored. @@ -2531,25 +2655,28 @@ INFO is a plist holding contextual information. See numbers "-")))))) (t raw-path)))) (t raw-path))) - ;; Extract attributes from parent's paragraph. HACK: Only do - ;; this for the first link in parent. This is needed as long - ;; as attributes cannot be set on a per link basis. + ;; Extract attributes from parent's paragraph. HACK: Only do + ;; this for the first link in parent (inner image link for + ;; inline images). This is needed as long as attributes + ;; cannot be set on a per link basis. + (attributes-plist + (let* ((parent (org-export-get-parent-element link)) + (link (let ((container (org-export-get-parent link))) + (if (and (eq (org-element-type container) 'link) + (org-html-inline-image-p link info)) + container + link)))) + (and (eq (org-element-map parent 'link 'identity info t) link) + (org-export-read-attribute :attr_html parent)))) (attributes - (let ((parent (org-export-get-parent-element link))) - (if (not (eq (org-element-map parent 'link 'identity info t) link)) - "" - (let ((att (org-html--make-attribute-string - (org-export-read-attribute :attr_html parent)))) - (cond ((not (org-string-nw-p att)) "") - ((and desc (string-match (regexp-quote att) desc)) "") - (t (concat " " att))))))) + (let ((attr (org-html--make-attribute-string attributes-plist))) + (if (org-string-nw-p attr) (concat " " attr) ""))) protocol) (cond ;; Image file. - ((and (or (eq t org-html-inline-images) - (and org-html-inline-images (not desc))) + ((and org-html-inline-images (org-export-inline-image-p link org-html-inline-image-rules)) - (org-html-link--inline-image link desc info)) + (org-html--format-image path attributes-plist info)) ;; Radio target: Transcode target's contents and use them as ;; link's description. ((string= type "radio") @@ -2580,8 +2707,6 @@ INFO is a plist holding contextual information. See (or desc (org-export-data (org-element-property :raw-link link) info)))) - ;; Fuzzy link points to an invisible target. - (keyword nil) ;; Link points to a headline. (headline (let ((href @@ -2615,21 +2740,24 @@ INFO is a plist holding contextual information. See :title destination) info))))) (format "<a href=\"#%s\"%s>%s</a>" (org-export-solidify-link-text href) attributes desc))) - ;; Fuzzy link points to a target. Do as above. + ;; Fuzzy link points to a target or an element. (t - (let ((path (org-export-solidify-link-text path)) number) - (unless desc - (setq number (cond - ((org-html-standalone-image-p destination info) - (org-export-get-ordinal - (assoc 'link (org-element-contents destination)) - info 'link 'org-html-standalone-image-p)) - (t (org-export-get-ordinal destination info)))) - (setq desc (when number - (if (atom number) (number-to-string number) - (mapconcat 'number-to-string number "."))))) - (format "<a href=\"#%s\"%s>%s</a>" - path attributes (or desc "No description for this link"))))))) + (let* ((path (org-export-solidify-link-text path)) + (org-html-standalone-image-predicate 'org-html--has-caption-p) + (number (cond + (desc nil) + ((org-html-standalone-image-p destination info) + (org-export-get-ordinal + (org-element-map destination 'link + 'identity info t) + info 'link 'org-html-standalone-image-p)) + (t (org-export-get-ordinal + destination info nil 'org-html--has-caption-p)))) + (desc (cond (desc) + ((not number) "No description for this link") + ((numberp number) (number-to-string number)) + (t (mapconcat 'number-to-string number "."))))) + (format "<a href=\"#%s\"%s>%s</a>" path attributes desc)))))) ;; Coderef: replace link with the reference name or the ;; equivalent line number. ((string= type "coderef") @@ -2668,11 +2796,27 @@ the plist used as a communication channel." ((and (eq (org-element-type parent) 'item) (= (org-element-property :begin paragraph) (org-element-property :contents-begin parent))) - ;; leading paragraph in a list item have no tags + ;; Leading paragraph in a list item have no tags. contents) ((org-html-standalone-image-p paragraph info) - ;; standalone image - contents) + ;; Standalone image. + (let ((caption + (let ((raw (org-export-data + (org-export-get-caption paragraph) info)) + (org-html-standalone-image-predicate + 'org-html--has-caption-p)) + (if (not (org-string-nw-p raw)) raw + (concat + "<span class=\"figure-number\">" + (format (org-html--translate "Figure %d:" info) + (org-export-get-ordinal + (org-element-map paragraph 'link + 'identity info t) + info nil 'org-html-standalone-image-p)) + "</span> " raw)))) + (label (org-element-property :name paragraph))) + (org-html--wrap-image contents info caption label))) + ;; Regular paragraph. (t (format "<p%s>\n%s</p>" extra contents))))) ;;;; Plain List @@ -2746,7 +2890,8 @@ contextual information." (when (plist-get info :preserve-breaks) (setq output (replace-regexp-in-string - "\\(\\\\\\\\\\)?[ \t]*\n" "<br/>\n" output))) + "\\(\\\\\\\\\\)?[ \t]*\n" + (concat (org-html-close-tag "br" nil info) "\n") output))) ;; Return value. output)) @@ -2846,9 +2991,25 @@ contextual information." "Transcode a SPECIAL-BLOCK element from Org to HTML. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." - (format "<div class=\"%s\">\n%s\n</div>" - (downcase (org-element-property :type special-block)) - contents)) + (let* ((block-type (downcase + (org-element-property :type special-block))) + (contents (or contents "")) + (html5-fancy (and (org-html-html5-p info) + (plist-get info :html-html5-fancy) + (member block-type org-html-html5-elements))) + (attributes (org-export-read-attribute :attr_html special-block))) + (unless html5-fancy + (let ((class (plist-get attributes :class))) + (setq attributes (plist-put attributes :class + (if class (concat class " " block-type) + block-type))))) + (setq attributes (org-html--make-attribute-string attributes)) + (when (not (equal attributes "")) + (setq attributes (concat " " attributes))) + (if html5-fancy + (format "<%s%s>\n%s</%s>" block-type attributes + contents block-type) + (format "<div%s>\n%s\n</div>" attributes contents)))) ;;;; Src Block @@ -3020,11 +3181,14 @@ contextual information." (t (let* ((label (org-element-property :name table)) (caption (org-export-get-caption table)) + (number (org-export-get-ordinal + table info nil 'org-html--has-caption-p)) (attributes (org-html--make-attribute-string (org-combine-plists (and label (list :id (org-export-solidify-link-text label))) - (plist-get info :html-table-attributes) + (and (not (org-html-html5-p info)) + (plist-get info :html-table-attributes)) (org-export-read-attribute :attr_html table)))) (alignspec (if (and (boundp 'org-html-format-table-no-css) @@ -3043,7 +3207,9 @@ contextual information." table-cell info) "\n<colgroup>") ;; Add a column. Also specify it's alignment. - (format "\n<col %s/>" (format alignspec alignment)) + (format "\n%s" + (org-html-close-tag + "col" (concat " " (format alignspec alignment)) info)) ;; End a colgroup? (when (org-export-table-cell-ends-colgroup-p table-cell info) @@ -3052,8 +3218,13 @@ contextual information." (format "<table%s>\n%s\n%s\n%s</table>" (if (equal attributes "") "" (concat " " attributes)) (if (not caption) "" - (format "<caption>%s</caption>" - (org-export-data caption info))) + (format (if org-html-table-caption-above + "<caption align=\"above\">%s</caption>" + "<caption align=\"bottom\">%s</caption>") + (concat + "<span class=\"table-number\">" + (format (org-html--translate "Table %d:" info) number) + "</span> " (org-export-data caption info)))) (funcall table-column-specs table info) contents))))) @@ -3105,9 +3276,10 @@ contextual information." ;; Replace each newline character with line break. Also replace ;; each blank line with a line break. (setq contents (replace-regexp-in-string - "^ *\\\\\\\\$" "<br/>\n" + "^ *\\\\\\\\$" (format "%s\n" (org-html-close-tag "br" nil info)) (replace-regexp-in-string - "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n" contents))) + "\\(\\\\\\\\\\)?[ \t]*\n" + (format "%s\n" (org-html-close-tag "br" nil info)) contents))) ;; Replace each white space at beginning of a line with a ;; non-breaking space. (while (string-match "^[ \t]+" contents) @@ -3167,23 +3339,9 @@ Export is done in a buffer named \"*Org HTML Export*\", which will be displayed when `org-export-show-temporary-export-buffer' is non-nil." (interactive) - (if async - (org-export-async-start - (lambda (output) - (with-current-buffer (get-buffer-create "*Org HTML Export*") - (erase-buffer) - (insert output) - (goto-char (point-min)) - (set-auto-mode t) - (org-export-add-to-stack (current-buffer) 'html))) - `(org-export-as 'html ,subtreep ,visible-only ,body-only ',ext-plist)) - (let ((outbuf (org-export-to-buffer - 'html "*Org HTML Export*" - subtreep visible-only body-only ext-plist))) - ;; Set major mode. - (with-current-buffer outbuf (set-auto-mode t)) - (when org-export-show-temporary-export-buffer - (switch-to-buffer-other-window outbuf))))) + (org-export-to-buffer 'html "*Org HTML Export*" + async subtreep visible-only body-only ext-plist + (lambda () (set-auto-mode t)))) ;;;###autoload (defun org-html-convert-region-to-html () @@ -3227,16 +3385,8 @@ Return output file's name." (let* ((extension (concat "." org-html-extension)) (file (org-export-output-file-name extension subtreep)) (org-export-coding-system org-html-coding-system)) - (if async - (org-export-async-start - (lambda (f) (org-export-add-to-stack f 'html)) - (let ((org-export-coding-system org-html-coding-system)) - `(expand-file-name - (org-export-to-file - 'html ,file ,subtreep ,visible-only ,body-only ',ext-plist)))) - (let ((org-export-coding-system org-html-coding-system)) - (org-export-to-file - 'html file subtreep visible-only body-only ext-plist))))) + (org-export-to-file 'html file + async subtreep visible-only body-only ext-plist))) ;;;###autoload (defun org-html-publish-to-html (plist filename pub-dir) @@ -3260,7 +3410,6 @@ Return output file name." ;;;; org-format-table-table-html ;;;; org-table-number-fraction ;;;; org-table-number-regexp -;;;; org-html-table-caption-above ;;;; org-html-inline-image-extensions ;;;; org-export-preferred-target-alist ;;;; class for anchors |