Merge upstream Org (from commit acbbe2)
[bpt/emacs.git] / lisp / org / org-exp.el
index 73e0951..a578fe7 100644 (file)
@@ -1,12 +1,10 @@
-;;; org-exp.el --- ASCII, HTML, XOXO and iCalendar export for Org-mode
+;;; org-exp.el --- Export internals for Org-mode
 
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 2004-2012 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
-;; Version: 7.3
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 (declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
 (declare-function org-table-cookie-line-p "org-table" (line))
 (declare-function org-table-colgroup-line-p "org-table" (line))
+(declare-function org-pop-to-buffer-same-window "org-compat"
+                 (&optional buffer-or-name norecord label))
+(declare-function org-unescape-code-in-region "org-src" (beg end))
+
 (autoload 'org-export-generic "org-export-generic" "Export using the generic exporter" t)
+
+(autoload 'org-export-as-odt "org-odt"
+  "Export the outline to a OpenDocument Text file." t)
+(autoload 'org-export-as-odt-and-open "org-odt"
+  "Export the outline to a OpenDocument Text file and open it." t)
+
 (defgroup org-export nil
   "Options for exporting org-listings."
   :tag "Org Export"
@@ -88,9 +96,10 @@ is nil, the buffer remains buried also in these cases."
 
 (defcustom org-export-kill-product-buffer-when-displayed nil
   "Non-nil means kill the product buffer if it is displayed immediately.
-This applied to the commands `org-export-html-and-open' and
+This applied to the commands `org-export-as-html-and-open' and
 `org-export-as-pdf-and-open'."
   :group 'org-export-general
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-export-run-in-background nil
@@ -109,6 +118,15 @@ force an export command into the current process."
   :group 'org-export-general
   :type 'boolean)
 
+(defcustom org-export-initial-scope 'buffer
+  "The initial scope when exporting with `org-export'.
+This variable can be either set to 'buffer or 'subtree."
+  :group 'org-export-general
+  :version "24.1"
+  :type '(choice
+         (const :tag "Export current buffer" 'buffer)
+         (const :tag "Export current subtree" 'subtree)))
+
 (defcustom org-export-select-tags '("export")
   "Tags that select a tree for export.
 If any such tag is found in a buffer, all trees that do not carry one
@@ -173,16 +191,31 @@ This option can also be set with the +OPTIONS line, e.g. \"-:nil\"."
     ("eo"  "A&#365;toro"      "Dato" "Enhavo" "Piednotoj")
     ("es" "Autor"      "Fecha" "&Iacute;ndice" "Pies de p&aacute;gina")
     ("fi" "Tekij&auml;"     "P&auml;iv&auml;m&auml;&auml;r&auml;"   "Sis&auml;llysluettelo"  "Alaviitteet")
-    ("fr" "Auteur"     "Date"  "Table des mati&egrave;res" "Notes de bas de page")
+    ("fr" "Auteur"     "Date"  "Sommaire" "Notes de bas de page")
     ("hu" "Szerz&otilde;" "D&aacute;tum" "Tartalomjegyz&eacute;k" "L&aacute;bjegyzet")
     ("is" "H&ouml;fundur" "Dagsetning" "Efnisyfirlit" "Aftanm&aacute;lsgreinar")
     ("it" "Autore"     "Data"  "Indice" "Note a pi&egrave; di pagina")
+    ;; Use numeric character entities for proper rendering of non-UTF8 documents
+    ;; ("ja" "著者"       "日付"  "目次"          "脚注")
+    ("ja" "&#33879;&#32773;" "&#26085;&#20184;" "&#30446;&#27425;" "&#33050;&#27880;")
     ("nl" "Auteur"     "Datum" "Inhoudsopgave" "Voetnoten")
     ("no" "Forfatter"  "Dato"  "Innhold" "Fotnoter")
     ("nb" "Forfatter"  "Dato"  "Innhold" "Fotnoter")  ;; nb = Norsk (bokm.l)
     ("nn" "Forfattar"  "Dato"  "Innhald" "Fotnotar")  ;; nn = Norsk (nynorsk)
     ("pl" "Autor"      "Data" "Spis tre&#x015b;ci"  "Przypis")
-    ("sv" "F&ouml;rfattare" "Datum" "Inneh&aring;ll" "Fotnoter"))
+    ;; Use numeric character entities for proper rendering of non-UTF8 documents
+    ;; ("ru" "Автор"      "Дата"  "Содержание" "Сноски")
+    ("ru" "&#1040;&#1074;&#1090;&#1086;&#1088;"      "&#1044;&#1072;&#1090;&#1072;"  "&#1057;&#1086;&#1076;&#1077;&#1088;&#1078;&#1072;&#1085;&#1080;&#1077;" "&#1057;&#1085;&#1086;&#1089;&#1082;&#1080;")
+    ("sv" "F&ouml;rfattare" "Datum" "Inneh&aring;ll" "Fotnoter")
+    ;; Use numeric character entities for proper rendering of non-UTF8 documents
+    ;; ("uk" "Автор" "Дата" "Зміст" "Примітки")
+    ("uk" "&#1040;&#1074;&#1090;&#1086;&#1088;" "&#1044;&#1072;&#1090;&#1072;" "&#1047;&#1084;&#1110;&#1089;&#1090;" "&#1055;&#1088;&#1080;&#1084;&#1110;&#1090;&#1082;&#1080;")
+    ;; Use numeric character entities for proper rendering of non-UTF8 documents
+    ;; ("zh-CN" "作者" "日期" "目录" "脚注")
+    ("zh-CN" "&#20316;&#32773;" "&#26085;&#26399;" "&#30446;&#24405;" "&#33050;&#27880;")
+    ;; Use numeric character entities for proper rendering of non-UTF8 documents
+    ;; ("zh-TW" "作者" "日期" "目錄" "腳註")
+    ("zh-TW" "&#20316;&#32773;" "&#26085;&#26399;" "&#30446;&#37636;" "&#33139;&#35387;"))
   "Terms used in export text, translated to different languages.
 Use the variable `org-export-default-language' to set the language,
 or use the +OPTION lines for a per-file setting."
@@ -196,11 +229,18 @@ or use the +OPTION lines for a per-file setting."
           (string :tag "Footnotes"))))
 
 (defcustom org-export-default-language "en"
-  "The default language of HTML export, as a string.
-This should have an association in `org-export-language-setup'."
+  "The default language for export and clocktable translations, as a string.
+This should have an association in `org-export-language-setup'
+and in `org-clock-clocktable-language-setup'."
   :group 'org-export-general
   :type 'string)
 
+(defcustom org-export-date-timestamp-format "%Y-%m-%d"
+  "Time string format for Org timestamps in the #+DATE option."
+  :group 'org-export-general
+  :version "24.1"
+  :type 'string)
+
 (defvar org-export-page-description ""
   "The page description, for the XHTML meta tag.
 This is best set with the #+DESCRIPTION line in a file, it does not make
@@ -287,6 +327,24 @@ When nil, remove all these keywords from the export."
   :group 'org-export-general
   :type 'boolean)
 
+(defcustom org-export-with-tasks t
+  "Non-nil means include TODO items for export.
+This may have the following values:
+t                    include tasks independent of state.
+todo                 include only tasks that are not yet done.
+done                 include only tasks that are already done.
+nil                  remove all tasks before export
+list of TODO kwds    keep only tasks with these keywords"
+  :group 'org-export-general
+  :version "24.1"
+  :type '(choice
+         (const :tag "All tasks" t)
+         (const :tag "No tasks" nil)
+         (const :tag "Not-done tasks" todo)
+         (const :tag "Only done tasks" done)
+         (repeat :tag "Specific TODO keywords"
+                 (string :tag "Keyword"))))
+
 (defcustom org-export-with-priority nil
   "Non-nil means include priority cookies in export.
 When nil, remove priority cookies for export."
@@ -329,6 +387,7 @@ e.g. \"author:nil\"."
 This option can also be set with the +OPTIONS line,
 e.g. \"email:t\"."
   :group 'org-export-general
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-export-creator-info t
@@ -388,7 +447,7 @@ Good for general initialization")
   "Hook for preprocessing an export buffer.
 Pretty much the first thing when exporting is running this hook.
 Point will be in a temporary buffer that contains a copy of
-the original buffer, or of the section that is being export.
+the original buffer, or of the section that is being exported.
 All the other hooks in the org-export-preprocess... category
 also work in that temporary buffer, already modified by various
 stages of the processing.")
@@ -475,19 +534,21 @@ This option can also be set with the +OPTIONS line, e.g. \"TeX:nil\"."
   "Non-nil means process LaTeX math fragments for HTML display.
 When set, the exporter will find and process LaTeX environments if the
 \\begin line is the first non-white thing on a line.  It will also find
-and process  the math delimiters like $a=b$ and \\( a=b \\) for inline math,
-$$a=b$$ and \\[ a=b \\] for display math.
+and process the math delimiters like $a=b$ and \\( a=b \\) for inline math,
+$$a=b$$ and \\=\\[ a=b \\] for display math.
 
 This option can also be set with the +OPTIONS line, e.g. \"LaTeX:mathjax\".
 
 Allowed values are:
 
-nil        Don't do anything.
-verbatim   Keep eveything in verbatim
-dvipng     Process the LaTeX fragments to images.
-           This will also include processing of non-math environments.
-t          Do MathJax preprocessing if there is at least on math snippet,
-           and arrange for MathJax.js to be loaded.
+nil             Don't do anything.
+verbatim        Keep everything in verbatim
+dvipng          Process the LaTeX fragments to images.
+                This will also include processing of non-math environments.
+imagemagick     Convert the LaTeX fragments to pdf files and use imagemagick
+                to convert pdf files to png files.
+t               Do MathJax preprocessing if there is at least on math snippet,
+                and arrange for MathJax.js to be loaded.
 
 The default is nil, because this option needs the `dvipng' program which
 is not available on all systems."
@@ -497,6 +558,7 @@ is not available on all systems."
          (const :tag "Do not process math in any way" nil)
          (const :tag "Obsolete, use dvipng setting" t)
          (const :tag "Use dvipng to make images" dvipng)
+         (const :tag "Use imagemagick to make images" imagemagick)
          (const :tag "Use MathJax to display math" mathjax)
          (const :tag "Leave math verbatim" verbatim)))
 
@@ -551,6 +613,14 @@ the values of constants may be useful to have."
   :group 'org-export-tables
   :type 'boolean)
 
+(defcustom org-export-table-remove-empty-lines t
+  "Remove empty lines when exporting tables.
+This is the global equivalent of the :remove-nil-lines option
+when locally sending a table with #+ORGTBL."
+  :group 'org-export-tables
+  :version "24.1"
+  :type 'boolean)
+
 (defcustom org-export-prefer-native-exporter-for-tables nil
   "Non-nil means always export tables created with table.el natively.
 Natively means use the HTML code generator in table.el.
@@ -563,18 +633,20 @@ table.el tables."
   :group 'org-export-tables
   :type 'boolean)
 
-
-(defgroup org-export-xml nil
-  "Options specific for XML export of Org-mode files."
-  :tag "Org Export XML"
-  :group 'org-export)
-
 ;;;; Exporting
 
 ;;; Variables, constants, and parameter plists
 
 (defconst org-level-max 20)
 
+(defvar org-export-current-backend nil
+  "During export, this will be bound to a symbol such as 'html,
+  'latex, 'docbook, 'ascii, etc, indicating which of the export
+  backends is in use.  Otherwise it has the value nil.  Users
+  should not attempt to change the value of this variable
+  directly, but it can be used in code to test whether export is
+  in progress, and if so, what the backend is.")
+
 (defvar org-current-export-file nil) ; dynamically scoped parameter
 (defvar org-current-export-dir nil) ; dynamically scoped parameter
 (defvar org-export-opt-plist nil
@@ -582,6 +654,11 @@ table.el tables."
 (defvar org-last-level nil) ; dynamically scoped variable
 (defvar org-min-level nil) ; dynamically scoped variable
 (defvar org-levels-open nil) ; dynamically scoped parameter
+(defvar org-export-footnotes-data nil
+  "Alist of labels used in buffers, along with their definition.")
+(defvar org-export-footnotes-seen nil
+  "Alist of labels encountered so far by the exporter, along with their definition.")
+
 
 (defconst org-export-plist-vars
   '((:link-up                nil         org-export-html-link-up)
@@ -603,6 +680,7 @@ table.el tables."
     (:drawers                "d"         org-export-with-drawers)
     (:tags                   "tags"      org-export-with-tags)
     (:todo-keywords          "todo"      org-export-with-todo-keywords)
+    (:tasks                  "tasks"     org-export-with-tasks)
     (:priority               "pri"       org-export-with-priority)
     (:TeX-macros             "TeX"       org-export-with-TeX-macros)
     (:LaTeX-fragments        "LaTeX"     org-export-with-LaTeX-fragments)
@@ -610,6 +688,8 @@ table.el tables."
     (:skip-before-1st-heading "skip"     org-export-skip-text-before-1st-heading)
     (:fixed-width            ":"         org-export-with-fixed-width)
     (:timestamps             "<"         org-export-with-timestamps)
+    (:author                 nil         user-full-name)
+    (:email                  nil         user-mail-address)
     (:author-info            "author"    org-export-author-info)
     (:email-info             "email"     org-export-email-info)
     (:creator-info           "creator"   org-export-creator-info)
@@ -624,17 +704,13 @@ table.el tables."
     (:convert-org-links              nil         org-export-html-link-org-files-as-html)
     (:inline-images          nil         org-export-html-inline-images)
     (:html-extension         nil         org-export-html-extension)
+    (:html-preamble          nil         org-export-html-preamble)
+    (:html-postamble         nil         org-export-html-postamble)
     (:xml-declaration         nil        org-export-html-xml-declaration)
     (:html-table-tag         nil         org-export-html-table-tag)
     (:expand-quoted-html      "@"        org-export-html-expand)
     (:timestamp                      nil         org-export-html-with-timestamp)
     (:publishing-directory    nil        org-export-publishing-directory)
-    (:preamble               nil         org-export-html-preamble)
-    (:postamble                      nil         org-export-html-postamble)
-    (:auto-preamble          nil         org-export-html-auto-preamble)
-    (:auto-postamble         nil         org-export-html-auto-postamble)
-    (:author                 nil         user-full-name)
-    (:email                  nil         user-mail-address)
     (:select-tags            nil         org-export-select-tags)
     (:exclude-tags           nil         org-export-exclude-tags)
 
@@ -645,7 +721,7 @@ Each element is a list of 3 items:
 2. The string that can be used in the OPTION lines to set this option,
    or nil if this option cannot be changed in this way
 3. The customization variable that sets the default for this option."
-)
+  )
 
 (defun org-default-export-plist ()
   "Return the property list with default settings for the export variables."
@@ -656,8 +732,7 @@ Each element is a list of 3 items:
       (setq s (nth 2 e)
            v (cond
               ((assq s letbind) (nth 1 (assq s letbind)))
-              ((boundp s) (symbol-value s))
-              (t nil))
+              ((boundp s) (symbol-value s)))
            rtn (cons (car e) (cons v rtn))))
     rtn))
 
@@ -680,6 +755,7 @@ must accept the property list as an argument, and must return the (possibly
 modified) list.")
 
 ;; FIXME: should we fold case here?
+
 (defun org-infile-export-plist ()
   "Return the property list with file-local settings for export."
   (save-excursion
@@ -691,14 +767,14 @@ modified) list.")
                  '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE"
                    "MATHJAX"
                    "LINK_UP" "LINK_HOME" "SETUPFILE" "STYLE"
-                   "LATEX_HEADER" "LATEX_CLASS"
+                   "LATEX_HEADER" "LATEX_CLASS" "LATEX_CLASS_OPTIONS"
                    "EXPORT_SELECT_TAGS" "EXPORT_EXCLUDE_TAGS"
                    "KEYWORDS" "DESCRIPTION" "MACRO" "BIND" "XSLT")
                  (mapcar 'car org-export-inbuffer-options-extra))))
            (case-fold-search t)
            p key val text options mathjax a pr style
-           latex-header latex-class macros letbind
-           ext-setup-or-nil setup-contents (start 0))
+           latex-header latex-class latex-class-options macros letbind
+           ext-setup-or-nil setup-file setup-dir setup-contents (start 0))
        (while (or (and ext-setup-or-nil
                        (string-match re ext-setup-or-nil start)
                        (setq start (match-end 0)))
@@ -713,7 +789,15 @@ modified) list.")
           ((string-equal key "TITLE") (setq p (plist-put p :title val)))
           ((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
           ((string-equal key "EMAIL") (setq p (plist-put p :email val)))
-          ((string-equal key "DATE") (setq p (plist-put p :date val)))
+          ((string-equal key "DATE")
+           ;; If date is an Org timestamp, convert it to a time
+           ;; string using `org-export-date-timestamp-format'
+           (when (string-match org-ts-regexp3 val)
+             (setq val (format-time-string
+                        org-export-date-timestamp-format
+                        (apply 'encode-time (org-parse-time-string
+                                             (match-string 0 val))))))
+           (setq p (plist-put p :date val)))
           ((string-equal key "KEYWORDS") (setq p (plist-put p :keywords val)))
           ((string-equal key "DESCRIPTION")
            (setq p (plist-put p :description val)))
@@ -724,6 +808,8 @@ modified) list.")
            (setq latex-header (concat latex-header "\n" val)))
           ((string-equal key "LATEX_CLASS")
            (setq latex-class val))
+           ((string-equal key "LATEX_CLASS_OPTIONS")
+            (setq latex-class-options val))
           ((string-equal key "TEXT")
            (setq text (if text (concat text "\n" val) val)))
           ((string-equal key "OPTIONS")
@@ -745,11 +831,14 @@ modified) list.")
           ((string-equal key "MACRO")
            (push val macros))
           ((equal key "SETUPFILE")
-           (setq setup-contents (org-file-contents
-                                 (expand-file-name
-                                  (org-remove-double-quotes
-                                   (org-trim val)))
-                                 'noerror))
+           (setq setup-file (org-remove-double-quotes (org-trim val))
+                 ;; take care of recursive inclusion of setupfiles
+                 setup-file (if (or (file-name-absolute-p val) (not setup-dir))
+                                (expand-file-name setup-file)
+                              (let ((default-directory setup-dir))
+                                (expand-file-name setup-file))))
+           (setq setup-dir (file-name-directory setup-file))
+           (setq setup-contents (org-file-contents setup-file 'noerror))
            (if (not ext-setup-or-nil)
                (setq ext-setup-or-nil setup-contents start 0)
              (setq ext-setup-or-nil
@@ -764,6 +853,8 @@ modified) list.")
          (setq p (plist-put p :latex-header-extra (substring latex-header 1))))
        (when latex-class
          (setq p (plist-put p :latex-class latex-class)))
+        (when latex-class-options
+          (setq p (plist-put p :latex-class-options latex-class-options)))
        (when options
          (setq p (org-export-add-options-to-plist p options)))
        (when mathjax
@@ -800,7 +891,7 @@ modified) list.")
 (defvar org-export-allow-BIND-local nil)
 (defun org-export-confirm-letbind ()
   "Can we use #+BIND values during export?
-By default this will ask fro confirmation by the user, to divert possible
+By default this will ask for confirmation by the user, to divert possible
 security risks."
   (cond
    ((not org-export-allow-BIND) nil)
@@ -824,12 +915,13 @@ security risks."
       (let ((op org-export-plist-vars))
        (while (setq o (pop op))
          (if (and (nth 1 o)
-                  (string-match (concat (regexp-quote (nth 1 o))
-                                        ":\\([^ \t\n\r;,.]*\\)")
+                  (string-match (concat "\\(\\`\\|[ \t]\\)"
+                                        (regexp-quote (nth 1 o))
+                                        ":\\(([^)\n]+)\\|[^ \t\n\r;,.]*\\)")
                                 options))
              (setq p (plist-put p (car o)
                                 (car (read-from-string
-                                      (match-string 1 options))))))))))
+                                      (match-string 2 options))))))))))
   p)
 
 (defun org-export-add-subtree-options (p pos)
@@ -874,13 +966,20 @@ to a file.  For details see the docstring of `org-export-run-in-background'.
 The prefix argument ARG will be passed to the exporter.  However, if
 ARG is a double universal prefix \\[universal-argument] \\[universal-argument], \
 that means to inverse the
-value of `org-export-run-in-background'."
+value of `org-export-run-in-background'.
+
+If `org-export-initial-scope' is set to 'subtree, try to export
+the current subtree, otherwise try to export the whole buffer.
+Pressing `1' will switch between these two options."
   (interactive "P")
   (let* ((bg (org-xor (equal arg '(16)) org-export-run-in-background))
-        subtree-p
+        (subtree-p (or (org-region-active-p)
+                       (eq org-export-initial-scope 'subtree)))
+        (regb (and (org-region-active-p) (region-beginning)))
+        (rege (and (org-region-active-p) (region-end)))
         (help "[t]   insert the export option template
 \[v]   limit export to visible part of outline tree
-\[1]   only export the current subtree
+\[1]   switch buffer/subtree export
 \[SPC] publish enclosing subtree (with LaTeX_CLASS or EXPORT_FILE_NAME prop)
 
 \[a/n/u] export as ASCII/Latin-1/UTF-8         [A/N/U] to temporary buffer
@@ -893,6 +992,8 @@ value of `org-export-run-in-background'."
 
 \[D] export as DocBook   [V] export as DocBook, process to PDF, and open
 
+\[o] export as OpenDocument Text                   [O] ... and open
+
 \[j] export as TaskJuggler                         [J] ... and open
 
 \[m] export as Freemind mind map
@@ -921,6 +1022,8 @@ value of `org-export-run-in-background'."
            (?g org-export-generic t)
            (?D org-export-as-docbook t)
            (?V org-export-as-docbook-pdf-and-open t)
+           (?o org-export-as-odt t)
+           (?O org-export-as-odt-and-open t)
            (?j org-export-as-taskjuggler t)
            (?J org-export-as-taskjuggler-and-open t)
            (?m org-export-as-freemind t)
@@ -939,30 +1042,42 @@ value of `org-export-run-in-background'."
         (cpos (point)) (cbuf (current-buffer)) bpos)
     (save-excursion
       (save-window-excursion
+       (if subtree-p
+           (message "Export subtree: ")
+         (message "Export buffer: "))
        (delete-other-windows)
        (with-output-to-temp-buffer "*Org Export/Publishing Help*"
          (princ help))
        (org-fit-window-to-buffer (get-buffer-window
                                   "*Org Export/Publishing Help*"))
-       (message "Select command: ")
-       (setq r1 (read-char-exclusive))
-       (when (eq r1 ?1)
-         (setq subtree-p t)
-         (message "Select command (for subtree): ")
-         (setq r1 (read-char-exclusive)))
+       (while (eq (setq r1 (read-char-exclusive)) ?1)
+         (cond (subtree-p
+                (setq subtree-p nil)
+                (message "Export buffer: "))
+               ((not subtree-p)
+                (setq subtree-p t)
+                (setq bpos (point))
+                (org-mark-subtree)
+                (org-activate-mark)
+                (setq regb (and (org-region-active-p) (region-beginning)))
+                (setq rege (and (org-region-active-p) (region-end)))
+                (message "Export subtree: "))))
        (when (eq r1 ?\ )
-         (let ((case-fold-search t))
+         (let ((case-fold-search t)
+               (end (save-excursion (while (org-up-heading-safe)) (point))))
+           (outline-next-heading)
            (if (re-search-backward
-                "^[ \t]+\\(:latex_class:\\|:export_title:\\)[ \t]+\\S-"
-                nil t)
+                "^[ \t]+\\(:latex_class:\\|:export_title:\\|:export_file_name:\\)[ \t]+\\S-"
+                end t)
                (progn
                  (org-back-to-heading t)
                  (setq subtree-p t)
                  (setq bpos (point))
                  (message "Select command (for subtree): ")
                  (setq r1 (read-char-exclusive)))
-             (error "No enclosing node with LaTeX_CLASS or EXPORT_FILE_NAME")
+             (error "No enclosing node with LaTeX_CLASS or EXPORT_TITLE or EXPORT_FILE_NAME")
              )))))
+    (if (fboundp 'redisplay) (redisplay)) ;; XEmacs does not have/need (redisplay)
     (and bpos (goto-char bpos))
     (setq r2 (if (< r1 27) (+ r1 96) r1))
     (unless (setq ass (assq r2 cmds))
@@ -983,8 +1098,9 @@ value of `org-export-run-in-background'."
                  "-f" (symbol-name (nth 1 ass)))))
          (set-process-sentinel p 'org-export-process-sentinel)
          (message "Background process \"%s\": started" p))
-      ;; background processing not requested, or not possible
-      (if subtree-p (progn (outline-mark-subtree) (activate-mark)))
+      ;; set the mark correctly when exporting a subtree
+      (if subtree-p (let (deactivate-mark) (push-mark rege t t) (goto-char regb)))
+
       (call-interactively (nth 1 ass))
       (when (and bpos (get-buffer-window cbuf))
        (let ((cw (selected-window)))
@@ -1010,24 +1126,18 @@ value of `org-export-run-in-background'."
   "Alist of code references and line numbers.")
 
 (defun org-export-preprocess-string (string &rest parameters)
-  "Cleanup STRING so that that the true exported has a more consistent source.
+  "Cleanup STRING so that the true exported has a more consistent source.
 This function takes STRING, which should be a buffer-string of an org-file
 to export.  It then creates a temporary buffer where it does its job.
 The result is then again returned as a string, and the exporter works
 on this string to produce the exported version."
   (interactive)
-  (let* ((htmlp (plist-get parameters :for-html))
-        (asciip (plist-get parameters :for-ascii))
-        (latexp (plist-get parameters :for-LaTeX))
-        (docbookp (plist-get parameters :for-docbook))
-        (backend (cond (htmlp 'html)
-                       (latexp 'latex)
-                       (asciip 'ascii)
-                       (docbookp 'docbook)))
+  (let* ((org-export-current-backend (or (plist-get parameters :for-backend)
+                                        org-export-current-backend))
         (archived-trees (plist-get parameters :archived-trees))
         (inhibit-read-only t)
         (drawers org-drawers)
-        (outline-regexp "\\*+ ")
+        (source-buffer (current-buffer))
         target-alist rtn)
 
     (setq org-export-target-aliases nil
@@ -1035,7 +1145,7 @@ on this string to produce the exported version."
          org-export-id-target-alist nil
          org-export-code-refs nil)
 
-    (with-current-buffer (get-buffer-create " org-mode-tmp")
+    (with-temp-buffer
       (erase-buffer)
       (insert string)
       (setq case-fold-search t)
@@ -1051,15 +1161,12 @@ on this string to produce the exported version."
 
       (let ((org-inhibit-startup t)) (org-mode))
       (setq case-fold-search t)
+      (org-clone-local-variables source-buffer "^\\(org-\\|orgtbl-\\)")
       (org-install-letbind)
 
       ;; Call the hook
       (run-hooks 'org-export-preprocess-hook)
 
-      ;; Process the macros
-      (org-export-preprocess-apply-macros)
-      (run-hooks 'org-export-preprocess-after-macros-hook)
-
       (untabify (point-min) (point-max))
 
       ;; Handle include files, and call a hook
@@ -1077,18 +1184,53 @@ on this string to produce the exported version."
                                     (plist-get parameters :exclude-tags))
       (run-hooks 'org-export-preprocess-after-tree-selection-hook)
 
-      ;; Mark end of lists
-      (org-export-mark-list-ending backend)
+      ;; Get rid of tasks, depending on configuration
+      (org-export-remove-tasks (plist-get parameters :tasks))
+
+      ;; Prepare footnotes for export.  During that process, footnotes
+      ;; actually included in the exported part of the buffer go
+      ;; though some transformations:
+
+      ;; 1. They have their label normalized (like "[N]");
+
+      ;; 2. They get moved at the same place in the buffer (usually at
+      ;;    its end, but backends may define another place via
+      ;;    `org-footnote-insert-pos-for-preprocessor');
+
+      ;; 3. The are stored in `org-export-footnotes-seen', while
+      ;;    `org-export-preprocess-string' is applied to their
+      ;;    definition.
+
+      ;; Line-wise exporters ignore `org-export-footnotes-seen', as
+      ;; they interpret footnotes at the moment they see them in the
+      ;; buffer.  Context-wise exporters grab all the info needed in
+      ;; that variable and delete moved definitions (as described in
+      ;; 2nd step).
+      (when (plist-get parameters :footnotes)
+       (org-footnote-normalize nil parameters))
+
+      ;; Change lists ending.  Other parts of export may insert blank
+      ;; lines and lists' structure could be altered.
+      (org-export-mark-list-end)
+
+      ;; Process the macros
+      (org-export-preprocess-apply-macros)
+      (run-hooks 'org-export-preprocess-after-macros-hook)
+
+      ;; Export code blocks
+      (org-export-blocks-preprocess)
+
+      ;; Mark lists with properties
+      (org-export-mark-list-properties)
 
       ;; Handle source code snippets
-      (org-export-replace-src-segments-and-examples backend)
+      (org-export-replace-src-segments-and-examples)
 
       ;; Protect short examples marked by a leading colon
       (org-export-protect-colon-examples)
 
-      ;; Normalize footnotes
-      (when (plist-get parameters :footnotes)
-       (org-footnote-normalize nil t))
+      ;; Protected spaces
+      (org-export-convert-protected-spaces)
 
       ;; Find all headings and compute the targets for them
       (setq target-alist (org-export-define-heading-targets target-alist))
@@ -1100,7 +1242,7 @@ on this string to produce the exported version."
 
       ;; Get rid of drawers
       (org-export-remove-or-extract-drawers
-       drawers (plist-get parameters :drawers) backend)
+       drawers (plist-get parameters :drawers))
 
       ;; Get the correct stuff before the first headline
       (when (plist-get parameters :skip-before-1st-heading)
@@ -1123,7 +1265,7 @@ on this string to produce the exported version."
       ;; Select and protect backend specific stuff, throw away stuff
       ;; that is specific for other backends
       (run-hooks 'org-export-preprocess-before-selecting-backend-code-hook)
-      (org-export-select-backend-specific-text backend)
+      (org-export-select-backend-specific-text)
 
       ;; Protect quoted subtrees
       (org-export-protect-quoted-subtrees)
@@ -1143,8 +1285,7 @@ on this string to produce the exported version."
        (org-export-remove-timestamps))
 
       ;; Attach captions to the correct object
-      (setq target-alist (org-export-attach-captions-and-attributes
-                         backend target-alist))
+      (setq target-alist (org-export-attach-captions-and-attributes target-alist))
 
       ;; Find matches for radio targets and turn them into internal links
       (org-export-mark-radio-links)
@@ -1175,35 +1316,22 @@ on this string to produce the exported version."
       ;; Another hook
       (run-hooks 'org-export-preprocess-before-backend-specifics-hook)
 
-      ;; LaTeX-specific preprocessing
-      (when latexp
-       (require 'org-latex nil)
-       (org-export-latex-preprocess parameters))
-
-      ;; ASCII-specific preprocessing
-      (when asciip
-       (org-export-ascii-preprocess parameters))
-
-      ;; HTML-specific preprocessing
-      (when htmlp
-       (org-export-html-preprocess parameters))
-
-      ;; DocBook-specific preprocessing
-      (when docbookp
-       (require 'org-docbook nil)
-       (org-export-docbook-preprocess parameters))
+      ;; Backend-specific preprocessing
+      (let* ((backend-name (symbol-name org-export-current-backend))
+            (f (intern (format "org-export-%s-preprocess" backend-name))))
+       (require (intern (concat "org-" backend-name)) nil)
+       (funcall f parameters))
 
       ;; Remove or replace comments
       (org-export-handle-comments (plist-get parameters :comments))
 
-      ;; Remove #+TBLFM and #+TBLNAME lines
-      (org-export-handle-table-metalines)
-      
+      ;; Remove #+TBLFM #+TBLNAME #+NAME #+RESULTS lines
+      (org-export-handle-metalines)
+
       ;; Run the final hook
       (run-hooks 'org-export-preprocess-final-hook)
 
       (setq rtn (buffer-string)))
-    (kill-buffer " org-mode-tmp")
     rtn))
 
 (defun org-export-kill-licensed-text ()
@@ -1256,7 +1384,7 @@ Also find all ID and CUSTOM_ID properties and store them."
                                       (org-outline-level))))
          (setq target (org-solidify-link-text
                        (format "sec-%s" (replace-regexp-in-string
-                                         "\\." "_"
+                                         "\\." "-"
                                          (org-section-number level)))))
          (setq last-section-target target)
          (push (cons target target) target-alist)
@@ -1300,52 +1428,53 @@ the current file."
   (goto-char (point-min))
   (while (re-search-forward org-bracket-link-regexp nil t)
     (org-if-unprotected-at (1+ (match-beginning 0))
-     (let* ((md (match-data))
-           (desc (match-end 2))
-           (link (org-link-unescape (match-string 1)))
-           (slink (org-solidify-link-text link))
-           found props pos cref
-           (target
-            (cond
-             ((= (string-to-char link) ?#)
-              ;; user wants exactly this link
-              link)
-             ((cdr (assoc slink target-alist))
-              (or (cdr (assoc (assoc slink target-alist)
-                              org-export-preferred-target-alist))
-                  (cdr (assoc slink target-alist))))
-             ((and (string-match "^id:" link)
-                   (cdr (assoc (substring link 3) target-alist))))
-             ((string-match "^(\\(.*\\))$" link)
-              (setq cref (match-string 1 link))
-              (concat "coderef:" cref))
-             ((string-match org-link-types-re link) nil)
-             ((or (file-name-absolute-p link)
-                  (string-match "^\\." link))
-              nil)
-             (t
-              (let ((org-link-search-inhibit-query t))
-                (save-excursion
-                  (setq found (condition-case nil (org-link-search link)
-                                (error nil)))
-                  (when (and found
-                             (or (org-on-heading-p)
-                                 (not (eq found 'dedicated))))
-                    (or (get-text-property (point) 'target)
-                        (get-text-property
-                         (max (point-min)
-                              (1- (or (previous-single-property-change
-                                       (point) 'target) 0)))
-                         'target)))))))))
-       (when target
-        (set-match-data md)
-        (goto-char (match-beginning 1))
-        (setq props (text-properties-at (point)))
-        (delete-region (match-beginning 1) (match-end 1))
-        (setq pos (point))
-        (insert target)
-        (unless desc (insert "][" link))
-        (add-text-properties pos (point) props))))))
+      (let* ((org-link-search-must-match-exact-headline t)
+            (md (match-data))
+            (desc (match-end 2))
+            (link (org-link-unescape (match-string 1)))
+            (slink (org-solidify-link-text link))
+            found props pos cref
+            (target
+             (cond
+              ((= (string-to-char link) ?#)
+               ;; user wants exactly this link
+               link)
+              ((cdr (assoc slink target-alist))
+               (or (cdr (assoc (assoc slink target-alist)
+                               org-export-preferred-target-alist))
+                   (cdr (assoc slink target-alist))))
+              ((and (string-match "^id:" link)
+                    (cdr (assoc (substring link 3) target-alist))))
+              ((string-match "^(\\(.*\\))$" link)
+               (setq cref (match-string 1 link))
+               (concat "coderef:" cref))
+              ((string-match org-link-types-re link) nil)
+              ((or (file-name-absolute-p link)
+                   (string-match "^\\." link))
+               nil)
+              (t
+               (let ((org-link-search-inhibit-query t))
+                 (save-excursion
+                   (setq found (condition-case nil (org-link-search link)
+                                 (error nil)))
+                   (when (and found
+                              (or (org-at-heading-p)
+                                  (not (eq found 'dedicated))))
+                     (or (get-text-property (point) 'target)
+                         (get-text-property
+                          (max (point-min)
+                               (1- (or (previous-single-property-change
+                                        (point) 'target) 0)))
+                          'target)))))))))
+       (when target
+         (set-match-data md)
+         (goto-char (match-beginning 1))
+         (setq props (text-properties-at (point)))
+         (delete-region (match-beginning 1) (match-end 1))
+         (setq pos (point))
+         (insert target)
+         (unless desc (insert "][" link))
+         (add-text-properties pos (point) props))))))
 
 (defun org-export-remember-html-container-classes ()
   "Store the HTML_CONTAINER_CLASS properties in a text property."
@@ -1355,25 +1484,26 @@ the current file."
            "^[ \t]*:HTML_CONTAINER_CLASS:[ \t]+\\(.+\\)$" nil t)
       (setq class (match-string 1))
       (save-excursion
-       (org-back-to-heading t)
-       (put-text-property (point-at-bol) (point-at-eol) 'html-container-class class)))))
+       (when (re-search-backward "^\\*" (point-min) t)
+         (org-back-to-heading t)
+         (put-text-property (point-at-bol) (point-at-eol)
+                            'html-container-class class))))))
 
 (defvar org-export-format-drawer-function nil
   "Function to be called to format the contents of a drawer.
-The function must accept three parameters:
+The function must accept two parameters:
   NAME     the drawer name, like \"PROPERTIES\"
   CONTENT  the content of the drawer.
-  BACKEND  one of the symbols html, docbook, latex, ascii, xoxo
+You can check the export backend through `org-export-current-backend'.
 The function should return the text to be inserted into the buffer.
 If this is nil, `org-export-format-drawer' is used as a default.")
 
-(defun org-export-remove-or-extract-drawers (all-drawers exp-drawers backend)
+(defun org-export-remove-or-extract-drawers (all-drawers exp-drawers)
   "Remove drawers, or extract and format the content.
 ALL-DRAWERS is a list of all drawer names valid in the current buffer.
 EXP-DRAWERS can be t to keep all drawer contents, or a list of drawers
 whose content to keep.  Any drawers that are in ALL-DRAWERS but not in
-EXP-DRAWERS will be removed.
-BACKEND is the current export backend."
+EXP-DRAWERS will be removed."
   (goto-char (point-min))
   (let ((re (concat "^[ \t]*:\\("
                    (mapconcat 'identity all-drawers "\\|")
@@ -1397,10 +1527,10 @@ BACKEND is the current export backend."
                   (member name exp-drawers))
           (setq content (funcall (or org-export-format-drawer-function
                                      'org-export-format-drawer)
-                                 name content backend))
+                                 name content))
           (insert content)))))))
 
-(defun org-export-format-drawer (name content backend)
+(defun org-export-format-drawer (name content)
   "Format the content of a drawer as a colon example."
   (if (string-match "[ \t]+\\'" content)
       (setq content (substring content (match-beginning 0))))
@@ -1426,8 +1556,8 @@ removed as well."
                                           select-tags "\\|")
                         "\\):"))
         (re-excl (concat ":\\(" (mapconcat 'regexp-quote
-                                          exclude-tags "\\|")
-                       "\\):"))
+                                           exclude-tags "\\|")
+                         "\\):"))
         beg end cont)
     (goto-char (point-min))
     (when (and select-tags
@@ -1441,7 +1571,7 @@ removed as well."
       (setq beg (point))
       (put-text-property beg (point-max) :org-delete t)
       (while (re-search-forward re-sel nil t)
-       (when (org-on-heading-p)
+       (when (org-at-heading-p)
          (org-back-to-heading)
          (remove-text-properties
           (max (1- (point)) (point-min))
@@ -1470,6 +1600,36 @@ removed as well."
                    (point-max)))
       (delete-region beg end))))
 
+(defun org-export-remove-tasks (keep)
+  "Remove tasks depending on configuration.
+When KEEP is nil, remove all tasks.
+When KEEP is `todo', remove the tasks that are DONE.
+When KEEP is `done', remove the tasks that are not yet done.
+When it is a list of strings, keep only tasks with these TODO keywords."
+  (when (or (listp keep) (memq keep '(todo done nil)))
+    (let ((re (concat "^\\*+[ \t]+\\("
+                     (mapconcat
+                      'regexp-quote
+                      (cond ((not keep) org-todo-keywords-1)
+                            ((eq keep 'todo) org-done-keywords)
+                            ((eq keep 'done) org-not-done-keywords)
+                            ((listp keep)
+                             (org-delete-all keep (copy-sequence
+                                                   org-todo-keywords-1))))
+                      "\\|")
+                     "\\)\\($\\|[ \t]\\)"))
+         (case-fold-search nil)
+         beg)
+      (goto-char (point-min))
+      (while (re-search-forward re nil t)
+       (org-if-unprotected
+        (setq beg (match-beginning 0))
+        (org-end-of-subtree t t)
+        (if (looking-at "^\\*+[ \t]+END[ \t]*$")
+            ;; Kill the END line of the inline task
+            (goto-char (min (point-max) (1+ (match-end 0)))))
+        (delete-region beg (point)))))))
+
 (defun org-export-remove-archived-trees (export-archived-trees)
   "Remove archived trees.
 When EXPORT-ARCHIVED-TREES is `headline;, only the headline will be exported.
@@ -1481,7 +1641,7 @@ from the buffer."
     (when (not (eq export-archived-trees t))
       (goto-char (point-min))
       (while (re-search-forward re-archive nil t)
-       (if (not (org-on-heading-p t))
+       (if (not (org-at-heading-p t))
            (goto-char (point-at-eol))
          (beginning-of-line 1)
          (setq a (if export-archived-trees
@@ -1496,6 +1656,7 @@ from the buffer."
        (tags (plist-get opts :tags))
        (pri  (plist-get opts :priority))
        (elts '(1 2 3 4 5))
+       (case-fold-search nil)
        rpl)
     (setq elts (delq nil (list 1 (if todo 2) (if pri 3) 4 (if tags 5))))
     (when (or (not todo) (not tags) (not pri))
@@ -1526,16 +1687,38 @@ from the buffer."
       (org-if-unprotected
        (replace-match "")))))
 
+(defvar org-heading-keyword-regexp-format) ; defined in org.el
 (defun org-export-protect-quoted-subtrees ()
   "Mark quoted subtrees with the protection property."
-  (let ((re-quote (concat "^\\*+[ \t]+" org-quote-string "\\>")))
+  (let ((org-re-quote (format org-heading-keyword-regexp-format
+                             org-quote-string)))
     (goto-char (point-min))
-    (while (re-search-forward re-quote nil t)
+    (while (re-search-forward org-re-quote nil t)
       (goto-char (match-beginning 0))
       (end-of-line 1)
       (add-text-properties (point) (org-end-of-subtree t)
                           '(org-protected t)))))
 
+(defun org-export-convert-protected-spaces ()
+  "Convert strings like \\____ to protected spaces in all backends."
+  (goto-char (point-min))
+  (while (re-search-forward "\\\\__+" nil t)
+    (org-if-unprotected-1
+     (replace-match
+      (org-add-props
+         (cond
+          ((eq org-export-current-backend 'latex)
+           (format "\\hspace{%dex}" (- (match-end 0) (match-beginning 0))))
+          ((eq org-export-current-backend 'html)
+           (org-add-props (match-string 0) nil
+             'org-whitespace (- (match-end 0) (match-beginning 0))))
+          ;; ((eq org-export-current-backend 'docbook))
+          ((eq org-export-current-backend 'ascii)
+           (org-add-props (match-string 0) '(org-whitespace t)))
+          (t (make-string (- (match-end 0) (match-beginning 0)) ?\ )))
+         '(org-protected t))
+      t t))))
+
 (defun org-export-protect-verbatim ()
   "Mark verbatim snippets with the protection property."
   (goto-char (point-min))
@@ -1558,48 +1741,57 @@ from the buffer."
       (add-text-properties beg (if (bolp) (1- (point)) (point))
                           '(org-protected t)))))
 
-(defun org-export-select-backend-specific-text (backend)
-  (let ((formatters
-        '((docbook "DOCBOOK" "BEGIN_DOCBOOK" "END_DOCBOOK")
-          (html "HTML" "BEGIN_HTML" "END_HTML")
-          (beamer "BEAMER" "BEGIN_BEAMER" "END_BEAMER")
-          (ascii "ASCII" "BEGIN_ASCII" "END_ASCII")
-          (latex "LaTeX" "BEGIN_LaTeX" "END_LaTeX")))
+(defvar org-export-backends
+  '(docbook html beamer ascii latex)
+  "List of Org supported export backends.")
+
+(defun org-export-select-backend-specific-text ()
+  (let ((formatters org-export-backends)
        (case-fold-search t)
-       fmt beg beg-content end end-content)
+       backend backend-name beg beg-content end end-content ind)
 
     (while formatters
-      (setq fmt (pop formatters))
-      ;; Handle #+Backend: stuff
+      (setq backend (pop formatters)
+           backend-name (symbol-name backend))
+
+      ;; Handle #+BACKEND: stuff
       (goto-char (point-min))
-      (while (re-search-forward (concat "^\\([ \t]*\\)#\\+" (cadr fmt)
+      (while (re-search-forward (concat "^\\([ \t]*\\)#\\+" backend-name
                                        ":[ \t]*\\(.*\\)") nil t)
-       (if (not (eq (car fmt) backend))
+       (if (not (eq backend org-export-current-backend))
            (delete-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))
-         (replace-match "\\1\\2" t)
-         (add-text-properties
-          (point-at-bol) (min (1+ (point-at-eol)) (point-max))
-          '(org-protected t))))
-      ;; Delete #+attr_Backend: stuff of another backend. Those
+         (let ((ind (get-text-property (point-at-bol) 'original-indentation)))
+           (replace-match "\\1\\2" t)
+           (add-text-properties
+            (point-at-bol) (min (1+ (point-at-eol)) (point-max))
+            `(org-protected t original-indentation ,ind org-native-text t)))))
+      ;; Delete #+ATTR_BACKEND: stuff of another backend.  Those
       ;; matching the current backend will be taken care of by
       ;; `org-export-attach-captions-and-attributes'
       (goto-char (point-min))
-      (while (re-search-forward (concat "^\\([ \t]*\\)#\\+attr_" (cadr fmt)
+      (while (re-search-forward (concat "^\\([ \t]*\\)#\\+ATTR_" backend-name
                                        ":[ \t]*\\(.*\\)") nil t)
-       (when (not (eq (car fmt) backend))
+       (setq ind (org-get-indentation))
+       (when (not (eq backend org-export-current-backend))
          (delete-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))))
-      ;; Handle #+begin_Backend and #+end_Backend stuff
+      ;; Handle #+BEGIN_BACKEND and #+END_BACKEND stuff
       (goto-char (point-min))
-      (while (re-search-forward (concat "^[ \t]*#\\+" (caddr fmt) "\\>.*\n?")
+      (while (re-search-forward (concat "^[ \t]*#\\+BEGIN_" backend-name "\\>.*\n?")
                                nil t)
        (setq beg (match-beginning 0) beg-content (match-end 0))
-       (when (re-search-forward (concat "^[ \t]*#\\+" (cadddr fmt) "\\>.*\n?")
+       (setq ind (or (get-text-property beg 'original-indentation)
+                     (save-excursion (goto-char beg) (org-get-indentation))))
+       (when (re-search-forward (concat "^[ \t]*#\\+END_" backend-name "\\>.*\n?")
                                 nil t)
          (setq end (match-end 0) end-content (match-beginning 0))
-         (if (eq (car fmt) backend)
+         (if (eq backend org-export-current-backend)
              ;; yes, keep this
              (progn
-               (add-text-properties beg-content end-content '(org-protected t))
+               (add-text-properties
+                beg-content end-content
+                `(org-protected t original-indentation ,ind org-native-text t))
+               ;; strip protective commas
+               (org-unescape-code-in-region beg-content end-content)
                (delete-region (match-beginning 0) (match-end 0))
                (save-excursion
                  (goto-char beg)
@@ -1631,32 +1823,104 @@ These special cookies will later be interpreted by the backend."
        (delete-region beg end)
        (insert (org-add-props content nil 'original-indentation ind))))))
 
-(defun org-export-mark-list-ending (backend)
-  "Mark list endings with special cookies.
-These special cookies will later be interpreted by the backend.
-`org-list-end-re' is replaced by a blank line in the process."
-  (let ((process-buffer
-        (lambda (end-list-marker)
+(defun org-export-mark-list-end ()
+  "Mark all list endings with a special string."
+  (unless (eq org-export-current-backend 'ascii)
+    (mapc
+     (lambda (e)
+       ;; For each type allowing list export, find every list, remove
+       ;; ending regexp if needed, and insert org-list-end.
+       (goto-char (point-min))
+       (while (re-search-forward (org-item-beginning-re) nil t)
+        (when (eq (nth 2 (org-list-context)) e)
+          (let* ((struct (org-list-struct))
+                 (bottom (org-list-get-bottom-point struct))
+                 (top (point-at-bol))
+                 (top-ind (org-list-get-ind top struct)))
+            (goto-char bottom)
+            (when (and (not (looking-at "[ \t]*$"))
+                       (looking-at org-list-end-re))
+              (replace-match ""))
+            (unless (bolp) (insert "\n"))
+            ;; As org-list-end is inserted at column 0, it would end
+            ;; by indentation any list.  It can be problematic when
+            ;; there are lists within lists: the inner list end would
+            ;; also become the outer list end.  To avoid this, text
+            ;; property `original-indentation' is added, as
+            ;; `org-list-struct' pays attention to it when reading a
+            ;; list.
+            (insert (org-add-props
+                        "ORG-LIST-END-MARKER\n"
+                        (list 'original-indentation top-ind)))))))
+     (cons nil org-list-export-context))))
+
+(defun org-export-mark-list-properties ()
+  "Mark list with special properties.
+These special properties will later be interpreted by the backend."
+  (let ((mark-list
+        (function
+         ;; Mark a list with 3 properties: `list-item' which is
+         ;; position at beginning of line, `list-struct' which is
+         ;; list structure, and `list-prevs' which is the alist of
+         ;; item and its predecessor.  Leave point at list ending.
+         (lambda (ctxt)
+           (let* ((struct (org-list-struct))
+                  (top (org-list-get-top-point struct))
+                  (bottom (org-list-get-bottom-point struct))
+                  (prevs (org-list-prevs-alist struct))
+                  poi)
+             ;; Get every item and ending position, without dups and
+             ;; without bottom point of list.
+             (mapc (lambda (e)
+                     (let ((pos (car e))
+                           (end (nth 6 e)))
+                       (unless (memq pos poi)
+                         (push pos poi))
+                       (unless (or (= end bottom) (memq end poi))
+                         (push end poi))))
+                   struct)
+             (setq poi (sort poi '<))
+             ;; For every point of interest, mark the whole line with
+             ;; its position in list.
+             (mapc
+              (lambda (e)
+                (goto-char e)
+                (add-text-properties (point-at-bol) (point-at-eol)
+                                     (list 'list-item (point-at-bol)
+                                           'list-struct struct
+                                           'list-prevs prevs)))
+              poi)
+             ;; Take care of bottom point.  As babel may have inserted
+             ;; a new list in buffer, list ending isn't always
+             ;; marked.  Now mark every list ending and add properties
+             ;; useful to line processing exporters.
+             (goto-char bottom)
+             (when (or (looking-at "^ORG-LIST-END-MARKER\n")
+                       (and (not (looking-at "[ \t]*$"))
+                            (looking-at org-list-end-re)))
+               (replace-match ""))
+             (unless (bolp) (insert "\n"))
+             (insert
+              (org-add-props "ORG-LIST-END-MARKER\n" (list 'list-item bottom
+                                                           'list-struct struct
+                                                           'list-prevs prevs)))
+             ;; Following property is used by LaTeX exporter.
+             (add-text-properties top (point) (list 'list-context ctxt)))))))
+    ;; Mark lists except for backends not interpreting them.
+    (unless (eq org-export-current-backend 'ascii)
+      (let ((org-list-end-re "^ORG-LIST-END-MARKER\n"))
+       (mapc
+        (lambda (e)
           (goto-char (point-min))
-          (while (org-search-forward-unenclosed org-item-beginning-re nil t)
-            (goto-char (org-list-bottom-point))
-            (when (and (not (eq org-list-ending-method 'indent))
-                       (looking-at (org-list-end-re)))
-              (replace-match "\n"))
-            (insert end-list-marker)))))
-  ;; We need to divide backends into 3 categories.
-  (cond
-   ;; 1. Backends using `org-list-parse-list' do not need markers.
-   ((memq backend '(latex))
-    nil)
-   ;; 2. Line-processing backends need to be told where lists end.
-   ((memq backend '(html docbook))
-    (funcall process-buffer "ORG-LIST-END\n"))
-   ;; 3. Others backends do not need to know this: clean list enders.
-   (t
-    (funcall process-buffer "")))))
-
-(defun org-export-attach-captions-and-attributes (backend target-alist)
+          (while (re-search-forward (org-item-beginning-re) nil t)
+            (let ((context (nth 2 (org-list-context))))
+              (if (eq context e)
+                  (funcall mark-list e)
+                (put-text-property (point-at-bol) (point-at-eol)
+                                   'list-context context)))))
+        (cons nil org-list-export-context))))))
+
+(defun org-export-attach-captions-and-attributes (target-alist)
   "Move #+CAPTION, #+ATTR_BACKEND, and #+LABEL text into text properties.
 If the next thing following is a table, add the text properties to the first
 table line.  If it is a link, add it to the line containing the link."
@@ -1666,7 +1930,7 @@ table line.  If it is a link, add it to the line containing the link."
   (let ((case-fold-search t)
        (re (concat "^[ \t]*#\\+caption:[ \t]+\\(.*\\)"
                    "\\|"
-                   "^[ \t]*#\\+attr_" (symbol-name backend) ":[ \t]+\\(.*\\)"
+                   "^[ \t]*#\\+attr_" (symbol-name org-export-current-backend) ":[ \t]+\\(.*\\)"
                    "\\|"
                    "^[ \t]*#\\+label:[ \t]+\\(.*\\)"
                    "\\|"
@@ -1676,6 +1940,7 @@ table line.  If it is a link, add it to the line containing the link."
        cap shortn attr label end)
     (while (re-search-forward re nil t)
       (cond
+       ;; there is a caption
        ((match-end 1)
        (progn
          (setq cap (concat cap (if cap " " "") (org-trim (match-string 1))))
@@ -1683,10 +1948,12 @@ table line.  If it is a link, add it to the line containing the link."
            (setq shortn (match-string 1 cap)
                  cap (match-string 2 cap)))
          (delete-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))))
+       ;; there is an attribute
        ((match-end 2)
        (progn
          (setq attr (concat attr (if attr " " "") (org-trim (match-string 2))))
          (delete-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))))
+       ;; there is a label
        ((match-end 3)
        (progn
          (setq label (org-trim (match-string 3)))
@@ -1703,18 +1970,19 @@ table line.  If it is a link, add it to the line containing the link."
                                   'org-label label))
        (if label (push (cons label label) target-alist))
        (goto-char end)
-       (setq cap nil attr nil label nil)))))
+       (setq cap nil shortn nil attr nil label nil)))))
   target-alist)
 
 (defun org-export-remove-comment-blocks-and-subtrees ()
   "Remove the comment environment, and also commented subtrees."
-  (let ((re-commented (concat "^\\*+[ \t]+" org-comment-string "\\>"))
+  (let ((re-commented (format org-heading-keyword-regexp-format
+                             org-comment-string))
        case-fold-search)
     ;; Remove comment environment
     (goto-char (point-min))
     (setq case-fold-search t)
     (while (re-search-forward
-           "^#\\+begin_comment[ \t]*\n[^\000]*?^#\\+end_comment\\>.*" nil t)
+           "^#\\+begin_comment[ \t]*\n[^\000]*?\n#\\+end_comment\\>.*" nil t)
       (replace-match "" t t))
     ;; Remove subtrees that are commented
     (goto-char (point-min))
@@ -1723,30 +1991,37 @@ table line.  If it is a link, add it to the line containing the link."
       (goto-char (match-beginning 0))
       (delete-region (point) (org-end-of-subtree t)))))
 
-(defun org-export-handle-comments (commentsp)
+(defun org-export-handle-comments (org-commentsp)
   "Remove comments, or convert to backend-specific format.
-COMMENTSP can be a format string for publishing comments.
+ORG-COMMENTSP can be a format string for publishing comments.
 When it is nil, all comments will be removed."
-  (let ((re "^\\(#\\|[ \t]*#\\+ \\)\\(.*\n?\\)")
-       pos)
+  (let ((re "^[ \t]*#\\( \\|$\\)"))
     (goto-char (point-min))
-    (while (or (looking-at re)
-              (re-search-forward re nil t))
-      (setq pos (match-beginning 0))
-      (if (get-text-property pos 'org-protected)
-         (goto-char (1+ pos))
-       (if (and commentsp
-                (not (equal (char-before (match-end 1)) ?+)))
-           (progn (add-text-properties
-                   (match-beginning 0) (match-end 0) '(org-protected t))
-                  (replace-match (format commentsp (match-string 2)) t t))
-         (goto-char (1+ pos))
-         (replace-match "")
-         (goto-char (max (point-min) (1- pos))))))))
-
-(defun org-export-handle-table-metalines ()
-  "Remove table specific metalines #+TBLNAME: and #+TBLFM:."
-  (let ((re "^[ \t]*#\\+TBL\\(NAME\\|FM\\):\\(.*\n?\\)")
+    (while (re-search-forward re nil t)
+      (let ((pos (match-beginning 0))
+           (end (progn (forward-line) (point))))
+       (if (get-text-property pos 'org-protected)
+           (forward-line)
+         (if (not org-commentsp) (delete-region pos end)
+           (add-text-properties pos end '(org-protected t))
+           (replace-match
+            (org-add-props
+                (format org-commentsp (buffer-substring (match-end 0) end))
+                nil 'org-protected t)
+            t t)))))
+    ;; Hack attack: previous implementation also removed keywords at
+    ;; column 0. Brainlessly do it again.
+    (goto-char (point-min))
+    (while (re-search-forward "^#\\+" nil t)
+      (unless (get-text-property (point-at-bol) 'org-protected)
+       (delete-region (point-at-bol) (progn (forward-line) (point)))))))
+
+(defun org-export-handle-metalines ()
+  "Remove tables and source blocks metalines.
+This function should only be called after all block processing
+has taken place."
+  (let ((re "^[ \t]*#\\+\\(tbl\\(?:name\\|fm\\)\\|results\\(?:\\[[a-z0-9]+\\]\\)?\\|name\\):\\(.*\n?\\)")
+       (case-fold-search t)
        pos)
     (goto-char (point-min))
     (while (or (looking-at re)
@@ -1775,28 +2050,33 @@ When it is nil, all comments will be removed."
 
 (defun org-store-forced-table-alignment ()
   "Find table lines which force alignment, store the results in properties."
-  (let (line cnt aligns)
+  (let (line cnt cookies)
     (goto-char (point-min))
-    (while (re-search-forward "|[ \t]*<[lrc][0-9]*>[ \t]*|" nil t)
+    (while (re-search-forward "|[ \t]*<\\([lrc]?[0-9]+\\|[lrc]\\)>[ \t]*|"
+                             nil t)
       ;; OK, this looks like a table line with an alignment cookie
       (org-if-unprotected
        (setq line (buffer-substring (point-at-bol) (point-at-eol)))
        (when (and (org-at-table-p)
                  (org-table-cookie-line-p line))
-        (setq cnt 0 aligns nil)
+        (setq cnt 0 cookies nil)
         (mapc
          (lambda (x)
            (setq cnt (1+ cnt))
-           (if (string-match "\\`<\\([lrc]\\)" x)
-               (push (cons cnt (downcase (match-string 1 x))) aligns)))
+           (when (string-match "\\`<\\([lrc]\\)?\\([0-9]+\\)?>\\'" x)
+             (let ((align (and (match-end 1)
+                               (downcase (match-string 1 x))))
+                   (width (and (match-end 2)
+                               (string-to-number (match-string 2 x)))))
+               (push (cons cnt (list align width)) cookies))))
          (org-split-string line "[ \t]*|[ \t]*"))
         (add-text-properties (org-table-begin) (org-table-end)
-                             (list 'org-forced-aligns aligns))))
+                             (list 'org-col-cookies cookies))))
       (goto-char (point-at-eol)))))
 
 (defun org-export-remove-special-table-lines ()
   "Remove tables lines that are used for internal purposes.
-Also, store forcedalignment information found in such lines."
+Also, store forced alignment information found in such lines."
   (goto-char (point-min))
   (while (re-search-forward "^[ \t]*|" nil t)
     (org-if-unprotected-at (1- (point))
@@ -1807,7 +2087,7 @@ Also, store forcedalignment information found in such lines."
                nil
                (mapcar
                 (lambda (f)
-                  (or (= (length f) 0)
+                  (or (and org-export-table-remove-empty-lines (= (length f) 0))
                       (string-match
                        "\\`<\\([0-9]\\|[lrc]\\|[lrc][0-9]+\\)>\\'" f)))
                 (org-split-string ;; FIXME, can't we do without splitting???
@@ -1829,10 +2109,11 @@ Also, store forcedalignment information found in such lines."
        (re-angle-link (concat "\\([^[]\\)" org-angle-link-re))
        nodesc)
     (goto-char (point-min))
+    (while (re-search-forward org-bracket-link-regexp nil t)
+      (put-text-property (match-beginning 0) (match-end 0) 'org-normalized-link t))
+    (goto-char (point-min))
     (while (re-search-forward re-plain-link nil t)
-      (unless (org-string-match-p
-              "\\[\\[\\S+:\\S-*?\\<"
-              (buffer-substring (point-at-bol) (match-beginning 0)))
+      (unless (get-text-property (match-beginning 0) 'org-normalized-link)
        (goto-char (1- (match-end 0)))
        (org-if-unprotected-at (1+ (match-beginning 0))
          (let* ((s (concat (match-string 1)
@@ -1881,8 +2162,8 @@ can work correctly."
   (goto-char (point-min))
   (while (re-search-forward "\\(\\(\\[\\|\\]\\)\\[[^]]*?\\)[ \t]*\n[ \t]*\\([^]]*\\]\\(\\[\\|\\]\\)\\)" nil t)
     (org-if-unprotected-at (match-beginning 1)
-     (replace-match "\\1 \\3")
-     (goto-char (match-beginning 0)))))
+      (replace-match "\\1 \\3")
+      (goto-char (match-beginning 0)))))
 
 (defun org-export-concatenate-multiline-emphasis ()
   "Find multi-line emphasis and put it all into a single line.
@@ -1912,23 +2193,31 @@ can work correctly."
                   (save-excursion (outline-next-heading) (point)))))
        (when (re-search-forward "^[ \t]*[^|# \t\r\n].*\n" end t)
          ;; Mark the line so that it will not be exported as normal text.
-         (org-unmodified
-          (add-text-properties (match-beginning 0) (match-end 0)
-                               (list :org-license-to-kill t)))
+         (unless (org-in-block-p org-list-forbidden-blocks)
+           (org-unmodified
+            (add-text-properties (match-beginning 0) (match-end 0)
+                                 (list :org-license-to-kill t))))
          ;; Return the title string
          (org-trim (match-string 0)))))))
 
 (defun org-export-get-title-from-subtree ()
   "Return subtree title and exclude it from export."
-  (let (title (rbeg (region-beginning)) (rend (region-end)))
+  (let ((rbeg (region-beginning)) (rend (region-end))
+       (inhibit-read-only t)
+       (tags (plist-get (org-infile-export-plist) :tags))
+       title)
     (save-excursion
       (goto-char rbeg)
       (when (and (org-at-heading-p)
                 (>= (org-end-of-subtree t t) rend))
+       (when (plist-member org-export-opt-plist :tags)
+         (setq tags (or (plist-get org-export-opt-plist :tags) tags)))
        ;; This is a subtree, we take the title from the first heading
        (goto-char rbeg)
-       (looking-at org-todo-line-regexp)
-       (setq title (match-string 3))
+       (looking-at org-todo-line-tags-regexp)
+       (setq title (if (and (eq tags t) (match-string 4))
+                       (format "%s\t%s" (match-string 3) (match-string 4))
+                     (match-string 3)))
        (org-unmodified
         (add-text-properties (point) (1+ (point-at-eol))
                              (list :org-license-to-kill t)))
@@ -1941,7 +2230,7 @@ can work correctly."
     (let* ((rtn
            (mapconcat
             'identity
-            (org-split-string s "[ \t\r\n]+") "=="))
+            (org-split-string s "[^a-zA-Z0-9_\\.-]+") "-"))
           (a (assoc rtn alist)))
       (or (cdr a) rtn))))
 
@@ -2048,26 +2337,35 @@ TYPE must be a string, any of:
 (defun org-export-preprocess-apply-macros ()
   "Replace macro references."
   (goto-char (point-min))
-  (let (sy val key args args2 s n)
+  (let (sy val key args args2 ind-str s n)
     (while (re-search-forward
            "{{{\\([a-zA-Z][-a-zA-Z0-9_]*\\)\\(([ \t\n]*\\([^\000]*?\\))\\)?}}}"
            nil t)
-      (unless (save-match-data
-               (save-excursion
-                 (goto-char (point-at-bol))
-                 (looking-at "[ \t]*#\\+macro")))
+      (unless (save-match-data (save-excursion
+                                (goto-char (point-at-bol))
+                                (looking-at "[ \t]*#\\+macro")))
+       ;; Get macro name (KEY), arguments (ARGS), and indentation of
+       ;; current line (IND-STR) as strings.
        (setq key (downcase (match-string 1))
-             args (match-string 3))
+             args (match-string 3)
+             ind-str (save-match-data (save-excursion
+                                        (beginning-of-line)
+                                        (looking-at "^\\([ \t]*\\).*")
+                                        (match-string 1))))
+       ;; When macro is defined, retrieve replacement text in VAL,
+       ;; and proceed with expansion.
        (when (setq val (or (plist-get org-export-opt-plist
                                       (intern (concat ":macro-" key)))
                            (plist-get org-export-opt-plist
                                       (intern (concat ":" key)))))
          (save-match-data
+           ;; If arguments are provided, first retrieve them properly
+           ;; (in ARGS, as a list), then replace them in VAL.
            (when args
              (setq args (org-split-string args ",") args2 nil)
              (while args
                (while (string-match "\\\\\\'" (car args))
-                 ;; repair bad splits
+                 ;; Repair bad splits.
                  (setcar (cdr args) (concat (substring (car args) 0 -1)
                                             "," (nth 1 args)))
                  (pop args))
@@ -2079,13 +2377,22 @@ TYPE must be a string, any of:
                      n (string-to-number (match-string 1 val)))
                (and (>= (length args) n)
                     (setq val (replace-match (nth (1- n) args) t t val)))))
+           ;; VAL starts with "(eval": it is a sexp, `eval' it.
            (when (string-match "\\`(eval\\>" val)
              (setq val (eval (read val))))
-           (if (and val (not (stringp val)))
-               (setq val (format "%s" val))))
-         (and (stringp val)
-              (prog1 (replace-match val t t)
-                (goto-char (match-beginning 0)))))))))
+           ;; Ensure VAL is a string (or nil) and that each new line
+           ;; is indented as the first one.
+           (setq val (and val
+                          (mapconcat 'identity
+                                     (org-split-string
+                                      (if (stringp val) val (format "%s" val))
+                                      "\n")
+                                     (concat "\n" ind-str)))))
+         ;; Eventually do the replacement, if VAL isn't nil.  Move
+         ;; point at beginning of macro for recursive expansions.
+         (when val
+           (replace-match val t t)
+           (goto-char (match-beginning 0))))))))
 
 (defun org-export-apply-macros-in-string (s)
   "Apply the macros in string S."
@@ -2100,19 +2407,23 @@ TYPE must be a string, any of:
 (defun org-export-handle-include-files ()
   "Include the contents of include files, with proper formatting."
   (let ((case-fold-search t)
-       params file markup lang start end prefix prefix1 switches all)
+       params file markup lang start end prefix prefix1 switches all minlevel currentlevel addlevel lines)
     (goto-char (point-min))
-    (while (re-search-forward "^#\\+INCLUDE:?[ \t]+\\(.*\\)" nil t)
+    (while (re-search-forward "^#\\+include:[ \t]+\\(.*\\)" nil t)
       (setq params (read (concat "(" (match-string 1) ")"))
            prefix (org-get-and-remove-property 'params :prefix)
            prefix1 (org-get-and-remove-property 'params :prefix1)
+           minlevel (org-get-and-remove-property 'params :minlevel)
+           addlevel (org-get-and-remove-property 'params :addlevel)
+           lines (org-get-and-remove-property 'params :lines)
            file (org-symname-or-string (pop params))
            markup (org-symname-or-string (pop params))
            lang (and (member markup '("src" "SRC"))
                      (org-symname-or-string (pop params)))
-           switches (mapconcat '(lambda (x) (format "%s" x)) params " ")
+           switches (mapconcat #'(lambda (x) (format "%s" x)) params " ")
            start nil end nil)
       (delete-region (match-beginning 0) (match-end 0))
+      (setq currentlevel (or (org-current-level) 0))
       (if (or (not file)
              (not (file-exists-p file))
              (not (file-readable-p file)))
@@ -2128,7 +2439,7 @@ TYPE must be a string, any of:
                  end  (format "#+end_%s" markup))))
        (insert (or start ""))
        (insert (org-get-file-contents (expand-file-name file)
-                                      prefix prefix1 markup))
+                                      prefix prefix1 markup currentlevel minlevel addlevel lines))
        (or (bolp) (newline))
        (insert (or end ""))))
     all))
@@ -2145,15 +2456,31 @@ TYPE must be a string, any of:
        (when intersection
          (error "Recursive #+INCLUDE: %S" intersection))))))
 
-(defun org-get-file-contents (file &optional prefix prefix1 markup)
+(defun org-get-file-contents (file &optional prefix prefix1 markup minlevel parentlevel addlevel lines)
   "Get the contents of FILE and return them as a string.
 If PREFIX is a string, prepend it to each line.  If PREFIX1
 is a string, prepend it to the first line instead of PREFIX.
 If MARKUP, don't protect org-like lines, the exporter will
-take care of the block they are in."
+take care of the block they are in.  If ADDLEVEL is a number,
+demote included file to current heading level+ADDLEVEL.
+If LINES is a string specifying a range of lines,
+include only those lines."
   (if (stringp markup) (setq markup (downcase markup)))
   (with-temp-buffer
     (insert-file-contents file)
+    (when lines
+      (let* ((lines (split-string lines "-"))
+            (lbeg (string-to-number (car lines)))
+            (lend (string-to-number (cadr lines)))
+            (beg (if (zerop lbeg) (point-min)
+                   (goto-char (point-min))
+                   (forward-line (1- lbeg))
+                   (point)))
+            (end (if (zerop lend) (point-max)
+                   (goto-char (point-min))
+                   (forward-line (1- lend))
+                   (point))))
+       (narrow-to-region beg end)))
     (when (or prefix prefix1)
       (goto-char (point-min))
       (while (not (eobp))
@@ -2167,6 +2494,17 @@ take care of the block they are in."
        (goto-char (match-beginning 0))
        (insert ",")
        (end-of-line 1)))
+    (when minlevel
+      (dotimes (lvl minlevel)
+       (org-map-region 'org-demote (point-min) (point-max))))
+    (when addlevel
+      (let ((inclevel (or (if (org-before-first-heading-p)
+                             (1- (and (outline-next-heading)
+                                      (org-current-level)))
+                           (1- (org-current-level)))
+                         0)))
+       (dotimes (level (- (+ parentlevel addlevel) inclevel))
+         (org-map-region 'org-demote (point-min) (point-max)))))
     (buffer-string)))
 
 (defun org-get-and-remove-property (listvar prop)
@@ -2192,7 +2530,7 @@ in the list) and remove property and value from the list in LISTVAR."
 
 (defvar org-export-last-code-line-counter-value 0)
 
-(defun org-export-replace-src-segments-and-examples (backend)
+(defun org-export-replace-src-segments-and-examples ()
   "Replace source code segments with special code for export."
   (setq org-export-last-code-line-counter-value 0)
   (let ((case-fold-search t)
@@ -2225,21 +2563,40 @@ in the list) and remove property and value from the list in LISTVAR."
               caption (get-text-property 0 'org-caption (match-string 0))))
 
       (setq trans (org-export-format-source-code-or-example
-                  backend lang code opts indent caption))
+                  lang code opts indent caption))
       (replace-match trans t t))))
 
-(defvar htmlp)  ;; dynamically scoped
-(defvar latexp)  ;; dynamically scoped
 (defvar org-export-latex-verbatim-wrap) ;; defined in org-latex.el
 (defvar org-export-latex-listings) ;; defined in org-latex.el
 (defvar org-export-latex-listings-langs) ;; defined in org-latex.el
 (defvar org-export-latex-listings-w-names) ;; defined in org-latex.el
 (defvar org-export-latex-minted-langs) ;; defined in org-latex.el
-(defvar org-export-latex-minted-with-line-numbers) ;; defined in org-latex.el
+(defvar org-export-latex-custom-lang-environments) ;; defined in org-latex.el
+(defvar org-export-latex-listings-options) ;; defined in org-latex.el
+(defvar org-export-latex-minted-options) ;; defined in org-latex.el
+
+(defun org-remove-formatting-on-newlines-in-region (beg end)
+  "Remove formatting on newline characters."
+  (interactive "r")
+  (save-excursion
+    (goto-char beg)
+    (while (progn (end-of-line) (< (point) end))
+      (put-text-property (point) (1+ (point)) 'face nil)
+      (forward-char 1))))
 
 (defun org-export-format-source-code-or-example
-  (backend lang code &optional opts indent caption)
+  (lang code &optional opts indent caption)
   "Format CODE from language LANG and return it formatted for export.
+The CODE is marked up in `org-export-current-backend' format.
+
+Check if a function by name
+\"org-<backend>-format-source-code-or-example\" is bound.  If yes,
+use it as the custom formatter.  Otherwise, use the default
+formatter.  Default formatters are provided for docbook, html,
+latex and ascii backends.  For example, use
+`org-html-format-source-code-or-example' to provide a custom
+formatter for export to \"html\".
+
 If LANG is nil, do not add any fontification.
 OPTS contains formatting options, like `-n' for triggering numbering lines,
 and `+n' for continuing previous numbering.
@@ -2247,7 +2604,15 @@ Code formatting according to language currently only works for HTML.
 Numbering lines works for all three major backends (html, latex, and ascii).
 INDENT was the original indentation of the block."
   (save-match-data
-    (let (num cont rtn rpllbl keepp textareap preserve-indentp cols rows fmt)
+    (let* ((backend-name (symbol-name org-export-current-backend))
+          (backend-formatter
+           (intern (format "org-%s-format-source-code-or-example"
+                           backend-name)))
+          (backend-feature (intern (concat "org-" backend-name)))
+          (backend-formatter
+           (and (require (intern (concat "org-" backend-name)) nil)
+                (fboundp backend-formatter) backend-formatter))
+          num cont rtn rpllbl keepp textareap preserve-indentp cols rows fmt)
       (setq opts (or opts "")
            num (string-match "[-+]n\\>" opts)
            cont (string-match "\\+n\\>" opts)
@@ -2264,7 +2629,7 @@ INDENT was the original indentation of the block."
                   (org-count-lines code))
            fmt (if (string-match "-l[ \t]+\"\\([^\"\n]+\\)\"" opts)
                    (match-string 1 opts)))
-      (when (and textareap (eq backend 'html))
+      (when (and textareap (eq org-export-current-backend 'html))
        ;; we cannot use numbering or highlighting.
        (setq num nil cont nil lang nil))
       (if keepp (setq rpllbl 'keep))
@@ -2284,15 +2649,15 @@ INDENT was the original indentation of the block."
       ;; Now backend-specific coding
       (setq rtn
            (cond
-            ((eq backend 'docbook)
-             (setq rtn (org-export-number-lines rtn 'docbook 0 0 num cont rpllbl fmt))
-             (concat "\n#+BEGIN_DOCBOOK\n"
-                     (org-add-props (concat "<programlisting><![CDATA["
-                                            rtn
-                                            "]]></programlisting>\n")
-                         '(org-protected t org-example t))
-                     "#+END_DOCBOOK\n"))
-            ((eq backend 'html)
+            (backend-formatter
+             (funcall backend-formatter rtn lang caption textareap cols rows num
+                      cont rpllbl fmt))
+            ((eq org-export-current-backend 'docbook)
+             (setq rtn (org-export-number-lines rtn 0 0 num cont rpllbl fmt))
+             (concat "<programlisting><![CDATA["
+                     rtn
+                     "]]></programlisting>\n"))
+            ((eq org-export-current-backend 'html)
              ;; We are exporting to HTML
              (when lang
                (if (featurep 'xemacs)
@@ -2323,6 +2688,8 @@ INDENT was the original indentation of the block."
                                (funcall mode)
                              (fundamental-mode))
                            (font-lock-fontify-buffer)
+                           ;; markup each line separately
+                           (org-remove-formatting-on-newlines-in-region (point-min) (point-max))
                            (org-src-mode)
                            (set-buffer-modified-p nil)
                            (org-export-htmlize-region-for-paste
@@ -2356,81 +2723,134 @@ INDENT was the original indentation of the block."
                    (setq rtn (buffer-string)))
                  (setq rtn (concat "<pre class=\"example\">\n" rtn "</pre>\n"))))
              (unless textareap
-               (setq rtn (org-export-number-lines rtn 'html 1 1 num
-                                                  cont rpllbl fmt)))
+               (setq rtn (org-export-number-lines rtn 1 1 num cont rpllbl fmt)))
              (if (string-match "\\(\\`<[^>]*>\\)\n" rtn)
                  (setq rtn (replace-match "\\1" t nil rtn)))
-             (concat "\n#+BEGIN_HTML\n" (org-add-props rtn '(org-protected t org-example t)) "\n#+END_HTML\n\n"))
-            ((eq backend 'latex)
-             (setq rtn (org-export-number-lines rtn 'latex 0 0 num cont rpllbl fmt))
-             (concat "#+BEGIN_LaTeX\n"
-                     (org-add-props
-                          (cond
-                          ((and org-export-latex-listings
-                                (not (eq org-export-latex-listings 'minted)))
-                           (concat
-                            (if lang
-                                (let*
-                                    ((lang-sym (intern lang))
-                                     (lstlang
-                                      (or (cadr
-                                           (assq
-                                            lang-sym
-                                            org-export-latex-listings-langs))
-                                          lang)))
-                                  (format "\\lstset{language=%s}\n" lstlang))
-                              "\n")
-                            (when (and caption
-                                       org-export-latex-listings-w-names)
-                              (format "\n%s $\\equiv$ \n"
-                                      (replace-regexp-in-string
-                                       "_" "\\\\_" caption)))
-                            "\\begin{lstlisting}\n"
-                            rtn "\\end{lstlisting}\n"))
-                          ((eq org-export-latex-listings 'minted)
-                           (if lang
-                               (let*
-                                   ((lang-sym (intern lang))
-                                    (minted-lang
-                                     (or (cadr
-                                          (assq
-                                           lang-sym
-                                           org-export-latex-minted-langs))
-                                         (downcase lang))))
-                                 (concat
-                                  (when (and caption
-                                             org-export-latex-listings-w-names)
-                                    (format "\n%s $\\equiv$ \n"
-                                            (replace-regexp-in-string
-                                             "_" "\\\\_" caption)))
-                                  (format
-                                   "\\begin{minted}[mathescape,%s\nnumbersep=5pt,\nframe=lines,\nframesep=2mm]{%s}\n" (if org-export-latex-minted-with-line-numbers "\nlinenos," "") minted-lang)
-                                  rtn "\\end{minted}\n"))))
-                           (t (concat (car org-export-latex-verbatim-wrap)
-                                      rtn (cdr org-export-latex-verbatim-wrap))))
-                          '(org-protected t org-example t))
-                         "#+END_LaTeX\n"))
-             ((eq backend 'ascii)
-              ;; This is not HTML or LaTeX, so just make it an example.
-              (setq rtn (org-export-number-lines rtn 'ascii 0 0 num cont rpllbl fmt))
-              (concat caption "\n"
-                     "#+BEGIN_ASCII\n"
-                     (org-add-props
-                         (concat
-                          (mapconcat
-                           (lambda (l) (concat "  " l))
-                           (org-split-string rtn "\n")
-                           "\n")
-                          "\n")
-                         '(org-protected t org-example t))
-                     "#+END_ASCII\n"))))
+             rtn)
+            ((eq org-export-current-backend 'latex)
+             (setq rtn (org-export-number-lines rtn 0 0 num cont rpllbl fmt))
+             (cond
+              ((and lang org-export-latex-listings)
+               (let* ((make-option-string
+                       (lambda (pair)
+                         (concat (first pair)
+                                 (if (> (length (second pair)) 0)
+                                     (concat "=" (second pair))))))
+                      (lang-sym (intern lang))
+                      (minted-p (eq org-export-latex-listings 'minted))
+                      (listings-p (not minted-p))
+                      (backend-lang
+                       (or (cadr
+                            (assq
+                             lang-sym
+                             (cond
+                              (minted-p org-export-latex-minted-langs)
+                              (listings-p org-export-latex-listings-langs))))
+                           lang))
+                      (custom-environment
+                       (cadr
+                        (assq
+                         lang-sym
+                         org-export-latex-custom-lang-environments))))
+                 (concat
+                  (when (and listings-p (not custom-environment))
+                    (format
+                     "\\lstset{%s}\n"
+                     (mapconcat
+                      make-option-string
+                      (append org-export-latex-listings-options
+                              `(("language" ,backend-lang))) ",")))
+                  (when (and caption org-export-latex-listings-w-names)
+                    (format
+                     "\n%s $\\equiv$ \n"
+                     (replace-regexp-in-string "_" "\\\\_" caption)))
+                  (cond
+                   (custom-environment
+                    (format "\\begin{%s}\n%s\\end{%s}\n"
+                            custom-environment rtn custom-environment))
+                   (listings-p
+                    (format "\\begin{%s}\n%s\\end{%s}"
+                            "lstlisting" rtn "lstlisting"))
+                   (minted-p
+                    (format
+                     "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+                     (mapconcat make-option-string
+                                org-export-latex-minted-options ",")
+                     backend-lang rtn))))))
+              (t (concat (car org-export-latex-verbatim-wrap)
+                         rtn (cdr org-export-latex-verbatim-wrap)))))
+            ((eq org-export-current-backend 'ascii)
+             ;; This is not HTML or LaTeX, so just make it an example.
+             (setq rtn (org-export-number-lines rtn 0 0 num cont rpllbl fmt))
+             (concat caption "\n"
+                     (concat
+                      (mapconcat
+                       (lambda (l) (concat "  " l))
+                       (org-split-string rtn "\n")
+                       "\n")
+                      "\n")))
+            (t
+             (error "Don't know how to markup source or example block in %s"
+                    (upcase backend-name)))))
+      (setq rtn
+           (concat
+            "\n#+BEGIN_" backend-name "\n"
+            (org-add-props rtn
+                '(org-protected t org-example t org-native-text t))
+            "\n#+END_" backend-name "\n"))
       (org-add-props rtn nil 'original-indentation indent))))
 
-(defun org-export-number-lines (text backend
-                                    &optional skip1 skip2 number cont
-                                    replace-labels label-format)
+(defun org-export-number-lines (text &optional skip1 skip2 number cont
+                                    replace-labels label-format preprocess)
+  "Apply line numbers to literal examples and handle code references.
+Handle user-specified options under info node `(org)Literal
+examples' and return the modified source block.
+
+TEXT contains the source or example block.
+
+SKIP1 and SKIP2 are the number of lines that are to be skipped at
+the beginning and end of TEXT.  Use these to skip over
+backend-specific lines pre-pended or appended to the original
+source block.
+
+NUMBER is non-nil if the literal example specifies \"+n\" or
+\"-n\" switch.  If NUMBER is non-nil add line numbers.
+
+CONT is non-nil if the literal example specifies \"+n\" switch.
+If CONT is nil, start numbering this block from 1.  Otherwise
+continue numbering from the last numbered block.
+
+REPLACE-LABELS is dual-purpose.
+1. It controls the retention of labels in the exported block.
+2. It specifies in what manner the links (or references) to a
+   labeled line be formatted.
+
+REPLACE-LABELS is the symbol `keep' if the literal example
+specifies \"-k\" option, is numeric if the literal example
+specifies \"-r\" option and is nil otherwise.
+
+Handle REPLACE-LABELS as below:
+- If nil, retain labels in the exported block and use
+  user-provided labels for referencing the labeled lines.
+- If it is a number, remove labels in the exported block and use
+  one of line numbers or labels for referencing labeled lines based
+  on NUMBER option.
+- If it is a keep, retain labels in the exported block and use
+  one of line numbers or labels for referencing labeled lines
+  based on NUMBER option.
+
+LABEL-FORMAT is the value of \"-l\" switch associated with
+literal example.  See `org-coderef-label-format'.
+
+PREPROCESS is intended for backend-agnostic handling of source
+block numbering.  When non-nil do the following:
+- do not number the lines
+- always strip the labels from exported block
+- do not make the labeled line a target of an incoming link.
+  Instead mark the labeled line with `org-coderef' property and
+  store the label in it."
   (setq skip1 (or skip1 0) skip2 (or skip2 0))
-  (if (not cont) (setq org-export-last-code-line-counter-value 0))
+  (if (and number (not cont)) (setq org-export-last-code-line-counter-value 0))
   (with-temp-buffer
     (insert text)
     (goto-char (point-max))
@@ -2443,11 +2863,11 @@ INDENT was the original indentation of the block."
           (fmt (format "%%%dd:  " (length (number-to-string nmax))))
           (fm
            (cond
-            ((eq backend 'html) (format "<span class=\"linenr\">%s</span>"
-                                        fmt))
-            ((eq backend 'ascii) fmt)
-            ((eq backend 'latex) fmt)
-            ((eq backend 'docbook) fmt)
+            ((eq org-export-current-backend 'html) (format "<span class=\"linenr\">%s</span>"
+                                                           fmt))
+            ((eq org-export-current-backend 'ascii) fmt)
+            ((eq org-export-current-backend 'latex) fmt)
+            ((eq org-export-current-backend 'docbook) fmt)
             (t "")))
           (label-format (or label-format org-coderef-label-format))
           (label-pre (if (string-match "%s" label-format)
@@ -2467,9 +2887,10 @@ INDENT was the original indentation of the block."
 
       (org-goto-line (1+ skip1))
       (while (and (re-search-forward "^" nil t) (not (eobp)) (< n nmax))
-       (if number
-           (insert (format fm (incf n)))
-         (forward-char 1))
+       (when number (incf n))
+       (if (or preprocess (not number))
+           (forward-char 1)
+         (insert (format fm n)))
        (when (looking-at lbl-re)
          (setq ref (match-string 3))
          (cond ((numberp replace-labels)
@@ -2482,7 +2903,8 @@ INDENT was the original indentation of the block."
                 ;; lines are numbered, use labels otherwise
                 (goto-char (match-beginning 2))
                 (delete-region (match-beginning 2) (match-end 2))
-                (insert "(" ref ")")
+                (unless preprocess
+                  (insert "(" ref ")"))
                 (push (cons ref (if (> n 0) n (concat "(" ref ")")))
                       org-export-code-refs))
                (t
@@ -2490,15 +2912,19 @@ INDENT was the original indentation of the block."
                 ;; references
                 (goto-char (match-beginning 2))
                 (delete-region (match-beginning 2) (match-end 2))
-                (insert "(" ref ")")
+                (unless preprocess
+                  (insert "(" ref ")"))
                 (push (cons ref (concat "(" ref ")")) org-export-code-refs)))
-         (when (eq backend 'html)
+         (when (and (eq org-export-current-backend 'html) (not preprocess))
            (save-excursion
              (beginning-of-line 1)
              (insert (format "<span id=\"coderef-%s\" class=\"coderef-off\">"
                              ref))
              (end-of-line 1)
-             (insert "</span>")))))
+             (insert "</span>")))
+         (when preprocess
+           (add-text-properties
+            (point-at-bol) (point-at-eol) (list 'org-coderef ref)))))
       (setq org-export-last-code-line-counter-value n)
       (goto-char (point-max))
       (newline)
@@ -2516,7 +2942,7 @@ INDENT was the original indentation of the block."
              (setq lv (- (match-end 1) (match-beginning 1))
                    todo (and (match-beginning 2)
                              (not (member (match-string 2 line)
-                                         org-done-keywords))))
+                                          org-done-keywords))))
                                        ; TODO, not DONE
              (if (<= lv level) (throw 'exit nil))
              (if todo (throw 'exit t))))))))
@@ -2536,7 +2962,7 @@ command."
           (message "Export visible: [a]SCII  [h]tml  [b]rowse HTML [H/R]buffer with HTML  [D]ocBook  [l]atex  [p]df  [d]view pdf  [L]atex buffer  [x]OXO  [ ]keep buffer")
           (read-char-exclusive))
         current-prefix-arg))
-  (if (not (member type '(?a ?n ?u ?\C-a ?b ?\C-b ?h ?D ?x ?\ ?l ?p ?d ?L)))
+  (if (not (member type '(?a ?n ?u ?\C-a ?b ?\C-b ?h ?D ?x ?\ ?l ?p ?d ?L ?H ?R)))
       (error "Invalid export key"))
   (let* ((binding (cdr (assoc type
                              '(
@@ -2569,7 +2995,7 @@ command."
       (goto-char (point-min))
       (while (re-search-forward org-drawer-regexp nil t)
        (goto-char (match-beginning 1))
-       (or (org-invisible-p) (org-flag-drawer nil))))
+       (or (outline-invisible-p) (org-flag-drawer nil))))
     (with-current-buffer buffer (erase-buffer))
     (save-excursion
       (setq s (goto-char (point-min)))
@@ -2585,9 +3011,10 @@ command."
        ;; does do the trick.
        (if (looking-at "#[^\r\n]*")
            (append-to-buffer buffer (match-beginning 0) (1+ (match-end 0))))
-       (while (re-search-forward "[\n\r]#[^\n\r]*" nil t)
-         (append-to-buffer buffer (1+ (match-beginning 0))
-                           (min (point-max) (1+ (match-end 0))))))
+       (when (re-search-forward "^\\*+[ \t]+" nil t)
+         (while (re-search-backward "[\n\r]#[^\n\r]*" nil t)
+           (append-to-buffer buffer (1+ (match-beginning 0))
+                             (min (point-max) (1+ (match-end 0)))))))
       (set-buffer buffer)
       (let ((buffer-file-name file)
            (org-inhibit-startup t))
@@ -2599,17 +3026,6 @@ command."
       (switch-to-buffer-other-window buffer)
       (goto-char (point-min)))))
 
-(defun org-find-visible ()
-  (let ((s (point)))
-    (while (and (not (= (point-max) (setq s (next-overlay-change s))))
-               (get-char-property s 'invisible)))
-    s))
-(defun org-find-invisible ()
-  (let ((s (point)))
-    (while (and (not (= (point-max) (setq s (next-overlay-change s))))
-               (not (get-char-property s 'invisible))))
-    s))
-
 (defvar org-export-htmlized-org-css-url) ;; defined in org-html.el
 
 (defun org-export-string (string fmt &optional dir)
@@ -2628,9 +3044,9 @@ to the value of `temporary-file-directory'."
          (org-load-modules-maybe)
          (unless org-local-vars
            (setq org-local-vars (org-get-local-variables)))
-         (eval ;; convert to fmt -- mimicing `org-run-like-in-org-mode'
+         (eval ;; convert to fmt -- mimicking `org-run-like-in-org-mode'
           (list 'let org-local-vars
-                (list (intern (concat "org-export-as-" fmt))
+                (list (intern (format "org-export-as-%s" fmt))
                       nil nil nil ''string t))))
       (delete-file tmp-file))))
 
@@ -2678,7 +3094,7 @@ directory."
         (region (buffer-string))
          str-ret)
     (save-excursion
-      (switch-to-buffer buffer)
+      (org-pop-to-buffer-same-window buffer)
       (erase-buffer)
       (insert region)
       (let ((org-inhibit-startup t)) (org-mode))
@@ -2738,8 +3154,8 @@ Does include HTML export options as well as TODO and CATEGORY stuff."
 #+AUTHOR:    %s
 #+EMAIL:     %s
 #+DATE:      %s
-#+DESCRIPTION: 
-#+KEYWORDS: 
+#+DESCRIPTION:
+#+KEYWORDS:
 #+LANGUAGE:  %s
 #+OPTIONS:   H:%d num:%s toc:%s \\n:%s @:%s ::%s |:%s ^:%s -:%s f:%s *:%s <:%s
 #+OPTIONS:   TeX:%s LaTeX:%s skip:%s d:%s todo:%s pri:%s tags:%s
@@ -2748,7 +3164,7 @@ Does include HTML export options as well as TODO and CATEGORY stuff."
 #+EXPORT_EXCLUDE_TAGS: %s
 #+LINK_UP:   %s
 #+LINK_HOME: %s
-#+XSLT: 
+#+XSLT:
 #+CATEGORY:  %s
 #+SEQ_TODO:  %s
 #+TYP_TODO:  %s
@@ -2813,10 +3229,8 @@ Does include HTML export options as well as TODO and CATEGORY stuff."
                  (or org-tag-alist (org-get-buffer-tags)) " ") "")
    (mapconcat 'identity org-file-tags " ")
    org-archive-location
-   "org file:~/org/%s.org"
-   ))
+   "org file:~/org/%s.org"))
 
-;;;###autoload
 (defun org-insert-export-options-template ()
   "Insert into the buffer a template with information for exporting."
   (interactive)
@@ -2855,8 +3269,7 @@ If yes remove the column and the special lines."
                         (mapcar (lambda (x)
                                   (cond ((member x '("<" "&lt;")) :start)
                                         ((member x '(">" "&gt;")) :end)
-                                        ((member x '("<>" "&lt;&gt;")) :startend)
-                                        (t nil)))
+                                        ((member x '("<>" "&lt;&gt;")) :startend)))
                                 (org-split-string x "[ \t]*|[ \t]*")))
                   nil)
                  ((org-table-cookie-line-p x)
@@ -2877,14 +3290,13 @@ If yes remove the column and the special lines."
                     (mapcar (lambda (x)
                               (cond ((member x '("<" "&lt;")) :start)
                                     ((member x '(">" "&gt;")) :end)
-                                    ((member x '("<>" "&lt;&gt;")) :startend)
-                                    (t nil)))
+                                    ((member x '("<>" "&lt;&gt;")) :startend)))
                             (cdr (org-split-string x "[ \t]*|[ \t]*"))))
               nil)
              ((org-table-cookie-line-p x)
               ;; This line contains formatting cookies, discard it
               nil)
-             ((string-match "^[ \t]*| *[!_^/] *|" x)
+             ((string-match "^[ \t]*| *\\([!_^/$]\\|\\\\\\$\\) *|" x)
               ;; ignore this line
               nil)
              ((or (string-match "^\\([ \t]*\\)|-+\\+" x)
@@ -2895,18 +3307,20 @@ If yes remove the column and the special lines."
 
 (defun org-export-cleanup-toc-line (s)
   "Remove tags and timestamps from lines going into the toc."
-  (when (memq org-export-with-tags '(not-in-toc nil))
-    (if (string-match (org-re " +:[[:alnum:]_@#%:]+: *$") s)
+  (if (not s)
+      "" ; Return a string when argument is nil
+    (when (memq org-export-with-tags '(not-in-toc nil))
+      (if (string-match (org-re " +:[[:alnum:]_@#%:]+: *$") s)
+         (setq s (replace-match "" t t s))))
+    (when org-export-remove-timestamps-from-toc
+      (while (string-match org-maybe-keyword-time-regexp s)
        (setq s (replace-match "" t t s))))
-  (when org-export-remove-timestamps-from-toc
-    (while (string-match org-maybe-keyword-time-regexp s)
-      (setq s (replace-match "" t t s))))
-  (while (string-match org-bracket-link-regexp s)
-    (setq s (replace-match (match-string (if (match-end 3) 3 1) s)
-                          t t s)))
-  (while (string-match "\\[\\([0-9]\\|fn:[^]]*\\)\\]" s)
-    (setq s (replace-match "" t t s)))
-  s)
+    (while (string-match org-bracket-link-regexp s)
+      (setq s (replace-match (match-string (if (match-end 3) 3 1) s)
+                            t t s)))
+    (while (string-match "\\[\\([0-9]\\|fn:[^]]*\\)\\]" s)
+      (setq s (replace-match "" t t s)))
+    s))
 
 
 (defun org-get-text-property-any (pos prop &optional object)
@@ -2924,7 +3338,7 @@ If yes remove the column and the special lines."
 
 (defun org-export-push-to-kill-ring (format)
   "Push buffer content to kill ring.
-The depends on the variable `org-export-copy-to-kill'."
+The depends on the variable `org-export-copy-to-kill-ring'."
   (when org-export-copy-to-kill-ring
     (org-kill-new (buffer-string))
     (when (fboundp 'x-set-selection)
@@ -2934,7 +3348,8 @@ The depends on the variable `org-export-copy-to-kill'."
 
 (provide 'org-exp)
 
-;; arch-tag: 65985fe9-095c-49c7-a7b6-cb4ee15c0a95
+;; Local variables:
+;; generated-autoload-file: "org-loaddefs.el"
+;; End:
 
 ;;; org-exp.el ends here
-