summaryrefslogtreecommitdiff
path: root/lisp/ox-html.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/ox-html.el')
-rw-r--r--lisp/ox-html.el663
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
'(("\\\\-" . "&#x00ad;") ; shy
("---\\([^-]\\)" . "&#x2014;\\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."
"\"" "&quot;" (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 "&#xa0;&#xa0;&#xa0;") (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