]> code.delx.au - gnu-emacs/blobdiff - lisp/org/ox-html.el
Bump version to 24.5 for the release-candidate
[gnu-emacs] / lisp / org / ox-html.el
index b4094d3e44c5dd7d3b4e47c77c6b938859a53945..78da031142d3847fe659f631e0db9320b999943f 100644 (file)
@@ -1,6 +1,6 @@
 ;;; ox-html.el --- HTML Back-End for Org Export Engine
 
-;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2015 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;;      Jambunathan K <kjambunathan at gmail dot com>
     (:infojs-opt "INFOJS_OPT" nil nil)
     ;; Redefine regular options.
     (:creator "CREATOR" nil org-html-creator-string)
-    (:with-latex nil "tex" org-html-with-latex)))
+    (:with-latex nil "tex" org-html-with-latex)
+    ;; Retrieve LaTeX header for fragments.
+    (:latex-header "LATEX_HEADER" nil nil newline)))
 
 \f
 ;;; Internal Variables
     "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.")
+For blocks that should contain headlines, use the HTML_CONTAINER
+property on the headline itself.")
 
 (defconst org-html-special-string-regexps
   '(("\\\\-" . "&#x00ad;")             ; shy
@@ -277,6 +277,8 @@ for the JavaScript code in this tag.
   pre.src-sql:before   { content: 'SQL'; }
 
   table { border-collapse:collapse; }
+  caption.t-above { caption-side: top; }
+  caption.t-bottom { caption-side: bottom; }
   td, th { vertical-align:top;  }
   th.right  { text-align: center;  }
   th.left   { text-align: center;   }
@@ -453,6 +455,7 @@ export back-end currently used."
              (not org-html-use-infojs)
              (and (eq org-html-use-infojs 'when-configured)
                   (or (not (plist-get exp-plist :infojs-opt))
+                      (string= "" (plist-get exp-plist :infojs-opt))
                       (string-match "\\<view:nil\\>"
                                     (plist-get exp-plist :infojs-opt)))))
     (let* ((template org-html-infojs-template)
@@ -544,6 +547,8 @@ a formatting string to wrap fontified text with.
 If no association can be found for a given markup, text will be
 returned as-is."
   :group 'org-export-html
+  :version "24.4"
+  :package-version '(Org . "8.0")
   :type '(alist :key-type (symbol :tag "Markup type")
                :value-type (string :tag "Format string"))
   :options '(bold code italic strike-through underline verbatim))
@@ -565,7 +570,8 @@ Warning: non-nil may break indentation of source code blocks."
 
 ;;;; Drawers
 
-(defcustom org-html-format-drawer-function nil
+(defcustom org-html-format-drawer-function
+  (lambda (name contents) contents)
   "Function called to format a drawer in HTML code.
 
 The function must accept two parameters:
@@ -575,12 +581,12 @@ The function must accept two parameters:
 The function should return the string to be exported.
 
 For example, the variable could be set to the following function
-in order to mimic default behaviour:
+in order to mimic default behavior:
 
-\(defun org-html-format-drawer-default \(name contents\)
-  \"Format a drawer element for HTML export.\"
-  contents\)"
+The default value simply returns the value of CONTENTS."
   :group 'org-export-html
+  :version "24.4"
+  :package-version '(Org . "8.0")
   :type 'function)
 
 ;;;; Footnotes
@@ -622,7 +628,7 @@ document title."
   :group 'org-export-html
   :type 'integer)
 
-(defcustom org-html-format-headline-function nil
+(defcustom org-html-format-headline-function 'ignore
   "Function to format headline text.
 
 This function will be called with 5 arguments:
@@ -634,6 +640,8 @@ TAGS      the tags (string or nil).
 
 The function result will be used in the section format string."
   :group 'org-export-html
+  :version "24.4"
+  :package-version '(Org . "8.0")
   :type 'function)
 
 ;;;; HTML-specific
@@ -649,7 +657,7 @@ attributes, when appropriate."
 
 ;;;; Inlinetasks
 
-(defcustom org-html-format-inlinetask-function nil
+(defcustom org-html-format-inlinetask-function 'ignore
   "Function called to format an inlinetask in HTML code.
 
 The function must accept six parameters:
@@ -662,6 +670,8 @@ The function must accept six parameters:
 
 The function should return the string to be exported."
   :group 'org-export-html
+  :version "24.4"
+  :package-version '(Org . "8.0")
   :type 'function)
 
 ;;;; LaTeX
@@ -1119,6 +1129,8 @@ like that: \"%%\"."
   "Information about the creator of the HTML document.
 This option can also be set on with the CREATOR keyword."
   :group 'org-export-html
+  :version "24.4"
+  :package-version '(Org . "8.0")
   :type '(string :tag "Creator string"))
 
 ;;;; Template :: Preamble
@@ -1971,7 +1983,8 @@ and value is its relative level, as an integer."
 (defun org-html--format-toc-headline (headline info)
   "Return an appropriate table of contents entry for HEADLINE.
 INFO is a plist used as a communication channel."
-  (let* ((todo (and (plist-get info :with-todo-keywords)
+  (let* ((headline-number (org-export-get-headline-number headline info))
+        (todo (and (plist-get info :with-todo-keywords)
                    (let ((todo (org-element-property :todo-keyword headline)))
                      (and todo (org-export-data todo info)))))
         (todo-type (and todo (org-element-property :todo-type headline)))
@@ -1992,19 +2005,23 @@ INFO is a plist used as a communication channel."
         (tags (and (eq (plist-get info :with-tags) t)
                    (org-export-get-tags headline info))))
     (format "<a href=\"#%s\">%s</a>"
+           ;; Label.
            (org-export-solidify-link-text
             (or (org-element-property :CUSTOM_ID headline)
                 (concat "sec-"
-                        (mapconcat
-                         #'number-to-string
-                         (org-export-get-headline-number headline info)
-                         "-"))))
-           (apply (if (functionp org-html-format-headline-function)
-                      (lambda (todo todo-type priority text tags &rest ignore)
-                        (funcall org-html-format-headline-function
-                                 todo todo-type priority text tags))
-                    #'org-html-format-headline)
-                  todo todo-type priority text tags :section-number nil))))
+                        (mapconcat #'number-to-string headline-number "-"))))
+           ;; Body.
+           (concat
+            (and (not (org-export-low-level-p headline info))
+                 (org-export-numbered-headline-p headline info)
+                 (concat (mapconcat #'number-to-string headline-number ".")
+                         ". "))
+            (apply (if (not (eq org-html-format-headline-function 'ignore))
+                       (lambda (todo todo-type priority text tags &rest ignore)
+                         (funcall org-html-format-headline-function
+                                  todo todo-type priority text tags))
+                     #'org-html-format-headline)
+                   todo todo-type priority text tags :section-number nil)))))
 
 (defun org-html-list-of-listings (info)
   "Build a list of listings.
@@ -2244,7 +2261,7 @@ holding contextual information."
                                                       headline-number "-"))))
         (format-function
          (cond ((functionp format-function) format-function)
-               ((functionp org-html-format-headline-function)
+               ((not (eq org-html-format-headline-function 'ignore))
                 (lambda (todo todo-type priority text tags &rest ignore)
                   (funcall org-html-format-headline-function
                            todo todo-type priority text tags)))
@@ -2258,83 +2275,70 @@ holding contextual information."
   "Transcode a HEADLINE element from Org to HTML.
 CONTENTS holds the contents of the headline.  INFO is a plist
 holding contextual information."
-  ;; Empty contents?
-  (setq contents (or contents ""))
-  (let* ((numberedp (org-export-numbered-headline-p headline info))
-        (level (org-export-get-relative-level headline info))
-        (text (org-export-data (org-element-property :title headline) info))
-        (todo (and (plist-get info :with-todo-keywords)
-                   (let ((todo (org-element-property :todo-keyword headline)))
-                     (and todo (org-export-data todo info)))))
-        (todo-type (and todo (org-element-property :todo-type headline)))
-        (tags (and (plist-get info :with-tags)
-                   (org-export-get-tags headline info)))
-        (priority (and (plist-get info :with-priority)
-                       (org-element-property :priority headline)))
-        (section-number (and (org-export-numbered-headline-p headline info)
-                             (mapconcat 'number-to-string
-                                        (org-export-get-headline-number
-                                         headline info) ".")))
-        ;; Create the headline text.
-        (full-text (org-html-format-headline--wrap headline info)))
-    (cond
-     ;; Case 1: This is a footnote section: ignore it.
-     ((org-element-property :footnote-section-p headline) nil)
-     ;; Case 2. This is a deep sub-tree: export it as a list item.
-     ;;         Also export as items headlines for which no section
-     ;;         format has been found.
-     ((org-export-low-level-p headline info)
-      ;; Build the real contents of the sub-tree.
-      (let* ((type (if numberedp 'ordered 'unordered))
-            (itemized-body (org-html-format-list-item
-                            contents type nil info nil full-text)))
-       (concat
-        (and (org-export-first-sibling-p headline info)
-             (org-html-begin-plain-list type))
-        itemized-body
-        (and (org-export-last-sibling-p headline info)
-             (org-html-end-plain-list type)))))
-     ;; Case 3. Standard headline.  Export it as a section.
-     (t
-      (let* ((section-number (mapconcat 'number-to-string
-                                       (org-export-get-headline-number
-                                        headline info) "-"))
-            (ids (remove 'nil
-                         (list (org-element-property :CUSTOM_ID headline)
-                               (concat "sec-" section-number)
-                               (org-element-property :ID headline))))
-            (preferred-id (car ids))
-            (extra-ids (cdr ids))
-            (extra-class (org-element-property :HTML_CONTAINER_CLASS headline))
-            (level1 (+ level (1- org-html-toplevel-hlevel)))
-            (first-content (car (org-element-contents headline))))
-       (format "<%s id=\"%s\" class=\"%s\">%s%s</%s>\n"
-               (org-html--container headline info)
-               (format "outline-container-%s"
-                       (or (org-element-property :CUSTOM_ID headline)
-                           (concat "sec-" section-number)))
-               (concat (format "outline-%d" level1) (and extra-class " ")
-                       extra-class)
-               (format "\n<h%d id=\"%s\">%s%s</h%d>\n"
-                       level1
-                       preferred-id
-                       (mapconcat
-                        (lambda (x)
-                          (let ((id (org-export-solidify-link-text
-                                     (if (org-uuidgen-p x) (concat "ID-" x)
-                                       x))))
-                            (org-html--anchor id)))
-                        extra-ids "")
-                       full-text
-                       level1)
-               ;; When there is no section, pretend there is an empty
-               ;; one to get the correct <div class="outline- ...>
-               ;; which is needed by `org-info.js'.
-               (if (not (eq (org-element-type first-content) 'section))
-                   (concat (org-html-section first-content "" info)
-                           contents)
-                 contents)
-               (org-html--container headline info)))))))
+  (unless (org-element-property :footnote-section-p headline)
+    (let* ((contents (or contents ""))
+          (numberedp (org-export-numbered-headline-p headline info))
+          (level (org-export-get-relative-level headline info))
+          (text (org-export-data (org-element-property :title headline) info))
+          (todo (and (plist-get info :with-todo-keywords)
+                     (let ((todo (org-element-property :todo-keyword headline)))
+                       (and todo (org-export-data todo info)))))
+          (todo-type (and todo (org-element-property :todo-type headline)))
+          (tags (and (plist-get info :with-tags)
+                     (org-export-get-tags headline info)))
+          (priority (and (plist-get info :with-priority)
+                         (org-element-property :priority headline)))
+          (section-number (mapconcat #'number-to-string
+                                     (org-export-get-headline-number
+                                      headline info) "-"))
+          (ids (delq 'nil
+                     (list (org-element-property :CUSTOM_ID headline)
+                           (concat "sec-" section-number)
+                           (org-element-property :ID headline))))
+          (preferred-id (car ids))
+          (extra-ids (mapconcat
+                      (lambda (id)
+                        (org-html--anchor
+                         (org-export-solidify-link-text
+                          (if (org-uuidgen-p id) (concat "ID-" id) id))))
+                      (cdr ids) ""))
+          ;; Create the headline text.
+          (full-text (org-html-format-headline--wrap headline info)))
+      (if (org-export-low-level-p headline info)
+         ;; This is a deep sub-tree: export it as a list item.
+         (let* ((type (if numberedp 'ordered 'unordered))
+                (itemized-body
+                 (org-html-format-list-item
+                  contents type nil info nil
+                  (concat (org-html--anchor preferred-id) extra-ids
+                          full-text))))
+           (concat
+            (and (org-export-first-sibling-p headline info)
+                 (org-html-begin-plain-list type))
+            itemized-body
+            (and (org-export-last-sibling-p headline info)
+                 (org-html-end-plain-list type))))
+       ;; Standard headline.  Export it as a section.
+       (let ((extra-class (org-element-property :HTML_CONTAINER_CLASS headline))
+             (level1 (+ level (1- org-html-toplevel-hlevel)))
+             (first-content (car (org-element-contents headline))))
+         (format "<%s id=\"%s\" class=\"%s\">%s%s</%s>\n"
+                 (org-html--container headline info)
+                 (format "outline-container-%s"
+                         (or (org-element-property :CUSTOM_ID headline)
+                             (concat "sec-" section-number)))
+                 (concat (format "outline-%d" level1) (and extra-class " ")
+                         extra-class)
+                 (format "\n<h%d id=\"%s\">%s%s</h%d>\n"
+                         level1 preferred-id extra-ids full-text level1)
+                 ;; When there is no section, pretend there is an
+                 ;; empty one to get the correct <div class="outline-
+                 ;; ...> which is needed by `org-info.js'.
+                 (if (not (eq (org-element-type first-content) 'section))
+                     (concat (org-html-section first-content "" info)
+                             contents)
+                   contents)
+                 (org-html--container headline info)))))))
 
 (defun org-html--container (headline info)
   (or (org-element-property :HTML_CONTAINER headline)
@@ -2371,9 +2375,9 @@ contextual information."
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
   (cond
-   ;; If `org-html-format-inlinetask-function' is provided, call it
+   ;; If `org-html-format-inlinetask-function' is not 'ignore, call it
    ;; with appropriate arguments.
-   ((functionp org-html-format-inlinetask-function)
+   ((not (eq org-html-format-inlinetask-function 'ignore))
     (let ((format-function
           (function*
            (lambda (todo todo-type priority text tags
@@ -2474,18 +2478,34 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 
 ;;;; Latex Environment
 
-(defun org-html-format-latex (latex-frag processing-type)
-  "Format a LaTeX fragment LATEX-FRAG into HTML."
+(defun org-html-format-latex (latex-frag processing-type info)
+  "Format a LaTeX fragment LATEX-FRAG into HTML.
+PROCESSING-TYPE designates the tool used for conversion.  It is
+a symbol among `mathjax', `dvipng', `imagemagick', `verbatim' nil
+and t.  See `org-html-with-latex' for more information.  INFO is
+a plist containing export properties."
   (let ((cache-relpath "") (cache-dir ""))
     (unless (eq processing-type 'mathjax)
       (let ((bfn (or (buffer-file-name)
                     (make-temp-name
-                     (expand-file-name "latex" temporary-file-directory)))))
+                     (expand-file-name "latex" temporary-file-directory))))
+           (latex-header
+            (let ((header (plist-get info :latex-header)))
+              (and header
+                   (concat (mapconcat
+                            (lambda (line) (concat "#+LATEX_HEADER: " line))
+                            (org-split-string header "\n")
+                            "\n")
+                           "\n")))))
        (setq cache-relpath
              (concat "ltxpng/"
                      (file-name-sans-extension
                       (file-name-nondirectory bfn)))
-             cache-dir (file-name-directory bfn))))
+             cache-dir (file-name-directory bfn))
+       ;; Re-create LaTeX environment from original buffer in
+       ;; temporary buffer so that dvipng/imagemagick can properly
+       ;; turn the fragment into an image.
+       (setq latex-frag (concat latex-header latex-frag))))
     (with-temp-buffer
       (insert latex-frag)
       (org-format-latex cache-relpath cache-dir nil "Creating LaTeX Image..."
@@ -2501,9 +2521,10 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
        (attributes (org-export-read-attribute :attr_html latex-environment)))
     (case processing-type
       ((t mathjax)
-       (org-html-format-latex latex-frag 'mathjax))
+       (org-html-format-latex latex-frag 'mathjax info))
       ((dvipng imagemagick)
-       (let ((formula-link (org-html-format-latex latex-frag processing-type)))
+       (let ((formula-link
+             (org-html-format-latex latex-frag processing-type info)))
         (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
           ;; Do not provide a caption or a name to be consistent with
           ;; `mathjax' handling.
@@ -2521,9 +2542,10 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
        (processing-type (plist-get info :with-latex)))
     (case processing-type
       ((t mathjax)
-       (org-html-format-latex latex-frag 'mathjax))
+       (org-html-format-latex latex-frag 'mathjax info))
       ((dvipng imagemagick)
-       (let ((formula-link (org-html-format-latex latex-frag processing-type)))
+       (let ((formula-link
+             (org-html-format-latex latex-frag processing-type info)))
         (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
           (org-html--format-image (match-string 1 formula-link) nil info))))
       (t latex-frag))))
@@ -2561,18 +2583,17 @@ if its description is a single link targeting an image file."
 
 (defvar org-html-standalone-image-predicate)
 (defun org-html-standalone-image-p (element info)
-  "Test if ELEMENT is a standalone image.
+  "Non-nil if ELEMENT is a standalone image.
 
 INFO is a plist holding contextual information.
 
-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.
+An element or object is a standalone image when
 
-Return non-nil, if ELEMENT is of type link and its containing
-paragraph has no other content save white spaces.
+  - its type is `paragraph' and its sole content, save for white
+    spaces, is a link that qualifies as an inline image;
 
-Return nil, otherwise.
+  - its type is `link' and its containing paragraph has no other
+    content save white spaces.
 
 Bind `org-html-standalone-image-predicate' to constrain paragraph
 further.  For example, to check for only captioned standalone
@@ -2583,19 +2604,21 @@ images, set it to:
                     (paragraph element)
                     (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)))
+        (or (not (fboundp '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))))))
+        (catch 'exit
+          (let ((link-count 0))
+            (org-element-map (org-element-contents paragraph)
+                (cons 'plain-text org-element-all-objects)
+              #'(lambda (obj)
+                  (when (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))
+                    (throw 'exit nil)))
+              info nil 'link)
+            (= link-count 1))))))
 
 (defun org-html-link (link desc info)
   "Transcode a LINK object from Org to HTML.
@@ -2625,19 +2648,20 @@ INFO is a plist holding contextual information.  See
         (path
          (cond
           ((member type '("http" "https" "ftp" "mailto"))
-           (concat type ":" raw-path))
+           (org-link-escape
+            (org-link-unescape
+             (concat type ":" raw-path)) org-link-escape-chars-browser))
           ((string= type "file")
            ;; Treat links to ".org" files as ".html", if needed.
            (setq raw-path
                  (funcall link-org-files-as-html-maybe raw-path info))
            ;; If file path is absolute, prepend it with protocol
-           ;; component - "file://".
-           (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))))
+           ;; component - "file:".
+           (cond
+            ((file-name-absolute-p raw-path)
+             (setq raw-path (concat "file:" 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.
@@ -2683,11 +2707,11 @@ INFO is a plist holding contextual information.  See
      ;; link's description.
      ((string= type "radio")
       (let ((destination (org-export-resolve-radio-link link info)))
-       (when destination
+       (if (not destination) desc
          (format "<a href=\"#%s\"%s>%s</a>"
-                 (org-export-solidify-link-text path)
-                 attributes
-                 (org-export-data (org-element-contents destination) info)))))
+                 (org-export-solidify-link-text
+                  (org-element-property :value destination))
+                 attributes desc))))
      ;; Links pointing to a headline: Find destination and build
      ;; appropriate referencing command.
      ((member type '("custom-id" "fuzzy" "id"))
@@ -3221,8 +3245,8 @@ contextual information."
               (if (equal attributes "") "" (concat " " attributes))
               (if (not caption) ""
                 (format (if org-html-table-caption-above
-                            "<caption align=\"above\">%s</caption>"
-                          "<caption align=\"bottom\">%s</caption>")
+                            "<caption class=\"t-above\">%s</caption>"
+                          "<caption class=\"t-bottom\">%s</caption>")
                         (concat
                          "<span class=\"table-number\">"
                           (format (org-html--translate "Table %d:" info) number)
@@ -3404,21 +3428,6 @@ Return output file name."
                                      org-html-extension "html"))
                      plist pub-dir))
 
-\f
-;;; FIXME
-
-;;;; org-format-table-html
-;;;; org-format-org-table-html
-;;;; org-format-table-table-html
-;;;; org-table-number-fraction
-;;;; org-table-number-regexp
-;;;; org-html-inline-image-extensions
-;;;; org-export-preferred-target-alist
-;;;; class for anchors
-;;;; org-export-mark-todo-in-toc
-;;;; org-html-format-org-link
-;;;; (caption (and caption (org-xml-encode-org-text caption)))
-;;;; alt = (file-name-nondirectory path)
 
 (provide 'ox-html)