From: Achim Gratz <Stromeko@nexgo.de>
To: emacs-orgmode@gnu.org
Subject: Re: Org release 7.8.04 (BUGFIX-only release)
Date: Sun, 18 Mar 2012 22:14:47 +0100 [thread overview]
Message-ID: <87pqc9harc.fsf@Rainer.invalid> (raw)
In-Reply-To: 87ty1lhb1m.fsf@Rainer.invalid
[-- Attachment #1: Type: text/plain, Size: 395 bytes --]
Achim Gratz <Stromeko@nexgo.de> writes:
> Here are two patches to clean up master and maint to where they should
> be (IMHO, please check). Needless to say, you _will_ have to do another
> release with these fixes.
Curses... here are the two patches, not that stuff I tried to kill
and instead had Gnus send it (don't you love it when the all-encompassing
C-c prefix suddenly enters twice?).
[-- Attachment #2: Fixup for master branch --]
[-- Type: text/x-patch, Size: 712207 bytes --]
From 4ede41abf73867d4af990ec9d444d50d21ff79c7 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Sun, 18 Mar 2012 21:02:41 +0100
Subject: [PATCH] Master fixup
---
EXPERIMENTAL/org-e-latex.el | 1317 +++++++----
Makefile | 4 +-
contrib/babel/langs/ob-fomus.el | 2 +-
contrib/babel/langs/ob-oz.el | 2 +-
contrib/lisp/htmlize.el | 8 +-
contrib/lisp/org-bookmark.el | 4 +-
contrib/lisp/org-checklist.el | 3 -
contrib/lisp/org-choose.el | 76 +-
contrib/lisp/org-collector.el | 4 +-
contrib/lisp/org-drill.el | 1 -
contrib/lisp/org-element.el | 2546 +++++++++++----------
contrib/lisp/org-eval-light.el | 4 +-
contrib/lisp/org-eval.el | 7 +-
contrib/lisp/org-expiry.el | 26 +-
contrib/lisp/org-export-generic.el | 60 +-
contrib/lisp/org-export.el | 3420 ++++++++++++++++++-----------
contrib/lisp/org-interactive-query.el | 8 +-
contrib/lisp/org-invoice.el | 18 +-
contrib/lisp/org-mac-iCal.el | 6 +-
contrib/lisp/org-mac-link-grabber.el | 10 +-
contrib/lisp/org-mairix.el | 6 +-
contrib/lisp/org-mime.el | 4 +-
contrib/lisp/org-mtags.el | 1 -
contrib/lisp/org-notmuch.el | 10 +-
contrib/lisp/org-panel.el | 2 -
contrib/lisp/org-registry.el | 8 +-
contrib/lisp/org-screen.el | 8 +-
contrib/lisp/org-static-mathjax.el | 12 +-
contrib/lisp/org-sudoku.el | 6 +-
contrib/lisp/org-toc.el | 8 +-
contrib/lisp/org-wikinodes.el | 6 +-
contrib/lisp/org2rem.el | 6 +-
contrib/lisp/test-org-export-preproc.el | 1 -
contrib/scripts/StartOzServer.oz | 2 +-
contrib/scripts/org2hpda | 2 +-
doc/org.texi | 295 ++-
doc/orgcard.tex | 2 +-
doc/orgguide.texi | 37 +-
doc/pdflayout.sty | 2 +-
doc/texinfo.tex | 4 +-
lisp/ob-awk.el | 4 +-
lisp/ob-ditaa.el | 19 +-
lisp/ob-exp.el | 130 +-
lisp/ob-gnuplot.el | 2 +-
lisp/ob-haskell.el | 2 +-
lisp/ob-js.el | 1 +
lisp/ob-lilypond.el | 96 +-
lisp/ob-lisp.el | 1 +
lisp/ob-lob.el | 5 +-
lisp/ob-ocaml.el | 2 +-
lisp/ob-picolisp.el | 9 +-
lisp/ob-plantuml.el | 1 +
lisp/ob-ref.el | 2 +-
lisp/ob-ruby.el | 4 +-
lisp/ob-scheme.el | 1 +
lisp/ob-sh.el | 46 +-
lisp/ob-sql.el | 6 +-
lisp/ob-tangle.el | 15 +-
lisp/ob.el | 110 +-
lisp/org-agenda.el | 49 +-
lisp/org-archive.el | 2 +
lisp/org-ascii.el | 2 +-
lisp/org-attach.el | 1 +
lisp/org-bbdb.el | 1 +
lisp/org-beamer.el | 10 +
lisp/org-bibtex.el | 9 +
lisp/org-capture.el | 14 +-
lisp/org-clock.el | 18 +-
lisp/org-crypt.el | 7 +-
lisp/org-ctags.el | 3 +
lisp/org-docbook.el | 2 +
lisp/org-entities.el | 2 +
lisp/org-eshell.el | 2 +-
lisp/org-exp-blocks.el | 7 +-
lisp/org-exp.el | 6 +
lisp/org-faces.el | 3 +
lisp/org-feed.el | 2 +-
| 1 +
lisp/org-freemind.el | 1 +
lisp/org-gnus.el | 3 +-
lisp/org-habit.el | 2 +
lisp/org-html.el | 9 +
lisp/org-icalendar.el | 4 +
lisp/org-id.el | 6 +-
lisp/org-indent.el | 7 +-
lisp/org-inlinetask.el | 21 +-
lisp/org-irc.el | 2 +-
lisp/org-latex.el | 21 +-
lisp/org-list.el | 66 +-
lisp/org-mks.el | 2 +-
lisp/org-mobile.el | 16 +-
lisp/org-pcomplete.el | 34 +-
lisp/org-publish.el | 11 +-
lisp/org-remember.el | 3 +-
lisp/org-special-blocks.el | 2 +-
lisp/org-src.el | 40 +-
lisp/org-table.el | 11 +-
lisp/org-taskjuggler.el | 16 +-
lisp/org-timer.el | 1 +
lisp/org-vm.el | 89 +-
lisp/org-wl.el | 5 +
lisp/org.el | 381 +++-
testing/examples/babel.org | 180 +-
testing/examples/normal.org | 10 +
testing/lisp/test-ob-C.el | 14 +-
testing/lisp/test-ob-R.el | 14 +-
testing/lisp/test-ob-awk.el | 14 +-
testing/lisp/test-ob-emacs-lisp.el | 12 -
testing/lisp/test-ob-exp.el | 250 ++-
testing/lisp/test-ob-fortran.el | 34 +-
testing/lisp/test-ob-lilypond.el | 35 +-
testing/lisp/test-ob-lob.el | 2 +-
testing/lisp/test-ob-maxima.el | 28 +-
testing/lisp/test-ob-octave.el | 14 +-
testing/lisp/test-ob-python.el | 14 +-
testing/lisp/test-ob-sh.el | 15 +-
testing/lisp/test-ob-table.el | 12 +-
testing/lisp/test-ob-tangle.el | 11 +-
testing/lisp/test-ob.el | 373 +++-
testing/lisp/test-org-exp.el | 11 +-
testing/lisp/test-org-html.el | 13 +-
testing/lisp/test-org-table.el | 38 +-
testing/lisp/test-org.el | 57 +-
testing/lisp/test-property-inheritance.el | 11 +-
testing/org-test-ob-consts.el | 4 +-
testing/org-test.el | 30 +-
126 files changed, 6557 insertions(+), 3937 deletions(-)
diff --git a/EXPERIMENTAL/org-e-latex.el b/EXPERIMENTAL/org-e-latex.el
index f9bf00d..0f52bec 100644
--- a/EXPERIMENTAL/org-e-latex.el
+++ b/EXPERIMENTAL/org-e-latex.el
@@ -1,6 +1,6 @@
;;; org-e-latex.el --- LaTeX Back-End For Org Export Engine
-;; Copyright (C) 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -36,8 +36,54 @@
;;; Code:
(eval-when-compile (require 'cl))
-(require 'org-element)
-(require 'org-export)
+
+(defvar org-export-latex-default-packages-alist)
+(defvar org-export-latex-packages-alist)
+
+(declare-function org-element-property "org-element" (property element))
+(declare-function org-element-normalize-string "org-element" (s))
+(declare-function org-element-parse-secondary-string
+ "org-element" (string restriction &optional buffer))
+(defvar org-element-string-restrictions)
+(defvar org-element-object-restrictions)
+
+(declare-function org-export-clean-table "org-export" (table specialp))
+(declare-function org-export-data "org-export" (data backend info))
+(declare-function org-export-directory "org-export" (type plist))
+(declare-function org-export-expand-macro "org-export" (macro info))
+(declare-function org-export-first-sibling-p "org-export" (headline info))
+(declare-function org-export-footnote-first-reference-p "org-export"
+ (footnote-reference info))
+(declare-function org-export-format-code "org-export"
+ (code fun &optional num-lines ref-alist))
+(declare-function org-export-format-code-default "org-export" (element info))
+(declare-function org-export-get-coderef-format "org-export" (path desc))
+(declare-function org-export-get-footnote-definition "org-export"
+ (footnote-reference info))
+(declare-function org-export-get-footnote-number "org-export" (footnote info))
+(declare-function org-export-get-previous-element "org-export" (blob info))
+(declare-function org-export-get-relative-level "org-export" (headline info))
+(declare-function org-export-unravel-code
+ "org-export" (element info &optional num-fmt ref-fmt delayed))
+(declare-function org-export-included-file "org-export" (keyword backend info))
+(declare-function org-export-inline-image-p "org-export"
+ (link &optional extensions))
+(declare-function org-export-last-sibling-p "org-export" (headline info))
+(declare-function org-export-low-level-p "org-export" (headline info))
+(declare-function org-export-output-file-name
+ "org-export" (extension &optional subtreep pub-dir))
+(declare-function org-export-resolve-coderef "org-export" (ref info))
+(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
+(declare-function org-export-secondary-string "org-export"
+ (secondary backend info))
+(declare-function org-export-solidify-link-text "org-export" (s))
+(declare-function org-export-table-format-info "org-export" (table))
+(declare-function
+ org-export-to-buffer "org-export"
+ (backend buffer &optional subtreep visible-only body-only ext-plist))
+(declare-function
+ org-export-to-file "org-export"
+ (backend file &optional subtreep visible-only body-only ext-plist))
\f
@@ -56,7 +102,7 @@ (defconst org-e-latex-option-alist
\f
;;; User Configurable Variables
-(defgroup org-export-latex nil
+(defgroup org-export-e-latex nil
"Options for exporting Org mode files to LaTeX."
:tag "Org Export LaTeX"
:group 'org-export)
@@ -66,7 +112,7 @@ (defgroup org-export-latex nil
(defcustom org-e-latex-default-class "article"
"The default LaTeX class."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type '(string :tag "LaTeX class"))
(defcustom org-e-latex-classes
@@ -103,20 +149,22 @@ (defcustom org-e-latex-classes
The header string
-----------------
-The HEADER-STRING is the header that will be inserted into the LaTeX file.
-It should contain the \\documentclass macro, and anything else that is needed
-for this setup. To this header, the following commands will be added:
+The HEADER-STRING is the header that will be inserted into the
+LaTeX file. It should contain the \\documentclass macro, and
+anything else that is needed for this setup. To this header, the
+following commands will be added:
-- Calls to \\usepackage for all packages mentioned in the variables
- `org-e-latex-default-packages-alist' and
- `org-e-latex-packages-alist'. Thus, your header definitions should
- avoid to also request these packages.
+- Calls to \\usepackage for all packages mentioned in the
+ variables `org-export-latex-default-packages-alist' and
+ `org-export-latex-packages-alist'. Thus, your header
+ definitions should avoid to also request these packages.
- Lines specified via \"#+LaTeX_HEADER:\"
-If you need more control about the sequence in which the header is built
-up, or if you want to exclude one of these building blocks for a particular
-class, you can use the following macro-like placeholders.
+If you need more control about the sequence in which the header
+is built up, or if you want to exclude one of these building
+blocks for a particular class, you can use the following
+macro-like placeholders.
[DEFAULT-PACKAGES] \\usepackage statements for default packages
[NO-DEFAULT-PACKAGES] do not include any of the default packages
@@ -134,23 +182,26 @@ (defcustom org-e-latex-classes
\\providecommand{\\alert}[1]{\\textbf{#1}}
[PACKAGES]
-will omit the default packages, and will include the #+LaTeX_HEADER lines,
-then have a call to \\providecommand, and then place \\usepackage commands
-based on the content of `org-e-latex-packages-alist'.
-
-If your header or `org-e-latex-default-packages-alist' inserts
-\"\\usepackage[AUTO]{inputenc}\", AUTO will automatically be replaced with
-a coding system derived from `buffer-file-coding-system'. See also the
-variable `org-e-latex-inputenc-alist' for a way to influence this
+will omit the default packages, and will include the
+#+LaTeX_HEADER lines, then have a call to \\providecommand, and
+then place \\usepackage commands based on the content of
+`org-export-latex-packages-alist'.
+
+If your header, `org-export-latex-default-packages-alist' or
+`org-export-latex-packages-alist' inserts
+\"\\usepackage[AUTO]{inputenc}\", AUTO will automatically be
+replaced with a coding system derived from
+`buffer-file-coding-system'. See also the variable
+`org-e-latex-inputenc-alist' for a way to influence this
mechanism.
The sectioning structure
------------------------
-The sectioning structure of the class is given by the elements following
-the header string. For each sectioning level, a number of strings is
-specified. A %s formatter is mandatory in each section string and will
-be replaced by the title of the section.
+The sectioning structure of the class is given by the elements
+following the header string. For each sectioning level, a number
+of strings is specified. A %s formatter is mandatory in each
+section string and will be replaced by the title of the section.
Instead of a cons cell \(numbered . unnumbered\), you can also
provide a list of 2 or 4 elements,
@@ -161,16 +212,16 @@ (defcustom org-e-latex-classes
\(numbered-open numbered-close unnumbered-open unnumbered-close\)
-providing opening and closing strings for a LaTeX environment that should
-represent the document section. The opening clause should have a %s
-to represent the section title.
+providing opening and closing strings for a LaTeX environment
+that should represent the document section. The opening clause
+should have a %s to represent the section title.
-Instead of a list of sectioning commands, you can also specify a
-function name. That function will be called with two parameters,
-the (reduced) level of the headline, and a predicate non-nil when
-the headline should be numbered. It must return a format string in
-which the section title will be added."
- :group 'org-export-latex
+Instead of a list of sectioning commands, you can also specify
+a function name. That function will be called with two
+parameters, the \(reduced) level of the headline, and a predicate
+non-nil when the headline should be numbered. It must return
+a format string in which the section title will be added."
+ :group 'org-export-e-latex
:type '(repeat
(list (string :tag "LaTeX class")
(string :tag "LaTeX header")
@@ -194,7 +245,7 @@ (defcustom org-e-latex-inputenc-alist nil
will cause \\usepackage[utf8x]{inputenc} to be used for buffers that
are written as utf8 files."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type '(repeat
(cons
(string :tag "Derived from buffer")
@@ -203,7 +254,7 @@ (defcustom org-e-latex-inputenc-alist nil
(defcustom org-e-latex-date-format
"\\today"
"Format string for \\date{...}."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'boolean)
(defcustom org-e-latex-title-command "\\maketitle"
@@ -211,7 +262,7 @@ (defcustom org-e-latex-title-command "\\maketitle"
If this string contains the formatting specification \"%s\" then
it will be used as a formatting string, passing the title as an
argument."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
@@ -232,13 +283,15 @@ (defcustom org-e-latex-format-headline-function nil
As an example, one could set the variable to the following, in
order to reproduce the default set-up:
-\(defun org-e-latex-format-headline-default \(todo todo-type priority text tags\)
+\(defun org-e-latex-format-headline \(todo todo-type priority text tags\)
\"Default format function for an headline.\"
- \(concat \(when todo \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
- \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
+ \(concat \(when todo
+ \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
+ \(when priority
+ \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
text
\(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'function)
@@ -261,7 +314,7 @@ (defcustom org-e-latex-emphasis-alist
create a format string and select a delimiter character that
isn't in the string. For the latter, Org will use \"\\texttt\"
to typeset and try to protect special characters."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'alist)
@@ -269,7 +322,7 @@ (defcustom org-e-latex-emphasis-alist
(defcustom org-e-latex-footnote-separator "\\textsuperscript{,}\\,"
"Text used to separate footnotes."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
@@ -277,17 +330,17 @@ (defcustom org-e-latex-footnote-separator "\\textsuperscript{,}\\,"
(defcustom org-e-latex-active-timestamp-format "\\textit{%s}"
"A printf format string to be applied to active time-stamps."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
(defcustom org-e-latex-inactive-timestamp-format "\\textit{%s}"
"A printf format string to be applied to inactive time-stamps."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
(defcustom org-e-latex-diary-timestamp-format "\\textit{%s}"
"A printf format string to be applied to diary time-stamps."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
@@ -295,48 +348,62 @@ (defcustom org-e-latex-diary-timestamp-format "\\textit{%s}"
(defcustom org-e-latex-image-default-option "width=.9\\linewidth"
"Default option for images."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
(defcustom org-e-latex-default-figure-position "htb"
"Default position for latex figures."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
-(defcustom org-e-latex-inline-image-extensions
- '("pdf" "jpeg" "jpg" "png" "ps" "eps")
- "Extensions of image files that can be inlined into LaTeX.
+(defcustom org-e-latex-inline-image-rules
+ '(("file" . "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\)\\'"))
+ "Rules characterizing image files that can be inlined into LaTeX.
-Note that the image extension *actually* allowed depend on the
-way the LaTeX file is processed. When used with pdflatex, pdf,
-jpg and png images are OK. When processing through dvi to
-Postscript, only ps and eps are allowed. The default we use here
-encompasses both."
- :group 'org-export-latex
- :type '(repeat (string :tag "Extension")))
+A rule consists in an association whose key is the type of link
+to consider, and value is a regexp that will be matched against
+link's path.
+
+Note that, by default, the image extension *actually* allowed
+depend on the way the LaTeX file is processed. When used with
+pdflatex, pdf, jpg and png images are OK. When processing
+through dvi to Postscript, only ps and eps are allowed. The
+default we use here encompasses both."
+ :group 'org-export-e-latex
+ :type '(alist :key-type (string :tag "Type")
+ :value-type (regexp :tag "Path")))
;;;; Tables
(defcustom org-e-latex-default-table-environment "tabular"
"Default environment used to build tables."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'string)
(defcustom org-e-latex-tables-centered t
"When non-nil, tables are exported in a center environment."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'boolean)
(defcustom org-e-latex-tables-verbatim nil
"When non-nil, tables are exported verbatim."
- :group 'org-export-latex
+ :group 'org-export-e-latex
+ :type 'boolean)
+
+(defcustom org-e-latex-tables-booktabs nil
+ "When non-nil, display tables in a formal \"booktabs\" style.
+This option assumes that the \"booktabs\" package is properly
+loaded in the header of the document. This value can be ignored
+locally with \"booktabs=yes\" and \"booktabs=no\" LaTeX
+attributes."
+ :group 'org-export-e-latex
:type 'boolean)
(defcustom org-e-latex-table-caption-above t
"When non-nil, place caption string at the beginning of the table.
Otherwise, place it near the end."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'boolean)
@@ -357,7 +424,7 @@ (defcustom org-e-latex-format-drawer-function nil
\(defun org-e-latex-format-drawer-default \(name contents\)
\"Format a drawer element for LaTeX export.\"
contents\)"
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'function)
@@ -379,11 +446,12 @@ (defcustom org-e-latex-format-inlinetask-function nil
For example, the variable could be set to the following function
in order to mimic default behaviour:
-\(defun org-e-latex-format-inlinetask-default \(todo type priority name tags contents\)
+\(defun org-e-latex-format-inlinetask \(todo type priority name tags contents\)
\"Format an inline task element for LaTeX export.\"
\(let \(\(full-title
\(concat
- \(when todo \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
+ \(when todo
+ \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
\(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
title
\(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
@@ -396,7 +464,7 @@ (defcustom org-e-latex-format-inlinetask-function nil
\"\\\\end{minipage}}\"
\"\\\\end{center}\"\)
full-title contents\)\)"
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type 'function)
@@ -407,30 +475,30 @@ (defcustom org-e-latex-listings nil
This package will fontify source code, possibly even with color.
If you want to use this, you also need to make LaTeX use the
listings package, and if you want to have color, the color
-package. Just add these to `org-e-latex-packages-alist',
-for example using customize, or with something like
+package. Just add these to `org-export-latex-packages-alist',
+for example using customize, or with something like:
- (require 'org-e-latex)
- (add-to-list 'org-export-latex-packages-alist '(\"\" \"listings\"))
- (add-to-list 'org-export-latex-packages-alist '(\"\" \"color\"))
+ \(require 'org-e-latex)
+ \(add-to-list 'org-export-latex-packages-alist '\(\"\" \"listings\"))
+ \(add-to-list 'org-export-latex-packages-alist '\(\"\" \"color\"))
Alternatively,
- (setq org-e-latex-listings 'minted)
+ \(setq org-e-latex-listings 'minted)
causes source code to be exported using the minted package as
opposed to listings. If you want to use minted, you need to add
-the minted package to `org-e-latex-packages-alist', for
+the minted package to `org-export-latex-packages-alist', for
example using customize, or with
- (require 'org-e-latex)
- (add-to-list 'org-e-latex-packages-alist '(\"\" \"minted\"))
+ \(require 'org-e-latex)
+ \(add-to-list 'org-export-latex-packages-alist '\(\"\" \"minted\"))
-In addition, it is necessary to install
-pygments (http://pygments.org), and to configure the variable
-`org-e-latex-to-pdf-process' so that the -shell-escape option is
+In addition, it is necessary to install pygments
+\(http://pygments.org), and to configure the variable
+`org-e-latex-pdf-process' so that the -shell-escape option is
passed to pdflatex."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type '(choice
(const :tag "Use listings" t)
(const :tag "Use minted" 'minted)
@@ -449,11 +517,11 @@ (defcustom org-e-latex-listings-langs
(sql "SQL") (sqlite "sql"))
"Alist mapping languages to their listing language counterpart.
The key is a symbol, the major mode symbol without the \"-mode\".
-The value is the string that should be inserted as the language parameter
-for the listings package. If the mode name and the listings name are
-the same, the language does not need an entry in this list - but it does not
-hurt if it is present."
- :group 'org-export-latex
+The value is the string that should be inserted as the language
+parameter for the listings package. If the mode name and the
+listings name are the same, the language does not need an entry
+in this list - but it does not hurt if it is present."
+ :group 'org-export-e-latex
:type '(repeat
(list
(symbol :tag "Major mode ")
@@ -463,11 +531,11 @@ (defcustom org-e-latex-listings-options nil
"Association list of options for the latex listings package.
These options are supplied as a comma-separated list to the
-\\lstset command. Each element of the association list should be
+\\lstset command. Each element of the association list should be
a list containing two strings: the name of the option, and the
-value. For example,
+value. For example,
- (setq org-export-latex-listings-options
+ (setq org-e-latex-listings-options
'((\"basicstyle\" \"\\small\")
(\"keywordstyle\" \"\\color{black}\\bfseries\\underbar\")))
@@ -476,7 +544,7 @@ (defcustom org-e-latex-listings-options nil
Note that the same options will be applied to blocks of all
languages."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type '(repeat
(list
(string :tag "Listings option name ")
@@ -490,16 +558,17 @@ (defcustom org-e-latex-minted-langs
(caml "ocaml"))
"Alist mapping languages to their minted language counterpart.
The key is a symbol, the major mode symbol without the \"-mode\".
-The value is the string that should be inserted as the language parameter
-for the minted package. If the mode name and the listings name are
-the same, the language does not need an entry in this list - but it does not
-hurt if it is present.
+The value is the string that should be inserted as the language
+parameter for the minted package. If the mode name and the
+listings name are the same, the language does not need an entry
+in this list - but it does not hurt if it is present.
Note that minted uses all lower case for language identifiers,
and that the full list of language identifiers can be obtained
with:
-pygmentize -L lexers"
- :group 'org-export-latex
+
+ pygmentize -L lexers"
+ :group 'org-export-e-latex
:type '(repeat
(list
(symbol :tag "Major mode ")
@@ -509,12 +578,12 @@ (defcustom org-e-latex-minted-options nil
"Association list of options for the latex minted package.
These options are supplied within square brackets in
-\\begin{minted} environments. Each element of the alist should be
-a list containing two strings: the name of the option, and the
-value. For example,
+\\begin{minted} environments. Each element of the alist should
+be a list containing two strings: the name of the option, and the
+value. For example,
- (setq org-export-latex-minted-options
- '((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
+ \(setq org-e-latex-minted-options
+ '\((\"bgcolor\" \"bg\") \(\"frame\" \"lines\")))
will result in src blocks being exported with
@@ -522,19 +591,20 @@ (defcustom org-e-latex-minted-options nil
as the start of the minted environment. Note that the same
options will be applied to blocks of all languages."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type '(repeat
(list
(string :tag "Minted option name ")
(string :tag "Minted option value"))))
(defvar org-e-latex-custom-lang-environments nil
- "Association list mapping languages to language-specific latex
-environments used during export of src blocks by the listings and
-minted latex packages. For example,
+ "Alist mapping languages to language-specific LaTeX environments.
- (setq org-export-latex-custom-lang-environments
- '((python \"pythoncode\")))
+It is used during export of src blocks by the listings and minted
+latex packages. For example,
+
+ \(setq org-e-latex-custom-lang-environments
+ '\(\(python \"pythoncode\"\)\)\)
would have the effect that if org encounters begin_src python
during latex export it will output
@@ -560,7 +630,7 @@ (defcustom org-e-latex-quotes
For each item in a CONS, the first string is a regexp
for allowed characters before/after the quote, the second
string defines the replacement string for this quote."
- :group 'org-export-latex
+ :group 'org-export-e-latex
:type '(list
(cons :tag "Opening quote"
(string :tag "Regexp for char before")
@@ -573,34 +643,100 @@ (defcustom org-e-latex-quotes
(string :tag "Replacement quote "))))
+;;;; Compilation
+
+(defcustom org-e-latex-pdf-process
+ '("pdflatex -interaction nonstopmode -output-directory %o %f"
+ "pdflatex -interaction nonstopmode -output-directory %o %f"
+ "pdflatex -interaction nonstopmode -output-directory %o %f")
+ "Commands to process a LaTeX file to a PDF file.
+This is a list of strings, each of them will be given to the
+shell as a command. %f in the command will be replaced by the
+full file name, %b by the file base name \(i.e. without
+extension) and %o by the base directory of the file.
+
+The reason why this is a list is that it usually takes several
+runs of `pdflatex', maybe mixed with a call to `bibtex'. Org
+does not have a clever mechanism to detect which of these
+commands have to be run to get to a stable result, and it also
+does not do any error checking.
+
+By default, Org uses 3 runs of `pdflatex' to do the processing.
+If you have texi2dvi on your system and if that does not cause
+the infamous egrep/locale bug:
+
+ http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html
+
+then `texi2dvi' is the superior choice. Org does offer it as one
+of the customize options.
+
+Alternatively, this may be a Lisp function that does the
+processing, so you could use this to apply the machinery of
+AUCTeX or the Emacs LaTeX mode. This function should accept the
+file name as its single argument."
+ :group 'org-export-pdf
+ :type '(choice
+ (repeat :tag "Shell command sequence"
+ (string :tag "Shell command"))
+ (const :tag "2 runs of pdflatex"
+ ("pdflatex -interaction nonstopmode -output-directory %o %f"
+ "pdflatex -interaction nonstopmode -output-directory %o %f"))
+ (const :tag "3 runs of pdflatex"
+ ("pdflatex -interaction nonstopmode -output-directory %o %f"
+ "pdflatex -interaction nonstopmode -output-directory %o %f"
+ "pdflatex -interaction nonstopmode -output-directory %o %f"))
+ (const :tag "pdflatex,bibtex,pdflatex,pdflatex"
+ ("pdflatex -interaction nonstopmode -output-directory %o %f"
+ "bibtex %b"
+ "pdflatex -interaction nonstopmode -output-directory %o %f"
+ "pdflatex -interaction nonstopmode -output-directory %o %f"))
+ (const :tag "texi2dvi"
+ ("texi2dvi -p -b -c -V %f"))
+ (const :tag "rubber"
+ ("rubber -d --into %o %f"))
+ (function)))
+
+(defcustom org-e-latex-logfiles-extensions
+ '("aux" "idx" "log" "out" "toc" "nav" "snm" "vrb")
+ "The list of file extensions to consider as LaTeX logfiles."
+ :group 'org-export-e-latex
+ :type '(repeat (string :tag "Extension")))
+
+(defcustom org-e-latex-remove-logfiles t
+ "Non-nil means remove the logfiles produced by PDF production.
+These are the .aux, .log, .out, and .toc files."
+ :group 'org-export-e-latex
+ :type 'boolean)
+
+
\f
;;; Internal Functions
(defun org-e-latex--caption/label-string (caption label info)
"Return caption and label LaTeX string for floats.
-CAPTION is a secondary string \(a list of strings and Org
-objects\) and LABEL a string representing the label. INFO is
-a plist holding contextual information.
+CAPTION is a cons cell of secondary strings, the car being the
+standard caption and the cdr its short form. LABEL is a string
+representing the label. INFO is a plist holding contextual
+information.
If there's no caption nor label, return the empty string.
For non-floats, see `org-e-latex--wrap-label'."
- (let ((caption-str (and caption
- (org-export-secondary-string
- caption 'e-latex info)))
- (label-str (if label (format "\\label{%s}" label) "")))
+ (let ((label-str (if label (format "\\label{%s}" label) "")))
(cond
- ((and (not caption-str) (not label)) "")
- ((not caption-str) (format "\\label{%s}\n" label))
+ ((and (not caption) (not label)) "")
+ ((not caption) (format "\\label{%s}\n" label))
;; Option caption format with short name.
- ((string-match "\\[\\([^][]*\\)\\]{\\([^{}]*\\)}" caption-str)
+ ((cdr caption)
(format "\\caption[%s]{%s%s}\n"
- (org-match-string-no-properties 1 caption-str)
+ (org-export-secondary-string (cdr caption) 'e-latex info)
label-str
- (org-match-string-no-properties 2 caption-str)))
+ (org-export-secondary-string (car caption) 'e-latex info)))
;; Standard caption format.
- (t (format "\\caption{%s%s}\n" label-str caption-str)))))
+ (t (format "\\caption{%s%s}\n"
+ label-str
+ (org-export-secondary-string (car caption) 'e-latex info))))))
(defun org-e-latex--guess-inputenc (header)
"Set the coding system in inputenc to what the buffer is.
@@ -612,8 +748,7 @@ (defun org-e-latex--guess-inputenc (header)
(latexenc-coding-system-to-inputenc
buffer-file-coding-system))
"utf8")))
- (if (not cs)
- header
+ (if (not cs) header
;; First translate if that is requested.
(setq cs (or (cdr (assoc cs org-e-latex-inputenc-alist)) cs))
;; Then find the \usepackage statement and replace the option.
@@ -641,7 +776,9 @@ (defun org-e-latex--make-option-string (options)
","))
(defun org-e-latex--quotation-marks (text info)
- "Export quotation marks depending on language conventions."
+ "Export quotation marks depending on language conventions.
+TEXT is a string containing quotation marks to be replaced. INFO
+is a plist used as a communication channel."
(mapc (lambda(l)
(let ((start 0))
(while (setq start (string-match (car l) text start))
@@ -654,9 +791,9 @@ (defun org-e-latex--quotation-marks (text info)
(defun org-e-latex--wrap-label (element output)
"Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-This function shouldn't be used for floats. See
+This function shouldn't be used for floats. See
`org-e-latex--caption/label-string'."
- (let ((label (org-element-get-property :name element)))
+ (let ((label (org-element-property :name element)))
(if (or (not output) (not label) (string= output "") (string= label ""))
output
(concat (format "\\label{%s}\n" label) output))))
@@ -667,7 +804,7 @@ (defun org-e-latex--wrap-label (element output)
(defun org-e-latex-template (contents info)
"Return complete document string after LaTeX conversion.
-CONTENTS is the transcoded contents string. INFO is a plist
+CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
(let ((title (org-export-secondary-string
(plist-get info :title) 'e-latex info)))
@@ -695,7 +832,11 @@ (defun org-e-latex-template (contents info)
(plist-get info :latex-header-extra))))))
;; 3. Define alert if not yet defined.
"\\providecommand{\\alert}[1]{\\textbf{#1}}\n"
- ;; 4. Author.
+ ;; 4. Possibly limit depth for headline numbering.
+ (let ((sec-num (plist-get info :section-numbers)))
+ (when (integerp sec-num)
+ (format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
+ ;; 5. Author.
(let ((author (and (plist-get info :with-author)
(let ((auth (plist-get info :author)))
(and auth (org-export-secondary-string
@@ -707,23 +848,20 @@ (defun org-e-latex-template (contents info)
(format "\\author{%s\\thanks{%s}}\n" author email))
(author (format "\\author{%s}\n" author))
(t "\\author{}\n")))
- ;; 5. Date.
+ ;; 6. Date.
(let ((date (plist-get info :date)))
(and date (format "\\date{%s}\n" date)))
- ;; 6. Title
+ ;; 7. Title
(format "\\title{%s}\n" title)
- ;; 7. Hyperref options.
+ ;; 8. Hyperref options.
(format "\\hypersetup{\n pdfkeywords={%s},\n pdfsubject={%s},\n pdfcreator={%s}}\n"
(or (plist-get info :keywords) "")
(or (plist-get info :description) "")
- (let ((creator-info (plist-get info :with-creator)))
- (cond
- ((not creator-info) "")
- ((eq creator-info 'comment) "")
- (t (plist-get info :creator)))))
- ;; 7. Document start.
+ (if (not (plist-get info :with-creator)) ""
+ (plist-get info :creator)))
+ ;; 9. Document start.
"\\begin{document}\n\n"
- ;; 8. Title command.
+ ;; 10. Title command.
(org-element-normalize-string
(cond ((string= "" title) nil)
((not (stringp org-e-latex-title-command)) nil)
@@ -731,22 +869,22 @@ (defun org-e-latex-template (contents info)
org-e-latex-title-command)
(format org-e-latex-title-command title))
(t org-e-latex-title-command)))
- ;; 9. Table of contents.
+ ;; 11. Table of contents.
(let ((depth (plist-get info :with-toc)))
(when depth
(concat (when (wholenump depth)
(format "\\setcounter{tocdepth}{%d}\n" depth))
"\\tableofcontents\n\\vspace*{1cm}\n\n")))
- ;; 10. Document's body.
+ ;; 12. Document's body.
contents
- ;; 11. Creator.
+ ;; 13. Creator.
(let ((creator-info (plist-get info :with-creator)))
(cond
- ((not creator-info))
+ ((not creator-info) "")
((eq creator-info 'comment)
(format "%% %s\n" (plist-get info :creator)))
(t (concat (plist-get info :creator) "\n"))))
- ;; 12. Document end.
+ ;; 14. Document end.
"\\end{document}")))
@@ -780,7 +918,7 @@ (defun org-e-latex-drawer (drawer contents info)
"Transcode a DRAWER element from Org to LaTeX.
CONTENTS holds the contents of the block. INFO is a plist
holding contextual information."
- (let* ((name (org-element-get-property :drawer-name drawer))
+ (let* ((name (org-element-property :drawer-name drawer))
(output (if (functionp org-e-latex-format-drawer-function)
(funcall org-e-latex-format-drawer-function
name contents)
@@ -806,7 +944,7 @@ (defun org-e-latex-emphasis (emphasis contents info)
"Transcode EMPHASIS from Org to LaTeX.
CONTENTS is the contents of the emphasized text. INFO is a plist
holding contextual information.."
- (format (cdr (assoc (org-element-get-property :marker emphasis)
+ (format (cdr (assoc (org-element-property :marker emphasis)
org-e-latex-emphasis-alist))
contents))
@@ -817,21 +955,20 @@ (defun org-e-latex-entity (entity contents info)
"Transcode an ENTITY object from Org to LaTeX.
CONTENTS are the definition itself. INFO is a plist holding
contextual information."
- (let ((ent (org-element-get-property :latex entity)))
- (if (org-element-get-property :latex-math-p entity)
- (format "$%s$" ent)
- ent)))
+ (let ((ent (org-element-property :latex entity)))
+ (if (org-element-property :latex-math-p entity) (format "$%s$" ent) ent)))
;;;; Example Block
(defun org-e-latex-example-block (example-block contents info)
- "Transcode a EXAMPLE-BLOCK element from Org to LaTeX.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((options (or (org-element-get-property :options example-block) ""))
- (value (org-export-handle-code
- (org-element-get-property :value example-block) options info)))
- (org-e-latex--wrap-label example-block value)))
+ "Transcode an EXAMPLE-BLOCK element from Org to LaTeX.
+CONTENTS is nil. INFO is a plist holding contextual
+information."
+ (org-e-latex--wrap-label
+ example-block
+ (format "\\begin{verbatim}\n%s\\end{verbatim}"
+ (org-export-format-code-default example-block info))))
;;;; Export Snippet
@@ -839,7 +976,8 @@ (defun org-e-latex-example-block (example-block contents info)
(defun org-e-latex-export-snippet (export-snippet contents info)
"Transcode a EXPORT-SNIPPET object from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-get-property :value export-snippet))
+ (when (eq (org-export-snippet-backend export-snippet) 'e-latex)
+ (org-element-property :value export-snippet)))
;;;; Export Block
@@ -847,8 +985,8 @@ (defun org-e-latex-export-snippet (export-snippet contents info)
(defun org-e-latex-export-block (export-block contents info)
"Transcode a EXPORT-BLOCK element from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
- (when (string= (org-element-get-property :type export-block) "latex")
- (org-remove-indentation (org-element-get-property :value export-block))))
+ (when (string= (org-element-property :type export-block) "latex")
+ (org-remove-indentation (org-element-property :value export-block))))
;;;; Fixed Width
@@ -859,10 +997,9 @@ (defun org-e-latex-fixed-width (fixed-width contents info)
(let* ((value (org-element-normalize-string
(replace-regexp-in-string
"^[ \t]*: ?" ""
- (org-element-get-property :value fixed-width)))))
+ (org-element-property :value fixed-width)))))
(org-e-latex--wrap-label
- fixed-width
- (format "\\begin{verbatim}\n%s\\end{verbatim}" value))))
+ fixed-width (format "\\begin{verbatim}\n%s\\end{verbatim}" value))))
;;;; Footnote Definition
@@ -874,31 +1011,61 @@ (defun org-e-latex-fixed-width (fixed-width contents info)
(defun org-e-latex-footnote-reference (footnote-reference contents info)
"Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX.
-CONTENTS is nil. INFO is a plist holding contextual information."
+CONTENTS is nil. INFO is a plist holding contextual information."
(concat
;; Insert separator between two footnotes in a row.
- (when (eq (plist-get info :previous-object) 'footnote-reference)
- org-e-latex-footnote-separator)
- ;; Use \footnotemark if the footnote has already been defined.
- ;; Otherwise, define it with \footnote command.
+ (let ((prev (org-export-get-previous-element footnote-reference info)))
+ (when (eq (org-element-type prev) 'footnote-reference)
+ org-e-latex-footnote-separator))
(cond
+ ;; Use \footnotemark if the footnote has already been defined.
((not (org-export-footnote-first-reference-p footnote-reference info))
- (format "\\footnotemark[%s]"
+ (format "\\footnotemark[%s]{}"
(org-export-get-footnote-number footnote-reference info)))
- ;; Inline definitions are secondary strings.
- ((eq (org-element-get-property :type footnote-reference) 'inline)
- (format "\\footnote{%s}"
- (org-trim
- (org-export-secondary-string
- (org-export-get-footnote-definition footnote-reference info)
- 'e-latex info))))
- ;; Non-inline footnotes definitions are full Org data.
+ ;; Use also \footnotemark if reference is within another footnote
+ ;; reference or footnote definition.
+ ((loop for parent in (org-export-get-genealogy footnote-reference info)
+ thereis (memq (org-element-type parent)
+ '(footnote-reference footnote-definition)))
+ (let ((num (org-export-get-footnote-number footnote-reference info)))
+ (format "\\footnotemark[%s]{}\\setcounter{footnote}{%s}" num num)))
+ ;; Otherwise, define it with \footnote command.
(t
- (format "\\footnote{%s}"
- (org-trim
- (org-export-data
- (org-export-get-footnote-definition footnote-reference info)
- 'e-latex info)))))))
+ (let ((def (org-export-get-footnote-definition footnote-reference info)))
+ (unless (eq (org-element-type def) 'org-data)
+ (setq def (cons 'org-data (cons nil def))))
+ (concat
+ (format "\\footnote{%s}" (org-trim (org-export-data def 'e-latex info)))
+ ;; Retrieve all footnote references within the footnote and
+ ;; add their definition after it, since LaTeX doesn't support
+ ;; them inside.
+ (let (all-refs
+ (search-refs
+ (function
+ (lambda (data)
+ ;; Return a list of all footnote references in DATA.
+ (org-element-map
+ data 'footnote-reference
+ (lambda (ref)
+ (when (org-export-footnote-first-reference-p ref info)
+ (push ref all-refs)
+ (when (eq (org-element-property :type ref) 'standard)
+ (funcall
+ search-refs
+ (org-export-get-footnote-definition ref info)))))
+ info) (reverse all-refs)))))
+ (mapconcat
+ (lambda (ref)
+ (format
+ "\\footnotetext[%s]{%s}"
+ (org-export-get-footnote-number ref info)
+ (org-trim
+ (funcall
+ (if (eq (org-element-property :type ref) 'inline)
+ 'org-export-secondary-string
+ 'org-export-data)
+ (org-export-get-footnote-definition ref info) 'e-latex info))))
+ (funcall search-refs def) ""))))))))
;;;; Headline
@@ -908,10 +1075,8 @@ (defun org-e-latex-headline (headline contents info)
CONTENTS holds the contents of the headline. INFO is a plist
holding contextual information."
(let* ((class (plist-get info :latex-class))
- (numberedp (plist-get info :section-numbers))
- ;; Get level relative to current parsed data.
- (level (+ (org-element-get-property :level headline)
- (plist-get info :headline-offset)))
+ (level (org-export-get-relative-level headline info))
+ (numberedp (org-export-numbered-headline-p headline info))
(class-sectionning (assoc class org-e-latex-classes))
;; Section formatting will set two placeholders: one for the
;; title and the other for the contents.
@@ -933,21 +1098,19 @@ (defun org-e-latex-headline (headline contents info)
(when numberedp (concat (car sec) "\n%s" (nth 1 sec))))
;; (num-in num-out no-num-in no-num-out)
((= (length sec) 4)
- (if numberedp
- (concat (car sec) "\n%s" (nth 1 sec))
+ (if numberedp (concat (car sec) "\n%s" (nth 1 sec))
(concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
(text (org-export-secondary-string
- (org-element-get-property :title headline) 'e-latex info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-get-property
- :todo-keyword headline)))
- (and todo
- (org-export-secondary-string todo 'e-latex info)))))
- (todo-type (and todo (org-element-get-property :todo-type headline)))
+ (org-element-property :title headline) 'e-latex info))
+ (todo
+ (and (plist-get info :with-todo-keywords)
+ (let ((todo (org-element-property :todo-keyword headline)))
+ (and todo (org-export-secondary-string todo 'e-latex info)))))
+ (todo-type (and todo (org-element-property :todo-type headline)))
(tags (and (plist-get info :with-tags)
- (org-element-get-property :tags headline)))
+ (org-element-property :tags headline)))
(priority (and (plist-get info :with-priority)
- (org-element-get-property :priority headline)))
+ (org-element-property :priority headline)))
;; Create the headline text.
(full-text (if (functionp org-e-latex-format-headline-function)
;; User-defined formatting function.
@@ -961,25 +1124,20 @@ (defun org-e-latex-headline (headline contents info)
text
(when tags (format "\\hfill{}\\textsc{%s}" tags)))))
;; Associate some \label to the headline for internal links.
- (headline-labels (mapconcat
- (lambda (p)
- (let ((val (org-element-get-property p headline)))
- (when val (format "\\label{%s}\n"
- (if (eq p :begin)
- (format "headline-%s" val)
- val)))))
- '(:custom-id :id :begin) ""))
- (pre-blanks (make-string (org-element-get-property :pre-blank headline)
- 10)))
+ (headline-label
+ (format "\\label{sec-%s}\n"
+ (mapconcat 'number-to-string
+ (org-export-get-headline-number headline info)
+ "-")))
+ (pre-blanks
+ (make-string (org-element-property :pre-blank headline) 10)))
(cond
;; Case 1: This is a footnote section: ignore it.
- ((org-element-get-property :footnote-section-p headline) nil)
+ ((org-element-property :footnote-section-p headline) nil)
;; Case 2. This is a deep sub-tree: export it as a list item.
;; Also export as items headlines for which no section
;; format has been found.
- ((or (not section-fmt)
- (and (wholenump (plist-get info :headline-levels))
- (> level (plist-get info :headline-levels))))
+ ((or (not section-fmt) (org-export-low-level-p headline info))
;; Build the real contents of the sub-tree.
(let ((low-level-body
(concat
@@ -987,18 +1145,18 @@ (defun org-e-latex-headline (headline contents info)
(when (org-export-first-sibling-p headline info)
(format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize)))
;; Itemize headline
- "\\item " full-text "\n" headline-labels pre-blanks contents)))
- ;; If headline in the last sibling, close the list, before any
- ;; blank line. Otherwise, simply return LOW-LEVEL-BODY.
- (if (org-export-last-sibling-p headline info)
- (replace-regexp-in-string
- "[ \t\n]*\\'"
- (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
- low-level-body)
- low-level-body)))
+ "\\item " full-text "\n" headline-label pre-blanks contents)))
+ ;; If headline is not the last sibling simply return
+ ;; LOW-LEVEL-BODY. Otherwise, also close the list, before any
+ ;; blank line.
+ (if (not (org-export-last-sibling-p headline info)) low-level-body
+ (replace-regexp-in-string
+ "[ \t\n]*\\'"
+ (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
+ low-level-body))))
;; Case 3. Standard headline. Export it as a section.
(t (format section-fmt full-text
- (concat headline-labels pre-blanks contents))))))
+ (concat headline-label pre-blanks contents))))))
;;;; Horizontal Rule
@@ -1007,7 +1165,7 @@ (defun org-e-latex-horizontal-rule (horizontal-rule contents info)
"Transcode an HORIZONTAL-RULE object from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
(let ((attr (mapconcat #'identity
- (org-element-get-property :attr_latex horizontal-rule)
+ (org-element-property :attr_latex horizontal-rule)
" ")))
(org-e-latex--wrap-label horizontal-rule (concat "\\hrule " attr))))
@@ -1023,7 +1181,7 @@ (defun org-e-latex-inline-src-block (inline-src-block contents info)
"Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
- (let* ((code (org-element-get-property :value inline-src-block))
+ (let* ((code (org-element-property :value inline-src-block))
(separator (org-e-latex--find-verb-separator code)))
(cond
;; Do not use a special package: transcode it verbatim.
@@ -1031,7 +1189,7 @@ (defun org-e-latex-inline-src-block (inline-src-block contents info)
(concat "\\verb" separator code separator))
;; Use minted package.
((eq org-e-latex-listings 'minted)
- (let* ((org-lang (org-element-get-property :language inline-src-block))
+ (let* ((org-lang (org-element-property :language inline-src-block))
(mint-lang (or (cadr (assq (intern org-lang)
org-e-latex-minted-langs))
org-lang))
@@ -1044,7 +1202,7 @@ (defun org-e-latex-inline-src-block (inline-src-block contents info)
;; Use listings package.
(t
;; Maybe translate language's name.
- (let* ((org-lang (org-element-get-property :language inline-src-block))
+ (let* ((org-lang (org-element-property :language inline-src-block))
(lst-lang (or (cadr (assq (intern org-lang)
org-e-latex-listings-langs))
org-lang))
@@ -1062,17 +1220,17 @@ (defun org-e-latex-inlinetask (inlinetask contents info)
CONTENTS holds the contents of the block. INFO is a plist
holding contextual information."
(let ((title (org-export-secondary-string
- (org-element-get-property :title inlinetask) 'e-latex info))
+ (org-element-property :title inlinetask) 'e-latex info))
(todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-get-property
+ (let ((todo (org-element-property
:todo-keyword inlinetask)))
(and todo
(org-export-secondary-string todo 'e-latex info)))))
- (todo-type (org-element-get-property :todo-type inlinetask))
+ (todo-type (org-element-property :todo-type inlinetask))
(tags (and (plist-get info :with-tags)
- (org-element-get-property :tags inlinetask)))
+ (org-element-property :tags inlinetask)))
(priority (and (plist-get info :with-priority)
- (org-element-get-property :priority inlinetask))))
+ (org-element-property :priority inlinetask))))
;; If `org-e-latex-format-inlinetask-function' is provided, call it
;; with appropriate arguments.
(if (functionp org-e-latex-format-inlinetask-function)
@@ -1105,18 +1263,20 @@ (defun org-e-latex-item (item contents info)
"Transcode an ITEM element from Org to LaTeX.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
- (let* ((level (plist-get (plist-get info :parent-properties) :level))
- (counter (let ((count (org-element-get-property :counter item)))
+ ;; Grab `:level' from plain-list properties, which is always the
+ ;; first element above current item.
+ (let* ((level (org-element-property :level (org-export-get-parent item info)))
+ (counter (let ((count (org-element-property :counter item)))
(and count
(< level 4)
(format "\\setcounter{enum%s}{%s}\n"
(nth level '("i" "ii" "iii" "iv"))
(1- count)))))
- (checkbox (let ((checkbox (org-element-get-property :checkbox item)))
+ (checkbox (let ((checkbox (org-element-property :checkbox item)))
(cond ((eq checkbox 'on) "$\\boxtimes$ ")
((eq checkbox 'off) "$\\Box$ ")
((eq checkbox 'trans) "$\\boxminus$ "))))
- (tag (let ((tag (org-element-get-property :tag item)))
+ (tag (let ((tag (org-element-property :tag item)))
(and tag
(format "[%s]" (org-export-secondary-string
tag 'e-latex info))))))
@@ -1128,13 +1288,13 @@ (defun org-e-latex-item (item contents info)
(defun org-e-latex-keyword (keyword contents info)
"Transcode a KEYWORD element from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((key (downcase (org-element-get-property :key keyword)))
- (value (org-element-get-property :value keyword)))
+ (let ((key (downcase (org-element-property :key keyword)))
+ (value (org-element-property :value keyword)))
(cond
((string= key "latex") value)
((string= key "index") (format "\\index{%s}" value))
- ((string= key "target")
- (format "\\label{%s}" (org-export-solidify-link-text value)))
+ ;; Invisible targets.
+ ((string= key "target") nil)
((string= key "toc")
(let ((value (downcase value)))
(cond
@@ -1148,9 +1308,13 @@ (defun org-e-latex-keyword (keyword contents info)
"\\tableofcontents")))
((string= "tables" value) "\\listoftables")
((string= "figures" value) "\\listoffigures")
- ((string= "listings" value) "\\listoflistings"))))
- ((string= key "include")
- (org-export-included-file keyword 'e-latex info)))))
+ ((string= "listings" value)
+ (cond
+ ((eq org-e-latex-listings 'minted) "\\listoflistings")
+ (org-e-latex-listings "\\lstlistoflistings")
+ ;; At the moment, src blocks with a caption are wrapped
+ ;; into a figure environment.
+ (t "\\listoffigures")))))))))
;;;; Latex Environment
@@ -1158,9 +1322,19 @@ (defun org-e-latex-keyword (keyword contents info)
(defun org-e-latex-latex-environment (latex-environment contents info)
"Transcode a LATEX-ENVIRONMENT element from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-latex--wrap-label
- latex-environment
- (org-remove-indentation (org-element-get-property :value latex-environment))))
+ (let ((label (org-element-property :name latex-environment))
+ (value (org-remove-indentation
+ (org-element-property :value latex-environment))))
+ (if (not (org-string-nw-p label)) value
+ ;; Environment is labelled: label must be within the environment
+ ;; (otherwise, a reference pointing to that element will count
+ ;; the section instead).
+ (with-temp-buffer
+ (insert value)
+ (goto-char (point-min))
+ (forward-line)
+ (insert (format "\\label{%s}\n" label))
+ (buffer-string)))))
;;;; Latex Fragment
@@ -1168,7 +1342,7 @@ (defun org-e-latex-latex-environment (latex-environment contents info)
(defun org-e-latex-latex-fragment (latex-fragment contents info)
"Transcode a LATEX-FRAGMENT object from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-get-property :value latex-fragment))
+ (org-element-property :value latex-fragment))
;;;; Line Break
@@ -1181,18 +1355,23 @@ (defun org-e-latex-line-break (line-break contents info)
;;;; Link
-(defun org-e-latex-link--inline-image (path info)
- "Return LaTeX code for an image at PATH.
-INFO is a plist containing export options."
- (let* ((parent-props (plist-get info :parent-properties))
+(defun org-e-latex-link--inline-image (link info)
+ "Return LaTeX code for an inline image.
+LINK is the link pointing to the inline image. INFO is a plist
+used as a communication channel."
+ (let* ((parent (org-export-get-parent-paragraph link info))
+ (path (let ((raw-path (org-element-property :path link)))
+ (if (not (file-name-absolute-p raw-path)) raw-path
+ (expand-file-name raw-path))))
(caption (org-e-latex--caption/label-string
- (plist-get parent-props :caption)
- (plist-get parent-props :name)
+ (org-element-property :caption parent)
+ (org-element-property :name parent)
info))
;; Retrieve latex attributes from the element around.
(attr (let ((raw-attr
(mapconcat #'identity
- (plist-get parent-props :attr_latex) " ")))
+ (org-element-property :attr_latex parent)
+ " ")))
(unless (string= raw-attr "") raw-attr)))
(disposition
(cond
@@ -1211,27 +1390,26 @@ (defun org-e-latex-link--inline-image (path info)
(t ""))))
;; Now clear ATTR from any special keyword and set a default
;; value if nothing is left.
- (if (not attr)
- (setq attr "")
- (while (string-match "\\(wrap\\|multicolumn\\|float\\|placement=\\S-+\\)"
- attr)
- (replace-match "" nil nil attr))
- (setq attr (org-trim attr)))
+ (setq attr
+ (if (not attr) ""
+ (org-trim
+ (replace-regexp-in-string
+ "\\(wrap\\|multicolumn\\|float\\|placement=\\S-+\\)" "" attr))))
(setq attr (cond ((not (string= attr "")) attr)
((eq disposition 'float) "width=0.7\\textwidth")
((eq disposition 'wrap) "width=0.48\\textwidth")
(t (or org-e-latex-image-default-option ""))))
;; Return proper string, depending on DISPOSITION.
(case disposition
- ('wrap (format "\\begin{wrapfigure}%s
+ (wrap (format "\\begin{wrapfigure}%s
\\centering
\\includegraphics[%s]{%s}
%s\\end{wrapfigure}" placement attr path caption))
- ('mulicolumn (format "\\begin{figure*}%s
+ (mulicolumn (format "\\begin{figure*}%s
\\centering
\\includegraphics[%s]{%s}
%s\\end{figure*}" placement attr path caption))
- ('float (format "\\begin{figure}%s
+ (float (format "\\begin{figure}%s
\\centering
\\includegraphics[%s]{%s}
%s\\end{figure}" placement attr path caption))
@@ -1241,18 +1419,18 @@ (defun org-e-latex-link (link desc info)
"Transcode a LINK object from Org to LaTeX.
DESC is the description part of the link, or the empty string.
-INFO is a plist holding contextual information. See
+INFO is a plist holding contextual information. See
`org-export-data'."
- (let* ((type (org-element-get-property :type link))
- (raw-path (org-element-get-property :path link))
+ (let* ((type (org-element-property :type link))
+ (raw-path (org-element-property :path link))
;; Ensure DESC really exists, or set it to nil.
(desc (and (not (string= desc "")) desc))
(imagep (org-export-inline-image-p
- link org-e-latex-inline-image-extensions))
+ link org-e-latex-inline-image-rules))
(path (cond
((member type '("http" "https" "ftp" "mailto"))
(concat type ":" raw-path))
- ((and (not imagep) (string= type "file"))
+ ((string= type "file")
(when (string-match "\\(.+\\)::.+" raw-path)
(setq raw-path (match-string 1 raw-path)))
(if (file-name-absolute-p raw-path)
@@ -1264,47 +1442,61 @@ (defun org-e-latex-link (link desc info)
protocol)
(cond
;; Image file.
- (imagep (org-e-latex-link--inline-image path info))
- ;; Id: for now, assume it's an internal link. TODO: do something
- ;; to check if it isn't in the current file.
- ((string= type "id")
- (format "\\hyperref[%s]{%s}" path (or desc path)))
- ;; Custom-id, target or radioed target: replace link with the
- ;; normalized custom-id/target name.
- ((member type '("custom-id" "target" "radio"))
+ (imagep (org-e-latex-link--inline-image link info))
+ ;; Radioed target: Target's name is obtained from original raw
+ ;; link. Path is parsed and transcoded in order to have a proper
+ ;; display of the contents.
+ ((string= type "radio")
(format "\\hyperref[%s]{%s}"
(org-export-solidify-link-text path)
- (or desc (org-export-secondary-string path 'e-latex info))))
- ;; Fuzzy: With the help of `org-export-resolve-fuzzy-link', find
- ;; the destination of the link.
- ((string= type "fuzzy")
- (let ((destination (org-export-resolve-fuzzy-link link info)))
- (cond
- ;; Target match.
- ((stringp destination)
- (format "\\hyperref[%s]{%s}"
- (org-export-solidify-link-text destination)
- (or desc
- (org-export-secondary-string
- (org-element-get-property :raw-link link) 'e-latex info))))
- ;; Headline match.
- ((integerp destination)
- (format "\\hyperref[headline-%d]{%s}"
- destination
- (or desc
- (org-export-secondary-string
- (org-element-get-property :raw-link link) 'e-latex info))))
- ;; No match.
- (t (format "\\texttt{%s}"
- (or desc
- (org-export-secondary-string
- (org-element-get-property :raw-link link)
- 'e-latex info)))))))
+ (org-export-secondary-string
+ (org-element-parse-secondary-string
+ path (cdr (assq 'radio-target org-element-object-restrictions)))
+ 'e-latex info)))
+ ;; Links pointing to an headline: Find destination and build
+ ;; appropriate referencing command.
+ ((member type '("custom-id" "fuzzy" "id"))
+ (let ((destination (if (string= type "fuzzy")
+ (org-export-resolve-fuzzy-link link info)
+ (org-export-resolve-id-link link info))))
+ (case (org-element-type destination)
+ ;; Fuzzy link points nowhere.
+ ('nil
+ (format "\\texttt{%s}"
+ (or desc
+ (org-export-secondary-string
+ (org-element-property :raw-link link)
+ 'e-latex info))))
+ ;; Fuzzy link points to an invisible target.
+ (keyword nil)
+ ;; LINK points to an headline. If headlines are numbered
+ ;; and the link has no description, display headline's
+ ;; number. Otherwise, display description or headline's
+ ;; title.
+ (headline
+ (let ((label
+ (format "sec-%s"
+ (mapconcat
+ 'number-to-string
+ (org-export-get-headline-number destination info)
+ "-"))))
+ (if (and (plist-get info :section-numbers) (not desc))
+ (format "\\ref{%s}" label)
+ (format "\\hyperref[%s]{%s}" label
+ (or desc
+ (org-export-secondary-string
+ (org-element-property :title destination)
+ 'e-latex info))))))
+ ;; Fuzzy link points to a target. Do as above.
+ (otherwise
+ (let ((path (org-export-solidify-link-text path)))
+ (if (not desc) (format "\\ref{%s}" path)
+ (format "\\hyperref[%s]{%s}" path desc)))))))
;; Coderef: replace link with the reference name or the
;; equivalent line number.
((string= type "coderef")
(format (org-export-get-coderef-format path (or desc ""))
- (cdr (assoc path (plist-get info :code-refs)))))
+ (org-export-resolve-coderef path info)))
;; Link type is handled by a special function.
((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
(funcall protocol (org-link-unescape path) desc 'latex))
@@ -1345,7 +1537,7 @@ (defun org-e-latex-plain-list (plain-list contents info)
"Transcode a PLAIN-LIST element from Org to LaTeX.
CONTENTS is the contents of the list. INFO is a plist holding
contextual information."
- (let* ((type (org-element-get-property :type plain-list))
+ (let* ((type (org-element-property :type plain-list))
(paralist-types '("inparaenum" "asparaenum" "inparaitem" "asparaitem"
"inparadesc" "asparadesc"))
(paralist-regexp (concat
@@ -1353,7 +1545,7 @@ (defun org-e-latex-plain-list (plain-list contents info)
(mapconcat 'identity paralist-types "\\|")
"\\)"))
(attr (mapconcat #'identity
- (org-element-get-property :attr_latex plain-list)
+ (org-element-property :attr_latex plain-list)
" "))
(latex-type (cond
((and attr
@@ -1442,10 +1634,19 @@ (defun org-e-latex-quote-section (quote-section contents info)
"Transcode a QUOTE-SECTION element from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
(let ((value (org-remove-indentation
- (org-element-get-property :value quote-section))))
+ (org-element-property :value quote-section))))
(when value (format "\\begin{verbatim}\n%s\\end{verbatim}" value))))
+;;;; Section
+
+(defun org-e-latex-section (section contents info)
+ "Transcode a SECTION element from Org to LaTeX.
+CONTENTS holds the contents of the section. INFO is a plist
+holding contextual information."
+ contents)
+
+
;;;; Radio Target
(defun org-e-latex-radio-target (radio-target text info)
@@ -1454,7 +1655,7 @@ (defun org-e-latex-radio-target (radio-target text info)
contextual information."
(format "\\label{%s}%s"
(org-export-solidify-link-text
- (org-element-get-property :raw-value radio-target))
+ (org-element-property :raw-value radio-target))
text))
@@ -1464,7 +1665,7 @@ (defun org-e-latex-special-block (special-block contents info)
"Transcode a SPECIAL-BLOCK element from Org to LaTeX.
CONTENTS holds the contents of the block. INFO is a plist
holding contextual information."
- (let ((type (downcase (org-element-get-property :type special-block))))
+ (let ((type (downcase (org-element-property :type special-block))))
(org-e-latex--wrap-label
special-block
(format "\\begin{%s}\n%s\\end{%s}" type contents type))))
@@ -1476,58 +1677,114 @@ (defun org-e-latex-src-block (src-block contents info)
"Transcode a SRC-BLOCK element from Org to LaTeX.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
- (let* ((lang (org-element-get-property :language src-block))
- (code (org-export-handle-code
- (org-element-get-property :value src-block)
- (org-element-get-property :switches src-block)
- info lang))
- (caption (org-element-get-property :caption src-block))
- (label (org-element-get-property :name src-block))
+ (let* ((lang (org-element-property :language src-block))
+ (caption (org-element-property :caption src-block))
+ (label (org-element-property :name src-block))
(custom-env (and lang
(cadr (assq (intern lang)
- org-e-latex-custom-lang-environments)))))
+ org-e-latex-custom-lang-environments))))
+ (num-start (case (org-element-property :number-lines src-block)
+ (continued (org-export-get-loc src-block info))
+ (new 0)))
+ (retain-labels (org-element-property :retain-labels src-block)))
(cond
- ;; No source fontification.
+ ;; Case 1. No source fontification.
((not org-e-latex-listings)
- (let ((caption-str (org-e-latex--caption/label-string
- caption label info))
+ (let ((caption-str (org-e-latex--caption/label-string caption label info))
(float-env (when caption "\\begin{figure}[H]\n%s\n\\end{figure}")))
- (format (or float-env "%s")
- (concat
- caption-str
- (format "\\begin{verbatim}\n%s\\end{verbatim}" code)))))
- ;; Custom environment.
- (custom-env
- (format "\\begin{%s}\n%s\\end{%s}\n" custom-env code custom-env))
- ;; Use minted package.
+ (format
+ (or float-env "%s")
+ (concat caption-str
+ (format "\\begin{verbatim}\n%s\\end{verbatim}"
+ (org-export-format-code-default src-block info))))))
+ ;; Case 2. Custom environment.
+ (custom-env (format "\\begin{%s}\n%s\\end{%s}\n"
+ custom-env
+ (org-export-format-code-default src-block info)
+ custom-env))
+ ;; Case 3. Use minted package.
((eq org-e-latex-listings 'minted)
- (let* ((mint-lang (or (cadr (assq (intern lang) org-e-latex-minted-langs))
- lang))
- (float-env (when (or label caption)
- (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}"
- (org-e-latex--caption/label-string
- caption label info))))
- (body (format "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
- (org-e-latex--make-option-string
- org-e-latex-minted-options)
- mint-lang code)))
+ (let ((float-env (when (or label caption)
+ (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}"
+ (org-e-latex--caption/label-string
+ caption label info))))
+ (body
+ (format
+ "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
+ ;; Options.
+ (org-e-latex--make-option-string
+ (if (not num-start) org-e-latex-minted-options
+ (append `(("linenos")
+ ("firstnumber" ,(number-to-string (1+ num-start))))
+ org-e-latex-minted-options)))
+ ;; Language.
+ (or (cadr (assq (intern lang) org-e-latex-minted-langs)) lang)
+ ;; Source code.
+ (let* ((code-info (org-export-unravel-code src-block))
+ (max-width
+ (apply 'max
+ (mapcar 'length
+ (org-split-string (car code-info) "\n")))))
+ (org-export-format-code
+ (car code-info)
+ (lambda (loc num ref)
+ (concat
+ loc
+ (when ref
+ ;; Ensure references are flushed to the right,
+ ;; separated with 6 spaces from the widest line
+ ;; of code.
+ (concat (make-string (+ (- max-width (length loc)) 6) ? )
+ (format "(%s)" ref)))))
+ nil (and retain-labels (cdr code-info)))))))
+ ;; Return value.
(if float-env (format float-env body) body)))
- ;; Use listings package.
+ ;; Case 4. Use listings package.
(t
- (let ((lst-lang (or (cadr (assq (intern lang) org-e-latex-listings-langs))
- lang))
- (caption-str (and caption
- (org-export-secondary-string
- (org-element-get-property :caption src-block)
- 'e-latex info))))
- (concat (format "\\lstset{%s}\n"
- (org-e-latex--make-option-string
- (append org-e-latex-listings-options
- `(("language" ,lst-lang))
- (when label `(("label" ,label)))
- (when caption-str
- `(("caption" ,caption-str))))))
- (format "\\begin{lstlisting}\n%s\\end{lstlisting}" code)))))))
+ (let ((lst-lang
+ (or (cadr (assq (intern lang) org-e-latex-listings-langs)) lang))
+ (caption-str
+ (when caption
+ (let ((main (org-export-secondary-string
+ (car caption) 'e-latex info)))
+ (if (not (cdr caption)) (format "{%s}" main)
+ (format
+ "{[%s]%s}"
+ (org-export-secondary-string (cdr caption) 'e-latex info)
+ main))))))
+ (concat
+ ;; Options.
+ (format "\\lstset{%s}\n"
+ (org-e-latex--make-option-string
+ (append org-e-latex-listings-options
+ `(("language" ,lst-lang))
+ (when label `(("label" ,label)))
+ (when caption-str `(("caption" ,caption-str)))
+ (cond ((not num-start) '(("numbers" "none")))
+ ((zerop num-start) '(("numbers" "left")))
+ (t `(("numbers" "left")
+ ("firstnumber"
+ ,(number-to-string (1+ num-start)))))))))
+ ;; Source code.
+ (format
+ "\\begin{lstlisting}\n%s\\end{lstlisting}"
+ (let* ((code-info (org-export-unravel-code src-block))
+ (max-width
+ (apply 'max
+ (mapcar 'length
+ (org-split-string (car code-info) "\n")))))
+ (org-export-format-code
+ (car code-info)
+ (lambda (loc num ref)
+ (concat
+ loc
+ (when ref
+ ;; Ensure references are flushed to the right,
+ ;; separated with 6 spaces from the widest line of
+ ;; code
+ (concat (make-string (+ (- max-width (length loc)) 6) ? )
+ (format "(%s)" ref)))))
+ nil (and retain-labels (cdr code-info)))))))))))
;;;; Statistics Cookie
@@ -1535,7 +1792,7 @@ (defun org-e-latex-src-block (src-block contents info)
(defun org-e-latex-statistics-cookie (statistics-cookie contents info)
"Transcode a STATISTICS-COOKIE object from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-get-property :value statistics-cookie))
+ (org-element-property :value statistics-cookie))
;;;; Subscript
@@ -1558,27 +1815,29 @@ (defun org-e-latex-superscript (superscript contents info)
;;;; Table
-(defun org-e-latex-table--format-string (table info)
+(defun org-e-latex-table--format-string (table table-info info)
"Return an appropriate format string for TABLE.
-INFO is the plist containing format info about the table, as
-returned by `org-export-table-format-info'.
+TABLE-INFO is the plist containing format info about the table,
+as returned by `org-export-table-format-info'. INFO is a plist
+used as a communication channel.
-The format string one placeholder for the body of the table."
- (let* ((label (org-element-get-property :name table))
+The format string leaves one placeholder for the body of the
+table."
+ (let* ((label (org-element-property :name table))
(caption (org-e-latex--caption/label-string
- (org-element-get-property :caption table) label info))
- (attr (mapconcat #'identity
- (org-element-get-property :attr_latex table)
+ (org-element-property :caption table) label info))
+ (attr (mapconcat 'identity
+ (org-element-property :attr_latex table)
" "))
;; Determine alignment string.
- (alignment (org-e-latex-table--align-string attr info))
+ (alignment (org-e-latex-table--align-string attr table-info))
;; Determine environment for the table: longtable, tabular...
(table-env (cond
((not attr) org-e-latex-default-table-environment)
((string-match "\\<longtable\\>" attr) "longtable")
- ((string-match "\\(tabular.\\)" attr)
- (org-match-string-no-properties 1 attr))
+ ((string-match "\\<tabular.?\\>" attr)
+ (org-match-string-no-properties 0 attr))
(t org-e-latex-default-table-environment)))
;; If table is a float, determine environment: table or table*.
(float-env (cond
@@ -1589,29 +1848,23 @@ (defun org-e-latex-table--format-string (table info)
"table*")
((or (not (string= caption "")) label) "table")))
;; Extract others display options.
- (width (and attr
- (string-match "\\<width=\\(\\S-+\\)" attr)
+ (width (and attr (string-match "\\<width=\\(\\S-+\\)" attr)
(org-match-string-no-properties 1 attr)))
- (placement (if (and attr
- (string-match "\\<placement=\\(\\S-+\\)" attr))
- (org-match-string-no-properties 1 attr)
- (concat "["
- org-e-latex-default-figure-position
- "]"))))
+ (placement
+ (if (and attr (string-match "\\<placement=\\(\\S-+\\)" attr))
+ (org-match-string-no-properties 1 attr)
+ (format "[%s]" org-e-latex-default-figure-position))))
;; Prepare the final format string for the table.
(cond
;; Longtable.
((string= "longtable" table-env)
- (format "\\begin{longtable}{%s}\n%s\n%%s\n%s\\end{longtable}"
- alignment
- (if (or (not org-e-latex-table-caption-above)
- (string= "" caption))
- ""
- (concat (org-trim caption) "\\\\"))
- (if (or org-e-latex-table-caption-above
- (string= "" caption))
- ""
- (concat (org-trim caption) "\\\\\n"))))
+ (format
+ "\\begin{longtable}{%s}\n%s\n%%s\n%s\\end{longtable}"
+ alignment
+ (if (or (not org-e-latex-table-caption-above) (string= "" caption)) ""
+ (concat (org-trim caption) "\\\\"))
+ (if (or org-e-latex-table-caption-above (string= "" caption)) ""
+ (concat (org-trim caption) "\\\\\n"))))
;; Others.
(t (concat (when float-env
(concat
@@ -1620,28 +1873,26 @@ (defun org-e-latex-table--format-string (table info)
(when org-e-latex-tables-centered "\\begin{center}\n")
(format "\\begin{%s}%s{%s}\n%%s\n\\end{%s}"
table-env
- (if width (format "{%s}" width) "")
- alignment
- table-env)
+ (if width (format "{%s}" width) "") alignment table-env)
(when org-e-latex-tables-centered "\n\\end{center}")
(when float-env
(concat (if org-e-latex-table-caption-above "" caption)
(format "\n\\end{%s}" float-env))))))))
-(defun org-e-latex-table--align-string (attr info)
+(defun org-e-latex-table--align-string (attr table-info)
"Return an appropriate LaTeX alignment string.
-
-INFO is the plist containing format info about the table, as
-returned by `org-export-table-format-info'."
+ATTR is a string containing table's LaTeX specific attributes.
+TABLE-INFO is the plist containing format info about the table,
+as returned by `org-export-table-format-info'."
(or (and attr
(string-match "\\<align=\\(\\S-+\\)" attr)
(match-string 1 attr))
- (let* ((align (copy-sequence (plist-get info :alignment)))
- (colgroups (copy-sequence (plist-get info :column-groups)))
+ (let* ((align (copy-sequence (plist-get table-info :alignment)))
+ (colgroups (copy-sequence (plist-get table-info :column-groups)))
(cols (length align))
(separators (make-vector (1+ cols) "")))
;; Ignore the first column if it's special.
- (when (plist-get info :special-column-p)
+ (when (plist-get table-info :special-column-p)
(aset align 0 "") (aset colgroups 0 nil))
(let ((col 0))
(mapc (lambda (el)
@@ -1662,9 +1913,9 @@ (defun org-e-latex-table (table contents info)
"Transcode a TABLE element from Org to LaTeX.
CONTENTS is nil. INFO is a plist holding contextual information."
(let ((attr (mapconcat #'identity
- (org-element-get-property :attr_latex table)
+ (org-element-property :attr_latex table)
" "))
- (raw-table (org-element-get-property :raw-table table)))
+ (raw-table (org-element-property :raw-table table)))
(cond
;; Case 1: verbatim table.
((or org-e-latex-tables-verbatim
@@ -1675,11 +1926,11 @@ (defun org-e-latex-table (table contents info)
(plist-get (org-export-table-format-info raw-table)
:special-column-p))))
;; Case 2: table.el table. Convert it using appropriate tools.
- ((eq (org-element-get-property :type table) 'table.el)
+ ((eq (org-element-property :type table) 'table.el)
(require 'table)
;; Ensure "*org-export-table*" buffer is empty.
- (and (get-buffer "*org-export-table*")
- (kill-buffer (get-buffer "*org-export-table*")))
+ (with-current-buffer (get-buffer-create "*org-export-table*")
+ (erase-buffer))
(let ((output (with-temp-buffer
(insert raw-table)
(goto-char 1)
@@ -1698,70 +1949,92 @@ (defun org-e-latex-table (table contents info)
(while (and (< (length output) pos)
(setq pos (string-match "^\\\\hline\n?" output pos)))
(incf n)
- (unless (= n 2) (setq output (replace-match "" nil nil output))))))
- (if org-e-latex-tables-centered
- (format "\\begin{center}\n%s\n\\end{center}" output)
- output)))
+ (unless (= n 2)
+ (setq output (replace-match "" nil nil output))))))
+ (if (not org-e-latex-tables-centered) output
+ (format "\\begin{center}\n%s\n\\end{center}" output))))
;; Case 3: Standard table.
(t
(let* ((table-info (org-export-table-format-info raw-table))
- (clean-table (org-export-clean-table
- raw-table (plist-get table-info :special-column-p)))
- (columns-number (length (plist-get table-info :alignment))))
+ (columns-number (length (plist-get table-info :alignment)))
+ (longtablep (and attr (string-match "\\<longtable\\>" attr)))
+ (booktabsp
+ (or (and attr (string-match "\\<booktabs=\\(yes\\|t\\)\\>" attr))
+ org-e-latex-tables-booktabs))
+ ;; CLEAN-TABLE is a table turned into a list, much like
+ ;; `org-table-to-lisp', with special column and
+ ;; formatting cookies removed, and cells already
+ ;; transcoded.
+ (clean-table
+ (mapcar
+ (lambda (row)
+ (if (string-match org-table-hline-regexp row) 'hline
+ (mapcar
+ (lambda (cell)
+ (org-export-secondary-string
+ (org-element-parse-secondary-string
+ cell
+ (cdr (assq 'table org-element-string-restrictions)))
+ 'e-latex info))
+ (org-split-string row "[ \t]*|[ \t]*"))))
+ (org-split-string
+ (org-export-clean-table
+ raw-table (plist-get table-info :special-column-p))
+ "\n"))))
+ ;; If BOOKTABSP is non-nil, remove any rule at the beginning
+ ;; and the end of the table, since booktabs' special rules
+ ;; will be inserted instead.
+ (when booktabsp
+ (when (eq (car clean-table) 'hline)
+ (setq clean-table (cdr clean-table)))
+ (when (eq (car (last clean-table)) 'hline)
+ (setq clean-table (butlast clean-table))))
;; Convert ROWS to send them to `orgtbl-to-latex'. In
;; particular, send each cell to
;; `org-element-parse-secondary-string' to expand any Org
- ;; object within. Eventually, flesh the format string out with
- ;; the table.
- (format (org-e-latex-table--format-string table table-info)
- (orgtbl-to-latex
- (mapcar
- (lambda (row)
- (if (string-match org-table-hline-regexp row)
- 'hline
- (mapcar
- (lambda (cell)
- (org-export-secondary-string
- (org-element-parse-secondary-string
- cell
- (cdr (assq 'table org-element-string-restrictions)))
- 'e-latex info))
- (org-split-string row "[ \t]*|[ \t]*"))))
- (org-split-string clean-table "\n"))
- `(:tstart nil :tend nil
- ;; Longtable environment requires specific
- ;; header line end.
- :hlend ,(and attr
- (string-match "\\<longtable\\>" attr)
- (format "\\\\
-\\hline
+ ;; object within. Eventually, flesh the format string out
+ ;; with the table.
+ (format
+ (org-e-latex-table--format-string table table-info info)
+ (orgtbl-to-latex
+ clean-table
+ ;; Parameters passed to `orgtbl-to-latex'.
+ `(:tstart ,(and booktabsp "\\toprule")
+ :tend ,(and booktabsp "\\bottomrule")
+ :hline ,(if booktabsp "\\midrule" "\\hline")
+ ;; Longtable environment requires specific header
+ ;; lines end string.
+ :hlend ,(and longtablep
+ (format "\\\\
+%s
\\endhead
-\\hline\\multicolumn{%d}{r}{Continued on next page}\\\\
+%s\\multicolumn{%d}{r}{Continued on next page}\\\\
\\endfoot
\\endlastfoot"
- columns-number))))))))))
+ (if booktabsp "\\midrule" "\\hline")
+ (if booktabsp "\\midrule" "\\hline")
+ columns-number))))))))))
;;;; Target
-(defun org-e-latex-target (target text info)
+(defun org-e-latex-target (target contents info)
"Transcode a TARGET object from Org to LaTeX.
-TEXT is the text of the target. INFO is a plist holding
-contextual information."
- (format "\\label{%s}%s"
- (org-export-solidify-link-text
- (org-element-get-property :raw-value target))
- text))
+CONTENTS is nil. INFO is a plist holding contextual
+information."
+ (format "\\label{%s}"
+ (org-export-solidify-link-text (org-element-property :value target))))
;;;; Time-stamp
(defun org-e-latex-time-stamp (time-stamp contents info)
"Transcode a TIME-STAMP object from Org to LaTeX.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((value (org-element-get-property :value time-stamp))
- (type (org-element-get-property :type time-stamp))
- (appt-type (org-element-get-property :appt-type time-stamp)))
+CONTENTS is nil. INFO is a plist holding contextual
+information."
+ (let ((value (org-element-property :value time-stamp))
+ (type (org-element-property :type time-stamp))
+ (appt-type (org-element-property :appt-type time-stamp)))
(concat (cond ((eq appt-type 'scheduled)
(format "\\textbf{\\textsc{%s}} " org-scheduled-string))
((eq appt-type 'deadline)
@@ -1778,11 +2051,13 @@ (defun org-e-latex-time-stamp (time-stamp contents info)
;;;; Verbatim
-(defun org-e-latex-verbatim (element contents info)
- "Return verbatim text in LaTeX."
- (let ((fmt (cdr (assoc (org-element-get-property :marker element)
+(defun org-e-latex-verbatim (verbatim contents info)
+ "Transcode a VERBATIM object from Org to LaTeX.
+CONTENTS is nil. INFO is a plist used as a communication
+channel."
+ (let ((fmt (cdr (assoc (org-element-property :marker verbatim)
org-e-latex-emphasis-alist)))
- (value (org-element-get-property :value element)))
+ (value (org-element-property :value verbatim)))
(cond
;; Handle the `verb' special case.
((eq 'verb fmt)
@@ -1816,7 +2091,7 @@ (defun org-e-latex-verbatim (element contents info)
(defun org-e-latex-verse-block (verse-block contents info)
"Transcode a VERSE-BLOCK element from Org to LaTeX.
-CONTENTS is nil. INFO is a plist holding contextual information."
+CONTENTS is nil. INFO is a plist holding contextual information."
(org-e-latex--wrap-label
verse-block
;; In a verse environment, add a line break to each newline
@@ -1830,7 +2105,7 @@ (defun org-e-latex-verse-block (verse-block contents info)
"\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
(org-remove-indentation
(org-export-secondary-string
- (org-element-get-property :value verse-block)
+ (org-element-property :value verse-block)
'e-latex info)))))
(while (string-match "^[ \t]+" contents)
(let ((new-str (format "\\hspace*{%dem}"
@@ -1839,5 +2114,161 @@ (defun org-e-latex-verse-block (verse-block contents info)
(format "\\begin{verse}\n%s\\end{verse}" contents))))
+\f
+;;; Interactive functions
+
+(defun org-e-latex-export-to-latex
+ (&optional subtreep visible-only body-only ext-plist pub-dir)
+ "Export current buffer to a LaTeX file.
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{document}\" and \"\\end{document}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+When optional argument PUB-DIR is set, use it as the publishing
+directory.
+
+Return output file's name."
+ (interactive)
+ (let ((outfile (org-export-output-file-name ".tex" subtreep pub-dir)))
+ (org-export-to-file
+ 'e-latex outfile subtreep visible-only body-only ext-plist)))
+
+(defun org-e-latex-export-to-pdf
+ (&optional subtreep visible-only body-only ext-plist pub-dir)
+ "Export current buffer to LaTeX then process through to PDF.
+
+If narrowing is active in the current buffer, only export its
+narrowed part.
+
+If a region is active, export that region.
+
+When optional argument SUBTREEP is non-nil, export the sub-tree
+at point, extracting information from the headline properties
+first.
+
+When optional argument VISIBLE-ONLY is non-nil, don't export
+contents of hidden elements.
+
+When optional argument BODY-ONLY is non-nil, only write code
+between \"\\begin{document}\" and \"\\end{document}\".
+
+EXT-PLIST, when provided, is a property list with external
+parameters overriding Org default settings, but still inferior to
+file-local settings.
+
+When optional argument PUB-DIR is set, use it as the publishing
+directory.
+
+Return PDF file's name."
+ (interactive)
+ (org-e-latex-compile
+ (org-e-latex-export-to-latex
+ subtreep visible-only body-only ext-plist pub-dir)))
+
+(defun org-e-latex-compile (texfile)
+ "Compile a TeX file.
+
+TEXFILE is the name of the file being compiled. Processing is
+done through the command specified in `org-e-latex-pdf-process'.
+
+Return PDF file name or an error if it couldn't be produced."
+ (let* ((wconfig (current-window-configuration))
+ (texfile (file-truename texfile))
+ (base (file-name-sans-extension texfile))
+ errors)
+ (message (format "Processing LaTeX file %s ..." texfile))
+ (unwind-protect
+ (progn
+ (cond
+ ;; A function is provided: Apply it.
+ ((functionp org-e-latex-pdf-process)
+ (funcall org-e-latex-pdf-process (shell-quote-argument texfile)))
+ ;; A list is provided: Replace %b, %f and %o with appropriate
+ ;; values in each command before applying it. Output is
+ ;; redirected to "*Org PDF LaTeX Output*" buffer.
+ ((consp org-e-latex-pdf-process)
+ (let* ((out-dir (or (file-name-directory texfile) "./"))
+ (outbuf (get-buffer-create "*Org PDF LaTeX Output*")))
+ (mapc
+ (lambda (command)
+ (shell-command
+ (replace-regexp-in-string
+ "%b" (shell-quote-argument base)
+ (replace-regexp-in-string
+ "%f" (shell-quote-argument texfile)
+ (replace-regexp-in-string
+ "%o" (shell-quote-argument out-dir) command t t) t t) t t)
+ outbuf))
+ org-e-latex-pdf-process)
+ ;; Collect standard errors from output buffer.
+ (setq errors (org-e-latex-collect-errors outbuf))))
+ (t (error "No valid command to process to PDF")))
+ (let ((pdffile (concat base ".pdf")))
+ ;; Check for process failure. Provide collected errors if
+ ;; possible.
+ (if (not (file-exists-p pdffile))
+ (error (concat (format "PDF file %s wasn't produced" pdffile)
+ (when errors (concat ": " errors))))
+ ;; Else remove log files, when specified, and signal end of
+ ;; process to user, along with any error encountered.
+ (when org-e-latex-remove-logfiles
+ (dolist (ext org-e-latex-logfiles-extensions)
+ (let ((file (concat base "." ext)))
+ (when (file-exists-p file) (delete-file file)))))
+ (message (concat "Process completed"
+ (if (not errors) "."
+ (concat " with errors: " errors)))))
+ ;; Return output file name.
+ pdffile))
+ (set-window-configuration wconfig))))
+
+(defun org-e-latex-collect-errors (buffer)
+ "Collect some kind of errors from \"pdflatex\" command output.
+
+BUFFER is the buffer containing output.
+
+Return collected error types as a string, or nil if there was
+none."
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char (point-max))
+ ;; Find final "pdflatex" run.
+ (when (re-search-backward "^[ \t]*This is pdf.*?TeX.*?Version" nil t)
+ (let ((case-fold-search t)
+ (errors ""))
+ (when (save-excursion
+ (re-search-forward "Reference.*?undefined" nil t))
+ (setq errors (concat errors " [undefined reference]")))
+ (when (save-excursion
+ (re-search-forward "Citation.*?undefined" nil t))
+ (setq errors (concat errors " [undefined citation]")))
+ (when (save-excursion
+ (re-search-forward "Undefined control sequence" nil t))
+ (setq errors (concat errors " [undefined control sequence]")))
+ (when (save-excursion
+ (re-search-forward "^! LaTeX.*?Error" nil t))
+ (setq errors (concat errors " [LaTeX error]")))
+ (when (save-excursion
+ (re-search-forward "^! Package.*?Error" nil t))
+ (setq errors (concat errors " [package error]")))
+ (and (org-string-nw-p errors) (org-trim errors)))))))
+
+
(provide 'org-e-latex)
;;; org-e-latex.el ends here
diff --git a/Makefile b/Makefile
index 1753dd8..1022cdc 100644
--- a/Makefile
+++ b/Makefile
@@ -170,7 +170,9 @@ LISPF = org.el \
ob-shen.el \
ob-fortran.el \
ob-picolisp.el \
- ob-maxima.el
+ ob-maxima.el \
+ ob-io.el \
+ ob-scala.el
LISPFILES0 = $(LISPF:%=lisp/%)
LISPFILES = $(LISPFILES0) lisp/org-install.el
diff --git a/contrib/babel/langs/ob-fomus.el b/contrib/babel/langs/ob-fomus.el
index ba25715..f7c6ca8 100644
--- a/contrib/babel/langs/ob-fomus.el
+++ b/contrib/babel/langs/ob-fomus.el
@@ -1,6 +1,6 @@
;;; ob-fomus.el --- org-babel functions for fomus evaluation
-;; Copyright (C) 2011, 2012 Torsten Anders
+;; Copyright (C) 2011-2012 Torsten Anders
;; Author: Torsten Anders
;; Keywords: literate programming, reproducible research
diff --git a/contrib/babel/langs/ob-oz.el b/contrib/babel/langs/ob-oz.el
index e906c73..2482ed6 100644
--- a/contrib/babel/langs/ob-oz.el
+++ b/contrib/babel/langs/ob-oz.el
@@ -1,6 +1,6 @@
;;; ob-oz.el --- org-babel functions for Oz evaluation
-;; Copyright (C) 2009, 2012 Torsten Anders and Eric Schulte
+;; Copyright (C) 2009-2012 Torsten Anders and Eric Schulte
;; Author: Torsten Anders and Eric Schulte
;; Keywords: literate programming, reproducible research
diff --git a/contrib/lisp/htmlize.el b/contrib/lisp/htmlize.el
index 8952e99..516fb1d 100644
--- a/contrib/lisp/htmlize.el
+++ b/contrib/lisp/htmlize.el
@@ -633,7 +633,7 @@ (defun htmlize-defang-local-variables ()
(goto-char (point-min))
(while (search-forward "Local Variables:" nil t)
(replace-match "Local Variables:" nil t)))
-
+
\f
;;; Color handling.
@@ -796,7 +796,7 @@ (defun htmlize-color-to-rgb (color)
(t
;; We're getting the RGB components from Emacs.
(let ((rgb
- ;; Here I cannot conditionalize on (fboundp ...)
+ ;; Here I cannot conditionalize on (fboundp ...)
;; because ps-print under some versions of GNU Emacs
;; defines its own dummy version of
;; `color-instance-rgb-components'.
@@ -1211,7 +1211,7 @@ (defun htmlize-faces-in-buffer ()
;; used methods are `doctype', `insert-head', `body-tag', and
;; `insert-text'. Not all output types define all methods.
;;
-;; Methods are called either with (htmlize-method METHOD ARGS...)
+;; Methods are called either with (htmlize-method METHOD ARGS...)
;; special form, or by accessing the function with
;; (htmlize-method-function 'METHOD) and calling (funcall FUNCTION).
;; The latter form is useful in tight loops because `htmlize-method'
@@ -1389,7 +1389,7 @@ (defun htmlize-font-body-tag (face-map)
(format "<body text=\"%s\" bgcolor=\"%s\">"
(htmlize-fstruct-foreground fstruct)
(htmlize-fstruct-background fstruct))))
-
+
(defun htmlize-font-insert-text (text fstruct-list buffer)
;; In `font' mode, we use the traditional HTML means of altering
;; presentation: <font> tag for colors, <b> for bold, <u> for
diff --git a/contrib/lisp/org-bookmark.el b/contrib/lisp/org-bookmark.el
index e57b2e6..586597a 100644
--- a/contrib/lisp/org-bookmark.el
+++ b/contrib/lisp/org-bookmark.el
@@ -67,7 +67,7 @@ (defun org-bookmark-store-link ()
(if (not file)
(when (eq major-mode 'bookmark-bmenu-mode)
(setq bookmark (bookmark-bmenu-bookmark)))
- (when (and (setq bmks
+ (when (and (setq bmks
(mapcar (lambda (name)
(if (equal file
(abbreviate-file-name
@@ -75,7 +75,7 @@ (defun org-bookmark-store-link ()
name))
(bookmark-all-names)))
(setq bmks (delete nil bmks)))
- (setq bookmark
+ (setq bookmark
(if (or (eq 1 (length bmks)) org-bookmark-use-first-bookmark)
(car bmks)
(completing-read "Bookmark: " bmks nil t nil nil (car bmks))))))
diff --git a/contrib/lisp/org-checklist.el b/contrib/lisp/org-checklist.el
index 05ad99d..a974874 100644
--- a/contrib/lisp/org-checklist.el
+++ b/contrib/lisp/org-checklist.el
@@ -138,6 +138,3 @@ (defun org-checklist ()
(provide 'org-checklist)
;;; org-checklist.el ends here
-
-
-
diff --git a/contrib/lisp/org-choose.el b/contrib/lisp/org-choose.el
index 77478c5..3513fe9 100644
--- a/contrib/lisp/org-choose.el
+++ b/contrib/lisp/org-choose.el
@@ -46,13 +46,13 @@
;; * Use C-S-right to change the keyword set. Use this to change to
;; the "choose" keyword set that you just defined.
-;; * Use S-right to advance the TODO mark to the next setting.
+;; * Use S-right to advance the TODO mark to the next setting.
;; For "choose", that means you like this alternative more than
;; before. Other alternatives will be automatically demoted to
;; keep your settings consistent.
-;; * Use S-left to demote TODO to the previous setting.
+;; * Use S-left to demote TODO to the previous setting.
;; For "choose", that means you don't like this alternative as much
;; as before. Other alternatives will be automatically promoted,
@@ -83,7 +83,7 @@ (defstruct (org-choose-mark-data. (:type list))
static-default
all-keywords)
-(defvar org-choose-mark-data
+(defvar org-choose-mark-data
()
"Alist of information for choose marks.
@@ -101,7 +101,7 @@ (defun org-choose-filter-one (i)
(not
(string-match "(.*)" i))
(list i i)
- (let*
+ (let*
(
(end-text (match-beginning 0))
(vanilla-text (substring i 0 end-text))
@@ -116,7 +116,7 @@ (defun org-choose-filter-one (i)
;;When string starts with "," `split-string' doesn't
;;make a first arg, so in that case make one
;;manually.
- (if
+ (if
(string-match "^," args)
(cons nil arglist-x)
arglist-x)))
@@ -157,11 +157,11 @@ (defun org-choose-setup-vars (bot-lower-range top-upper-range
;;item.
(top-upper-range
(or top-upper-range (1- num-items)))
- (lower-range-length
+ (lower-range-length
(1+ (- static-default bot-lower-range)))
- (upper-range-length
+ (upper-range-length
(- top-upper-range static-default))
- (range-length
+ (range-length
(min upper-range-length lower-range-length)))
@@ -194,7 +194,7 @@ (defun org-choose-setup-vars (bot-lower-range top-upper-range
;;;_ . org-choose-filter-tail
(defun org-choose-filter-tail (raw)
"Return a translation of RAW to vanilla and set appropriate
-buffer-local variables.
+buffer-local variables.
RAW is a list of strings representing the input text of a choose
interpretation."
@@ -219,7 +219,7 @@ (defun org-choose-filter-tail (raw)
(push vanilla-mark vanilla-list)))
(org-choose-setup-vars bot-lower-range top-upper-range
- static-default index (reverse all-mark-texts))
+ static-default index (reverse all-mark-texts))
(nreverse vanilla-list)))
;;;_ . org-choose-setup-filter
@@ -234,35 +234,35 @@ (defun org-choose-setup-filter (raw)
;;;_ . org-choose-conform-after-promotion
(defun org-choose-conform-after-promotion (entry-pos keywords highest-ok-ix)
"Conform the current item after another item was promoted"
-
+
(unless
;;Skip the entry that triggered this by skipping any entry with
;;the same starting position. plist uses the start of the
;;header line as the position, but map no longer does, so we
;;have to go back to the heading.
- (=
+ (=
(save-excursion
(org-back-to-heading)
- (point))
+ (point))
entry-pos)
(let
((ix
(org-choose-get-entry-index keywords)))
;;If the index of the entry exceeds the highest allowable
;;index, change it to that.
- (when (and ix
+ (when (and ix
(> ix highest-ok-ix))
- (org-todo
+ (org-todo
(nth highest-ok-ix keywords))))))
;;;_ . org-choose-conform-after-demotion
(defun org-choose-conform-after-demotion (entry-pos keywords
raise-to-ix
- old-highest-ok-ix)
+ old-highest-ok-ix)
"Conform the current item after another item was demoted."
(unless
;;Skip the entry that triggered this.
- (=
+ (=
(save-excursion
(org-back-to-heading)
(point))
@@ -273,11 +273,11 @@ (defun org-choose-conform-after-demotion (entry-pos keywords
;;If the index of the entry was at or above the old allowable
;;position, change it to the new mirror position if there is
;;one.
- (when (and
- ix
+ (when (and
+ ix
raise-to-ix
(>= ix old-highest-ok-ix))
- (org-todo
+ (org-todo
(nth raise-to-ix keywords))))))
;;;_ , org-choose-keep-sensible (the org-trigger-hook function)
@@ -287,7 +287,7 @@ (defun org-choose-keep-sensible (change-plist)
(let*
( (from (plist-get change-plist :from))
(to (plist-get change-plist :to))
- (entry-pos
+ (entry-pos
(set-marker
(make-marker)
(plist-get change-plist :position)))
@@ -303,11 +303,11 @@ (defun org-choose-keep-sensible (change-plist)
(org-choose-mark-data.-all-keywords data))
(old-index
(org-choose-get-index-in-keywords
- from
+ from
keywords))
(new-index
(org-choose-get-index-in-keywords
- to
+ to
keywords))
(highest-ok-ix
(org-choose-highest-other-ok
@@ -324,7 +324,7 @@ (defun org-choose-keep-sensible (change-plist)
(> new-index old-index))
(list
#'org-choose-conform-after-promotion
- entry-pos keywords
+ entry-pos keywords
highest-ok-ix))
(t ;;Otherwise the entry was demoted.
(let
@@ -338,14 +338,14 @@ (defun org-choose-keep-sensible (change-plist)
(org-choose-highest-other-ok
old-index
data)))
-
+
(list
- #'org-choose-conform-after-demotion
- entry-pos
+ #'org-choose-conform-after-demotion
+ entry-pos
keywords
raise-to-ix
old-highest-ok-ix))))))
-
+
(if funcdata
;;The funny-looking names are to make variable capture
;;unlikely. (Poor-man's lexical bindings).
@@ -356,8 +356,8 @@ (defun org-choose-keep-sensible (change-plist)
;;We may call `org-todo', so let various hooks
;;`nil' so we don't cause loops.
org-after-todo-state-change-hook
- org-trigger-hook
- org-blocker-hook
+ org-trigger-hook
+ org-blocker-hook
org-todo-get-default-hook
;;Also let this alist `nil' so we don't log
;;secondary transitions.
@@ -366,7 +366,7 @@ (defun org-choose-keep-sensible (change-plist)
(funcall map-over-entries
#'(lambda ()
(apply func-d473 args-46k))))))))
-
+
;;Remove the marker
(set-marker entry-pos nil)))
@@ -393,7 +393,7 @@ (defun org-choose-get-entry-index (all-keywords)
(defun org-choose-get-fn-map-group ()
"Return a function to map over the group"
-
+
#'(lambda (fn)
(require 'org-agenda) ;; `org-map-entries' seems to need it.
(save-excursion
@@ -402,7 +402,7 @@ (defun org-choose-get-fn-map-group ()
(let
((level (org-reduced-level (org-outline-level))))
(save-restriction
- (org-map-entries
+ (org-map-entries
fn
(format "LEVEL=%d" level)
'tree))))))
@@ -418,10 +418,10 @@ (defun org-choose-get-highest-mark-index (keywords)
;;Func maps over applicable entries.
(map-over-entries
(org-choose-get-fn-map-group))
-
+
(indexes-list
(remove nil
- (funcall map-over-entries
+ (funcall map-over-entries
#'(lambda ()
(org-choose-get-entry-index keywords))))))
(if
@@ -438,7 +438,7 @@ (defun org-choose-highest-other-ok (ix data)
DATA must be a `org-choose-mark-data.'."
(let
- (
+ (
(bot-lower-range
(org-choose-mark-data.-bot-lower-range data))
(top-upper-range
@@ -455,7 +455,7 @@ (defun org-choose-highest-other-ok (ix data)
;;;_ . org-choose-get-default-mark-index
-(defun org-choose-get-default-mark-index (data)
+(defun org-choose-get-default-mark-index (data)
"Return the index of the default mark in a choose interpretation.
DATA must be a `org-choose-mark-data.'."
@@ -475,7 +475,7 @@ (defun org-choose-get-default-mark-index (data)
;;;_ . org-choose-get-mark-N
(defun org-choose-get-mark-N (n data)
"Get the text of the nth mark in a choose interpretation."
-
+
(let*
((l (org-choose-mark-data.-all-keywords data)))
(nth n l)))
diff --git a/contrib/lisp/org-collector.el b/contrib/lisp/org-collector.el
index da612e9..ad198ed 100644
--- a/contrib/lisp/org-collector.el
+++ b/contrib/lisp/org-collector.el
@@ -87,7 +87,7 @@
;; | run (50) | 0.116446 |
;; | run (100) | 0.118863 |
;; #+END:
-;;
+;;
;;; Code:
(require 'org)
@@ -134,7 +134,7 @@ (defun org-dblock-write:propview (params)
(org-narrow-to-subtree)
(setq stringformat (if noquote "%s" "%S"))
(setq table (org-propview-to-table
- (org-propview-collect cols stringformat conds match scope inherit
+ (org-propview-collect cols stringformat conds match scope inherit
(if colnames colnames cols)) stringformat))
(widen))
(setq pos (point))
diff --git a/contrib/lisp/org-drill.el b/contrib/lisp/org-drill.el
index b022359..4adaf58 100644
--- a/contrib/lisp/org-drill.el
+++ b/contrib/lisp/org-drill.el
@@ -2915,4 +2915,3 @@ (defun org-drill-present-spanish-verb ()
(provide 'org-drill)
-
diff --git a/contrib/lisp/org-element.el b/contrib/lisp/org-element.el
index 3db8e36..3c6e396 100644
--- a/contrib/lisp/org-element.el
+++ b/contrib/lisp/org-element.el
@@ -1,6 +1,6 @@
;;; org-element.el --- Parser And Applications for Org syntax
-;; Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -43,15 +43,15 @@
;; Elements containing paragraphs are called greater elements.
;; Concerned types are: `center-block', `drawer', `dynamic-block',
;; `footnote-definition', `headline', `inlinetask', `item',
-;; `plain-list', `quote-block' and `special-block'.
+;; `plain-list', `quote-block', `section' and `special-block'.
-;; Greater elements (excepted `headline' and `item' types) and
-;; elements (excepted `keyword', `babel-call', and `property-drawer'
-;; types) can have a fixed set of keywords as attributes. Those are
-;; called "affiliated keywords", to distinguish them from others
-;; keywords, which are full-fledged elements. In particular, the
-;; "name" affiliated keyword allows to label almost any element in an
-;; Org buffer.
+;; Greater elements (excepted `headline', `item' and `section' types)
+;; and elements (excepted `keyword', `babel-call', and
+;; `property-drawer' types) can have a fixed set of keywords as
+;; attributes. Those are called "affiliated keywords", to distinguish
+;; them from others keywords, which are full-fledged elements. In
+;; particular, the "name" affiliated keyword allows to label almost
+;; any element in an Org buffer.
;; Notwithstanding affiliated keywords, each greater element, element
;; and object has a fixed set of properties attached to it. Among
@@ -79,10 +79,10 @@
;; The first part of this file implements a parser and an interpreter
;; for each type of Org syntax.
-;; The next two parts introduce two accessors and a function
-;; retrieving the smallest element containing point (respectively
-;; `org-element-get-property', `org-element-get-contents' and
-;; `org-element-at-point').
+;; The next two parts introduce three accessors and a function
+;; retrieving the smallest element starting at point (respectively
+;; `org-element-type', `org-element-property', `org-element-contents'
+;; and `org-element-current-element').
;; The following part creates a fully recursive buffer parser. It
;; also provides a tool to map a function to elements or objects
@@ -95,7 +95,8 @@
;; relative, `org-element-interpret-secondary').
;; The library ends by furnishing a set of interactive tools for
-;; element's navigation and manipulation.
+;; element's navigation and manipulation, mostly based on
+;; `org-element-at-point' function.
;;; Code:
@@ -128,12 +129,13 @@
;; cannot contain other greater elements of their own type.
;; Beside implementing a parser and an interpreter, adding a new
-;; greater element requires to tweak `org-element-guess-type'.
+;; greater element requires to tweak `org-element-current-element'.
;; Moreover, the newly defined type must be added to both
;; `org-element-all-elements' and `org-element-greater-elements'.
;;;; Center Block
+
(defun org-element-center-block-parser ()
"Parse a center block.
@@ -158,21 +160,23 @@ (defun org-element-center-block-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'center-block
- `(:begin ,begin
- :end ,end
- :hiddenp ,hidden
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(center-block
+ (:begin ,begin
+ :end ,end
+ :hiddenp ,hidden
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-center-block-interpreter (center-block contents)
"Interpret CENTER-BLOCK element as Org syntax.
CONTENTS is the contents of the element."
(format "#+begin_center\n%s#+end_center" contents))
+
;;;; Drawer
+
(defun org-element-drawer-parser ()
"Parse a drawer.
@@ -194,24 +198,26 @@ (defun org-element-drawer-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'drawer
- `(:begin ,begin
- :end ,end
- :drawer-name ,name
- :hiddenp ,hidden
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(drawer
+ (:begin ,begin
+ :end ,end
+ :drawer-name ,name
+ :hiddenp ,hidden
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-drawer-interpreter (drawer contents)
"Interpret DRAWER element as Org syntax.
CONTENTS is the contents of the element."
(format ":%s:\n%s:END:"
- (org-element-get-property :drawer-name drawer)
+ (org-element-property :drawer-name drawer)
contents))
+
;;;; Dynamic Block
+
(defun org-element-dynamic-block-parser ()
"Parse a dynamic block.
@@ -250,11 +256,12 @@ (defun org-element-dynamic-block-interpreter (dynamic-block contents)
"Interpret DYNAMIC-BLOCK element as Org syntax.
CONTENTS is the contents of the element."
(format "#+BEGIN: %s%s\n%s#+END:"
- (org-element-get-property :block-name dynamic-block)
- (let ((args (org-element-get-property :arguments dynamic-block)))
+ (org-element-property :block-name dynamic-block)
+ (let ((args (org-element-property :arguments dynamic-block)))
(and arg (concat " " args)))
contents))
+
;;;; Footnote Definition
(defun org-element-footnote-definition-parser ()
@@ -277,24 +284,25 @@ (defun org-element-footnote-definition-parser ()
(contents-end (progn (skip-chars-backward " \r\t\n")
(forward-line)
(point))))
- (list 'footnote-definition
- `(:label ,label
- :begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,(count-lines contents-end end)
- ,@(cadr keywords))))))
+ `(footnote-definition
+ (:label ,label
+ :begin ,begin
+ :end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,(count-lines contents-end end)
+ ,@(cadr keywords))))))
(defun org-element-footnote-definition-interpreter (footnote-definition contents)
"Interpret FOOTNOTE-DEFINITION element as Org syntax.
CONTENTS is the contents of the footnote-definition."
- (concat (format "[%s]" (org-element-get-property :label footnote-definition))
+ (concat (format "[%s]" (org-element-property :label footnote-definition))
" "
contents))
;;;; Headline
+
(defun org-element-headline-parser ()
"Parse an headline.
@@ -315,15 +323,20 @@ (defun org-element-headline-parser ()
(let* ((components (org-heading-components))
(level (nth 1 components))
(todo (nth 2 components))
- (todo-type (and todo
- (if (member todo org-done-keywords) 'done 'todo)))
+ (todo-type
+ (and todo (if (member todo org-done-keywords) 'done 'todo)))
(tags (nth 5 components))
(raw-value (nth 4 components))
- (quotedp (string-match (format "^%s +" org-quote-string) raw-value))
- (commentedp (string-match
- (format "^%s +" org-comment-string) raw-value))
- (archivedp (and tags
- (string-match (format ":%s:" org-archive-tag) tags)))
+ (quotedp
+ (let ((case-fold-search nil))
+ (string-match (format "^%s +" org-quote-string) raw-value)))
+ (commentedp
+ (let ((case-fold-search nil))
+ (string-match (format "^%s +" org-comment-string) raw-value)))
+ (archivedp
+ (and tags
+ (let ((case-fold-search nil))
+ (string-match (format ":%s:" org-archive-tag) tags))))
(footnote-section-p (and org-footnote-section
(string= org-footnote-section raw-value)))
(standard-props (let (plist)
@@ -372,55 +385,55 @@ (defun org-element-headline-parser ()
(setq title (org-element-parse-secondary-string
raw-value
(cdr (assq 'headline org-element-string-restrictions))))
- (list 'headline
- `(:raw-value ,raw-value
- :title ,title
- :begin ,begin
- :end ,end
- :pre-blank ,(count-lines pos-after-head contents-begin)
- :hiddenp ,hidden
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :level ,level
- :priority ,(nth 3 components)
- :tags ,tags
- :todo-keyword ,todo
- :todo-type ,todo-type
- :scheduled ,scheduled
- :deadline ,deadline
- :timestamp ,timestamp
- :clock ,clock
- :post-blank ,(count-lines contents-end end)
- :footnote-section-p ,footnote-section-p
- :archivedp ,archivedp
- :commentedp ,commentedp
- :quotedp ,quotedp
- ,@standard-props)))))
+ `(headline
+ (:raw-value ,raw-value
+ :title ,title
+ :begin ,begin
+ :end ,end
+ :pre-blank ,(count-lines pos-after-head contents-begin)
+ :hiddenp ,hidden
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :level ,level
+ :priority ,(nth 3 components)
+ :tags ,tags
+ :todo-keyword ,todo
+ :todo-type ,todo-type
+ :scheduled ,scheduled
+ :deadline ,deadline
+ :timestamp ,timestamp
+ :clock ,clock
+ :post-blank ,(count-lines contents-end end)
+ :footnote-section-p ,footnote-section-p
+ :archivedp ,archivedp
+ :commentedp ,commentedp
+ :quotedp ,quotedp
+ ,@standard-props)))))
(defun org-element-headline-interpreter (headline contents)
"Interpret HEADLINE element as Org syntax.
CONTENTS is the contents of the element."
- (let* ((level (org-element-get-property :level headline))
- (todo (org-element-get-property :todo-keyword headline))
- (priority (org-element-get-property :priority headline))
- (title (org-element-get-property :raw-value headline))
- (tags (let ((tag-string (org-element-get-property :tags headline))
- (archivedp (org-element-get-property :archivedp headline)))
+ (let* ((level (org-element-property :level headline))
+ (todo (org-element-property :todo-keyword headline))
+ (priority (org-element-property :priority headline))
+ (title (org-element-property :raw-value headline))
+ (tags (let ((tag-string (org-element-property :tags headline))
+ (archivedp (org-element-property :archivedp headline)))
(cond
((and (not tag-string) archivedp)
(format ":%s:" org-archive-tag))
(archivedp (concat ":" org-archive-tag tag-string))
(t tag-string))))
- (commentedp (org-element-get-property :commentedp headline))
- (quotedp (org-element-get-property :quotedp headline))
- (pre-blank (org-element-get-property :pre-blank headline))
+ (commentedp (org-element-property :commentedp headline))
+ (quotedp (org-element-property :quotedp headline))
+ (pre-blank (org-element-property :pre-blank headline))
(heading (concat (make-string level ?*)
(and todo (concat " " todo))
(and quotedp (concat " " org-quote-string))
(and commentedp (concat " " org-comment-string))
(and priority (concat " " priority))
(cond ((and org-footnote-section
- (org-element-get-property
+ (org-element-property
:footnote-section-p headline))
(concat " " org-footnote-section))
(title (concat " " title)))))
@@ -440,7 +453,9 @@ (defun org-element-headline-interpreter (headline contents)
(make-string (1+ pre-blank) 10)
contents)))
+
;;;; Inlinetask
+
(defun org-element-inlinetask-parser ()
"Parse an inline task.
@@ -493,35 +508,35 @@ (defun org-element-inlinetask-parser ()
(save-excursion (forward-line -1) (point))))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'inlinetask
- `(:raw-value ,raw-value
- :title ,title
- :begin ,begin
- :end ,end
- :hiddenp ,(and (> contents-end contents-begin) hidden)
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :level ,(nth 1 components)
- :priority ,(nth 3 components)
- :tags ,(nth 5 components)
- :todo-keyword ,todo
- :todo-type ,todo-type
- :scheduled ,scheduled
- :deadline ,deadline
- :timestamp ,timestamp
- :clock ,clock
- :post-blank ,(count-lines pos-before-blank end)
- ,@standard-props
- ,@(cadr keywords))))))
+ `(inlinetask
+ (:raw-value ,raw-value
+ :title ,title
+ :begin ,begin
+ :end ,end
+ :hiddenp ,(and (> contents-end contents-begin) hidden)
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :level ,(nth 1 components)
+ :priority ,(nth 3 components)
+ :tags ,(nth 5 components)
+ :todo-keyword ,todo
+ :todo-type ,todo-type
+ :scheduled ,scheduled
+ :deadline ,deadline
+ :timestamp ,timestamp
+ :clock ,clock
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@standard-props
+ ,@(cadr keywords))))))
(defun org-element-inlinetask-interpreter (inlinetask contents)
"Interpret INLINETASK element as Org syntax.
CONTENTS is the contents of inlinetask."
- (let* ((level (org-element-get-property :level inlinetask))
- (todo (org-element-get-property :todo-keyword inlinetask))
- (priority (org-element-get-property :priority inlinetask))
- (title (org-element-get-property :raw-value inlinetask))
- (tags (org-element-get-property :tags inlinetask))
+ (let* ((level (org-element-property :level inlinetask))
+ (todo (org-element-property :todo-keyword inlinetask))
+ (priority (org-element-property :priority inlinetask))
+ (title (org-element-property :raw-value inlinetask))
+ (tags (org-element-property :tags inlinetask))
(task (concat (make-string level ?*)
(and todo (concat " " todo))
(and priority (concat " " priority))
@@ -540,7 +555,9 @@ (defun org-element-inlinetask-interpreter (inlinetask contents)
1)))))))
(concat inlinetask (and tags (format tags-fmt tags) "\n" contents))))
+
;;;; Item
+
(defun org-element-item-parser (struct)
"Parse an item.
@@ -577,9 +594,11 @@ (defun org-element-item-parser (struct)
(contents-begin (progn (looking-at org-list-full-item-re)
(goto-char (match-end 0))
(org-skip-whitespace)
- (if (>= (point) end)
- (point-at-bol)
- (point))))
+ ;; If first line isn't empty,
+ ;; contents really start at the text
+ ;; after item's meta-data.
+ (if (= (point-at-bol) begin) (point)
+ (point-at-bol))))
(hidden (progn (forward-line)
(and (not (= (point) end))
(org-truely-invisible-p))))
@@ -587,39 +606,51 @@ (defun org-element-item-parser (struct)
(skip-chars-backward " \r\t\n")
(forward-line)
(point))))
- (list 'item
- `(:bullet ,bullet
- :begin ,begin
- :end ,end
- ;; CONTENTS-BEGIN and CONTENTS-END may be mixed
- ;; up in the case of an empty item separated
- ;; from the next by a blank line. Thus, ensure
- ;; the former is always the smallest of two.
- :contents-begin ,(min contents-begin contents-end)
- :contents-end ,(max contents-begin contents-end)
- :checkbox ,checkbox
- :counter ,counter
- :raw-tag ,raw-tag
- :tag ,tag
- :hiddenp ,hidden
- :structure ,struct
- :post-blank ,(count-lines contents-end end))))))
+ `(item
+ (:bullet ,bullet
+ :begin ,begin
+ :end ,end
+ ;; CONTENTS-BEGIN and CONTENTS-END may be mixed
+ ;; up in the case of an empty item separated
+ ;; from the next by a blank line. Thus, ensure
+ ;; the former is always the smallest of two.
+ :contents-begin ,(min contents-begin contents-end)
+ :contents-end ,(max contents-begin contents-end)
+ :checkbox ,checkbox
+ :counter ,counter
+ :raw-tag ,raw-tag
+ :tag ,tag
+ :hiddenp ,hidden
+ :structure ,struct
+ :post-blank ,(count-lines contents-end end))))))
(defun org-element-item-interpreter (item contents)
"Interpret ITEM element as Org syntax.
CONTENTS is the contents of the element."
- (let* ((bullet (org-element-get-property :bullet item))
- (checkbox (org-element-get-property :checkbox item))
- (counter (org-element-get-property :counter item))
- (tag (org-element-get-property :raw-tag item))
+ (let* ((bullet
+ (let* ((beg (org-element-property :begin item))
+ (struct (org-element-property :structure item))
+ (pre (org-list-prevs-alist struct))
+ (bul (org-element-property :bullet item)))
+ (org-list-bullet-string
+ (if (not (eq (org-list-get-list-type beg struct pre) 'ordered)) "-"
+ (let ((num
+ (car
+ (last
+ (org-list-get-item-number
+ beg struct pre (org-list-parents-alist struct))))))
+ (format "%d%s"
+ num
+ (if (eq org-plain-list-ordered-item-terminator ?\)) ")"
+ ".")))))))
+ (checkbox (org-element-property :checkbox item))
+ (counter (org-element-property :counter item))
+ (tag (org-element-property :raw-tag item))
;; Compute indentation.
(ind (make-string (length bullet) 32)))
;; Indent contents.
(concat
bullet
- (when (and org-list-two-spaces-after-bullet-regexp
- (string-match org-list-two-spaces-after-bullet-regexp bullet))
- " ")
(and counter (format "[@%d] " counter))
(cond
((eq checkbox 'on) "[X] ")
@@ -627,13 +658,17 @@ (defun org-element-item-interpreter (item contents)
((eq checkbox 'trans) "[-] "))
(and tag (format "%s :: " tag))
(org-trim
- (replace-regexp-in-string
- "\\(^\\)[ \t]*\\S-" ind contents nil nil 1)))))
+ (replace-regexp-in-string "\\(^\\)[ \t]*\\S-" ind contents nil nil 1)))))
+
;;;; Plain List
+
(defun org-element-plain-list-parser (&optional structure)
"Parse a plain list.
+Optional argument STRUCTURE, when non-nil, is the structure of
+the plain list being parsed.
+
Return a list whose car is `plain-list' and cdr is a plist
containing `:type', `:begin', `:end', `:contents-begin' and
`:contents-end', `:level', `:structure' and `:post-blank'
@@ -667,23 +702,25 @@ (defun org-element-plain-list-parser (&optional structure)
(progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol))))))
;; Return value.
- (list 'plain-list
- `(:type ,type
- :begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :level ,level
- :structure ,struct
- :post-blank ,(count-lines contents-end end)
- ,@(cadr keywords))))))
+ `(plain-list
+ (:type ,type
+ :begin ,begin
+ :end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :level ,level
+ :structure ,struct
+ :post-blank ,(count-lines contents-end end)
+ ,@(cadr keywords))))))
(defun org-element-plain-list-interpreter (plain-list contents)
"Interpret PLAIN-LIST element as Org syntax.
CONTENTS is the contents of the element."
contents)
+
;;;; Quote Block
+
(defun org-element-quote-block-parser ()
"Parse a quote block.
@@ -708,22 +745,57 @@ (defun org-element-quote-block-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'quote-block
- `(:begin ,begin
- :end ,end
- :hiddenp ,hidden
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
-
+ `(quote-block
+ (:begin ,begin
+ :end ,end
+ :hiddenp ,hidden
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-quote-block-interpreter (quote-block contents)
"Interpret QUOTE-BLOCK element as Org syntax.
CONTENTS is the contents of the element."
(format "#+begin_quote\n%s#+end_quote" contents))
+
+;;;; Section
+
+(defun org-element-section-parser ()
+ "Parse a section.
+
+Return a list whose car is `section' and cdr is a plist
+containing `:begin', `:end', `:contents-begin', `contents-end'
+and `:post-blank' keywords."
+ (save-excursion
+ ;; Beginning of section is the beginning of the first non-blank
+ ;; line after previous headline.
+ (org-with-limited-levels
+ (let ((begin
+ (save-excursion
+ (outline-previous-heading)
+ (if (not (org-at-heading-p)) (point)
+ (forward-line) (org-skip-whitespace) (point-at-bol))))
+ (end (progn (outline-next-heading) (point)))
+ (pos-before-blank (progn (skip-chars-backward " \r\t\n")
+ (forward-line)
+ (point))))
+ `(section
+ (:begin ,begin
+ :end ,end
+ :contents-begin ,begin
+ :contents-end ,pos-before-blank
+ :post-blank ,(count-lines pos-before-blank end)))))))
+
+(defun org-element-section-interpreter (section contents)
+ "Interpret SECTION element as Org syntax.
+CONTENTS is the contents of the element."
+ contents)
+
+
;;;; Special Block
+
(defun org-element-special-block-parser ()
"Parse a special block.
@@ -751,20 +823,20 @@ (defun org-element-special-block-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'special-block
- `(:type ,type
- :begin ,begin
- :end ,end
- :hiddenp ,hidden
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(special-block
+ (:type ,type
+ :begin ,begin
+ :end ,end
+ :hiddenp ,hidden
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-special-block-interpreter (special-block contents)
"Interpret SPECIAL-BLOCK element as Org syntax.
CONTENTS is the contents of the element."
- (let ((block-type (org-element-get-property :type special-block)))
+ (let ((block-type (org-element-property :type special-block)))
(format "#+begin_%s\n%s#+end_%s" block-type contents block-type)))
@@ -776,8 +848,8 @@ (defun org-element-special-block-interpreter (special-block contents)
;; Also, as for greater elements, adding a new element type is done
;; through the following steps: implement a parser and an interpreter,
-;; tweak `org-element-guess-type' so that it recognizes the new type
-;; and add that new type to `org-element-all-elements'.
+;; tweak `org-element-current-element' so that it recognizes the new
+;; type and add that new type to `org-element-all-elements'.
;; As a special case, when the newly defined type is a block type,
;; `org-element-non-recursive-block-alist' has to be modified
@@ -785,6 +857,7 @@ (defun org-element-special-block-interpreter (special-block contents)
;;;; Babel Call
+
(defun org-element-babel-call-parser ()
"Parse a babel call.
@@ -798,16 +871,16 @@ (defun org-element-babel-call-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'babel-call
- `(:beg ,beg
- :end ,end
- :info ,info
- :post-blank ,(count-lines pos-before-blank end))))))
+ `(babel-call
+ (:beg ,beg
+ :end ,end
+ :info ,info
+ :post-blank ,(count-lines pos-before-blank end))))))
(defun org-element-babel-call-interpreter (inline-babel-call contents)
"Interpret INLINE-BABEL-CALL object as Org syntax.
CONTENTS is nil."
- (let* ((babel-info (org-element-get-property :info inline-babel-call))
+ (let* ((babel-info (org-element-property :info inline-babel-call))
(main-source (car babel-info))
(post-options (nth 1 babel-info)))
(concat "#+call: "
@@ -818,54 +891,62 @@ (defun org-element-babel-call-interpreter (inline-babel-call contents)
main-source)
(and post-options (format "[%s]" post-options)))))
+
;;;; Comment
+
(defun org-element-comment-parser ()
"Parse a comment.
Return a list whose car is `comment' and cdr is a plist
containing `:begin', `:end', `:value' and `:post-blank'
keywords."
- (let ((comment-re "\\(#\\|[ \t]*#\\+\\( \\|$\\)\\)")
- beg-coms begin end value pos-before-blank keywords)
+ (let (beg-coms begin end end-coms keywords)
(save-excursion
- ;; Move to the beginning of comments.
- (unless (bobp)
- (while (and (not (bobp)) (looking-at comment-re))
- (forward-line -1))
- (unless (looking-at comment-re) (forward-line 1)))
- (setq beg-coms (point))
- ;; Get affiliated keywords, if any.
- (setq keywords (org-element-collect-affiliated-keywords))
- ;; Store true beginning of element.
- (setq begin (car keywords))
- ;; Get ending of comments. If point is in a list, ensure to not
- ;; get outside of it.
- (let* ((itemp (org-in-item-p))
- (max-pos (if itemp
- (org-list-get-bottom-point
- (save-excursion (goto-char itemp) (org-list-struct)))
- (point-max))))
- (while (and (looking-at comment-re) (< (point) max-pos))
- (forward-line)))
- (setq pos-before-blank (point))
+ (if (looking-at "#")
+ ;; First type of comment: comments at column 0.
+ (let ((comment-re "^\\([^#]\\|#\\+[a-z]\\)"))
+ (save-excursion
+ (re-search-backward comment-re nil 'move)
+ (if (bobp) (setq keywords nil beg-coms (point))
+ (forward-line)
+ (setq keywords (org-element-collect-affiliated-keywords)
+ beg-coms (point))))
+ (re-search-forward comment-re nil 'move)
+ (setq end-coms (if (eobp) (point) (match-beginning 0))))
+ ;; Second type of comment: indented comments.
+ (let ((comment-re "[ \t]*#\\+\\(?: \\|$\\)"))
+ (unless (bobp)
+ (while (and (not (bobp)) (looking-at comment-re))
+ (forward-line -1))
+ (unless (looking-at comment-re) (forward-line)))
+ (setq beg-coms (point))
+ (setq keywords (org-element-collect-affiliated-keywords))
+ ;; Get comments ending. This may not be accurate if
+ ;; commented lines within an item are followed by commented
+ ;; lines outside of the list. Though, parser will always
+ ;; get it right as it already knows surrounding element and
+ ;; has narrowed buffer to its contents.
+ (while (looking-at comment-re) (forward-line))
+ (setq end-coms (point))))
;; Find position after blank.
+ (goto-char end-coms)
(org-skip-whitespace)
- (setq end (if (eobp) (point) (point-at-bol)))
- ;; Extract value.
- (setq value (buffer-substring-no-properties beg-coms pos-before-blank)))
- (list 'comment
- `(:begin ,begin
- :end ,end
- :value ,value
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords)))))
+ (setq end (if (eobp) (point) (point-at-bol))))
+ `(comment
+ (:begin ,(or (car keywords) beg-coms)
+ :end ,end
+ :value ,(buffer-substring-no-properties beg-coms end-coms)
+ :post-blank ,(count-lines end-coms end)
+ ,@(cadr keywords)))))
(defun org-element-comment-interpreter (comment contents)
"Interpret COMMENT element as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value comment))
+ (org-element-property :value comment))
+
;;;; Comment Block
+
(defun org-element-comment-block-parser ()
"Parse an export block.
@@ -888,66 +969,96 @@ (defun org-element-comment-block-parser ()
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol))))
(value (buffer-substring-no-properties contents-begin contents-end)))
- (list 'comment-block
- `(:begin ,begin
- :end ,end
- :value ,value
- :hiddenp ,hidden
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(comment-block
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :hiddenp ,hidden
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-comment-block-interpreter (comment-block contents)
"Interpret COMMENT-BLOCK element as Org syntax.
CONTENTS is nil."
(concat "#+begin_comment\n"
(org-remove-indentation
- (org-element-get-property :value comment-block))
+ (org-element-property :value comment-block))
"#+begin_comment"))
+
;;;; Example Block
+
(defun org-element-example-block-parser ()
"Parse an example block.
-Return a list whose car is `example' and cdr is a plist
-containing `:begin', `:end', `:options', `:hiddenp', `:value' and
-`:post-blank' keywords."
+Return a list whose car is `example-block' and cdr is a plist
+containing `:begin', `:end', `:number-lines', `:preserve-indent',
+`:retain-labels', `:use-labels', `:label-fmt', `:hiddenp',
+`:switches', `:value' and `:post-blank' keywords."
(save-excursion
(end-of-line)
(let* ((case-fold-search t)
- (options (progn
- (re-search-backward
- "^[ \t]*#\\+begin_example\\(?: +\\(.*\\)\\)?" nil t)
- (org-match-string-no-properties 1)))
+ (switches (progn
+ (re-search-backward
+ "^[ \t]*#\\+BEGIN_EXAMPLE\\(?: +\\(.*\\)\\)?" nil t)
+ (org-match-string-no-properties 1)))
+ ;; Switches analysis
+ (number-lines (cond ((not switches) nil)
+ ((string-match "-n\\>" switches) 'new)
+ ((string-match "+n\\>" switches) 'continued)))
+ (preserve-indent (and switches (string-match "-i\\>" switches)))
+ ;; Should labels be retained in (or stripped from) example
+ ;; blocks?
+ (retain-labels
+ (or (not switches)
+ (not (string-match "-r\\>" switches))
+ (and number-lines (string-match "-k\\>" switches))))
+ ;; What should code-references use - labels or
+ ;; line-numbers?
+ (use-labels
+ (or (not switches)
+ (and retain-labels (not (string-match "-k\\>" switches)))))
+ (label-fmt (and switches
+ (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
+ (match-string 1 switches)))
+ ;; Standard block parsing.
(keywords (org-element-collect-affiliated-keywords))
(begin (car keywords))
(contents-begin (progn (forward-line) (point)))
(hidden (org-truely-invisible-p))
(contents-end (progn
- (re-search-forward "^[ \t]*#\\+end_example" nil t)
+ (re-search-forward "^[ \t]*#\\+END_EXAMPLE" nil t)
(point-at-bol)))
(value (buffer-substring-no-properties contents-begin contents-end))
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'example-block
- `(:begin ,begin
- :end ,end
- :value ,value
- :options ,options
- :hiddenp ,hidden
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(example-block
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :switches ,switches
+ :number-lines ,number-lines
+ :preserve-indent ,preserve-indent
+ :retain-labels ,retain-labels
+ :use-labels ,use-labels
+ :label-fmt ,label-fmt
+ :hiddenp ,hidden
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-example-block-interpreter (example-block contents)
"Interpret EXAMPLE-BLOCK element as Org syntax.
CONTENTS is nil."
- (let ((options (org-element-get-property :options example-block)))
+ (let ((options (org-element-property :options example-block)))
(concat "#+begin_example" (and options (concat " " options)) "\n"
(org-remove-indentation
- (org-element-get-property :value example-block))
+ (org-element-property :value example-block))
"#+end_example")))
+
;;;; Export Block
+
(defun org-element-export-block-parser ()
"Parse an export block.
@@ -973,24 +1084,26 @@ (defun org-element-export-block-parser ()
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol))))
(value (buffer-substring-no-properties contents-begin contents-end)))
- (list 'export-block
- `(:begin ,begin
- :end ,end
- :type ,type
- :value ,value
- :hiddenp ,hidden
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(export-block
+ (:begin ,begin
+ :end ,end
+ :type ,type
+ :value ,value
+ :hiddenp ,hidden
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-export-block-interpreter (export-block contents)
"Interpret EXPORT-BLOCK element as Org syntax.
CONTENTS is nil."
- (let ((type (org-element-get-property :type export-block)))
+ (let ((type (org-element-property :type export-block)))
(concat (format "#+begin_%s\n" type)
- (org-element-get-property :value export-block)
+ (org-element-property :value export-block)
(format "#+end_%s" type))))
+
;;;; Fixed-width
+
(defun org-element-fixed-width-parser ()
"Parse a fixed-width section.
@@ -1025,19 +1138,21 @@ (defun org-element-fixed-width-parser ()
(setq end (if (eobp) (point) (point-at-bol)))
;; Extract value.
(setq value (buffer-substring-no-properties beg-area pos-before-blank)))
- (list 'fixed-width
- `(:begin ,begin
- :end ,end
- :value ,value
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords)))))
+ `(fixed-width
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords)))))
(defun org-element-fixed-width-interpreter (fixed-width contents)
"Interpret FIXED-WIDTH element as Org syntax.
CONTENTS is nil."
- (org-remove-indentation (org-element-get-property :value fixed-width)))
+ (org-remove-indentation (org-element-property :value fixed-width)))
+
;;;; Horizontal Rule
+
(defun org-element-horizontal-rule-parser ()
"Parse an horizontal rule.
@@ -1050,18 +1165,20 @@ (defun org-element-horizontal-rule-parser ()
(post-hr (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'horizontal-rule
- `(:begin ,begin
- :end ,end
- :post-blank ,(count-lines post-hr end)
- ,@(cadr keywords))))))
+ `(horizontal-rule
+ (:begin ,begin
+ :end ,end
+ :post-blank ,(count-lines post-hr end)
+ ,@(cadr keywords))))))
(defun org-element-horizontal-rule-interpreter (horizontal-rule contents)
"Interpret HORIZONTAL-RULE element as Org syntax.
CONTENTS is nil."
"-----")
+
;;;; Keyword
+
(defun org-element-keyword-parser ()
"Parse a keyword at point.
@@ -1078,21 +1195,23 @@ (defun org-element-keyword-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'keyword
- `(:key ,key
- :value ,value
- :begin ,begin
- :end ,end
- :post-blank ,(count-lines pos-before-blank end))))))
+ `(keyword
+ (:key ,key
+ :value ,value
+ :begin ,begin
+ :end ,end
+ :post-blank ,(count-lines pos-before-blank end))))))
(defun org-element-keyword-interpreter (keyword contents)
"Interpret KEYWORD element as Org syntax.
CONTENTS is nil."
(format "#+%s: %s"
- (org-element-get-property :key keyword)
- (org-element-get-property :value keyword)))
+ (org-element-property :key keyword)
+ (org-element-property :value keyword)))
+
;;;; Latex Environment
+
(defun org-element-latex-environment-parser ()
"Parse a LaTeX environment.
@@ -1110,19 +1229,21 @@ (defun org-element-latex-environment-parser ()
(value (buffer-substring-no-properties contents-begin contents-end))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'latex-environment
- `(:begin ,begin
- :end ,end
- :value ,value
- :post-blank ,(count-lines contents-end end)
- ,@(cadr keywords))))))
+ `(latex-environment
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :post-blank ,(count-lines contents-end end)
+ ,@(cadr keywords))))))
(defun org-element-latex-environment-interpreter (latex-environment contents)
"Interpret LATEX-ENVIRONMENT element as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value latex-environment))
+ (org-element-property :value latex-environment))
+
;;;; Paragraph
+
(defun org-element-paragraph-parser ()
"Parse a paragraph.
@@ -1144,20 +1265,22 @@ (defun org-element-paragraph-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'paragraph
- `(:begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(paragraph
+ (:begin ,begin
+ :end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-paragraph-interpreter (paragraph contents)
"Interpret PARAGRAPH element as Org syntax.
CONTENTS is the contents of the element."
contents)
+
;;;; Property Drawer
+
(defun org-element-property-drawer-parser ()
"Parse a property drawer.
@@ -1188,17 +1311,17 @@ (defun org-element-property-drawer-parser ()
(pos-before-blank (progn (forward-line) (point)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
- (list 'property-drawer
- `(:begin ,begin
- :end ,end
- :hiddenp ,hidden
- :properties ,properties
- :post-blank ,(count-lines pos-before-blank end))))))
+ `(property-drawer
+ (:begin ,begin
+ :end ,end
+ :hiddenp ,hidden
+ :properties ,properties
+ :post-blank ,(count-lines pos-before-blank end))))))
(defun org-element-property-drawer-interpreter (property-drawer contents)
"Interpret PROPERTY-DRAWER element as Org syntax.
CONTENTS is nil."
- (let ((props (org-element-get-property :properties property-drawer)))
+ (let ((props (org-element-property :properties property-drawer)))
(concat
":PROPERTIES:\n"
(mapconcat (lambda (p)
@@ -1206,69 +1329,90 @@ (defun org-element-property-drawer-interpreter (property-drawer contents)
(nreverse props) "\n")
"\n:END:")))
+
;;;; Quote Section
+
(defun org-element-quote-section-parser ()
"Parse a quote section.
Return a list whose car is `quote-section' and cdr is a plist
containing `:begin', `:end', `:value' and `:post-blank'
-keywords."
+keywords.
+
+Assume point is at beginning of the section."
(save-excursion
- (let* ((begin (progn (org-back-to-heading t)
- (forward-line)
- (org-skip-whitespace)
- (point-at-bol)))
+ (let* ((begin (point))
(end (progn (org-with-limited-levels (outline-next-heading))
(point)))
(pos-before-blank (progn (skip-chars-backward " \r\t\n")
(forward-line)
(point)))
- (value (unless (= begin end)
- (buffer-substring-no-properties begin pos-before-blank))))
- (list 'quote-section
- `(:begin ,begin
- :end ,end
- :value ,value
- :post-blank ,(if value
- (count-lines pos-before-blank end)
- 0))))))
+ (value (buffer-substring-no-properties begin pos-before-blank)))
+ `(quote-section
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :post-blank ,(count-lines pos-before-blank end))))))
(defun org-element-quote-section-interpreter (quote-section contents)
"Interpret QUOTE-SECTION element as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value quote-section))
+ (org-element-property :value quote-section))
+
;;;; Src Block
+
(defun org-element-src-block-parser ()
"Parse a src block.
Return a list whose car is `src-block' and cdr is a plist
containing `:language', `:switches', `:parameters', `:begin',
-`:end', `:hiddenp', `:contents-begin', `:contents-end', `:value'
-and `:post-blank' keywords."
+`:end', `:hiddenp', `:contents-begin', `:contents-end',
+`:number-lines', `:retain-labels', `:use-labels', `:label-fmt',
+`:preserve-indent', `:value' and `:post-blank' keywords."
(save-excursion
(end-of-line)
(let* ((case-fold-search t)
;; Get position at beginning of block.
(contents-begin
(re-search-backward
- (concat "^[ \t]*#\\+begin_src"
- "\\(?: +\\(\\S-+\\)\\)?" ; language
- "\\(\\(?: +[-+][A-Za-z]\\)*\\)" ; switches
- "\\(.*\\)[ \t]*$") ; arguments
+ (concat
+ "^[ \t]*#\\+BEGIN_SRC"
+ "\\(?: +\\(\\S-+\\)\\)?" ; language
+ "\\(\\(?: +\\(?:-l \".*?\"\\|[-+][A-Za-z]\\)\\)*\\)" ; switches
+ "\\(.*\\)[ \t]*$") ; parameters
nil t))
;; Get language as a string.
(language (org-match-string-no-properties 1))
- ;; Get switches.
- (switches (org-match-string-no-properties 2))
;; Get parameters.
(parameters (org-trim (org-match-string-no-properties 3)))
+ ;; Get switches.
+ (switches (org-match-string-no-properties 2))
+ ;; Switches analysis
+ (number-lines (cond ((not switches) nil)
+ ((string-match "-n\\>" switches) 'new)
+ ((string-match "+n\\>" switches) 'continued)))
+ (preserve-indent (and switches (string-match "-i\\>" switches)))
+ (label-fmt (and switches
+ (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
+ (match-string 1 switches)))
+ ;; Should labels be retained in (or stripped from) src
+ ;; blocks?
+ (retain-labels
+ (or (not switches)
+ (not (string-match "-r\\>" switches))
+ (and number-lines (string-match "-k\\>" switches))))
+ ;; What should code-references use - labels or
+ ;; line-numbers?
+ (use-labels
+ (or (not switches)
+ (and retain-labels (not (string-match "-k\\>" switches)))))
;; Get affiliated keywords.
(keywords (org-element-collect-affiliated-keywords))
;; Get beginning position.
(begin (car keywords))
;; Get position at end of block.
- (contents-end (progn (re-search-forward "^[ \t]*#\\+end_src" nil t)
+ (contents-end (progn (re-search-forward "^[ \t]*#\\+END_SRC" nil t)
(forward-line)
(point)))
;; Retrieve code.
@@ -1282,26 +1426,31 @@ (defun org-element-src-block-parser ()
(if (eobp) (point) (point-at-bol))))
;; Get visibility status.
(hidden (progn (goto-char contents-begin)
- (forward-line)
- (org-truely-invisible-p))))
- (list 'src-block
- `(:language ,language
- :switches ,switches
- :parameters ,parameters
- :begin ,begin
- :end ,end
- :hiddenp ,hidden
- :value ,value
- :post-blank ,(count-lines contents-end end)
- ,@(cadr keywords))))))
+ (forward-line)
+ (org-truely-invisible-p))))
+ `(src-block
+ (:language ,language
+ :switches ,switches
+ :parameters ,parameters
+ :begin ,begin
+ :end ,end
+ :number-lines ,number-lines
+ :preserve-indent ,preserve-indent
+ :retain-labels ,retain-labels
+ :use-labels ,use-labels
+ :label-fmt ,label-fmt
+ :hiddenp ,hidden
+ :value ,value
+ :post-blank ,(count-lines contents-end end)
+ ,@(cadr keywords))))))
(defun org-element-src-block-interpreter (src-block contents)
"Interpret SRC-BLOCK element as Org syntax.
CONTENTS is nil."
- (let ((lang (org-element-get-property :language src-block))
- (switches (org-element-get-property :switches src-block))
- (params (org-element-get-property :parameters src-block))
- (value (let ((val (org-element-get-property :value src-block)))
+ (let ((lang (org-element-property :language src-block))
+ (switches (org-element-property :switches src-block))
+ (params (org-element-property :parameters src-block))
+ (value (let ((val (org-element-property :value src-block)))
(cond
(org-src-preserve-indentation val)
((zerop org-edit-src-content-indentation)
@@ -1319,7 +1468,9 @@ (defun org-element-src-block-interpreter (src-block contents)
value
"#+end_src")))
+
;;;; Table
+
(defun org-element-table-parser ()
"Parse a table at point.
@@ -1340,21 +1491,23 @@ (defun org-element-table-parser ()
(if (eobp) (point) (point-at-bol))))
(raw-table (org-remove-indentation
(buffer-substring-no-properties table-begin table-end))))
- (list 'table
- `(:begin ,begin
- :end ,end
- :type ,type
- :raw-table ,raw-table
- :tblfm ,tblfm
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
+ `(table
+ (:begin ,begin
+ :end ,end
+ :type ,type
+ :raw-table ,raw-table
+ :tblfm ,tblfm
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-table-interpreter (table contents)
"Interpret TABLE element as Org syntax.
CONTENTS is nil."
- (org-element-get-property :raw-table table))
+ (org-element-property :raw-table table))
+
;;;; Verse Block
+
(defun org-element-verse-block-parser ()
"Parse a verse block.
@@ -1382,23 +1535,22 @@ (defun org-element-verse-block-parser ()
(if (eobp) (point) (point-at-bol))))
(value (org-element-parse-secondary-string
(org-remove-indentation raw-val)
- (cdr (assq 'verse org-element-string-restrictions)))))
- (list 'verse-block
- `(:begin ,begin
- :end ,end
- :hiddenp ,hidden
- :raw-value ,raw-val
- :value ,value
- :post-blank ,(count-lines pos-before-blank end)
- ,@(cadr keywords))))))
-
+ (cdr (assq 'verse-block org-element-string-restrictions)))))
+ `(verse-block
+ (:begin ,begin
+ :end ,end
+ :hiddenp ,hidden
+ :raw-value ,raw-val
+ :value ,value
+ :post-blank ,(count-lines pos-before-blank end)
+ ,@(cadr keywords))))))
(defun org-element-verse-block-interpreter (verse-block contents)
"Interpret VERSE-BLOCK element as Org syntax.
CONTENTS is nil."
(format "#+begin_verse\n%s#+end_verse"
(org-remove-indentation
- (org-element-get-property :raw-value verse-block))))
+ (org-element-property :raw-value verse-block))))
\f
@@ -1417,16 +1569,18 @@ (defun org-element-verse-block-interpreter (verse-block contents)
;; org-element-NAME-successor, where NAME is the name of the
;; successor, as defined in `org-element-all-successors'.
-;; Some object types (i.e `emphasis') are recursive. Restrictions on
+;; Some object types (i.e. `emphasis') are recursive. Restrictions on
;; object types they can contain will be specified in
;; `org-element-object-restrictions'.
;; Adding a new type of object is simple. Implement a successor,
;; a parser, and an interpreter for it, all following the naming
-;; convention. Register successor in `org-element-all-successors',
-;; maybe tweak restrictions about it, and that's it.
+;; convention. Register type in `org-element-all-objects' and
+;; successor in `org-element-all-successors'. Maybe tweak
+;; restrictions about it, and that's it.
;;;; Emphasis
+
(defun org-element-emphasis-parser ()
"Parse text markup object at point.
@@ -1445,22 +1599,22 @@ (defun org-element-emphasis-parser ()
(post-blank (progn (goto-char (match-end 2))
(skip-chars-forward " \t")))
(end (point)))
- (list 'emphasis
- `(:marker ,marker
- :begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,post-blank)))))
+ `(emphasis
+ (:marker ,marker
+ :begin ,begin
+ :end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,post-blank)))))
(defun org-element-emphasis-interpreter (emphasis contents)
"Interpret EMPHASIS object as Org syntax.
CONTENTS is the contents of the object."
- (let ((marker (org-element-get-property :marker emphasis)))
+ (let ((marker (org-element-property :marker emphasis)))
(concat marker contents marker)))
(defun org-element-text-markup-successor (limit)
- "Search for the next emphasis or verbatim and return position.
+ "Search for the next emphasis or verbatim object.
LIMIT bounds the search.
@@ -1475,6 +1629,7 @@ (defun org-element-text-markup-successor (limit)
(match-beginning 2)))))
;;;; Entity
+
(defun org-element-entity-parser ()
"Parse entity at point.
@@ -1493,25 +1648,25 @@ (defun org-element-entity-parser ()
(when bracketsp (forward-char 2))
(skip-chars-forward " \t")))
(end (point)))
- (list 'entity
- `(:name ,(car value)
- :latex ,(nth 1 value)
- :latex-math-p ,(nth 2 value)
- :html ,(nth 3 value)
- :ascii ,(nth 4 value)
- :latin1 ,(nth 5 value)
- :utf-8 ,(nth 6 value)
- :begin ,begin
- :end ,end
- :use-brackets-p ,bracketsp
- :post-blank ,post-blank)))))
+ `(entity
+ (:name ,(car value)
+ :latex ,(nth 1 value)
+ :latex-math-p ,(nth 2 value)
+ :html ,(nth 3 value)
+ :ascii ,(nth 4 value)
+ :latin1 ,(nth 5 value)
+ :utf-8 ,(nth 6 value)
+ :begin ,begin
+ :end ,end
+ :use-brackets-p ,bracketsp
+ :post-blank ,post-blank)))))
(defun org-element-entity-interpreter (entity contents)
"Interpret ENTITY object as Org syntax.
CONTENTS is nil."
(concat "\\"
- (org-element-get-property :name entity)
- (when (org-element-get-property :use-brackets-p entity) "{}")))
+ (org-element-property :name entity)
+ (when (org-element-property :use-brackets-p entity) "{}")))
(defun org-element-latex-or-entity-successor (limit)
"Search for the next latex-fragment or entity object.
@@ -1547,7 +1702,9 @@ (defun org-element-latex-or-entity-successor (limit)
matchers)
(point))))))))
+
;;;; Export Snippet
+
(defun org-element-export-snippet-parser ()
"Parse export snippet at point.
@@ -1565,19 +1722,19 @@ (defun org-element-export-snippet-parser ()
(match-end 0) (1- before-blank)))
(post-blank (skip-chars-forward " \t"))
(end (point)))
- (list 'export-snippet
- `(:back-end ,back-end
- :value ,value
- :begin ,begin
- :end ,end
- :post-blank ,post-blank)))))
+ `(export-snippet
+ (:back-end ,back-end
+ :value ,value
+ :begin ,begin
+ :end ,end
+ :post-blank ,post-blank)))))
(defun org-element-export-snippet-interpreter (export-snippet contents)
"Interpret EXPORT-SNIPPET object as Org syntax.
CONTENTS is nil."
(format "@%s{%s}"
- (org-element-get-property :back-end export-snippet)
- (org-element-get-property :value export-snippet)))
+ (org-element-property :back-end export-snippet)
+ (org-element-property :value export-snippet)))
(defun org-element-export-snippet-successor (limit)
"Search for the next export-snippet object.
@@ -1593,6 +1750,7 @@ (defun org-element-export-snippet-successor (limit)
(and end (eq (char-before end) ?})))
(throw 'exit (cons 'export-snippet (match-beginning 0))))))))
+
;;;; Footnote Reference
(defun org-element-footnote-reference-parser ()
@@ -1605,35 +1763,37 @@ (defun org-element-footnote-reference-parser ()
(let* ((ref (org-footnote-at-reference-p))
(label (car ref))
(raw-def (nth 3 ref))
- (inline-def (and raw-def
- (org-element-parse-secondary-string raw-def nil)))
+ (inline-def
+ (and raw-def
+ (org-element-parse-secondary-string
+ raw-def
+ (cdr (assq 'footnote-reference
+ org-element-string-restrictions)))))
(type (if (nth 3 ref) 'inline 'standard))
(begin (nth 1 ref))
(post-blank (progn (goto-char (nth 2 ref))
(skip-chars-forward " \t")))
(end (point)))
- (list 'footnote-reference
- `(:label ,label
- :type ,type
- :inline-definition ,inline-def
- :begin ,begin
- :end ,end
- :post-blank ,post-blank
- :raw-definition ,raw-def)))))
+ `(footnote-reference
+ (:label ,label
+ :type ,type
+ :inline-definition ,inline-def
+ :begin ,begin
+ :end ,end
+ :post-blank ,post-blank
+ :raw-definition ,raw-def)))))
(defun org-element-footnote-reference-interpreter (footnote-reference contents)
"Interpret FOOTNOTE-REFERENCE object as Org syntax.
CONTENTS is nil."
- (let ((label (or (org-element-get-property :label footnote-reference)
- "fn:"))
- (def (let ((raw (org-element-get-property
- :raw-definition footnote-reference)))
- (if raw (concat ":" raw) ""))))
+ (let ((label (or (org-element-property :label footnote-reference) "fn:"))
+ (def
+ (let ((raw (org-element-property :raw-definition footnote-reference)))
+ (if raw (concat ":" raw) ""))))
(format "[%s]" (concat label def))))
(defun org-element-footnote-reference-successor (limit)
- "Search for the next footnote-reference and return beginning
- position.
+ "Search for the next footnote-reference object.
LIMIT bounds the search.
@@ -1645,6 +1805,7 @@ (defun org-element-footnote-reference-successor (limit)
;;;; Inline Babel Call
+
(defun org-element-inline-babel-call-parser ()
"Parse inline babel call at point.
@@ -1660,16 +1821,16 @@ (defun org-element-inline-babel-call-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'inline-babel-call
- `(:begin ,begin
- :end ,end
- :info ,info
- :post-blank ,post-blank)))))
+ `(inline-babel-call
+ (:begin ,begin
+ :end ,end
+ :info ,info
+ :post-blank ,post-blank)))))
(defun org-element-inline-babel-call-interpreter (inline-babel-call contents)
"Interpret INLINE-BABEL-CALL object as Org syntax.
CONTENTS is nil."
- (let* ((babel-info (org-element-get-property :info inline-babel-call))
+ (let* ((babel-info (org-element-property :info inline-babel-call))
(main-source (car babel-info))
(post-options (nth 1 babel-info)))
(concat "call_"
@@ -1681,8 +1842,7 @@ (defun org-element-inline-babel-call-interpreter (inline-babel-call contents)
(and post-options (format "[%s]" post-options)))))
(defun org-element-inline-babel-call-successor (limit)
- "Search for the next inline-babel-call and return beginning
- position.
+ "Search for the next inline-babel-call object.
LIMIT bounds the search.
@@ -1696,7 +1856,9 @@ (defun org-element-inline-babel-call-successor (limit)
limit t)
(cons 'inline-babel-call (match-beginning 0)))))
+
;;;; Inline Src Block
+
(defun org-element-inline-src-block-parser ()
"Parse inline source block at point.
@@ -1715,18 +1877,27 @@ (defun org-element-inline-src-block-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'inline-src-block
- `(:language ,language
- :value ,value
- :parameters ,parameters
- :begin ,begin
- :end ,end
- :post-blank ,post-blank)))))
-
+ `(inline-src-block
+ (:language ,language
+ :value ,value
+ :parameters ,parameters
+ :begin ,begin
+ :end ,end
+ :post-blank ,post-blank)))))
+(defun org-element-inline-src-block-interpreter (inline-src-block contents)
+ "Interpret INLINE-SRC-BLOCK object as Org syntax.
+CONTENTS is nil."
+ (let ((language (org-element-property :language inline-src-block))
+ (arguments (org-element-property :parameters inline-src-block))
+ (body (org-element-property :value inline-src-block)))
+ (format "src_%s%s{%s}"
+ language
+ (if arguments (format "[%s]" arguments) "")
+ body)))
(defun org-element-inline-src-block-successor (limit)
- "Search for the next inline-babel-call and return beginning position.
+ "Search for the next inline-babel-call element.
LIMIT bounds the search.
@@ -1736,7 +1907,9 @@ (defun org-element-inline-src-block-successor (limit)
(when (re-search-forward org-babel-inline-src-block-regexp limit t)
(cons 'inline-src-block (match-beginning 1)))))
+
;;;; Latex Fragment
+
(defun org-element-latex-fragment-parser ()
"Parse latex fragment at point.
@@ -1764,18 +1937,19 @@ (defun org-element-latex-fragment-parser ()
(post-blank (progn (goto-char (match-end substring-match))
(skip-chars-forward " \t")))
(end (point)))
- (list 'latex-fragment
- `(:value ,value
- :begin ,begin
- :end ,end
- :post-blank ,post-blank)))))
+ `(latex-fragment
+ (:value ,value
+ :begin ,begin
+ :end ,end
+ :post-blank ,post-blank)))))
(defun org-element-latex-fragment-interpreter (latex-fragment contents)
"Interpret LATEX-FRAGMENT object as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value latex-fragment))
+ (org-element-property :value latex-fragment))
;;;; Line Break
+
(defun org-element-line-break-parser ()
"Parse line break at point.
@@ -1783,23 +1957,17 @@ (defun org-element-line-break-parser ()
`:begin', `:end' and `:post-blank' keywords.
Assume point is at the beginning of the line break."
- (save-excursion
- (let* ((begin (point))
- (end (progn (end-of-line) (point)))
- (post-blank (- (skip-chars-backward " \t")))
- (end (point)))
- (list 'line-break
- `(:begin ,begin
- :end ,end
- :post-blank ,post-blank)))))
+ (let ((begin (point))
+ (end (save-excursion (forward-line) (point))))
+ `(line-break (:begin ,begin :end ,end :post-blank 0))))
(defun org-element-line-break-interpreter (line-break contents)
"Interpret LINE-BREAK object as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value line-break))
+ "\\\\\n")
(defun org-element-line-break-successor (limit)
- "Search for the next statistics cookie and return position.
+ "Search for the next line-break object.
LIMIT bounds the search.
@@ -1812,7 +1980,9 @@ (defun org-element-line-break-successor (limit)
(when (and beg (re-search-backward "\\S-" (point-at-bol) t))
(cons 'line-break beg)))))
+
;;;; Link
+
(defun org-element-link-parser ()
"Parse link at point.
@@ -1826,13 +1996,11 @@ (defun org-element-link-parser ()
end contents-begin contents-end link-end post-blank path type
raw-link link)
(cond
- ;; Type 1: text targeted from a radio target.
+ ;; Type 1: Text targeted from a radio target.
((and org-target-link-regexp (looking-at org-target-link-regexp))
(setq type "radio"
- path (org-match-string-no-properties 0)
- contents-begin (match-beginning 0)
- contents-end (match-end 0)
- link-end (match-end 0)))
+ link-end (match-end 0)
+ path (org-match-string-no-properties 0)))
;; Type 2: Standard link, i.e. [[http://orgmode.org][homepage]]
((looking-at org-bracket-link-regexp)
(setq contents-begin (match-beginning 3)
@@ -1881,29 +2049,28 @@ (defun org-element-link-parser ()
;; LINK-END variable.
(setq post-blank (progn (goto-char link-end) (skip-chars-forward " \t"))
end (point))
- (list 'link
- `(:type ,type
- :path ,path
- :raw-link ,(or raw-link path)
- :begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,post-blank)))))
+ `(link
+ (:type ,type
+ :path ,path
+ :raw-link ,(or raw-link path)
+ :begin ,begin
+ :end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,post-blank)))))
(defun org-element-link-interpreter (link contents)
"Interpret LINK object as Org syntax.
CONTENTS is the contents of the object."
- (let ((type (org-element-get-property :type link))
- (raw-link (org-element-get-property :raw-link link)))
- (cond
- ((string= type "radio") raw-link)
- (t (format "[[%s]%s]"
- raw-link
- (if (string= contents "") "" (format "[%s]" contents)))))))
+ (let ((type (org-element-property :type link))
+ (raw-link (org-element-property :raw-link link)))
+ (if (string= type "radio") raw-link
+ (format "[[%s]%s]"
+ raw-link
+ (if (string= contents "") "" (format "[%s]" contents))))))
(defun org-element-link-successor (limit)
- "Search for the next link and return position.
+ "Search for the next link object.
LIMIT bounds the search.
@@ -1911,13 +2078,14 @@ (defun org-element-link-successor (limit)
beginning position."
(save-excursion
(let ((link-regexp
- (if org-target-link-regexp
- (concat org-any-link-re "\\|" org-target-link-regexp)
- org-any-link-re)))
+ (if (not org-target-link-regexp) org-any-link-re
+ (concat org-any-link-re "\\|" org-target-link-regexp))))
(when (re-search-forward link-regexp limit t)
(cons 'link (match-beginning 0))))))
+
;;;; Macro
+
(defun org-element-macro-parser ()
"Parse macro at point.
@@ -1945,21 +2113,21 @@ (defun org-element-macro-parser ()
(pop args))
(push (pop args) args2))
(mapcar 'org-trim (nreverse args2))))))
- (list 'macro
- `(:key ,key
- :value ,value
- :args ,args
- :begin ,begin
- :end ,end
- :post-blank ,post-blank)))))
+ `(macro
+ (:key ,key
+ :value ,value
+ :args ,args
+ :begin ,begin
+ :end ,end
+ :post-blank ,post-blank)))))
(defun org-element-macro-interpreter (macro contents)
"Interpret MACRO object as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value macro))
+ (org-element-property :value macro))
(defun org-element-macro-successor (limit)
- "Search for the next macro and return position.
+ "Search for the next macro object.
LIMIT bounds the search.
@@ -1971,7 +2139,9 @@ (defun org-element-macro-successor (limit)
limit t)
(cons 'macro (match-beginning 0)))))
+
;;;; Radio-target
+
(defun org-element-radio-target-parser ()
"Parse radio target at point.
@@ -1989,21 +2159,21 @@ (defun org-element-radio-target-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'radio-target
- `(:begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :raw-value ,raw-value
- :post-blank ,post-blank)))))
+ `(radio-target
+ (:begin ,begin
+ :end ,end
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :raw-value ,raw-value
+ :post-blank ,post-blank)))))
(defun org-element-radio-target-interpreter (target contents)
"Interpret TARGET object as Org syntax.
CONTENTS is the contents of the object."
- (concat ">"))
+ (concat "<<<" contents ">>>"))
(defun org-element-radio-target-successor (limit)
- "Search for the next radio-target and return position.
+ "Search for the next radio-target object.
LIMIT bounds the search.
@@ -2013,7 +2183,9 @@ (defun org-element-radio-target-successor (limit)
(when (re-search-forward org-radio-target-regexp limit t)
(cons 'radio-target (match-beginning 0)))))
+
;;;; Statistics Cookie
+
(defun org-element-statistics-cookie-parser ()
"Parse statistics cookie at point.
@@ -2029,19 +2201,19 @@ (defun org-element-statistics-cookie-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'statistics-cookie
- `(:begin ,begin
- :end ,end
- :value ,value
- :post-blank ,post-blank)))))
+ `(statistics-cookie
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :post-blank ,post-blank)))))
(defun org-element-statistics-cookie-interpreter (statistics-cookie contents)
"Interpret STATISTICS-COOKIE object as Org syntax.
CONTENTS is nil."
- (org-element-get-property :value statistics-cookie))
+ (org-element-property :value statistics-cookie))
(defun org-element-statistics-cookie-successor (limit)
- "Search for the next statistics cookie and return position.
+ "Search for the next statistics cookie object.
LIMIT bounds the search.
@@ -2051,7 +2223,9 @@ (defun org-element-statistics-cookie-successor (limit)
(when (re-search-forward "\\[[0-9]*\\(%\\|/[0-9]*\\)\\]" limit t)
(cons 'statistics-cookie (match-beginning 0)))))
+
;;;; Subscript
+
(defun org-element-subscript-parser ()
"Parse subscript at point.
@@ -2072,24 +2246,23 @@ (defun org-element-subscript-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'subscript
- `(:begin ,begin
- :end ,end
- :use-brackets-p ,bracketsp
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,post-blank)))))
+ `(subscript
+ (:begin ,begin
+ :end ,end
+ :use-brackets-p ,bracketsp
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,post-blank)))))
(defun org-element-subscript-interpreter (subscript contents)
"Interpret SUBSCRIPT object as Org syntax.
CONTENTS is the contents of the object."
(format
- (if (org-element-get-property :use-brackets-p subscript) "_{%s}" "_%s")
+ (if (org-element-property :use-brackets-p subscript) "_{%s}" "_%s")
contents))
(defun org-element-sub/superscript-successor (limit)
- "Search for the next sub/superscript and return beginning
-position.
+ "Search for the next sub/superscript object.
LIMIT bounds the search.
@@ -2100,7 +2273,9 @@ (defun org-element-sub/superscript-successor (limit)
(cons (if (string= (match-string 2) "_") 'subscript 'superscript)
(match-beginning 2)))))
+
;;;; Superscript
+
(defun org-element-superscript-parser ()
"Parse superscript at point.
@@ -2121,46 +2296,44 @@ (defun org-element-superscript-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'superscript
- `(:begin ,begin
- :end ,end
- :use-brackets-p ,bracketsp
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :post-blank ,post-blank)))))
+ `(superscript
+ (:begin ,begin
+ :end ,end
+ :use-brackets-p ,bracketsp
+ :contents-begin ,contents-begin
+ :contents-end ,contents-end
+ :post-blank ,post-blank)))))
(defun org-element-superscript-interpreter (superscript contents)
"Interpret SUPERSCRIPT object as Org syntax.
CONTENTS is the contents of the object."
(format
- (if (org-element-get-property :use-brackets-p superscript) "^{%s}" "^%s")
+ (if (org-element-property :use-brackets-p superscript) "^{%s}" "^%s")
contents))
+
;;;; Target
+
(defun org-element-target-parser ()
"Parse target at point.
Return a list whose car is `target' and cdr a plist with
-`:begin', `:end', `:contents-begin', `:contents-end', `raw-value'
-and `:post-blank' as keywords.
+`:begin', `:end', `:contents-begin', `:contents-end', `value' and
+`:post-blank' as keywords.
Assume point is at the target."
(save-excursion
(looking-at org-target-regexp)
(let ((begin (point))
- (contents-begin (match-beginning 1))
- (contents-end (match-end 1))
- (raw-value (org-match-string-no-properties 1))
+ (value (org-match-string-no-properties 1))
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'target
- `(:begin ,begin
- :end ,end
- :contents-begin ,contents-begin
- :contents-end ,contents-end
- :raw-value ,raw-value
- :post-blank ,post-blank)))))
+ `(target
+ (:begin ,begin
+ :end ,end
+ :value ,value
+ :post-blank ,post-blank)))))
(defun org-element-target-interpreter (target contents)
"Interpret TARGET object as Org syntax.
@@ -2168,7 +2341,7 @@ (defun org-element-target-interpreter (target contents)
(concat ""))
(defun org-element-target-successor (limit)
- "Search for the next target and return position.
+ "Search for the next target object.
LIMIT bounds the search.
@@ -2178,7 +2351,9 @@ (defun org-element-target-successor (limit)
(when (re-search-forward org-target-regexp limit t)
(cons 'target (match-beginning 0)))))
+
;;;; Time-stamp
+
(defun org-element-time-stamp-parser ()
"Parse time stamp at point.
@@ -2215,26 +2390,26 @@ (defun org-element-time-stamp-parser ()
(post-blank (progn (goto-char (match-end 0))
(skip-chars-forward " \t")))
(end (point)))
- (list 'time-stamp
- `(:appt-type ,appt-type
- :type ,type
- :value ,value
- :begin ,begin
- :end ,end
- :post-blank ,post-blank)))))
+ `(time-stamp
+ (:appt-type ,appt-type
+ :type ,type
+ :value ,value
+ :begin ,begin
+ :end ,end
+ :post-blank ,post-blank)))))
(defun org-element-time-stamp-interpreter (time-stamp contents)
"Interpret TIME-STAMP object as Org syntax.
CONTENTS is nil."
(concat
- (case (org-element-get-property :appt-type time-stamp)
+ (case (org-element-property :appt-type time-stamp)
(closed (concat org-closed-string " "))
(deadline (concat org-deadline-string " "))
(scheduled (concat org-scheduled-string " ")))
- (org-element-get-property :value time-stamp)))
+ (org-element-property :value time-stamp)))
(defun org-element-time-stamp-successor (limit)
- "Search for the next time-stamp and return position.
+ "Search for the next time-stamp object.
LIMIT bounds the search.
@@ -2252,7 +2427,9 @@ (defun org-element-time-stamp-successor (limit)
limit t)
(cons 'time-stamp (match-beginning 0)))))
+
;;;; Verbatim
+
(defun org-element-verbatim-parser ()
"Parse verbatim object at point.
@@ -2269,18 +2446,18 @@ (defun org-element-verbatim-parser ()
(post-blank (progn (goto-char (match-end 2))
(skip-chars-forward " \t")))
(end (point)))
- (list 'verbatim
- `(:marker ,marker
- :begin ,begin
- :end ,end
- :value ,value
- :post-blank ,post-blank)))))
+ `(verbatim
+ (:marker ,marker
+ :begin ,begin
+ :end ,end
+ :value ,value
+ :post-blank ,post-blank)))))
(defun org-element-verbatim-interpreter (verbatim contents)
"Interpret VERBATIM object as Org syntax.
CONTENTS is nil."
- (let ((marker (org-element-get-property :marker verbatim))
- (value (org-element-get-property :value verbatim)))
+ (let ((marker (org-element-property :marker verbatim))
+ (value (org-element-property :value verbatim)))
(concat marker value marker)))
@@ -2316,12 +2493,13 @@ (defconst org-element-all-elements
export-block fixed-width footnote-definition headline
horizontal-rule inlinetask item keyword latex-environment
babel-call paragraph plain-list property-drawer quote-block
- quote-section special-block src-block table verse-block)
- "Complete list of elements.")
+ quote-section section special-block src-block table
+ verse-block)
+ "Complete list of element types.")
(defconst org-element-greater-elements
'(center-block drawer dynamic-block footnote-definition headline inlinetask
- item plain-list quote-block special-block)
+ item plain-list quote-block section special-block)
"List of recursive element types aka Greater Elements.")
(defconst org-element-all-successors
@@ -2340,8 +2518,15 @@ (defconst org-element-object-successor-alist
Sharing the same successor comes handy when, for example, the
regexp matching one object can also match the other object.")
+(defconst org-element-all-objects
+ '(emphasis entity export-snippet footnote-reference inline-babel-call
+ inline-src-block line-break latex-fragment link macro radio-target
+ statistics-cookie subscript superscript target time-stamp
+ verbatim)
+ "Complete list of object types.")
+
(defconst org-element-recursive-objects
- '(emphasis link subscript superscript target radio-target)
+ '(emphasis link macro subscript superscript radio-target)
"List of recursive object types.")
(defconst org-element-non-recursive-block-alist
@@ -2350,7 +2535,7 @@ (defconst org-element-non-recursive-block-alist
("docbook" . export-block)
("example" . example-block)
("html" . export-block)
- ("latex" . latex-block)
+ ("latex" . export-block)
("odt" . export-block)
("src" . src-block)
("verse" . verse-block))
@@ -2389,7 +2574,7 @@ (defconst org-element-parsed-keywords '("author" "caption" "title")
This list is checked after translations have been applied. See
`org-element-keyword-translation-alist'.")
-(defconst org-element-dual-keywords '("results")
+(defconst org-element-dual-keywords '("caption" "results")
"List of keywords which can have a secondary value.
In Org syntax, they can be written with optional square brackets
@@ -2402,19 +2587,19 @@ (defconst org-element-dual-keywords '("results")
`org-element-keyword-translation-alist'.")
(defconst org-element-object-restrictions
- '((emphasis entity export-snippet inline-babel-call inline-src-block
+ '((emphasis entity export-snippet inline-babel-call inline-src-block link
radio-target sub/superscript target text-markup time-stamp)
(link entity export-snippet inline-babel-call inline-src-block
- latex-fragment sub/superscript text-markup)
+ latex-fragment link sub/superscript text-markup)
+ (macro macro)
(radio-target entity export-snippet latex-fragment sub/superscript)
(subscript entity export-snippet inline-babel-call inline-src-block
latex-fragment sub/superscript text-markup)
(superscript entity export-snippet inline-babel-call inline-src-block
- latex-fragment sub/superscript text-markup)
- (target entity export-snippet latex-fragment sub/superscript text-markup))
+ latex-fragment sub/superscript text-markup))
"Alist of recursive objects restrictions.
-Car is a recursive object type and cdr is a list of successors
+CAR is a recursive object type and CDR is a list of successors
that will be called within an object of such type.
For example, in a `radio-target' object, one can only find
@@ -2422,239 +2607,206 @@ (defconst org-element-object-restrictions
superscript.")
(defconst org-element-string-restrictions
- '((headline entity inline-babel-call latex-fragment link macro radio-target
- statistics-cookie sub/superscript text-markup time-stamp)
- (inlinetask entity inline-babel-call latex-fragment link macro radio-target
- sub/superscript text-markup time-stamp)
+ '((footnote-reference entity export-snippet footnote-reference
+ inline-babel-call inline-src-block latex-fragment
+ line-break link macro radio-target sub/superscript
+ target text-markup time-stamp)
+ (headline entity inline-babel-call inline-src-block latex-fragment link
+ macro radio-target statistics-cookie sub/superscript text-markup
+ time-stamp)
+ (inlinetask entity inline-babel-call inline-src-block latex-fragment link
+ macro radio-target sub/superscript text-markup time-stamp)
(item entity inline-babel-call latex-fragment macro radio-target
- sub/superscript target verbatim)
+ sub/superscript target text-markup)
(keyword entity latex-fragment macro sub/superscript text-markup)
- (table entity latex-fragment macro text-markup)
- (verse entity footnote-reference inline-babel-call inline-src-block
- latex-fragment line-break link macro radio-target sub/superscript
- target text-markup time-stamp))
+ (table entity latex-fragment macro target text-markup)
+ (verse-block entity footnote-reference inline-babel-call inline-src-block
+ latex-fragment line-break link macro radio-target
+ sub/superscript target text-markup time-stamp))
"Alist of secondary strings restrictions.
When parsed, some elements have a secondary string which could
contain various objects (i.e. headline's name, or table's cells).
-For association, the car is the element type, and the cdr a list
-of successors that will be called in that secondary string.
+For association, CAR is the element type, and CDR a list of
+successors that will be called in that secondary string.
Note: `keyword' secondary string type only applies to keywords
matching `org-element-parsed-keywords'.")
+(defconst org-element-secondary-value-alist
+ '((headline . :title)
+ (inlinetask . :title)
+ (item . :tag)
+ (footnote-reference . :inline-definition)
+ (verse-block . :value))
+ "Alist between element types and location of secondary value.
+Only elements with a secondary value available at parse time are
+considered here. This is used internally by `org-element-map',
+which will look into the secondary strings of an element only if
+its type is listed here.")
+
\f
;;; Accessors
;;
-;; Provide two accessors: `org-element-get-property' and
-;; `org-element-get-contents'.
-(defun org-element-get-property (property element)
+;; Provide three accessors: `org-element-type', `org-element-property'
+;; and `org-element-contents'.
+
+(defun org-element-type (element)
+ "Return type of element ELEMENT.
+
+The function returns the type of the element or object provided.
+It can also return the following special value:
+ `plain-text' for a string
+ `org-data' for a complete document
+ nil in any other case."
+ (cond
+ ((not (consp element)) (and (stringp element) 'plain-text))
+ ((symbolp (car element)) (car element))))
+
+(defun org-element-property (property element)
"Extract the value from the PROPERTY of an ELEMENT."
(plist-get (nth 1 element) property))
-(defun org-element-get-contents (element)
+(defun org-element-contents (element)
"Extract contents from an ELEMENT."
(nthcdr 2 element))
\f
-;; Obtaining The Smallest Element Containing Point
-
-;; `org-element-at-point' is the core function of this section. It
-;; returns the Lisp representation of the element at point. It uses
-;; `org-element-guess-type' and `org-element-skip-keywords' as helper
-;; functions.
-
-;; When point is at an item, there is no automatic way to determine if
-;; the function should return the `plain-list' element, or the
-;; corresponding `item' element. By default, `org-element-at-point'
-;; works at the `plain-list' level. But, by providing an optional
-;; argument, one can make it switch to the `item' level.
-(defconst org-element--affiliated-re
- (format "[ \t]*#\\+\\(%s\\):"
- (mapconcat
- (lambda (keyword)
- (if (member keyword org-element-dual-keywords)
- (format "\\(%s\\)\\(?:\\[\\(.*?\\)\\]\\)?"
- (regexp-quote keyword))
- (regexp-quote keyword)))
- org-element-affiliated-keywords "\\|"))
- "Regexp matching any affiliated keyword.
-
-Keyword name is put in match group 1. Moreover, if keyword
-belongs to `org-element-dual-keywords', put the dual value in
-match group 2.
-
-Don't modify it, set `org-element--affiliated-keywords' instead.")
-
-(defun org-element-at-point (&optional toggle-item structure)
- "Determine closest element around point.
-
-Return value is a list \(TYPE PROPS\) where TYPE is the type of
-the element and PROPS a plist of properties associated to the
+;;; Parsing Element Starting At Point
+
+;; `org-element-current-element' is the core function of this section.
+;; It returns the Lisp representation of the element starting at
+;; point. It uses `org-element--element-block-re' for quick access to
+;; a common regexp.
+
+(defconst org-element--element-block-re
+ (format "[ \t]*#\\+begin_\\(%s\\)\\(?: \\|$\\)"
+ (mapconcat
+ 'regexp-quote
+ (mapcar 'car org-element-non-recursive-block-alist) "\\|"))
+ "Regexp matching the beginning of a non-recursive block type.
+Used internally by `org-element-current-element'. Do not modify
+it directly, set `org-element-recursive-block-alist' instead.")
+
+(defun org-element-current-element (&optional special structure)
+ "Parse the element starting at point.
+
+Return value is a list like (TYPE PROPS) where TYPE is the type
+of the element and PROPS a plist of properties associated to the
element.
Possible types are defined in `org-element-all-elements'.
-If optional argument TOGGLE-ITEM is non-nil, parse item wise
+Optional argument SPECIAL, when non-nil, can be either `item',
+`section' or `quote-section'. `item' allows to parse item wise
instead of plain-list wise, using STRUCTURE as the current list
-structure.
+structure. `section' (resp. `quote-section') will try to parse
+a section (resp. a quote section) before anything else.
+
+If STRUCTURE isn't provided but SPECIAL is set to `item', it will
+be computed.
-If STRUCTURE isn't provided but TOGGLE-ITEM is non-nil, it will
-be computed."
+Unlike to `org-element-at-point', this function assumes point is
+always at the beginning of the element it has to parse. As such,
+it is quicker than its counterpart, albeit more restrictive."
(save-excursion
(beginning-of-line)
- ;; Move before any blank line.
- (when (looking-at "[ \t]*$")
- (skip-chars-backward " \r\t\n")
- (beginning-of-line))
+ ;; If point is at an affiliated keyword, try moving to the
+ ;; beginning of the associated element. If none is found, the
+ ;; keyword is orphaned and will be treated as plain text.
+ (when (looking-at org-element--affiliated-re)
+ (let ((opoint (point)))
+ (while (looking-at org-element--affiliated-re) (forward-line))
+ (when (looking-at "[ \t]*$") (goto-char opoint))))
(let ((case-fold-search t))
- ;; Check if point is at an affiliated keyword. In that case,
- ;; try moving to the beginning of the associated element. If
- ;; the keyword is orphaned, treat it as plain text.
- (when (looking-at org-element--affiliated-re)
- (let ((opoint (point)))
- (while (looking-at org-element--affiliated-re) (forward-line))
- (when (looking-at "[ \t]*$") (goto-char opoint))))
- (let ((type (org-element-guess-type)))
- (cond
- ;; Guessing element type on the current line is impossible:
- ;; try to find the beginning of the current element to get
- ;; more information.
- ((not type)
- (let ((search-origin (point))
- (opoint-in-item-p (org-in-item-p))
- (par-found-p
- (progn
- (end-of-line)
- (re-search-backward org-element-paragraph-separate nil 'm))))
- (cond
- ;; Unable to find a paragraph delimiter above: we're at
- ;; bob and looking at a paragraph.
- ((not par-found-p) (org-element-paragraph-parser))
- ;; Trying to find element's beginning set point back to
- ;; its original position. There's something peculiar on
- ;; this line that prevents parsing, probably an
- ;; ill-formed keyword or an undefined drawer name. Parse
- ;; it as plain text anyway.
- ((< search-origin (point-at-eol)) (org-element-paragraph-parser))
- ;; Original point wasn't in a list but previous paragraph
- ;; is. It means that either point was inside some block,
- ;; or current list was ended without using a blank line.
- ;; In the last case, paragraph really starts at list end.
- ((let (item)
- (and (not opoint-in-item-p)
- (not (looking-at "[ \t]*#\\+begin"))
- (setq item (org-in-item-p))
- (let ((struct (save-excursion (goto-char item)
- (org-list-struct))))
- (goto-char (org-list-get-bottom-point struct))
- (org-skip-whitespace)
- (beginning-of-line)
- (org-element-paragraph-parser)))))
- ((org-footnote-at-definition-p)
- (org-element-footnote-definition-parser))
- ((and opoint-in-item-p (org-at-item-p) (= opoint-in-item-p (point)))
- (if toggle-item
- (org-element-item-parser (or structure (org-list-struct)))
- (org-element-plain-list-parser (or structure (org-list-struct)))))
- ;; In any other case, the paragraph started the line
- ;; below.
- (t (forward-line) (org-element-paragraph-parser)))))
- ((eq type 'plain-list)
- (if toggle-item
- (org-element-item-parser (or structure (org-list-struct)))
- (org-element-plain-list-parser (or structure (org-list-struct)))))
- ;; Straightforward case: call the appropriate parser.
- (t (funcall (intern (format "org-element-%s-parser" type)))))))))
-
-
-;; It is obvious to tell if point is in most elements, either by
-;; looking for a specific regexp in the current line, or by using
-;; already implemented functions. This is the goal of
-;; `org-element-guess-type'.
-(defconst org-element--element-block-types
- (mapcar 'car org-element-non-recursive-block-alist)
- "List of non-recursive block types, as strings.
-Used internally by `org-element-guess-type'. Do not modify it
-directly, set `org-element-non-recursive-block-alist' instead.")
-
-(defun org-element-guess-type ()
- "Return the type of element at point, or nil if undetermined.
-This function may move point to an appropriate position for
-parsing. Used internally by `org-element-at-point'."
- ;; Beware: Order matters for some cases in that function.
- (beginning-of-line)
- (let ((case-fold-search t))
- (cond
- ((org-with-limited-levels (org-at-heading-p)) 'headline)
- ((let ((headline (ignore-errors (nth 4 (org-heading-components)))))
- (and headline
- (let (case-fold-search)
- (string-match (format "^%s\\(?: \\|$\\)" org-quote-string)
- headline))))
- 'quote-section)
- ;; Non-recursive block.
- ((let ((type (org-in-block-p org-element--element-block-types)))
- (and type (cdr (assoc type org-element-non-recursive-block-alist)))))
- ((org-at-heading-p) 'inlinetask)
- ((org-between-regexps-p
- "^[ \t]*\\\\begin{" "^[ \t]*\\\\end{[^}]*}[ \t]*") 'latex-environment)
- ;; Property drawer. Almost `org-at-property-p', but allow drawer
- ;; boundaries.
- ((org-with-wide-buffer
- (and (not (org-before-first-heading-p))
- (let ((pblock (org-get-property-block)))
- (and pblock
- (<= (point) (cdr pblock))
- (>= (point-at-eol) (1- (car pblock)))))))
- 'property-drawer)
- ;; Recursive block. If the block isn't complete, parse the
- ;; current part as a paragraph.
- ((looking-at "[ \t]*#\\+\\(begin\\|end\\)_\\([-A-Za-z0-9]+\\)\\(?:$\\|\\s-\\)")
- (let ((type (downcase (match-string 2))))
- (cond
- ((not (org-in-block-p (list type))) 'paragraph)
- ((string= type "center") 'center-block)
- ((string= type "quote") 'quote-block)
- (t 'special-block))))
- ;; Regular drawers must be tested after property drawer as both
- ;; elements share the same ending regexp.
- ((or (looking-at org-drawer-regexp) (looking-at "[ \t]*:END:[ \t]*$"))
- (let ((completep (org-between-regexps-p
- org-drawer-regexp "^[ \t]*:END:[ \t]*$")))
- (if (not completep)
- 'paragraph
- (goto-char (car completep)) 'drawer)))
- ((looking-at "[ \t]*:\\( \\|$\\)") 'fixed-width)
- ;; Babel calls must be tested before general keywords as they are
- ;; a subset of them.
- ((looking-at org-babel-block-lob-one-liner-regexp) 'babel-call)
- ((looking-at org-footnote-definition-re) 'footnote-definition)
- ((looking-at "[ \t]*#\\+\\([a-z]+\\(:?_[a-z]+\\)*\\):")
- (if (member (downcase (match-string 1)) org-element-affiliated-keywords)
- 'paragraph
- 'keyword))
- ;; Dynamic block: simplify regexp used for match. If it isn't
- ;; complete, parse the current part as a paragraph.
- ((looking-at "[ \t]*#\\+\\(begin\\end\\):\\(?:\\s-\\|$\\)")
- (let ((completep (org-between-regexps-p
- "^[ \t]*#\\+begin:\\(?:\\s-\\|$\\)"
- "^[ \t]*#\\+end:\\(?:\\s-\\|$\\)")))
- (if (not completep)
- 'paragraph
- (goto-char (car completep)) 'dynamic-block)))
- ((looking-at "\\(#\\|[ \t]*#\\+\\( \\|$\\)\\)") 'comment)
- ((looking-at "[ \t]*-\\{5,\\}[ \t]*$") 'horizontal-rule)
- ((org-at-table-p t) 'table)
- ((looking-at "[ \t]*#\\+tblfm:")
- (forward-line -1)
- ;; A TBLFM line separated from any table is just plain text.
- (if (org-at-table-p)
- 'table
- (forward-line) 'paragraph))
- ((looking-at (org-item-re)) 'plain-list))))
+ (cond
+ ;; Headline.
+ ((org-with-limited-levels (org-at-heading-p))
+ (org-element-headline-parser))
+ ;; Quote section.
+ ((eq special 'quote-section) (org-element-quote-section-parser))
+ ;; Section.
+ ((eq special 'section) (org-element-section-parser))
+ ;; Non-recursive block.
+ ((when (looking-at org-element--element-block-re)
+ (let ((type (downcase (match-string 1))))
+ (if (save-excursion
+ (re-search-forward
+ (format "[ \t]*#\\+end_%s\\(?: \\|$\\)" type) nil t))
+ ;; Build appropriate parser.
+ (funcall
+ (intern
+ (format "org-element-%s-parser"
+ (cdr (assoc type
+ org-element-non-recursive-block-alist)))))
+ (org-element-paragraph-parser)))))
+ ;; Inlinetask.
+ ((org-at-heading-p) (org-element-inlinetask-parser))
+ ;; LaTeX Environment or paragraph if incomplete.
+ ((looking-at "^[ \t]*\\\\begin{")
+ (if (save-excursion
+ (re-search-forward "^[ \t]*\\\\end{[^}]*}[ \t]*" nil t))
+ (org-element-latex-environment-parser)
+ (org-element-paragraph-parser)))
+ ;; Property drawer.
+ ((looking-at org-property-start-re)
+ (if (save-excursion (re-search-forward org-property-end-re nil t))
+ (org-element-property-drawer-parser)
+ (org-element-paragraph-parser)))
+ ;; Recursive block, or paragraph if incomplete.
+ ((looking-at "[ \t]*#\\+begin_\\([-A-Za-z0-9]+\\)\\(?: \\|$\\)")
+ (let ((type (downcase (match-string 1))))
+ (cond
+ ((not (save-excursion
+ (re-search-forward
+ (format "[ \t]*#\\+end_%s\\(?: \\|$\\)" type) nil t)))
+ (org-element-paragraph-parser))
+ ((string= type "center") (org-element-center-block-parser))
+ ((string= type "quote") (org-element-quote-block-parser))
+ (t (org-element-special-block-parser)))))
+ ;; Drawer.
+ ((looking-at org-drawer-regexp)
+ (if (save-excursion (re-search-forward "^[ \t]*:END:[ \t]*$" nil t))
+ (org-element-drawer-parser)
+ (org-element-paragraph-parser)))
+ ((looking-at "[ \t]*:\\( \\|$\\)") (org-element-fixed-width-parser))
+ ;; Babel call.
+ ((looking-at org-babel-block-lob-one-liner-regexp)
+ (org-element-babel-call-parser))
+ ;; Keyword, or paragraph if at an affiliated keyword.
+ ((looking-at "[ \t]*#\\+\\([a-z]+\\(:?_[a-z]+\\)*\\):")
+ (let ((key (downcase (match-string 1))))
+ (if (or (string= key "tblfm")
+ (member key org-element-affiliated-keywords))
+ (org-element-paragraph-parser)
+ (org-element-keyword-parser))))
+ ;; Footnote definition.
+ ((looking-at org-footnote-definition-re)
+ (org-element-footnote-definition-parser))
+ ;; Dynamic block or paragraph if incomplete.
+ ((looking-at "[ \t]*#\\+begin:\\(?: \\|$\\)")
+ (if (save-excursion
+ (re-search-forward "^[ \t]*#\\+end:\\(?: \\|$\\)" nil t))
+ (org-element-dynamic-block-parser)
+ (org-element-paragraph-parser)))
+ ;; Comment.
+ ((looking-at "\\(#\\|[ \t]*#\\+\\(?: \\|$\\)\\)")
+ (org-element-comment-parser))
+ ;; Horizontal rule.
+ ((looking-at "[ \t]*-\\{5,\\}[ \t]*$")
+ (org-element-horizontal-rule-parser))
+ ;; Table.
+ ((org-at-table-p t) (org-element-table-parser))
+ ;; List or item.
+ ((looking-at (org-item-re))
+ (if (eq special 'item)
+ (org-element-item-parser (or structure (org-list-struct)))
+ (org-element-plain-list-parser (or structure (org-list-struct)))))
+ ;; Default element: Paragraph.
+ (t (org-element-paragraph-parser))))))
+
;; Most elements can have affiliated keywords. When looking for an
;; element beginning, we want to move before them, as they belong to
@@ -2683,6 +2835,24 @@ (defun org-element-guess-type ()
;; optional square brackets as the secondary one.
;; A keyword may belong to more than one category.
+
+(defconst org-element--affiliated-re
+ (format "[ \t]*#\\+\\(%s\\):"
+ (mapconcat
+ (lambda (keyword)
+ (if (member keyword org-element-dual-keywords)
+ (format "\\(%s\\)\\(?:\\[\\(.*\\)\\]\\)?"
+ (regexp-quote keyword))
+ (regexp-quote keyword)))
+ org-element-affiliated-keywords "\\|"))
+ "Regexp matching any affiliated keyword.
+
+Keyword name is put in match group 1. Moreover, if keyword
+belongs to `org-element-dual-keywords', put the dual value in
+match group 2.
+
+Don't modify it, set `org-element-affiliated-keywords' instead.")
+
(defun org-element-collect-affiliated-keywords (&optional key-re trans-list
consed parsed duals)
"Collect affiliated keywords before point.
@@ -2708,8 +2878,8 @@ (defun org-element-collect-affiliated-keywords (&optional key-re trans-list
DUALS is a list of strings. Any keyword member of this list can
have two parts: one mandatory and one optional. Its value is
a cons cell whose car is the former, and the cdr the latter. If
-a keyword is a member of both PARSED and DUALS, only the primary
-part will be parsed. It defaults to `org-element-dual-keywords'.
+a keyword is a member of both PARSED and DUALS, both values will
+be parsed. It defaults to `org-element-dual-keywords'.
Return a list whose car is the position at the first of them and
cdr a plist of keywords and values."
@@ -2720,6 +2890,9 @@ (defun org-element-collect-affiliated-keywords (&optional key-re trans-list
(consed (or consed org-element-multiple-keywords))
(parsed (or parsed org-element-parsed-keywords))
(duals (or duals org-element-dual-keywords))
+ ;; RESTRICT is the list of objects allowed in parsed
+ ;; keywords value.
+ (restrict (cdr (assq 'keyword org-element-string-restrictions)))
output)
(unless (bobp)
(while (and (not (bobp))
@@ -2728,21 +2901,27 @@ (defun org-element-collect-affiliated-keywords (&optional key-re trans-list
;; Apply translation to RAW-KWD. From there, KWD is
;; the official keyword.
(kwd (or (cdr (assoc raw-kwd trans-list)) raw-kwd))
- ;; If KWD is a dual keyword, find it secondary value.
- (dual-value (and (member kwd duals)
- (org-match-string-no-properties 3)))
;; Find main value for any keyword.
- (value (org-trim (buffer-substring-no-properties
- (match-end 0) (point-at-eol))))
+ (value
+ (save-match-data
+ (org-trim
+ (buffer-substring-no-properties
+ (match-end 0) (point-at-eol)))))
+ ;; If KWD is a dual keyword, find its secondary
+ ;; value. Maybe parse it.
+ (dual-value
+ (and (member kwd duals)
+ (let ((sec (org-match-string-no-properties 3)))
+ (if (or (not sec) (not (member kwd parsed))) sec
+ (org-element-parse-secondary-string sec restrict)))))
;; Attribute a property name to KWD.
(kwd-sym (and kwd (intern (concat ":" kwd)))))
;; Now set final shape for VALUE.
(when (member kwd parsed)
- (setq value
- (org-element-parse-secondary-string
- value
- (cdr (assq 'keyword org-element-string-restrictions)))))
- (when (member kwd duals) (setq value (cons value dual-value)))
+ (setq value (org-element-parse-secondary-string value restrict)))
+ (when (member kwd duals)
+ ;; VALUE is mandatory. Set it to nil if there is none.
+ (setq value (and value (cons value dual-value))))
(when (member kwd consed)
(setq value (cons value (plist-get output kwd-sym))))
;; Eventually store the new value in OUTPUT.
@@ -2763,9 +2942,8 @@ (defun org-element-collect-affiliated-keywords (&optional key-re trans-list
;; The (almost) almighty `org-element-map' allows to apply a function
;; on elements or objects matching some type, and accumulate the
;; resulting values. In an export situation, it also skips unneeded
-;; parts of the parse tree, transparently walks into included files,
-;; and maintain a list of local properties (i.e. those inherited from
-;; parent headlines) for function's consumption.
+;; parts of the parse tree.
+
(defun org-element-parse-buffer (&optional granularity visible-only)
"Recursively parse the buffer and return structure.
If narrowing is in effect, only parse the visible part of the
@@ -2790,7 +2968,9 @@ (defun org-element-parse-buffer (&optional granularity visible-only)
(nconc (list 'org-data nil)
(org-element-parse-elements
(point-at-bol) (point-max)
- nil nil granularity visible-only nil))))
+ ;; Start is section mode so text before the first headline
+ ;; belongs to a section.
+ 'section nil granularity visible-only nil))))
(defun org-element-parse-secondary-string (string restriction &optional buffer)
"Recursively parse objects in STRING and return structure.
@@ -2807,27 +2987,31 @@ (defun org-element-parse-secondary-string (string restriction &optional buffer)
(insert string)
(org-element-parse-objects (point-min) (point-max) nil restriction)))
-(defun org-element-map (data types fun &optional info first-match)
+(defun org-element-map (data types fun &optional info first-match no-recursion)
"Map a function on selected elements or objects.
DATA is the parsed tree, as returned by, i.e,
`org-element-parse-buffer'. TYPES is a symbol or list of symbols
of elements or objects types. FUN is the function called on the
-matching element or object. It must accept two arguments: the
-element or object itself and a plist holding contextual
-information.
+matching element or object. It must accept one arguments: the
+element or object itself.
When optional argument INFO is non-nil, it should be a plist
holding export options. In that case, parts of the parse tree
-not exportable according to that property list will be skipped
-and files included through a keyword will be visited.
+not exportable according to that property list will be skipped.
When optional argument FIRST-MATCH is non-nil, stop at the first
match for which FUN doesn't return nil, and return that value.
-Nil values returned from FUN are ignored in the result."
- ;; Ensure TYPES is a list, even of one element.
+Optional argument NO-RECURSION is a symbol or a list of symbols
+representing elements or objects types. `org-element-map' won't
+enter any recursive element or object whose type belongs to that
+list. Though, FUN can still be applied on them.
+
+Nil values returned from FUN do not appear in the results."
+ ;; Ensure TYPES and NO-RECURSION are a list, even of one element.
(unless (listp types) (setq types (list types)))
+ (unless (listp no-recursion) (setq no-recursion (list no-recursion)))
;; Recursion depth is determined by --CATEGORY.
(let* ((--category
(cond
@@ -2838,117 +3022,89 @@ (defun org-element-map (data types fun &optional info first-match)
always (memq type org-element-all-elements))
'elements)
(t 'objects)))
- walk-tree ; For byte-compiler
+ ;; --RESTRICTS is a list of element types whose secondary
+ ;; string could possibly contain an object with a type among
+ ;; TYPES.
+ (--restricts
+ (and (eq --category 'objects)
+ (loop for el in org-element-secondary-value-alist
+ when
+ (loop for o in types
+ thereis
+ (memq o (cdr
+ (assq (car el)
+ org-element-string-restrictions))))
+ collect (car el))))
--acc
- (accumulate-maybe
- (function
- (lambda (--type types fun --blob --local)
- ;; Check if TYPE is matching among TYPES. If so, apply
- ;; FUN to --BLOB and accumulate return value
- ;; into --ACC. --LOCAL is the communication channel.
- (when (memq --type types)
- (let ((result (funcall fun --blob --local)))
- (cond ((not result))
- (first-match (throw 'first-match result))
- (t (push result --acc))))))))
- (walk-tree
+ (--walk-tree
(function
- (lambda (--data --local)
- ;; Recursively walk DATA. --LOCAL, if non-nil, is
+ (lambda (--data)
+ ;; Recursively walk DATA. INFO, if non-nil, is
;; a plist holding contextual information.
(mapc
(lambda (--blob)
- (let ((--type (if (stringp --blob) 'plain-text (car --blob))))
- ;; Determine if a recursion into --BLOB is
- ;; possible and allowed.
- (cond
- ;; Element or object not exportable.
- ((and info (org-export-skip-p --blob info)))
- ;; Archived headline: Maybe apply fun on it, but
- ;; skip contents.
- ((and info
- (eq --type 'headline)
- (eq (plist-get info :with-archived-trees) 'headline)
- (org-element-get-property :archivedp --blob))
- (funcall accumulate-maybe --type types fun --blob --local))
- ;; At an include keyword: apply mapping to its
- ;; contents.
- ((and --local
- (eq --type 'keyword)
- (string=
- (downcase (org-element-get-property :key --blob))
- "include"))
- (funcall accumulate-maybe --type types fun --blob --local)
- (let* ((--data
- (org-export-parse-included-file --blob --local))
- (--value (org-element-get-property :value --blob))
- (--file
- (and (string-match "^\"\\(\\S-+\\)\"" --value)
- (match-string 1 --value))))
+ (unless (and info (member --blob (plist-get info :ignore-list)))
+ (let ((--type (org-element-type --blob)))
+ ;; Check if TYPE is matching among TYPES. If so,
+ ;; apply FUN to --BLOB and accumulate return value
+ ;; into --ACC (or exit if FIRST-MATCH is non-nil).
+ (when (memq --type types)
+ (let ((result (funcall fun --blob)))
+ (cond ((not result))
+ (first-match (throw 'first-match result))
+ (t (push result --acc)))))
+ ;; If --BLOB has a secondary string that can
+ ;; contain objects with their type among TYPES,
+ ;; look into that string.
+ (when (memq --type --restricts)
(funcall
- walk-tree --data
- (org-combine-plists
- --local
- ;; Store full path of already included files
- ;; to avoid recursive file inclusion.
- `(:included-files
- ,(cons (expand-file-name --file)
- (plist-get --local :included-files))
- ;; Ensure that a top-level headline in the
- ;; included file becomes a direct child of
- ;; the current headline in the buffer.
- :headline-offset
- ,(- (+ (plist-get
- (plist-get --local :inherited-properties)
- :level)
- (or (plist-get --local :headline-offset) 0))
- (1- (org-export-get-min-level
- --data --local))))))))
- ;; Limiting recursion to greater elements, and --BLOB
- ;; isn't one.
- ((and (eq --category 'greater-elements)
- (not (memq --type org-element-greater-elements)))
- (funcall accumulate-maybe --type types fun --blob --local))
- ;; Limiting recursion to elements, and --BLOB only
- ;; contains objects.
- ((and (eq --category 'elements) (eq --type 'paragraph)))
- ;; No limitation on recursion, but --BLOB hasn't
- ;; got a recursive type.
- ((and (eq --category 'objects)
- (not (or (eq --type 'paragraph)
- (memq --type org-element-greater-elements)
- (memq --type org-element-recursive-objects))))
- (funcall accumulate-maybe --type types fun --blob --local))
- ;; Recursion is possible and allowed: Update local
- ;; information and move into --BLOB.
- (t (funcall accumulate-maybe --type types fun --blob --local)
- (funcall
- walk-tree --blob
- (and info (org-export-update-info --blob --local t)))))))
- (org-element-get-contents --data))))))
+ --walk-tree
+ `(org-data
+ nil
+ ,@(org-element-property
+ (cdr (assq --type org-element-secondary-value-alist))
+ --blob))))
+ ;; Now determine if a recursion into --BLOB is
+ ;; possible. If so, do it.
+ (unless (memq --type no-recursion)
+ (when (or (and (memq --type org-element-greater-elements)
+ (not (eq --category 'greater-elements)))
+ (and (memq --type org-element-all-elements)
+ (not (eq --category 'elements)))
+ (memq --type org-element-recursive-objects))
+ (funcall --walk-tree --blob))))))
+ (org-element-contents --data))))))
(catch 'first-match
- (funcall walk-tree data info)
+ (funcall --walk-tree data)
;; Return value in a proper order.
(reverse --acc))))
-;; The following functions are internal parts of the parser. The
-;; first one, `org-element-parse-elements' acts at the element's
-;; level. The second one, `org-element-parse-objects' applies on all
-;; objects of a paragraph or a secondary string. It uses
+;; The following functions are internal parts of the parser.
+
+;; The first one, `org-element-parse-elements' acts at the element's
+;; level.
+
+;; The second one, `org-element-parse-objects' applies on all objects
+;; of a paragraph or a secondary string. It uses
;; `org-element-get-candidates' to optimize the search of the next
;; object in the buffer.
-;;
+
;; More precisely, that function looks for every allowed object type
;; first. Then, it discards failed searches, keeps further matches,
;; and searches again types matched behind point, for subsequent
;; calls. Thus, searching for a given type fails only once, and every
;; object is searched only once at top level (but sometimes more for
;; nested types).
-(defun org-element-parse-elements (beg end item structure granularity visible-only acc)
- "Parse ELEMENT with point at its beginning.
-If ITEM is non-nil, parse item wise instead of plain-list wise,
-using STRUCTURE as the current list structure.
+(defun org-element-parse-elements
+ (beg end special structure granularity visible-only acc)
+ "Parse elements between BEG and END positions.
+
+SPECIAL prioritize some elements over the others. It can set to
+`quote-section', `section' or `item', which will focus search,
+respectively, on quote sections, sections and items. Moreover,
+when value is `item', STRUCTURE will be used as the current list
+structure.
GRANULARITY determines the depth of the recursion. It can be set
to the following symbols:
@@ -2960,85 +3116,70 @@ (defun org-element-parse-elements (beg end item structure granularity visible-on
`object' or nil Parse the complete buffer.
When VISIBLE-ONLY is non-nil, don't parse contents of hidden
-greater elements.
+elements.
Elements are accumulated into ACC."
(save-excursion
- (goto-char beg)
- ;; Shortcut when parsing only headlines.
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char beg)
+ ;; When parsing only headlines, skip any text before first one.
(when (and (eq granularity 'headline) (not (org-at-heading-p)))
(org-with-limited-levels (outline-next-heading)))
;; Main loop start.
- (while (and (< (point) end) (not (eobp)))
+ (while (not (eobp))
(push
- ;; 1. If ITEM is toggled, point is at an item. Knowing that,
- ;; there's no need to go through `org-element-at-point'.
- (if item
- (let* ((element (org-element-item-parser structure))
- (cbeg (org-element-get-property :contents-begin element))
- (cend (org-element-get-property :contents-end element)))
- (goto-char (org-element-get-property :end element))
- ;; Narrow region to contents, so that item bullet don't
- ;; interfere with paragraph parsing.
- (save-restriction
- (narrow-to-region cbeg cend)
- (org-element-parse-elements
- cbeg cend nil structure granularity visible-only
- (reverse element))))
+ ;; 1. Item mode is active: point must be at an item. Parse it
+ ;; directly, skipping `org-element-current-element'.
+ (if (eq special 'item)
+ (let ((element (org-element-item-parser structure)))
+ (goto-char (org-element-property :end element))
+ (org-element-parse-elements
+ (org-element-property :contents-begin element)
+ (org-element-property :contents-end element)
+ nil structure granularity visible-only (reverse element)))
;; 2. When ITEM is nil, find current element's type and parse
;; it accordingly to its category.
- (let ((element (org-element-at-point nil structure)))
- (goto-char (org-element-get-property :end element))
+ (let* ((element (org-element-current-element special structure))
+ (type (org-element-type element)))
+ (goto-char (org-element-property :end element))
(cond
- ;; Case 1: ELEMENT is a footnote-definition. If
- ;; GRANURALITY allows parsing, use narrowing so that
- ;; footnote label don't interfere with paragraph
- ;; recognition.
- ((and (eq (car element) 'footnote-definition)
- (not (memq granularity '(headline greater-element))))
- (let ((cbeg (org-element-get-property :contents-begin element))
- (cend (org-element-get-property :contents-end element)))
- (save-restriction
- (narrow-to-region cbeg cend)
- (org-element-parse-elements
- cbeg cend nil structure granularity visible-only
- (reverse element)))))
- ;; Case 1: ELEMENT is a paragraph. Parse objects inside,
- ;; if GRANULARITY allows it.
- ((and (eq (car element) 'paragraph)
+ ;; Case 1. ELEMENT is a paragraph. Parse objects inside,
+ ;; if GRANULARITY allows it.
+ ((and (eq type 'paragraph)
(or (not granularity) (eq granularity 'object)))
(org-element-parse-objects
- (org-element-get-property :contents-begin element)
- (org-element-get-property :contents-end element)
- (reverse element)
- nil))
- ;; Case 2: ELEMENT is recursive: parse it between
- ;; `contents-begin' and `contents-end'. If it's
- ;; a plain list, also switch to item mode. Make
- ;; sure GRANULARITY allows the recursion, or
- ;; ELEMENT is an headline, in which case going
- ;; inside is mandatory, in order to get sub-level
- ;; headings. If VISIBLE-ONLY is true and element
- ;; is hidden, do not recurse into it.
- ((and (memq (car element) org-element-greater-elements)
+ (org-element-property :contents-begin element)
+ (org-element-property :contents-end element)
+ (reverse element) nil))
+ ;; Case 2. ELEMENT is recursive: parse it between
+ ;; `contents-begin' and `contents-end'. Make sure
+ ;; GRANULARITY allows the recursion, or ELEMENT is an
+ ;; headline, in which case going inside is mandatory, in
+ ;; order to get sub-level headings. If VISIBLE-ONLY is
+ ;; true and element is hidden, do not recurse into it.
+ ((and (memq type org-element-greater-elements)
(or (not granularity)
(memq granularity '(element object))
- (eq (car element) 'headline))
+ (eq type 'headline))
(not (and visible-only
- (org-element-get-property :hiddenp element))))
+ (org-element-property :hiddenp element))))
(org-element-parse-elements
- (org-element-get-property :contents-begin element)
- (org-element-get-property :contents-end element)
- (eq (car element) 'plain-list)
- (org-element-get-property :structure element)
- granularity
- visible-only
- (reverse element)))
- ;; Case 3: Else, just accumulate ELEMENT, unless
- ;; GRANULARITY is set to `headline'.
- ((not (eq granularity 'headline)) element))))
- acc)
- (org-skip-whitespace))
+ (org-element-property :contents-begin element)
+ (org-element-property :contents-end element)
+ ;; At a plain list, switch to item mode. At an
+ ;; headline, switch to section mode. Any other
+ ;; element turns off special modes.
+ (case type
+ (plain-list 'item)
+ (headline (if (org-element-property :quotedp element)
+ 'quote-section
+ 'section)))
+ (org-element-property :structure element)
+ granularity visible-only (reverse element)))
+ ;; Case 3. Else, just accumulate ELEMENT.
+ (t element))))
+ acc)))
;; Return result.
(nreverse acc)))
@@ -3066,13 +3207,16 @@ (defun org-element-parse-objects (beg end acc restriction)
(while (setq candidates (org-element-get-next-object-candidates
end restriction candidates))
(setq next-object (funcall get-next-object candidates))
- ;; 1. Text before any object.
- (let ((obj-beg (org-element-get-property :begin next-object)))
- (unless (= beg obj-beg)
- (push (buffer-substring-no-properties (point) obj-beg) acc)))
+ ;; 1. Text before any object. Untabify it.
+ (let ((obj-beg (org-element-property :begin next-object)))
+ (unless (= (point) obj-beg)
+ (push (replace-regexp-in-string
+ "\t" (make-string tab-width ? )
+ (buffer-substring-no-properties (point) obj-beg))
+ acc)))
;; 2. Object...
- (let ((obj-end (org-element-get-property :end next-object))
- (cont-beg (org-element-get-property :contents-begin next-object)))
+ (let ((obj-end (org-element-property :end next-object))
+ (cont-beg (org-element-property :contents-begin next-object)))
(push (if (and (memq (car next-object) org-element-recursive-objects)
cont-beg)
;; ... recursive. The CONT-BEG check is for
@@ -3081,7 +3225,7 @@ (defun org-element-parse-objects (beg end acc restriction)
(save-restriction
(narrow-to-region
cont-beg
- (org-element-get-property :contents-end next-object))
+ (org-element-property :contents-end next-object))
(org-element-parse-objects
(point-min) (point-max) (reverse next-object)
;; Restrict allowed objects. This is the
@@ -3090,19 +3234,20 @@ (defun org-element-parse-objects (beg end acc restriction)
(let ((new-restr
(cdr (assq (car next-object)
org-element-object-restrictions))))
- (if (not restriction)
- new-restr
- (delq nil
- (mapcar (lambda (e)
- (and (memq e restriction) e))
- new-restr))))))
+ (if (not restriction) new-restr
+ (delq nil (mapcar
+ (lambda (e) (and (memq e restriction) e))
+ new-restr))))))
;; ... not recursive.
next-object)
acc)
(goto-char obj-end)))
- ;; 3. Text after last object.
+ ;; 3. Text after last object. Untabify it.
(unless (= (point) end)
- (push (buffer-substring-no-properties (point) end) acc))
+ (push (replace-regexp-in-string
+ "\t" (make-string tab-width ? )
+ (buffer-substring-no-properties (point) end))
+ acc))
;; Result.
(nreverse acc))))
@@ -3123,13 +3268,11 @@ (defun org-element-get-next-object-candidates (limit restriction objects)
;; If no previous result, search every object type in RESTRICTION.
;; Otherwise, keep potential candidates (old objects located after
;; point) and ask to search again those which had matched before.
- (if objects
- (mapc (lambda (obj)
- (if (< (cdr obj) (point))
- (push (car obj) types-to-search)
- (push obj next-candidates)))
- objects)
- (setq types-to-search restriction))
+ (if (not objects) (setq types-to-search restriction)
+ (mapc (lambda (obj)
+ (if (< (cdr obj) (point)) (push (car obj) types-to-search)
+ (push obj next-candidates)))
+ objects))
;; Call the appropriate "get-next" function for each type to
;; search and accumulate matches.
(mapc
@@ -3160,6 +3303,7 @@ (defun org-element-get-next-object-candidates (limit restriction objects)
;;
;; Both functions rely internally on
;; `org-element-interpret--affiliated-keywords'.
+
(defun org-element-interpret-data (data &optional genealogy previous)
"Interpret a parse tree representing Org data.
@@ -3180,10 +3324,9 @@ (defun org-element-interpret-data (data &optional genealogy previous)
((equal blob "") nil)
((stringp blob) blob)
(t
- (let* ((type (car blob))
+ (let* ((type (org-element-type blob))
(interpreter
- (if (eq type 'org-data)
- 'identity
+ (if (eq type 'org-data) 'identity
(intern (format "org-element-%s-interpreter" type))))
(contents
(cond
@@ -3221,12 +3364,11 @@ (defun org-element-interpret-data (data &optional genealogy previous)
(concat
(org-element-interpret--affiliated-keywords blob)
(org-element-normalize-string results)
- (make-string (org-element-get-property :post-blank blob) 10)))
+ (make-string (org-element-property :post-blank blob) 10)))
(t (concat
results
- (make-string
- (org-element-get-property :post-blank blob) 32))))))))
- (org-element-get-contents data) ""))
+ (make-string (org-element-property :post-blank blob) 32))))))))
+ (org-element-contents data) ""))
(defun org-element-interpret-secondary (secondary)
"Interpret SECONDARY string as Org syntax.
@@ -3257,7 +3399,7 @@ (defun org-element-interpret--affiliated-keywords (element)
"\n"))))))
(mapconcat
(lambda (key)
- (let ((value (org-element-get-property (intern (concat ":" key)) element)))
+ (let ((value (org-element-property (intern (concat ":" key)) element)))
(when value
(if (member key org-element-multiple-keywords)
(mapconcat (lambda (line)
@@ -3283,6 +3425,7 @@ (defun org-element-interpret--affiliated-keywords (element)
;;
;; The second function, `org-element-normalize-contents', removes
;; global indentation from the contents of the current element.
+
(defun org-element-normalize-string (s)
"Ensure string S ends with a single newline character.
@@ -3300,63 +3443,178 @@ (defun org-element-normalize-contents (element &optional ignore-first)
ELEMENT must only contain plain text and objects.
-The following changes are applied to plain text:
- - Remove global indentation, preserving relative one.
- - Untabify it.
-
If optional argument IGNORE-FIRST is non-nil, ignore first line's
indentation to compute maximal common indentation.
-Return the normalized element."
- (nconc
- (list (car element) (nth 1 element))
- (let ((contents (org-element-get-contents element)))
- (cond
- ((and (not ignore-first) (not (stringp (car contents)))) contents)
- (t
- (catch 'exit
- ;; 1. Remove tabs from each string in CONTENTS. Get maximal
- ;; common indentation (MCI) along the way.
- (let* ((ind-list (unless ignore-first
- (list (org-get-string-indentation (car contents)))))
- (contents
- (mapcar (lambda (object)
- (if (not (stringp object))
- object
- (let ((start 0)
- (object (org-remove-tabs object)))
- (while (string-match "\n\\( *\\)" object start)
- (setq start (match-end 0))
- (push (length (match-string 1 object))
- ind-list))
- object)))
- contents))
- (mci (if ind-list
- (apply 'min ind-list)
- (throw 'exit contents))))
- ;; 2. Remove that indentation from CONTENTS. First string
- ;; must be treated differently because it's the only one
- ;; whose indentation doesn't happen after a newline
- ;; character.
- (let ((first-obj (car contents)))
- (unless (or (not (stringp first-obj)) ignore-first)
- (setq contents
- (cons (replace-regexp-in-string
- (format "\\` \\{%d\\}" mci) "" first-obj)
- (cdr contents)))))
- (mapcar (lambda (object)
- (if (not (stringp object))
- object
- (replace-regexp-in-string
- (format "\n \\{%d\\}" mci) "\n" object)))
- contents))))))))
+Return the normalized element that is element with global
+indentation removed from its contents. The function assumes that
+indentation is not done with TAB characters."
+ (let (ind-list
+ (collect-inds
+ (function
+ ;; Return list of indentations within BLOB. This is done by
+ ;; walking recursively BLOB and updating IND-LIST along the
+ ;; way. FIRST-FLAG is non-nil when the first string hasn't
+ ;; been seen yet. It is required as this string is the only
+ ;; one whose indentation doesn't happen after a newline
+ ;; character.
+ (lambda (blob first-flag)
+ (mapc
+ (lambda (object)
+ (when (and first-flag (stringp object))
+ (setq first-flag nil)
+ (string-match "\\`\\( *\\)" object)
+ (let ((len (length (match-string 1 object))))
+ ;; An indentation of zero means no string will be
+ ;; modified. Quit the process.
+ (if (zerop len) (throw 'zero (setq ind-list nil))
+ (push len ind-list))))
+ (cond
+ ((stringp object)
+ (let ((start 0))
+ (while (string-match "\n\\( *\\)" object start)
+ (setq start (match-end 0))
+ (push (length (match-string 1 object)) ind-list))))
+ ((memq (org-element-type object) org-element-recursive-objects)
+ (funcall collect-inds object first-flag))))
+ (org-element-contents blob))))))
+ ;; Collect indentation list in ELEMENT. Possibly remove first
+ ;; value if IGNORE-FIRST is non-nil.
+ (catch 'zero (funcall collect-inds element (not ignore-first)))
+ (if (not ind-list) element
+ ;; Build ELEMENT back, replacing each string with the same
+ ;; string minus common indentation.
+ (let ((build
+ (function
+ (lambda (blob mci first-flag)
+ ;; Return BLOB with all its strings indentation
+ ;; shortened from MCI white spaces. FIRST-FLAG is
+ ;; non-nil when the first string hasn't been seen
+ ;; yet.
+ (nconc
+ (list (org-element-type blob) (nth 1 blob))
+ (mapcar
+ (lambda (object)
+ (when (and first-flag (stringp object))
+ (setq first-flag nil)
+ (setq object
+ (replace-regexp-in-string
+ (format "\\` \\{%d\\}" mci) "" object)))
+ (cond
+ ((stringp object)
+ (replace-regexp-in-string
+ (format "\n \\{%d\\}" mci) "\n" object))
+ ((memq (org-element-type object) org-element-recursive-objects)
+ (funcall build object mci first-flag))
+ (t object)))
+ (org-element-contents blob)))))))
+ (funcall build element (apply 'min ind-list) (not ignore-first))))))
\f
;;; The Toolbox
-;; Once the structure of an Org file is well understood, it's easy to
-;; implement some replacements for `forward-paragraph'
+;; The first move is to implement a way to obtain the smallest element
+;; containing point. This is the job of `org-element-at-point'. It
+;; basically jumps back to the beginning of section containing point
+;; and moves, element after element, with
+;; `org-element-current-element' until the container is found.
+
+(defun org-element-at-point (&optional keep-trail)
+ "Determine closest element around point.
+
+Return value is a list like (TYPE PROPS) where TYPE is the type
+of the element and PROPS a plist of properties associated to the
+element. Possible types are defined in
+`org-element-all-elements'.
+
+As a special case, if point is at the very beginning of a list or
+sub-list, element returned will be that list instead of the first
+item.
+
+If optional argument KEEP-TRAIL is non-nil, the function returns
+a list of of elements leading to element at point. The list's
+CAR is always the element at point. Its last item will be the
+element's parent, unless element was either the first in its
+section (in which case the last item in the list is the first
+element of section) or an headline (in which case the list
+contains that headline as its single element). Elements
+in-between, if any, are siblings of the element at point."
+ (org-with-wide-buffer
+ ;; If at an headline, parse it. It is the sole element that
+ ;; doesn't require to know about context.
+ (if (org-with-limited-levels (org-at-heading-p))
+ (if (not keep-trail) (org-element-headline-parser)
+ (list (org-element-headline-parser)))
+ ;; Otherwise move at the beginning of the section containing
+ ;; point.
+ (let ((origin (point)) element type item-flag trail struct prevs)
+ (org-with-limited-levels
+ (if (org-before-first-heading-p) (goto-char (point-min))
+ (org-back-to-heading)
+ (forward-line)))
+ (org-skip-whitespace)
+ (beginning-of-line)
+ ;; Starting parsing successively each element with
+ ;; `org-element-current-element'. Skip those ending before
+ ;; original position.
+ (catch 'exit
+ (while t
+ (setq element (org-element-current-element item-flag struct)
+ type (car element))
+ (when keep-trail (push element trail))
+ (cond
+ ;; 1. Skip any element ending before point or at point.
+ ((let ((end (org-element-property :end element)))
+ (when (<= end origin)
+ (if (> (point-max) end) (goto-char end)
+ (throw 'exit (or trail element))))))
+ ;; 2. An element containing point is always the element at
+ ;; point.
+ ((not (memq type org-element-greater-elements))
+ (throw 'exit (if keep-trail trail element)))
+ ;; 3. At a plain list.
+ ((eq type 'plain-list)
+ (setq struct (org-element-property :structure element)
+ prevs (or prevs (org-list-prevs-alist struct)))
+ (let ((beg (org-element-property :contents-begin element)))
+ (if (= beg origin) (throw 'exit (or trail element))
+ ;; Find the item at this level containing ORIGIN.
+ (let ((items (org-list-get-all-items beg struct prevs)))
+ (let (parent)
+ (catch 'local
+ (mapc
+ (lambda (pos)
+ (cond
+ ;; Item ends before point: skip it.
+ ((<= (org-list-get-item-end pos struct) origin))
+ ;; Item contains point: store is in PARENT.
+ ((<= pos origin) (setq parent pos))
+ ;; We went too far: return PARENT.
+ (t (throw 'local nil)))) items))
+ ;; No parent: no item contained point, though
+ ;; the plain list does. Point is in the blank
+ ;; lines after the list: return plain list.
+ (if (not parent) (throw 'exit (or trail element))
+ (setq item-flag 'item)
+ (goto-char parent)))))))
+ ;; 4. At any other greater element type, if point is
+ ;; within contents, move into it. Otherwise, return
+ ;; that element.
+ (t
+ (when (eq type 'item) (setq item-flag nil))
+ (let ((beg (org-element-property :contents-begin element))
+ (end (org-element-property :contents-end element)))
+ (if (or (> beg origin) (< end origin))
+ (throw 'exit (or trail element))
+ ;; Reset trail, since we found a parent.
+ (when keep-trail (setq trail (list element)))
+ (narrow-to-region beg end)
+ (goto-char beg)))))))))))
+
+
+;; Once the local structure around point is well understood, it's easy
+;; to implement some replacements for `forward-paragraph'
;; `backward-paragraph', namely `org-element-forward' and
;; `org-element-backward'.
@@ -3372,12 +3630,13 @@ (defun org-element-normalize-contents (element &optional ignore-first)
;; `org-element-nested-p' and `org-element-swap-A-B' are used
;; internally by some of the previously cited tools.
+
(defsubst org-element-nested-p (elem-A elem-B)
"Non-nil when elements ELEM-A and ELEM-B are nested."
- (let ((beg-A (org-element-get-property :begin elem-A))
- (beg-B (org-element-get-property :begin elem-B))
- (end-A (org-element-get-property :end elem-A))
- (end-B (org-element-get-property :end elem-B)))
+ (let ((beg-A (org-element-property :begin elem-A))
+ (beg-B (org-element-property :begin elem-B))
+ (end-A (org-element-property :end elem-A))
+ (end-B (org-element-property :end elem-B)))
(or (and (>= beg-A beg-B) (<= end-A end-B))
(and (>= beg-B beg-A) (<= end-B end-A)))))
@@ -3387,16 +3646,16 @@ (defun org-element-swap-A-B (elem-A elem-B)
Leave point at the end of ELEM-A.
Assume ELEM-A is before ELEM-B and that they are not nested."
- (goto-char (org-element-get-property :begin elem-A))
- (let* ((beg-B (org-element-get-property :begin elem-B))
+ (goto-char (org-element-property :begin elem-A))
+ (let* ((beg-B (org-element-property :begin elem-B))
(end-B-no-blank (save-excursion
- (goto-char (org-element-get-property :end elem-B))
+ (goto-char (org-element-property :end elem-B))
(skip-chars-backward " \r\t\n")
(forward-line)
(point)))
- (beg-A (org-element-get-property :begin elem-A))
+ (beg-A (org-element-property :begin elem-A))
(end-A-no-blank (save-excursion
- (goto-char (org-element-get-property :end elem-A))
+ (goto-char (org-element-property :end elem-A))
(skip-chars-backward " \r\t\n")
(forward-line)
(point)))
@@ -3405,50 +3664,39 @@ (defun org-element-swap-A-B (elem-A elem-B)
(between-A-B (buffer-substring end-A-no-blank beg-B)))
(delete-region beg-A end-B-no-blank)
(insert body-B between-A-B body-A)
- (goto-char (org-element-get-property :end elem-B))))
+ (goto-char (org-element-property :end elem-B))))
(defun org-element-backward ()
- "Move backward by one element."
+ "Move backward by one element.
+Move to the previous element at the same level, when possible."
(interactive)
- (let* ((opoint (point))
- (element (org-element-at-point))
- (start-el-beg (org-element-get-property :begin element)))
- ;; At an headline. The previous element is the previous sibling,
- ;; or the parent if any.
- (cond
- ;; Already at the beginning of the current element: move to the
- ;; beginning of the previous one.
- ((= opoint start-el-beg)
- (forward-line -1)
- (skip-chars-backward " \r\t\n")
- (let* ((prev-element (org-element-at-point))
- (itemp (org-in-item-p))
- (struct (and itemp
- (save-excursion (goto-char itemp)
- (org-list-struct)))))
- ;; When moving into a new list, go directly at the
- ;; beginning of the top list structure.
- (if (and itemp (<= (org-list-get-bottom-point struct) opoint))
- (progn
- (goto-char (org-list-get-top-point struct))
- (goto-char (org-element-get-property
- :begin (org-element-at-point))))
- (goto-char (org-element-get-property :begin prev-element))))
- (while (org-truely-invisible-p) (org-element-up)))
- ;; Else, move at the element beginning. One exception: if point
- ;; was in the blank lines after the end of a list, move directly
- ;; to the top item.
- (t
- (let (struct itemp)
- (if (and (setq itemp (org-in-item-p))
- (<= (org-list-get-bottom-point
- (save-excursion (goto-char itemp)
- (setq struct (org-list-struct))))
- opoint))
- (progn (goto-char (org-list-get-top-point struct))
- (goto-char (org-element-get-property
- :begin (org-element-at-point))))
- (goto-char start-el-beg)))))))
+ (if (save-excursion (skip-chars-backward " \r\t\n") (bobp))
+ (error "Cannot move further up")
+ (let* ((trail (org-element-at-point 'keep-trail))
+ (element (car trail))
+ (beg (org-element-property :begin element)))
+ ;; Move to beginning of current element if point isn't there.
+ (if (/= (point) beg) (goto-char beg)
+ (let ((type (org-element-type element)))
+ (cond
+ ;; At an headline: move to previous headline at the same
+ ;; level, a parent, or BOB.
+ ((eq type 'headline)
+ (let ((dest (save-excursion (org-backward-same-level 1) (point))))
+ (if (= (point-min) dest) (error "Cannot move further up")
+ (goto-char dest))))
+ ;; At an item: try to move to the previous item, if any.
+ ((and (eq type 'item)
+ (let* ((struct (org-element-property :structure element))
+ (prev (org-list-get-prev-item
+ beg struct (org-list-prevs-alist struct))))
+ (when prev (goto-char prev)))))
+ ;; In any other case, find the previous element in the
+ ;; trail and move to its beginning. If no previous element
+ ;; can be found, move to headline.
+ (t (let ((prev (nth 1 trail)))
+ (if prev (goto-char (org-element-property :begin prev))
+ (org-back-to-heading))))))))))
(defun org-element-drag-backward ()
"Drag backward element at point."
@@ -3458,9 +3706,9 @@ (defun org-element-drag-backward ()
(when (= (progn (goto-char (point-min))
(org-skip-whitespace)
(point-at-bol))
- (org-element-get-property :end elem))
+ (org-element-property :end elem))
(error "Cannot drag element backward"))
- (goto-char (org-element-get-property :begin elem))
+ (goto-char (org-element-property :begin elem))
(org-element-backward)
(let ((prev-elem (org-element-at-point)))
(when (or (org-element-nested-p elem prev-elem)
@@ -3470,8 +3718,8 @@ (defun org-element-drag-backward ()
(error "Cannot drag element backward"))
;; Compute new position of point: it's shifted by PREV-ELEM
;; body's length.
- (let ((size-prev (- (org-element-get-property :end prev-elem)
- (org-element-get-property :begin prev-elem))))
+ (let ((size-prev (- (org-element-property :end prev-elem)
+ (org-element-property :begin prev-elem))))
(org-element-swap-A-B prev-elem elem)
(goto-char (- pos size-prev))))))
@@ -3480,9 +3728,9 @@ (defun org-element-drag-forward ()
(interactive)
(let* ((pos (point))
(elem (org-element-at-point)))
- (when (= (point-max) (org-element-get-property :end elem))
+ (when (= (point-max) (org-element-property :end elem))
(error "Cannot drag element forward"))
- (goto-char (org-element-get-property :end elem))
+ (goto-char (org-element-property :end elem))
(let ((next-elem (org-element-at-point)))
(when (or (org-element-nested-p elem next-elem)
(and (eq (car next-elem) 'headline)
@@ -3493,14 +3741,14 @@ (defun org-element-drag-forward ()
;; body's length (without final blanks) and by the length of
;; blanks between ELEM and NEXT-ELEM.
(let ((size-next (- (save-excursion
- (goto-char (org-element-get-property :end next-elem))
+ (goto-char (org-element-property :end next-elem))
(skip-chars-backward " \r\t\n")
(forward-line)
(point))
- (org-element-get-property :begin next-elem)))
- (size-blank (- (org-element-get-property :end elem)
+ (org-element-property :begin next-elem)))
+ (size-blank (- (org-element-property :end elem)
(save-excursion
- (goto-char (org-element-get-property :end elem))
+ (goto-char (org-element-property :end elem))
(skip-chars-backward " \r\t\n")
(forward-line)
(point)))))
@@ -3508,37 +3756,41 @@ (defun org-element-drag-forward ()
(goto-char (+ pos size-next size-blank))))))
(defun org-element-forward ()
- "Move forward by one element."
+ "Move forward by one element.
+Move to the next element at the same level, when possible."
(interactive)
- (beginning-of-line)
- (cond ((eobp) (error "Cannot move further down"))
- ((looking-at "[ \t]*$")
- (org-skip-whitespace)
- (goto-char (if (eobp) (point) (point-at-bol))))
- (t
- (let ((element (org-element-at-point t))
- (origin (point)))
- (cond
- ;; At an item: Either move to the next element inside, or
- ;; to its end if it's hidden.
- ((eq (car element) 'item)
- (if (org-element-get-property :hiddenp element)
- (goto-char (org-element-get-property :end element))
- (end-of-line)
- (re-search-forward org-element-paragraph-separate nil t)
- (org-skip-whitespace)
- (beginning-of-line)))
- ;; At a recursive element: Either move inside, or if it's
- ;; hidden, move to its end.
- ((memq (car element) org-element-greater-elements)
- (let ((cbeg (org-element-get-property :contents-begin element)))
- (goto-char
- (if (or (org-element-get-property :hiddenp element)
- (> origin cbeg))
- (org-element-get-property :end element)
- cbeg))))
- ;; Else: move to the current element's end.
- (t (goto-char (org-element-get-property :end element))))))))
+ (if (eobp) (error "Cannot move further down")
+ (let* ((trail (org-element-at-point 'keep-trail))
+ (element (car trail))
+ (type (org-element-type element))
+ (end (org-element-property :end element)))
+ (cond
+ ;; At an headline, move to next headline at the same level.
+ ((eq type 'headline) (goto-char end))
+ ;; At an item. Move to the next item, if possible.
+ ((and (eq type 'item)
+ (let* ((struct (org-element-property :structure element))
+ (prevs (org-list-prevs-alist struct))
+ (beg (org-element-property :begin element))
+ (next-item (org-list-get-next-item beg struct prevs)))
+ (when next-item (goto-char next-item)))))
+ ;; In any other case, move to element's end, unless this
+ ;; position is also the end of its parent's contents, in which
+ ;; case, directly jump to parent's end.
+ (t
+ (let ((parent
+ ;; Determine if TRAIL contains the real parent of ELEMENT.
+ (and (> (length trail) 1)
+ (let* ((parent-candidate (car (last trail))))
+ (and (memq (org-element-type parent-candidate)
+ org-element-greater-elements)
+ (>= (org-element-property
+ :contents-end parent-candidate) end)
+ parent-candidate)))))
+ (cond ((not parent) (goto-char end))
+ ((= (org-element-property :contents-end parent) end)
+ (goto-char (org-element-property :end parent)))
+ (t (goto-char end)))))))))
(defun org-element-mark-element ()
"Put point at beginning of this element, mark at end.
@@ -3553,11 +3805,11 @@ (defun org-element-mark-element ()
(set-mark
(save-excursion
(goto-char (mark))
- (goto-char (org-element-get-property :end (org-element-at-point)))))
+ (goto-char (org-element-property :end (org-element-at-point)))))
(let ((element (org-element-at-point)))
(end-of-line)
- (push-mark (org-element-get-property :end element) t t)
- (goto-char (org-element-get-property :begin element))))))
+ (push-mark (org-element-property :end element) t t)
+ (goto-char (org-element-property :begin element))))))
(defun org-narrow-to-element ()
"Narrow buffer to current element."
@@ -3566,16 +3818,16 @@ (defun org-narrow-to-element ()
(cond
((eq (car elem) 'headline)
(narrow-to-region
- (org-element-get-property :begin elem)
- (org-element-get-property :end elem)))
+ (org-element-property :begin elem)
+ (org-element-property :end elem)))
((memq (car elem) org-element-greater-elements)
(narrow-to-region
- (org-element-get-property :contents-begin elem)
- (org-element-get-property :contents-end elem)))
+ (org-element-property :contents-begin elem)
+ (org-element-property :contents-end elem)))
(t
(narrow-to-region
- (org-element-get-property :begin elem)
- (org-element-get-property :end elem))))))
+ (org-element-property :begin elem)
+ (org-element-property :end elem))))))
(defun org-transpose-elements ()
"Transpose current and previous elements, keeping blank lines between.
@@ -3587,9 +3839,9 @@ (defun org-transpose-elements ()
(when (= (save-excursion (goto-char (point-min))
(org-skip-whitespace)
(point-at-bol))
- (org-element-get-property :begin cur))
+ (org-element-property :begin cur))
(error "No previous element"))
- (goto-char (org-element-get-property :begin cur))
+ (goto-char (org-element-property :begin cur))
(forward-line -1)
(let ((prev (org-element-at-point)))
(when (org-element-nested-p cur prev)
@@ -3610,57 +3862,67 @@ (defun org-element-unindent-buffer ()
(function
(lambda (contents)
(mapc (lambda (element)
- (if (eq (car element) 'headline)
+ (if (eq (org-element-type element) 'headline)
(funcall unindent-tree
- (org-element-get-contents element))
+ (org-element-contents element))
(save-excursion
(save-restriction
(narrow-to-region
- (org-element-get-property :begin element)
- (org-element-get-property :end element))
+ (org-element-property :begin element)
+ (org-element-property :end element))
(org-do-remove-indentation)))))
(reverse contents))))))
- (funcall unindent-tree (org-element-get-contents parse-tree))))
+ (funcall unindent-tree (org-element-contents parse-tree))))
(defun org-element-up ()
- "Move to upper element.
-Return position at the beginning of the upper element."
+ "Move to upper element."
(interactive)
- (let ((opoint (point)) elem)
+ (cond
+ ((bobp) (error "No surrounding element"))
+ ((org-with-limited-levels (org-at-heading-p))
+ (or (org-up-heading-safe) (error "No surronding element")))
+ (t
+ (let* ((trail (org-element-at-point 'keep-trail))
+ (element (car trail))
+ (type (org-element-type element)))
+ (cond
+ ;; At an item, with a parent in the list: move to that parent.
+ ((and (eq type 'item)
+ (let* ((beg (org-element-property :begin element))
+ (struct (org-element-property :structure element))
+ (parents (org-list-parents-alist struct))
+ (parentp (org-list-get-parent beg struct parents)))
+ (and parentp (goto-char parentp)))))
+ ;; Determine parent in the trail.
+ (t
+ (let ((parent
+ (and (> (length trail) 1)
+ (let ((parentp (car (last trail))))
+ (and (memq (org-element-type parentp)
+ org-element-greater-elements)
+ (>= (org-element-property :contents-end parentp)
+ (org-element-property :end element))
+ parentp)))))
+ (cond
+ ;; When parent is found move to its beginning.
+ (parent (goto-char (org-element-property :begin parent)))
+ ;; If no parent was found, move to headline above, if any
+ ;; or return an error.
+ ((org-before-first-heading-p) (error "No surrounding element"))
+ (t (org-back-to-heading))))))))))
+
+(defun org-element-down ()
+ "Move to inner element."
+ (interactive)
+ (let ((element (org-element-at-point)))
(cond
- ((bobp) (error "No surrounding element"))
- ((org-with-limited-levels (org-at-heading-p))
- (or (org-up-heading-safe) (error "No surronding element")))
- ((and (org-at-item-p)
- (setq elem (org-element-at-point))
- (let* ((top-list-p (zerop (org-element-get-property :level elem))))
- (unless top-list-p
- ;; If parent is bound to be in the same list as the
- ;; original point, move to that parent.
- (let ((struct (org-element-get-property :structure elem)))
- (goto-char
- (org-list-get-parent
- (point-at-bol) struct (org-list-parents-alist struct))))))))
- (t
- (let* ((elem (or elem (org-element-at-point)))
- (end (save-excursion
- (goto-char (org-element-get-property :end elem))
- (skip-chars-backward " \r\t\n")
- (forward-line)
- (point)))
- prev-elem)
- (goto-char (org-element-get-property :begin elem))
- (forward-line -1)
- (while (and (< (org-element-get-property
- :end (setq prev-elem (org-element-at-point)))
- end)
- (not (bobp)))
- (goto-char (org-element-get-property :begin prev-elem))
- (forward-line -1))
- (if (and (bobp) (< (org-element-get-property :end prev-elem) end))
- (progn (goto-char opoint)
- (error "No surrounding element"))
- (goto-char (org-element-get-property :begin prev-elem))))))))
+ ((eq (org-element-type element) 'plain-list)
+ (forward-char))
+ ((memq (org-element-type element) org-element-greater-elements)
+ ;; If contents are hidden, first disclose them.
+ (when (org-element-property :hiddenp element) (org-cycle))
+ (goto-char (org-element-property :contents-begin element)))
+ (t (error "No inner element")))))
(provide 'org-element)
diff --git a/contrib/lisp/org-eval-light.el b/contrib/lisp/org-eval-light.el
index 5cae699..36f3c6d 100644
--- a/contrib/lisp/org-eval-light.el
+++ b/contrib/lisp/org-eval-light.el
@@ -67,7 +67,7 @@ (defun org-eval-light-set-interpreters (var value)
(defcustom org-eval-light-interpreters '("lisp" "emacs-lisp" "ruby" "shell")
"Interpreters allows for evaluation tags.
This is a list of program names (as strings) that can evaluate code and
-insert the output into an Org-mode buffer. Valid choices are
+insert the output into an Org-mode buffer. Valid choices are
lisp Interpret Emacs Lisp code and display the result
shell Pass command to the shell and display the result
@@ -189,7 +189,7 @@ (defun org-eval-light-run (cmd code)
(with-temp-buffer
(insert code)
(shell-command-on-region (point-min) (point-max) cmd nil 'replace)
- (buffer-string)))
+ (buffer-string)))
(defadvice org-ctrl-c-ctrl-c (around org-cc-eval-source activate)
(if (org-eval-light-inside-snippet)
diff --git a/contrib/lisp/org-eval.el b/contrib/lisp/org-eval.el
index 31b91c1..9968669 100644
--- a/contrib/lisp/org-eval.el
+++ b/contrib/lisp/org-eval.el
@@ -105,7 +105,7 @@ (defun org-eval-set-interpreters (var value)
(defcustom org-eval-interpreters '("lisp")
"Interpreters allows for evaluation tags.
This is a list of program names (as strings) that can evaluate code and
-insert the output into an Org-mode buffer. Valid choices are
+insert the output into an Org-mode buffer. Valid choices are
lisp Interpret Emacs Lisp code and display the result
shell Pass command to the shell and display the result
@@ -120,7 +120,7 @@ (defcustom org-eval-interpreters '("lisp")
(const "python")
(const "ruby")
(const "shell")))
-
+
(defun org-eval-handle-snippets (limit &optional replace)
"Evaluate code snippets and display the results as display property.
When REPLACE is non-nil, replace the code region with the result (used
@@ -212,9 +212,8 @@ (defun org-eval-run (cmd code)
(with-temp-buffer
(insert code)
(shell-command-on-region (point-min) (point-max) cmd nil 'replace)
- (buffer-string)))
+ (buffer-string)))
(provide 'org-eval)
;;; org-eval.el ends here
-
diff --git a/contrib/lisp/org-expiry.el b/contrib/lisp/org-expiry.el
index 88a1ab2..9f4517d 100644
--- a/contrib/lisp/org-expiry.el
+++ b/contrib/lisp/org-expiry.el
@@ -25,7 +25,7 @@
;;; Commentary:
;;
;; This gives you a chance to get rid of old entries in your Org files
-;; by expiring them.
+;; by expiring them.
;;
;; By default, entries that have no EXPIRY property are considered to be
;; new (i.e. 0 day old) and only entries older than one year go to the
@@ -33,7 +33,7 @@
;; your tasks will be deleted with the default settings.
;;
;; When does an entry expires?
-;;
+;;
;; Consider this entry:
;;
;; * Stop watching TV
@@ -41,8 +41,8 @@
;; :CREATED: <2008-01-07 lun 08:01>
;; :EXPIRY: <2008-01-09 08:01>
;; :END:
-;;
-;; This entry will expire on the 9th, january 2008.
+;;
+;; This entry will expire on the 9th, january 2008.
;; * Stop watching TV
;; :PROPERTIES:
@@ -56,19 +56,19 @@
;; What happen when an entry is expired? Nothing until you explicitely
;; M-x org-expiry-process-entries When doing this, org-expiry will check
;; for expired entries and request permission to process them.
-;;
+;;
;; Processing an expired entries means calling the function associated
;; with `org-expiry-handler-function'; the default is to add the tag
-;; :ARCHIVE:, but you can also add a EXPIRED keyword or even archive
-;; the subtree.
+;; :ARCHIVE:, but you can also add a EXPIRED keyword or even archive
+;; the subtree.
;;
;; Is this useful? Well, when you're in a brainstorming session, it
;; might be useful to know about the creation date of an entry, and be
;; able to archive those entries that are more than xxx days/weeks old.
-;;
+;;
;; When you're in such a session, you can insinuate org-expiry like
-;; this: M-x org-expiry-insinuate
-;;
+;; this: M-x org-expiry-insinuate
+;;
;; Then, each time you're pressing M-RET to insert an item, the CREATION
;; property will be automatically added. Same when you're scheduling or
;; deadlining items. You can deinsinuate: M-x org-expiry-deinsinuate
@@ -218,7 +218,7 @@ (defun org-expiry-expired-p ()
Return nil if the entry is not expired. Otherwise return the
amount of time between today and the expiry date.
-If there is no creation date, use `org-expiry-created-date'.
+If there is no creation date, use `org-expiry-created-date'.
If there is no expiry date, use `org-expiry-expiry-date'."
(let* ((ex-prop org-expiry-expiry-property-name)
(cr-prop org-expiry-created-property-name)
@@ -292,7 +292,7 @@ (defun org-expiry-insert-created (&optional arg)
d-time d-hour timestr)
(when (or (null d) arg)
;; update if no date or non-nil prefix argument
- ;; FIXME Use `org-time-string-to-time'
+ ;; FIXME Use `org-time-string-to-time'
(setq d-time (if d (org-time-string-to-time d)
(current-time)))
(setq d-hour (format-time-string "%H:%M" d-time))
@@ -326,7 +326,7 @@ (defun org-expiry-insert-expiry (&optional today)
;; maybe transform to inactive timestamp
(if org-expiry-inactive-timestamps
(setq timestr (concat "[" (substring timestr 1 -1) "]")))
-
+
(save-excursion
(org-entry-put
(point) org-expiry-expiry-property-name timestr))))
diff --git a/contrib/lisp/org-export-generic.el b/contrib/lisp/org-export-generic.el
index 24794d2..436badc 100644
--- a/contrib/lisp/org-export-generic.el
+++ b/contrib/lisp/org-export-generic.el
@@ -35,7 +35,7 @@
;; org-set-generic-type function:
;;
;; (org-set-generic-type
-;; "really-basic-text"
+;; "really-basic-text"
;; '(:file-suffix ".txt"
;; :key-binding ?R
;;
@@ -155,10 +155,10 @@ (defvar org-generic-alist
:toc-section-numbers t
:toc-section-number-format "\#(%s) "
- :toc-format "--%s--"
+ :toc-format "--%s--"
:toc-format-with-todo "!!%s!!\n"
- :toc-indent-char ?\
- :toc-indent-depth 4
+ :toc-indent-char ?\
+ :toc-indent-depth 4
:toc-tags-export t
:toc-tags-prefix " <tags>"
@@ -217,7 +217,7 @@ (defvar org-generic-alist
:body-list-checkbox-half-end "</checkbox (half)>"
-
+
; other body lines
:body-line-format "%s"
@@ -257,10 +257,10 @@ (defvar org-generic-alist
:toc-export t
:toc-section-numbers t
:toc-section-number-format "%s "
- :toc-format "%s\n"
+ :toc-format "%s\n"
:toc-format-with-todo "%s (*)\n"
- :toc-indent-char ?\
- :toc-indent-depth 4
+ :toc-indent-char ?\
+ :toc-indent-depth 4
:body-header-section-numbers 3
:body-section-prefix "\n"
@@ -310,7 +310,7 @@ (defvar org-generic-alist
:body-section-header-prefix ("= " "== " "=== "
"==== " "===== " "====== ")
- :body-section-header-suffix (" =\n\n" " ==\n\n" " ===\n\n"
+ :body-section-header-suffix (" =\n\n" " ==\n\n" " ===\n\n"
" ====\n\n" " =====\n\n" " ======\n\n")
:body-line-export-preformated t ;; yes/no/maybe???
@@ -390,7 +390,7 @@ (defvar org-generic-alist
:body-list-format "<t>%s</t>\n"
)
- ("trac-wiki"
+ ("trac-wiki"
:file-suffix ".txt"
:key-binding ?T
@@ -409,7 +409,7 @@ (defvar org-generic-alist
:body-section-header-prefix (" == " " === " " ==== "
" ===== " )
- :body-section-header-suffix (" ==\n\n" " ===\n\n" " ====\n\n"
+ :body-section-header-suffix (" ==\n\n" " ===\n\n" " ====\n\n"
" =====\n\n" " ======\n\n" " =======\n\n")
:body-line-export-preformated t ;; yes/no/maybe???
@@ -426,7 +426,7 @@ (defvar org-generic-alist
;; this is ignored! [2010/02/02:rpg]
:body-bullet-list-prefix ("* " "** " "*** " "**** " "***** ")
)
- ("tikiwiki"
+ ("tikiwiki"
:file-suffix ".txt"
:key-binding ?U
@@ -445,7 +445,7 @@ (defvar org-generic-alist
:body-section-header-prefix ("! " "!! " "!!! " "!!!! "
"!!!!! " "!!!!!! " "!!!!!!! ")
- :body-section-header-suffix (" \n" " \n" " \n"
+ :body-section-header-suffix (" \n" " \n" " \n"
" \n" " \n" " \n")
@@ -498,12 +498,12 @@ (defvar org-export-generic-keywords nil)
))
(def-org-export-generic-keyword :body-newline-paragraph
- :documentation "Bound either to NIL or to a pattern to be
+ :documentation "Bound either to NIL or to a pattern to be
inserted in the output for every blank line in the input.
The intention is to handle formats where text is flowed, and
newlines are interpreted as significant \(e.g., as indicating
preformatted text\). A common non-nil value for this keyword
-is \"\\n\". Should typically be combined with a value for
+is \"\\n\". Should typically be combined with a value for
:body-line-format that does NOT end with a newline."
:type string)
@@ -515,8 +515,8 @@ (defvar org-export-generic-keywords nil)
(def-org-export-generic-keyword :code-format)
(def-org-export-generic-keyword :verbatim-format)
-
-
+
+
(defun org-export-generic-remember-section (type suffix &optional prefix)
(setq org-export-generic-section-type type)
@@ -569,7 +569,7 @@ (defun org-export-generic (arg)
(org-export-add-subtree-options opt-plist rbeg)
opt-plist)))
- helpstart
+ helpstart
(bogus (mapc (lambda (x)
(setq helpstart
(concat helpstart "\["
@@ -611,7 +611,7 @@ (defun org-export-generic (arg)
(unless (setq ass (cadr (assq r2 cmds)))
(error "No command associated with key %c" r1))
- (cdr (assoc
+ (cdr (assoc
(if (equal ass "default") org-generic-export-type ass)
org-generic-alist))))
@@ -732,11 +732,11 @@ (defun org-export-generic (arg)
(format-code (plist-get export-plist :code-format))
(format-verbatim (plist-get export-plist :verbatim-format))
-
+
thetoc toctags have-headings first-heading-pos
table-open table-buffer link-buffer link desc desc0 rpl wrap)
-
+
(let ((inhibit-read-only t))
(org-unmodified
(remove-text-properties (point-min) (point-max)
@@ -841,7 +841,7 @@ (defun org-export-generic (arg)
(org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$")
txt)
(progn
- (setq
+ (setq
toctags
(org-export-generic-header
(match-string 1 txt)
@@ -852,7 +852,7 @@ (defun org-export-generic (arg)
txt)
(setq txt (replace-match "" t t txt)))
(setq toctags tocnotagsstr)))
-
+
(if (string-match quote-re0 txt)
(setq txt (replace-match "" t t txt)))
@@ -871,7 +871,7 @@ (defun org-export-generic (arg)
"")
(format
- (if todo tocformtodo tocformat)
+ (if todo tocformtodo tocformat)
txt)
toctags)
@@ -908,7 +908,7 @@ (defun org-export-generic (arg)
(substring link 8)
org-export-code-refs)))
t t line))
- (setq rpl (concat "["
+ (setq rpl (concat "["
(or (match-string 3 line) (match-string 1 line))
"]"))
(when (and desc0 (not (equal desc0 link)))
@@ -1043,7 +1043,7 @@ (defun org-export-generic (arg)
;;
(org-export-generic-check-section "body" bodytextpre bodytextsuf)
- (setq line
+ (setq line
(org-export-generic-fontify line))
;; XXX: properties? list?
@@ -1208,7 +1208,7 @@ (defun org-export-generic-wrap (line where)
(setq result (concat result line))
(setq len 0)))
(concat result indstr line)))
-
+
(defun org-export-generic-push-links (link-buffer)
"Push out links in the buffer."
(when link-buffer
@@ -1258,13 +1258,13 @@ (defun org-generic-level-start (level old-level title umax export-plist
))
;; same level
((= level old-level)
- (insert
+ (insert
(org-export-generic-format export-plist :body-section-suffix 0 level))
)
)
(insert
(org-export-generic-format export-plist :body-section-prefix 0 level))
-
+
(if (and org-export-with-section-numbers
secnums
(or (not (numberp secnums))
@@ -1365,7 +1365,7 @@ (defvar org-export-generic-emphasis-alist
Each element of the list is a list of three elements.
The first element is the character used as a marker for fontification.
The second element is a variable name, set in org-export-generic. That
-variable will be dereferenced to obtain a formatting string to wrap
+variable will be dereferenced to obtain a formatting string to wrap
fontified text with.
The third element decides whether to protect converted text from other
conversions.")
diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
index 7219873..0d8a04f 100644
--- a/contrib/lisp/org-export.el
+++ b/contrib/lisp/org-export.el
@@ -1,6 +1,6 @@
;;; org-export.el --- Generic Export Engine For Org
-;; Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -28,9 +28,9 @@
;; - The communication channel consists in a property list, which is
;; created and updated during the process. Its use is to offer
-;; every piece of information, would it be export options or
-;; contextual data, all in a single place. The exhaustive list of
-;; properties is given in "The Communication Channel" section of
+;; every piece of information, would it be about initial environment
+;; or contextual data, all in a single place. The exhaustive list
+;; of properties is given in "The Communication Channel" section of
;; this file.
;; - The transcoder walks the parse tree, ignores or treat as plain
@@ -85,12 +85,20 @@
;; back-end. See `org-export-option-alist' for supported defaults and
;; syntax.
-;; Tools for common tasks across back-ends are implemented in the last
-;; part of this file.
+;; Tools for common tasks across back-ends are implemented in the
+;; penultimate part of this file. A dispatcher for standard back-ends
+;; is provided in the last one.
;;; Code:
(eval-when-compile (require 'cl))
(require 'org-element)
+;; Require major back-ends and publishing tools
+(require 'org-e-ascii "../../EXPERIMENTAL/org-e-ascii.el")
+(require 'org-e-html "../../EXPERIMENTAL/org-e-html.el")
+(require 'org-e-latex "../../EXPERIMENTAL/org-e-latex.el")
+(require 'org-e-odt "../../EXPERIMENTAL/org-e-odt.el")
+(require 'org-e-publish "../../EXPERIMENTAL/org-e-publish.el")
+
\f
;;; Internal Variables
@@ -120,7 +128,7 @@ (defconst org-export-option-alist
(:with-archived-trees nil "arch" org-export-with-archived-trees)
(:with-author nil "author" org-export-with-author)
(:with-creator nil "creator" org-export-with-creator)
- (:with-drawers nil "drawer" org-export-with-drawers)
+ (:with-drawers nil "d" org-export-with-drawers)
(:with-email nil "email" org-export-with-email)
(:with-emphasize nil "*" org-export-with-emphasize)
(:with-entities nil "e" org-export-with-entities)
@@ -168,6 +176,80 @@ (defconst org-export-special-keywords
way they are handled must be hard-coded into
`org-export-get-inbuffer-options' function.")
+(defconst org-export-filters-alist
+ '((:filter-babel-call . org-export-filter-babel-call-functions)
+ (:filter-center-block . org-export-filter-center-block-functions)
+ (:filter-comment . org-export-filter-comment-functions)
+ (:filter-comment-block . org-export-filter-comment-block-functions)
+ (:filter-drawer . org-export-filter-drawer-functions)
+ (:filter-dynamic-block . org-export-filter-dynamic-block-functions)
+ (:filter-emphasis . org-export-filter-emphasis-functions)
+ (:filter-entity . org-export-filter-entity-functions)
+ (:filter-example-block . org-export-filter-example-block-functions)
+ (:filter-export-block . org-export-filter-export-block-functions)
+ (:filter-export-snippet . org-export-filter-export-snippet-functions)
+ (:filter-final-output . org-export-filter-final-output-functions)
+ (:filter-fixed-width . org-export-filter-fixed-width-functions)
+ (:filter-footnote-definition . org-export-filter-footnote-definition-functions)
+ (:filter-footnote-reference . org-export-filter-footnote-reference-functions)
+ (:filter-headline . org-export-filter-headline-functions)
+ (:filter-horizontal-rule . org-export-filter-horizontal-rule-functions)
+ (:filter-inline-babel-call . org-export-filter-inline-babel-call-functions)
+ (:filter-inline-src-block . org-export-filter-inline-src-block-functions)
+ (:filter-inlinetask . org-export-filter-inlinetask-functions)
+ (:filter-item . org-export-filter-item-functions)
+ (:filter-keyword . org-export-filter-keyword-functions)
+ (:filter-latex-environment . org-export-filter-latex-environment-functions)
+ (:filter-latex-fragment . org-export-filter-latex-fragment-functions)
+ (:filter-line-break . org-export-filter-line-break-functions)
+ (:filter-link . org-export-filter-link-functions)
+ (:filter-macro . org-export-filter-macro-functions)
+ (:filter-paragraph . org-export-filter-paragraph-functions)
+ (:filter-parse-tree . org-export-filter-parse-tree-functions)
+ (:filter-plain-list . org-export-filter-plain-list-functions)
+ (:filter-plain-text . org-export-filter-plain-text-functions)
+ (:filter-property-drawer . org-export-filter-property-drawer-functions)
+ (:filter-quote-block . org-export-filter-quote-block-functions)
+ (:filter-quote-section . org-export-filter-quote-section-functions)
+ (:filter-radio-target . org-export-filter-radio-target-functions)
+ (:filter-section . org-export-filter-section-functions)
+ (:filter-special-block . org-export-filter-special-block-functions)
+ (:filter-src-block . org-export-filter-src-block-functions)
+ (:filter-statistics-cookie . org-export-filter-statistics-cookie-functions)
+ (:filter-subscript . org-export-filter-subscript-functions)
+ (:filter-superscript . org-export-filter-superscript-functions)
+ (:filter-table . org-export-filter-table-functions)
+ (:filter-target . org-export-filter-target-functions)
+ (:filter-time-stamp . org-export-filter-time-stamp-functions)
+ (:filter-verbatim . org-export-filter-verbatim-functions)
+ (:filter-verse-block . org-export-filter-verse-block-functions))
+ "Alist between filters properties and initial values.
+
+The key of each association is a property name accessible through
+the communication channel its value is a configurable global
+variable defining initial filters.
+
+This list is meant to install user specified filters. Back-end
+developers may install their own filters using
+`org-BACKEND-filters-alist', where BACKEND is the name of the
+considered back-end. Filters defined there will always be
+prepended to the current list, so they always get applied
+first.")
+
+(defconst org-export-default-inline-image-rule
+ `(("file" .
+ ,(format "\\.%s\\'"
+ (regexp-opt
+ '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm"
+ "xpm" "pbm" "pgm" "ppm") t))))
+ "Default rule for link matching an inline image.
+This rule applies to links with no description. By default, it
+will be considered as an inline image if it targets a local file
+whose extension is either \"png\", \"jpeg\", \"jpg\", \"gif\",
+\"tiff\", \"tif\", \"xbm\", \"xpm\", \"pbm\", \"pgm\" or \"ppm\".
+See `org-export-inline-image-p' for more information about
+rules.")
+
\f
;;; User-configurable Variables
@@ -229,10 +311,15 @@ (defcustom org-export-creator-string
:group 'org-export-general
:type '(string :tag "Creator string"))
-(defcustom org-export-with-drawers nil
- "Non-nil means export with drawers like the property drawer.
+(defcustom org-export-with-drawers t
+ "Non-nil means export contents of standard drawers.
+
When t, all drawers are exported. This may also be a list of
-drawer names to export."
+drawer names to export. This variable doesn't apply to
+properties drawers.
+
+This option can also be set with the #+OPTIONS line,
+e.g. \"d:nil\"."
:group 'org-export-general
:type '(choice
(const :tag "All drawers" t)
@@ -260,9 +347,13 @@ (defcustom org-export-with-emphasize t
(defcustom org-export-exclude-tags '("noexport")
"Tags that exclude a tree from export.
+
All trees carrying any of these tags will be excluded from
export. This is without condition, so even subtrees inside that
-carry one of the `org-export-select-tags' will be removed."
+carry one of the `org-export-select-tags' will be removed.
+
+This option can also be set with the #+EXPORT_EXCLUDE_TAGS:
+keyword."
:group 'org-export-general
:type '(repeat (string :tag "Tag")))
@@ -332,13 +423,20 @@ (defcustom org-export-with-entities t
(defcustom org-export-with-priority nil
"Non-nil means include priority cookies in export.
-When nil, remove priority cookies for export."
+
+When nil, remove priority cookies for export.
+
+This option can also be set with the #+OPTIONS line,
+e.g. \"pri:t\"."
:group 'org-export-general
:type 'boolean)
(defcustom org-export-with-section-numbers t
"Non-nil means add section numbers to headlines when exporting.
+When set to an integer n, numbering will only happen for
+headlines whose relative level is higher or equal to n.
+
This option can also be set with the #+OPTIONS line,
e.g. \"num:t\"."
:group 'org-export-general
@@ -346,10 +444,14 @@ (defcustom org-export-with-section-numbers t
(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 of these tags will be deleted before export. Inside trees
+one of these tags will be ignored during export. Inside trees
that are selected like this, you can still deselect a subtree by
-tagging it with one of the `org-export-exclude-tags'."
+tagging it with one of the `org-export-exclude-tags'.
+
+This option can also be set with the #+EXPORT_SELECT_TAGS:
+keyword."
:group 'org-export-general
:type '(repeat (string :tag "Tag")))
@@ -503,6 +605,44 @@ (defcustom org-export-snippet-translation-alist nil
(string :tag "Shortcut")
(string :tag "Back-end"))))
+(defcustom org-export-coding-system nil
+ "Coding system for the exported file."
+ :group 'org-export-general
+ :type 'coding-system)
+
+(defcustom org-export-copy-to-kill-ring t
+ "Non-nil means exported stuff will also be pushed onto the kill ring."
+ :group 'org-export-general
+ :type 'boolean)
+
+(defcustom org-export-initial-scope 'buffer
+ "The initial scope when exporting with `org-export-dispatch'.
+This variable can be either set to `buffer' or `subtree'."
+ :group 'org-export-general
+ :type '(choice
+ (const :tag "Export current buffer" 'buffer)
+ (const :tag "Export current subtree" 'subtree)))
+
+(defcustom org-export-show-temporary-export-buffer t
+ "Non-nil means show buffer after exporting to temp buffer.
+When Org exports to a file, the buffer visiting that file is ever
+shown, but remains buried. However, when exporting to a temporary
+buffer, that buffer is popped up in a second window. When this variable
+is nil, the buffer remains buried also in these cases."
+ :group 'org-export-general
+ :type 'boolean)
+
+(defcustom org-export-dispatch-use-expert-ui nil
+ "Non-nil means using a non-intrusive `org-export-dispatch'.
+In that case, no help buffer is displayed. Though, an indicator
+for current export scope is added to the prompt \(i.e. \"b\" when
+output is restricted to body only, \"s\" when it is restricted to
+the current subtree and \"v\" when only visible elements are
+considered for export\). Also, \[?] allows to switch back to
+standard mode."
+ :group 'org-export-general
+ :type 'boolean)
+
\f
;;; The Communication Channel
@@ -510,76 +650,56 @@ (defcustom org-export-snippet-translation-alist nil
;; During export process, every function has access to a number of
;; properties. They are of three types:
-;; 1. Export options are collected once at the very beginning of the
-;; process, out of the original buffer and environment. The task
-;; is handled by `org-export-collect-options' function.
+;; 1. Environment options are collected once at the very beginning of
+;; the process, out of the original buffer and configuration.
+;; Associated to the parse tree, they make an Org closure.
+;; Collecting them is handled by `org-export-get-environment'
+;; function.
;;
-;; All export options are defined through the
+;; Most environment options are defined through the
;; `org-export-option-alist' variable.
;;
-;; 2. Persistent properties are stored in
-;; `org-export-persistent-properties' and available at every level
-;; of recursion. Their value is extracted directly from the parsed
-;; tree, and depends on export options (whole trees may be filtered
-;; out of the export process).
+;; 2. Tree properties are extracted directly from the parsed tree,
+;; just before export, by `org-export-collect-tree-properties'.
;;
-;; Properties belonging to that type are defined in the
-;; `org-export-persistent-properties-list' variable.
-;;
-;; 3. Every other property is considered local, and available at
-;; a precise level of recursion and below.
-
-;; Managing properties during transcode process is mainly done with
-;; `org-export-update-info'. Even though they come from different
-;; sources, the function transparently concatenates them in a single
-;; property list passed as an argument to each transcode function.
-;; Thus, during export, all necessary information is available through
-;; that single property list, and the element or object itself.
-;; Though, modifying a property will still require some special care,
-;; and should be done with `org-export-set-property' instead of plain
-;; `plist-put'.
+;; 3. Local options are updated during parsing, and their value
+;; depends on the level of recursion. For now, only `:ignore-list'
+;; belongs to that category.
;; Here is the full list of properties available during transcode
-;; process, with their category (option, persistent or local), their
-;; value type and the function updating them, when appropriate.
+;; process, with their category (option, tree or local) and their
+;; value type.
-;; + `author' :: Author's name.
+;; + `:author' :: Author's name.
;; - category :: option
;; - type :: string
-;; + `back-end' :: Current back-end used for transcoding.
-;; - category :: persistent
+;; + `:back-end' :: Current back-end used for transcoding.
+;; - category :: tree
;; - type :: symbol
-;; + `code-refs' :: Association list between reference name and real
-;; labels in source code. It is used to properly
-;; resolve links inside source blocks.
-;; - category :: persistent
-;; - type :: alist (INT-OR-STRING . STRING)
-;; - update :: `org-export-handle-code'
-
-;; + `creator' :: String to write as creation information.
+;; + `:creator' :: String to write as creation information.
;; - category :: option
;; - type :: string
-;; + `date' :: String to use as date.
+;; + `:date' :: String to use as date.
;; - category :: option
;; - type :: string
-;; + `description' :: Description text for the current data.
+;; + `:description' :: Description text for the current data.
;; - category :: option
;; - type :: string
-;; + `email' :: Author's email.
+;; + `:email' :: Author's email.
;; - category :: option
;; - type :: string
-;; + `exclude-tags' :: Tags for exclusion of subtrees from export
+;; + `:exclude-tags' :: Tags for exclusion of subtrees from export
;; process.
;; - category :: option
;; - type :: list of strings
-;; + `footnote-definition-alist' :: Alist between footnote labels and
+;; + `:footnote-definition-alist' :: Alist between footnote labels and
;; their definition, as parsed data. Only non-inlined footnotes
;; are represented in this alist. Also, every definition isn't
;; guaranteed to be referenced in the parse tree. The purpose of
@@ -591,204 +711,152 @@ (defcustom org-export-snippet-translation-alist nil
;; - category :: option
;; - type :: alist (STRING . LIST)
-;; + `footnote-seen-labels' :: List of already transcoded footnote
-;; labels. It is used to know when a reference appears for the
-;; first time. (cf. `org-export-footnote-first-reference-p').
-;; - category :: persistent
-;; - type :: list of strings
-;; - update :: `org-export-update-info'
-
-;; + `genealogy' :: List of current element's parents types.
-;; - category :: local
-;; - type :: list of symbols
-;; - update :: `org-export-update-info'
-
-;; + `headline-alist' :: Alist between headlines raw name and their
-;; boundaries. It is used to resolve "fuzzy" links
-;; (cf. `org-export-resolve-fuzzy-link').
-;; - category :: persistent
-;; - type :: alist (STRING INTEGER INTEGER)
-
-;; + `headline-levels' :: Maximum level being exported as an
+;; + `:headline-levels' :: Maximum level being exported as an
;; headline. Comparison is done with the relative level of
;; headlines in the parse tree, not necessarily with their
;; actual level.
;; - category :: option
;; - type :: integer
-;; + `headline-offset' :: Difference between relative and real level
+;; + `:headline-offset' :: Difference between relative and real level
;; of headlines in the parse tree. For example, a value of -1
;; means a level 2 headline should be considered as level
;; 1 (cf. `org-export-get-relative-level').
-;; - category :: persistent
+;; - category :: tree
;; - type :: integer
-;; + `headline-numbering' :: Alist between headlines' beginning
-;; position and their numbering, as a list of numbers
+;; + `:headline-numbering' :: Alist between headlines and their
+;; numbering, as a list of numbers
;; (cf. `org-export-get-headline-number').
-;; - category :: persistent
+;; - category :: tree
;; - type :: alist (INTEGER . LIST)
-;; + `included-files' :: List of files, with full path, included in
-;; the current buffer, through the "#+include:" keyword. It is
-;; mainly used to verify that no infinite recursive inclusion
-;; happens.
+;; + `:ignore-list' :: List of elements and objects that should be
+;; ignored during export.
;; - category :: local
-;; - type :: list of strings
+;; - type :: list of elements and objects
-;; + `inherited-properties' :: Properties of the headline ancestors
-;; of the current element or object. Those from the closest
-;; headline have precedence over the others.
-;; - category :: local
-;; - type :: plist
+;; + `:input-file' :: Full path to input file, if any.
+;; - category :: option
+;; - type :: string or nil
-;; + `keywords' :: List of keywords attached to data.
+;; + `:keywords' :: List of keywords attached to data.
;; - category :: option
;; - type :: string
-;; + `language' :: Default language used for translations.
+;; + `:language' :: Default language used for translations.
;; - category :: option
;; - type :: string
-;; + `parent-properties' :: Properties of the parent element.
-;; - category :: local
-;; - type :: plist
-;; - update :: `org-export-update-info'
+;; + `:macro-input-file' :: Macro returning file name of input file,
+;; or nil.
+;; - category :: option
+;; - type :: string or nil
-;; + `parse-tree' :: Whole parse tree, available at any time during
+;; + `:parse-tree' :: Whole parse tree, available at any time during
;; transcoding.
;; - category :: global
;; - type :: list (as returned by `org-element-parse-buffer')
-;; + `point-max' :: Last ending position in the parse tree.
-;; - category :: global
-;; - type :: integer
-
-;; + `preserve-breaks' :: Non-nil means transcoding should preserve
+;; + `:preserve-breaks' :: Non-nil means transcoding should preserve
;; all line breaks.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `previous-element' :: Previous element's type at the same
-;; level.
-;; - category :: local
-;; - type :: symbol
-;; - update :: `org-export-update-info'
-
-;; + `previous-object' :: Previous object type (or `plain-text') at
-;; the same level.
-;; - category :: local
-;; - type :: symbol
-;; - update :: `org-export-update-info'
-
-;; + `section-numbers' :: Non-nil means transcoding should add
+;; + `:section-numbers' :: Non-nil means transcoding should add
;; section numbers to headlines.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `select-tags' :: List of tags enforcing inclusion of sub-trees in
-;; transcoding. When such a tag is present,
+;; + `:select-tags' :: List of tags enforcing inclusion of sub-trees
+;; in transcoding. When such a tag is present,
;; subtrees without it are de facto excluded from
;; the process. See `use-select-tags'.
;; - category :: option
;; - type :: list of strings
-;; + `target-list' :: List of targets raw names encoutered in the
-;; parse tree. This is used to partly resolve
-;; "fuzzy" links
+;; + `:target-list' :: List of targets encountered in the parse tree.
+;; This is used to partly resolve "fuzzy" links
;; (cf. `org-export-resolve-fuzzy-link').
-;; - category :: persistent
+;; - category :: tree
;; - type :: list of strings
-;; + `time-stamp-file' :: Non-nil means transcoding should insert
+;; + `:time-stamp-file' :: Non-nil means transcoding should insert
;; a time stamp in the output.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `total-loc' :: Contains total lines of code accumulated by source
-;; blocks with the "+n" option so far.
-;; - category :: persistent
-;; - type :: integer
-;; - update :: `org-export-handle-code'
-
-;; + `use-select-tags' :: When non-nil, a select tags has been found
-;; in the parse tree. Thus, any headline without one will be
-;; filtered out. See `select-tags'.
-;; - category :: persistent
-;; - type :: interger or nil
-
-;; + `with-archived-trees' :: Non-nil when archived subtrees should
+;; + `:with-archived-trees' :: Non-nil when archived subtrees should
;; also be transcoded. If it is set to the `headline' symbol,
;; only the archived headline's name is retained.
;; - category :: option
;; - type :: symbol (nil, t, `headline')
-;; + `with-author' :: Non-nil means author's name should be included
+;; + `:with-author' :: Non-nil means author's name should be included
;; in the output.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-creator' :: Non-nild means a creation sentence should be
+;; + `:with-creator' :: Non-nild means a creation sentence should be
;; inserted at the end of the transcoded string. If the value
;; is `comment', it should be commented.
;; - category :: option
;; - type :: symbol (`comment', nil, t)
-;; + `with-drawers' :: Non-nil means drawers should be exported. If
+;; + `:with-drawers' :: Non-nil means drawers should be exported. If
;; its value is a list of names, only drawers with such names
;; will be transcoded.
;; - category :: option
;; - type :: symbol (nil, t) or list of strings
-;; + `with-email' :: Non-nil means output should contain author's
+;; + `:with-email' :: Non-nil means output should contain author's
;; email.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-emphasize' :: Non-nil means emphasized text should be
+;; + `:with-emphasize' :: Non-nil means emphasized text should be
;; interpreted.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-fixed-width' :: Non-nil if transcoder should interpret
-;; strings starting with a colon as a fixed-with (verbatim)
-;; area.
+;; + `:with-fixed-width' :: Non-nil if transcoder should interpret
+;; strings starting with a colon as a fixed-with (verbatim) area.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-footnotes' :: Non-nil if transcoder should interpret
+;; + `:with-footnotes' :: Non-nil if transcoder should interpret
;; footnotes.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-priority' :: Non-nil means transcoding should include
+;; + `:with-priority' :: Non-nil means transcoding should include
;; priority cookies.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-special-strings' :: Non-nil means transcoding should
+;; + `:with-special-strings' :: Non-nil means transcoding should
;; interpret special strings in plain text.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-sub-superscript' :: Non-nil means transcoding should
+;; + `:with-sub-superscript' :: Non-nil means transcoding should
;; interpret subscript and superscript. With a value of "{}",
;; only interpret those using curly brackets.
;; - category :: option
;; - type :: symbol (nil, {}, t)
-;; + `with-tables' :: Non-nil means transcoding should interpret
+;; + `:with-tables' :: Non-nil means transcoding should interpret
;; tables.
;; - category :: option
;; - type :: symbol (nil, t)
-;; + `with-tags' :: Non-nil means transcoding should keep tags in
+;; + `:with-tags' :: Non-nil means transcoding should keep tags in
;; headlines. A `not-in-toc' value will remove them
;; from the table of contents, if any, nonetheless.
;; - category :: option
;; - type :: symbol (nil, t, `not-in-toc')
-;; + `with-tasks' :: Non-nil means transcoding should include
+;; + `:with-tasks' :: Non-nil means transcoding should include
;; headlines with a TODO keyword. A `todo' value
;; will only include headlines with a todo type
;; keyword while a `done' value will do the
@@ -798,36 +866,37 @@ (defcustom org-export-snippet-translation-alist nil
;; - category :: option
;; - type :: symbol (t, todo, done, nil) or list of strings
-;; + `with-timestamps' :: Non-nil means transcoding should include
+;; + `:with-timestamps' :: Non-nil means transcoding should include
;; time stamps and associated keywords. Otherwise, completely
;; remove them.
;; - category :: option
;; - type :: symbol: (t, nil)
-;; + `with-toc' :: Non-nil means that a table of contents has to be
+;; + `:with-toc' :: Non-nil means that a table of contents has to be
;; added to the output. An integer value limits its
;; depth.
;; - category :: option
;; - type :: symbol (nil, t or integer)
-;; + `with-todo-keywords' :: Non-nil means transcoding should
+;; + `:with-todo-keywords' :: Non-nil means transcoding should
;; include TODO keywords.
;; - category :: option
;; - type :: symbol (nil, t)
-;;;; Export Options
-;; Export options come from five sources, in increasing precedence
-;; order:
+;;;; Environment Options
+;; Environment options encompass all parameters defined outside the
+;; scope of the parsed data. They come from five sources, in
+;; increasing precedence order:
+;;
;; - Global variables,
-;; - External options provided at export time,
;; - Options keyword symbols,
;; - Buffer keywords,
;; - Subtree properties.
-;; The central internal function with regards to export options is
-;; `org-export-collect-options'. It updates global variables with
+;; The central internal function with regards to environment options
+;; is `org-export-get-environment'. It updates global variables with
;; "#+BIND:" keywords, then retrieve and prioritize properties from
;; the different sources.
@@ -837,61 +906,62 @@ (defcustom org-export-snippet-translation-alist nil
;; `org-export-get-inbuffer-options' and
;; `org-export-get-global-options'.
;;
-;; Some properties do not rely on the previous sources but still
-;; depend on the original buffer are taken care of in
+;; Some properties, which do not rely on the previous sources but
+;; still depend on the original buffer, are taken care of with
;; `org-export-initial-options'.
;; Also, `org-export-confirm-letbind' and `org-export-install-letbind'
;; take care of the part relative to "#+BIND:" keywords.
-(defun org-export-collect-options (backend subtreep ext-plist)
+(defun org-export-get-environment (&optional backend subtreep ext-plist)
"Collect export options from the current buffer.
-BACKEND is a symbol specifying the back-end to use.
+Optional argument BACKEND is a symbol specifying which back-end
+specific options to read, if any.
-When SUBTREEP is non-nil, assume the export is done against the
-current sub-tree.
+When optional argument SUBTREEP is non-nil, assume the export is
+done against the current sub-tree.
-EXT-PLIST is a property list with external parameters overriding
-org-mode's default settings, but still inferior to file-local
-settings."
+Third optional argument EXT-PLIST is a property list with
+external parameters overriding Org default settings, but still
+inferior to file-local settings."
;; First install #+BIND variables.
(org-export-install-letbind-maybe)
;; Get and prioritize export options...
(let ((options (org-combine-plists
;; ... from global variables...
(org-export-get-global-options backend)
+ ;; ... from buffer's name (default title)...
+ `(:title
+ ,(or (let ((file (buffer-file-name (buffer-base-buffer))))
+ (and file
+ (file-name-sans-extension
+ (file-name-nondirectory file))))
+ (buffer-name (buffer-base-buffer))))
;; ... from an external property list...
ext-plist
;; ... from in-buffer settings...
(org-export-get-inbuffer-options
- (org-with-wide-buffer (buffer-string)) backend
+ backend
(and buffer-file-name
(org-remove-double-quotes buffer-file-name)))
;; ... and from subtree, when appropriate.
- (and subtreep
- (org-export-get-subtree-options)))))
+ (and subtreep (org-export-get-subtree-options)))))
;; Add initial options.
- (setq options (append (org-export-initial-options options)
- options))
- ;; Set a default title if none has been specified so far.
- (unless (plist-get options :title)
- (setq options (plist-put options :title
- (or (and buffer-file-name
- (file-name-sans-extension
- (file-name-nondirectory
- buffer-file-name)))
- (buffer-name)))))
+ (setq options (append (org-export-initial-options) options))
;; Return plist.
options))
-(defun org-export-parse-option-keyword (options backend)
+(defun org-export-parse-option-keyword (options &optional backend)
"Parse an OPTIONS line and return values as a plist.
-BACKEND is a symbol specifying the back-end to use."
- (let* ((all (append org-export-option-alist
- (let ((var (intern
- (format "org-%s-option-alist" backend))))
- (and (boundp var) (eval var)))))
+Optional argument BACKEND is a symbol specifying which back-end
+specific items to read, if any."
+ (let* ((all
+ (append org-export-option-alist
+ (and backend
+ (let ((var (intern
+ (format "org-%s-option-alist" backend))))
+ (and (boundp var) (eval var))))))
;; Build an alist between #+OPTION: item and property-name.
(alist (delq nil
(mapcar (lambda (e)
@@ -913,162 +983,226 @@ (defun org-export-parse-option-keyword (options backend)
(defun org-export-get-subtree-options ()
"Get export options in subtree at point.
-Return the options as a plist."
- (org-with-wide-buffer
- (when (ignore-errors (org-back-to-heading t))
- (let (prop plist)
- (when (setq prop (progn (looking-at org-todo-line-regexp)
- (or (org-entry-get (point) "EXPORT_TITLE")
- (org-match-string-no-properties 3))))
- (setq plist (plist-put plist :title prop)))
- (when (setq prop (org-entry-get (point) "EXPORT_TEXT"))
- (setq plist (plist-put plist :text prop)))
- (when (setq prop (org-entry-get (point) "EXPORT_AUTHOR"))
- (setq plist (plist-put plist :author prop)))
- (when (setq prop (org-entry-get (point) "EXPORT_DATE"))
- (setq plist (plist-put plist :date prop)))
- (when (setq prop (org-entry-get (point) "EXPORT_OPTIONS"))
- (setq plist (org-export-add-options-to-plist plist prop)))
- plist))))
-
-(defun org-export-get-inbuffer-options (buffer-string backend files)
- "Return in-buffer options as a plist.
-BUFFER-STRING is the string of the buffer. BACKEND is a symbol
-specifying which back-end should be used."
- (let ((case-fold-search t) plist)
- ;; 1. Special keywords, as in `org-export-special-keywords'.
- (let ((start 0)
- (special-re (org-make-options-regexp org-export-special-keywords)))
- (while (string-match special-re buffer-string start)
- (setq start (match-end 0))
- (let ((key (upcase (org-match-string-no-properties 1 buffer-string)))
- ;; Special keywords do not have their value expanded.
- (val (org-match-string-no-properties 2 buffer-string)))
- (setq plist
- (org-combine-plists
- (cond
- ((string= key "SETUP_FILE")
- (let ((file (expand-file-name
- (org-remove-double-quotes (org-trim val)))))
- ;; Avoid circular dependencies.
- (unless (member file files)
- (org-export-get-inbuffer-options
- (org-file-contents file 'noerror)
- backend
- (cons file files)))))
- ((string= key "OPTIONS")
- (org-export-parse-option-keyword val backend))
- ((string= key "MACRO")
- (string-match "^\\([-a-zA-Z0-9_]+\\)[ \t]+\\(.*?[ \t]*$\\)"
- val)
- (plist-put nil
- (intern (concat ":macro-"
- (downcase (match-string 1 val))))
- (match-string 2 val))))
- plist)))))
- ;; 2. Standard options, as in `org-export-option-alist'.
- (let* ((all (append org-export-option-alist
- (let ((var (intern
- (format "org-%s-option-alist" backend))))
- (and (boundp var) (eval var)))))
- ;; Build alist between keyword name and property name.
- (alist (delq nil (mapcar (lambda (e)
- (when (nth 1 e) (cons (nth 1 e) (car e))))
- all)))
- ;; Build regexp matching all keywords associated to export
- ;; options. Note: the search is case insensitive.
- (opt-re (org-make-options-regexp
- (delq nil (mapcar (lambda (e) (nth 1 e)) all))))
- (start 0))
- (while (string-match opt-re buffer-string start)
- (setq start (match-end 0))
- (let* ((key (upcase (org-match-string-no-properties 1 buffer-string)))
- ;; Expand value, applying restrictions for keywords.
- (val (org-match-string-no-properties 2 buffer-string))
- (prop (cdr (assoc key alist)))
- (behaviour (nth 4 (assq prop all))))
- (setq plist
- (plist-put
- plist prop
- ;; Handle value depending on specified BEHAVIOUR.
- (case behaviour
- (space (if (plist-get plist prop)
- (concat (plist-get plist prop) " " (org-trim val))
- (org-trim val)))
- (newline (org-trim
- (concat
- (plist-get plist prop) "\n" (org-trim val))))
- (split `(,@(plist-get plist prop) ,@(org-split-string val)))
- ('t val)
- (otherwise (plist-get plist prop)))))))
- ;; Parse keywords specified in `org-element-parsed-keywords'.
- (mapc
- (lambda (key)
- (let* ((prop (cdr (assoc (upcase key) alist)))
- (value (and prop (plist-get plist prop))))
- (when (stringp value)
- (setq plist
- (plist-put
- plist prop
- (org-element-parse-secondary-string
- value
- (cdr (assq 'keyword org-element-string-restrictions))))))))
- org-element-parsed-keywords))
- ;; Return final value.
+
+Assume point is at subtree's beginning.
+
+Return options as a plist."
+ (let (prop plist)
+ (when (setq prop (progn (looking-at org-todo-line-regexp)
+ (or (save-match-data
+ (org-entry-get (point) "EXPORT_TITLE"))
+ (org-match-string-no-properties 3))))
+ (setq plist
+ (plist-put
+ plist :title
+ (org-element-parse-secondary-string
+ prop
+ (cdr (assq 'keyword org-element-string-restrictions))))))
+ (when (setq prop (org-entry-get (point) "EXPORT_TEXT"))
+ (setq plist (plist-put plist :text prop)))
+ (when (setq prop (org-entry-get (point) "EXPORT_AUTHOR"))
+ (setq plist (plist-put plist :author prop)))
+ (when (setq prop (org-entry-get (point) "EXPORT_DATE"))
+ (setq plist (plist-put plist :date prop)))
+ (when (setq prop (org-entry-get (point) "EXPORT_OPTIONS"))
+ (setq plist (org-export-add-options-to-plist plist prop)))
plist))
-(defun org-export-get-global-options (backend)
+(defun org-export-get-inbuffer-options (&optional backend files)
+ "Return current buffer export options, as a plist.
+
+Optional argument BACKEND, when non-nil, is a symbol specifying
+which back-end specific options should also be read in the
+process.
+
+Optional argument FILES is a list of setup files names read so
+far, used to avoid circular dependencies.
+
+Assume buffer is in Org mode. Narrowing, if any, is ignored."
+ (org-with-wide-buffer
+ (goto-char (point-min))
+ (let ((case-fold-search t) plist)
+ ;; 1. Special keywords, as in `org-export-special-keywords'.
+ (let ((special-re (org-make-options-regexp org-export-special-keywords)))
+ (while (re-search-forward special-re nil t)
+ (let ((element (org-element-at-point)))
+ (when (eq (org-element-type element) 'keyword)
+ (let* ((key (upcase (org-element-property :key element)))
+ (val (org-element-property :value element))
+ (prop
+ (cond
+ ((string= key "SETUP_FILE")
+ (let ((file
+ (expand-file-name
+ (org-remove-double-quotes (org-trim val)))))
+ ;; Avoid circular dependencies.
+ (unless (member file files)
+ (with-temp-buffer
+ (insert (org-file-contents file 'noerror))
+ (org-mode)
+ (org-export-get-inbuffer-options
+ backend (cons file files))))))
+ ((string= key "OPTIONS")
+ (org-export-parse-option-keyword val backend))
+ ((string= key "MACRO")
+ (when (string-match
+ "^\\([-a-zA-Z0-9_]+\\)\\(?:[ \t]+\\(.*?\\)[ \t]*$\\)?"
+ val)
+ (let ((key
+ (intern
+ (concat ":macro-"
+ (downcase (match-string 1 val)))))
+ (value (org-match-string-no-properties 2 val)))
+ (cond
+ ((not value) nil)
+ ;; Value will be evaled. Leave it as-is.
+ ((string-match "\\`(eval\\>" value)
+ (list key value))
+ ;; Value has to be parsed for nested
+ ;; macros.
+ (t
+ (list
+ key
+ (let ((restr
+ (cdr
+ (assq 'macro
+ org-element-object-restrictions))))
+ (org-element-parse-secondary-string
+ ;; If user explicitly asks for
+ ;; a newline, be sure to preserve it
+ ;; from further filling with
+ ;; `hard-newline'. Also replace
+ ;; "\\n" with "\n", "\\\n" with "\\n"
+ ;; and so on...
+ (replace-regexp-in-string
+ "\\(\\\\\\\\\\)n" "\\\\"
+ (replace-regexp-in-string
+ "\\(?:^\\|[^\\\\]\\)\\(\\\\n\\)"
+ hard-newline value nil nil 1)
+ nil nil 1)
+ restr)))))))))))
+ (setq plist (org-combine-plists plist prop)))))))
+ ;; 2. Standard options, as in `org-export-option-alist'.
+ (let* ((all (append org-export-option-alist
+ ;; Also look for back-end specific options
+ ;; if BACKEND is defined.
+ (and backend
+ (let ((var
+ (intern
+ (format "org-%s-option-alist" backend))))
+ (and (boundp var) (eval var))))))
+ ;; Build alist between keyword name and property name.
+ (alist
+ (delq nil (mapcar
+ (lambda (e) (when (nth 1 e) (cons (nth 1 e) (car e))))
+ all)))
+ ;; Build regexp matching all keywords associated to export
+ ;; options. Note: the search is case insensitive.
+ (opt-re (org-make-options-regexp
+ (delq nil (mapcar (lambda (e) (nth 1 e)) all)))))
+ (goto-char (point-min))
+ (while (re-search-forward opt-re nil t)
+ (let ((element (org-element-at-point)))
+ (when (eq (org-element-type element) 'keyword)
+ (let* ((key (upcase (org-element-property :key element)))
+ (val (org-element-property :value element))
+ (prop (cdr (assoc key alist)))
+ (behaviour (nth 4 (assq prop all))))
+ (setq plist
+ (plist-put
+ plist prop
+ ;; Handle value depending on specified BEHAVIOUR.
+ (case behaviour
+ (space
+ (if (not (plist-get plist prop)) (org-trim val)
+ (concat (plist-get plist prop) " " (org-trim val))))
+ (newline
+ (org-trim
+ (concat (plist-get plist prop) "\n" (org-trim val))))
+ (split
+ `(,@(plist-get plist prop) ,@(org-split-string val)))
+ ('t val)
+ (otherwise (if (not (plist-member plist prop)) val
+ (plist-get plist prop))))))))))
+ ;; Parse keywords specified in `org-element-parsed-keywords'.
+ (mapc
+ (lambda (key)
+ (let* ((prop (cdr (assoc key alist)))
+ (value (and prop (plist-get plist prop))))
+ (when (stringp value)
+ (setq plist
+ (plist-put
+ plist prop
+ (org-element-parse-secondary-string
+ value
+ (cdr (assq 'keyword org-element-string-restrictions))))))))
+ org-element-parsed-keywords))
+ ;; 3. Return final value.
+ plist)))
+
+(defun org-export-get-global-options (&optional backend)
"Return global export options as a plist.
-BACKEND is a symbol specifying which back-end should be used."
+
+Optional argument BACKEND, if non-nil, is a symbol specifying
+which back-end specific export options should also be read in the
+process."
(let ((all (append org-export-option-alist
- (let ((var (intern
- (format "org-%s-option-alist" backend))))
- (and (boundp var) (eval var)))))
+ (and backend
+ (let ((var (intern
+ (format "org-%s-option-alist" backend))))
+ (and (boundp var) (eval var))))))
;; Output value.
plist)
(mapc (lambda (cell)
- (setq plist
- (plist-put plist (car cell) (eval (nth 3 cell)))))
+ (setq plist (plist-put plist (car cell) (eval (nth 3 cell)))))
all)
;; Return value.
plist))
-(defun org-export-initial-options (options)
- "Return a plist with non-optional properties.
-OPTIONS is the export options plist computed so far."
- (list
- ;; `:macro-date', `:macro-time' and `:macro-property' could as well
- ;; be initialized as persistent properties, since they don't depend
- ;; on initial environment. Though, it may be more logical to keep
- ;; them close to other ":macro-" properties.
- :macro-date "(eval (format-time-string \"$1\"))"
- :macro-time "(eval (format-time-string \"$1\"))"
- :macro-property "(eval (org-entry-get nil \"$1\" 'selective))"
- :macro-modification-time
- (and (buffer-file-name)
- (file-exists-p (buffer-file-name))
- (concat "(eval (format-time-string \"$1\" '"
- (prin1-to-string (nth 5 (file-attributes (buffer-file-name))))
- "))"))
- :macro-input-file (and (buffer-file-name)
- (file-name-nondirectory (buffer-file-name)))
- ;; Footnotes definitions must be collected in the original buffer,
- ;; as there's no insurance that they will still be in the parse
- ;; tree, due to some narrowing.
- :footnote-definition-alist
- (let (alist)
- (org-with-wide-buffer
- (goto-char (point-min))
- (while (re-search-forward org-footnote-definition-re nil t)
- (let ((def (org-footnote-at-definition-p)))
- (when def
- (org-skip-whitespace)
- (push (cons (car def)
- (save-restriction
- (narrow-to-region (point) (nth 2 def))
- (org-element-parse-buffer)))
- alist))))
- alist))))
+(defun org-export-initial-options ()
+ "Return a plist with properties related to input buffer."
+ (let ((visited-file (buffer-file-name (buffer-base-buffer))))
+ (list
+ ;; Store full path of input file name, or nil. For internal use.
+ :input-file visited-file
+ ;; `:macro-date', `:macro-time' and `:macro-property' could as well
+ ;; be initialized as tree properties, since they don't depend on
+ ;; initial environment. Though, it may be more logical to keep
+ ;; them close to other ":macro-" properties.
+ :macro-date "(eval (format-time-string \"$1\"))"
+ :macro-time "(eval (format-time-string \"$1\"))"
+ :macro-property "(eval (org-entry-get nil \"$1\" 'selective))"
+ :macro-modification-time
+ (and visited-file
+ (file-exists-p visited-file)
+ (concat "(eval (format-time-string \"$1\" '"
+ (prin1-to-string (nth 5 (file-attributes visited-file)))
+ "))"))
+ ;; Store input file name as a macro.
+ :macro-input-file (and visited-file (file-name-nondirectory visited-file))
+ ;; Footnotes definitions must be collected in the original buffer,
+ ;; as there's no insurance that they will still be in the parse
+ ;; tree, due to some narrowing.
+ :footnote-definition-alist
+ (let (alist)
+ (org-with-wide-buffer
+ (goto-char (point-min))
+ (while (re-search-forward org-footnote-definition-re nil t)
+ (let ((def (org-footnote-at-definition-p)))
+ (when def
+ (org-skip-whitespace)
+ (push (cons (car def)
+ (save-restriction
+ (narrow-to-region (point) (nth 2 def))
+ ;; Like `org-element-parse-buffer', but
+ ;; makes sure the definition doesn't start
+ ;; with a section element.
+ (nconc
+ (list 'org-data nil)
+ (org-element-parse-elements
+ (point-min) (point-max) nil nil nil nil nil))))
+ alist))))
+ alist)))))
(defvar org-export-allow-BIND-local nil)
(defun org-export-confirm-letbind ()
@@ -1097,125 +1231,74 @@ (defun org-export-install-letbind-maybe ()
(org-set-local (car pair) (nth 1 pair)))))
-;;;; Persistent Properties
-
-;; Persistent properties are declared in
-;; `org-export-persistent-properties-list' variable. Most of them are
-;; initialized at the beginning of the transcoding process by
-;; `org-export-initialize-persistent-properties'. The others are
-;; updated during that process.
-
-;; Dedicated functions focus on computing the value of specific
-;; persistent properties during initialization. Thus,
-;; `org-export-use-select-tag-p' determines if an headline makes use
-;; of an export tag enforcing inclusion. `org-export-get-min-level'
-;; gets the minimal exportable level, used as a basis to compute
-;; relative level for headlines. `org-export-get-point-max' returns
-;; the maximum exportable ending position in the parse tree.
-;; Eventually `org-export-collect-headline-numbering' builds an alist
-;; between headlines' beginning position and their numbering.
-
-(defconst org-export-persistent-properties-list
- '(:back-end :code-refs :headline-alist :headline-numbering :headline-offset
- :parse-tree :point-max :footnote-seen-labels :target-list
- :total-loc :use-select-tags)
- "List of persistent properties.")
+;;;; Tree Properties
-(defconst org-export-persistent-properties nil
- "Used internally to store properties and values during transcoding.
+;; Tree properties are infromation extracted from parse tree. They
+;; are initialized at the beginning of the transcoding process by
+;; `org-export-collect-tree-properties'.
-Only properties that should survive recursion are saved here.
+;; Dedicated functions focus on computing the value of specific tree
+;; properties during initialization. Thus,
+;; `org-export-populate-ignore-list' lists elements and objects that
+;; should be skipped during export, `org-export-get-min-level' gets
+;; the minimal exportable level, used as a basis to compute relative
+;; level for headlines. Eventually
+;; `org-export-collect-headline-numbering' builds an alist between
+;; headlines and their numbering.
-This variable is reset before each transcoding.")
+(defun org-export-collect-tree-properties (data info backend)
+ "Extract tree properties from parse tree.
-(defun org-export-initialize-persistent-properties (data options backend)
- "Initialize `org-export-persistent-properties'.
+DATA is the parse tree from which information is retrieved. INFO
+is a list holding export options. BACKEND is the back-end called
+for transcoding, as a symbol.
-DATA is the parse tree from which information is retrieved.
-OPTIONS is a list holding export options. BACKEND is the
-back-end called for transcoding, as a symbol.
-
-Following initial persistent properties are set:
+Following tree properties are set:
`:back-end' Back-end used for transcoding.
-`:headline-alist' Alist of all headlines' name as key and a list
- holding beginning and ending positions as
- value.
-
`:headline-offset' Offset between true level of headlines and
- local level. An offset of -1 means an headline
+ local level. An offset of -1 means an headline
of level 2 should be considered as a level
1 headline in the context.
-`:headline-numbering' Alist of all headlines' beginning position
- as key an the associated numbering as value.
+`:headline-numbering' Alist of all headlines as key an the
+ associated numbering as value.
+
+`:ignore-list' List of elements that should be ignored during
+ export.
`:parse-tree' Whole parse tree.
-`:point-max' Last position in the parse tree
-
-`:target-list' List of all targets' raw name in the parse tree.
-
-`:use-select-tags' Non-nil when parsed tree use a special tag to
- enforce transcoding of the headline."
- ;; First delete any residual persistent property.
- (setq org-export-persistent-properties nil)
- ;; Immediately after, set `:use-select-tags' property, as it will be
- ;; required for further computations.
- (setq options
- (org-export-set-property
- options
- :use-select-tags
- (org-export-use-select-tags-p data options)))
- ;; Get the rest of the initial persistent properties, now
- ;; `:use-select-tags' is set...
- ;; 1. `:parse-tree' ...
- (setq options (org-export-set-property options :parse-tree data))
- ;; 2. `:headline-offset' ...
- (setq options
- (org-export-set-property
- options :headline-offset
- (- 1 (org-export-get-min-level data options))))
- ;; 3. `:point-max' ...
- (setq options (org-export-set-property
- options :point-max
- (org-export-get-point-max data options)))
- ;; 4. `:target-list'...
- (setq options (org-export-set-property
- options :target-list
- (org-element-map
- data 'target
- (lambda (target info)
- (org-element-get-property :raw-value target)))))
- ;; 5. `:headline-alist'
- (setq options (org-export-set-property
- options :headline-alist
- (org-element-map
- data 'headline
- (lambda (headline info)
- (list (org-element-get-property :raw-value headline)
- (org-element-get-property :begin headline)
- (org-element-get-property :end headline))))))
- ;; 6. `:headline-numbering'
- (setq options (org-export-set-property
- options :headline-numbering
- (org-export-collect-headline-numbering data options)))
- ;; 7. `:back-end'
- (setq options (org-export-set-property options :back-end backend)))
-
-(defun org-export-use-select-tags-p (data options)
- "Non-nil when data use a tag enforcing transcoding.
-DATA is parsed data as returned by `org-element-parse-buffer'.
-OPTIONS is a plist holding export options."
- (org-element-map
- data
- 'headline
- (lambda (headline info)
- (let ((tags (org-element-get-property :with-tags headline)))
- (and tags (string-match
- (format ":%s:" (plist-get info :select-tags)) tags))))
- options
- 'stop-at-first-match))
+`:target-list' List of all targets in the parse tree."
+ ;; First, get the list of elements and objects to ignore, and put it
+ ;; into `:ignore-list'. Do not overwrite any user ignore that might
+ ;; have been done during parse tree filtering.
+ (setq info
+ (plist-put info
+ :ignore-list
+ (append (org-export-populate-ignore-list data info)
+ (plist-get info :ignore-list))))
+ ;; Then compute `:headline-offset' in order to be able to use
+ ;; `org-export-get-relative-level'.
+ (setq info
+ (plist-put info
+ :headline-offset (- 1 (org-export-get-min-level data info))))
+ ;; Now, properties order doesn't matter: get the rest of the tree
+ ;; properties.
+ (nconc
+ `(:parse-tree
+ ,data
+ :target-list
+ ,(org-element-map
+ data '(keyword target)
+ (lambda (blob)
+ (when (or (eq (org-element-type blob) 'target)
+ (string= (upcase (org-element-property :key blob))
+ "TARGET"))
+ blob)) info)
+ :headline-numbering ,(org-export-collect-headline-numbering data info)
+ :back-end ,backend)
+ info))
(defun org-export-get-min-level (data options)
"Return minimum exportable headline's level in DATA.
@@ -1223,47 +1306,35 @@ (defun org-export-get-min-level (data options)
OPTIONS is a plist holding export options."
(catch 'exit
(let ((min-level 10000))
- (mapc (lambda (blob)
- (when (and (eq (car blob) 'headline)
- (not (org-export-skip-p blob options)))
- (setq min-level
- (min (org-element-get-property :level blob) min-level)))
- (when (= min-level 1) (throw 'exit 1)))
- (org-element-get-contents data))
+ (mapc
+ (lambda (blob)
+ (when (and (eq (org-element-type blob) 'headline)
+ (not (member blob (plist-get options :ignore-list))))
+ (setq min-level
+ (min (org-element-property :level blob) min-level)))
+ (when (= min-level 1) (throw 'exit 1)))
+ (org-element-contents data))
;; If no headline was found, for the sake of consistency, set
;; minimum level to 1 nonetheless.
(if (= min-level 10000) 1 min-level))))
-(defun org-export-get-point-max (data options)
- "Return last exportable ending position in DATA.
-DATA is parsed tree as returned by `org-element-parse-buffer'.
-OPTIONS is a plist holding export options."
- (let ((pos-max 1))
- (mapc (lambda (blob)
- (unless (and (eq (car blob) 'headline)
- (org-export-skip-p blob options))
- (setq pos-max (org-element-get-property :end blob))))
- (org-element-get-contents data))
- pos-max))
-
(defun org-export-collect-headline-numbering (data options)
"Return numbering of all exportable headlines in a parse tree.
DATA is the parse tree. OPTIONS is the plist holding export
options.
-Return an alist whose key is headline's beginning position and
-value is its associated numbering (in the shape of a list of
-numbers)."
+Return an alist whose key is an headline and value is its
+associated numbering \(in the shape of a list of numbers\)."
(let ((numbering (make-vector org-export-max-depth 0)))
(org-element-map
data
'headline
- (lambda (headline info)
+ (lambda (headline)
(let ((relative-level
- (1- (org-export-get-relative-level headline info))))
+ (1- (org-export-get-relative-level headline options))))
(cons
- (org-element-get-property :begin headline)
+ headline
(loop for n across numbering
for idx from 0 to org-export-max-depth
when (< idx relative-level) collect n
@@ -1271,92 +1342,107 @@ (defun org-export-collect-headline-numbering (data options)
when (> idx relative-level) do (aset numbering idx 0)))))
options)))
+(defun org-export-populate-ignore-list (data options)
+ "Return list of elements and objects to ignore during export.
+
+DATA is the parse tree to traverse. OPTIONS is the plist holding
+export options.
+
+Return elements or objects to ignore as a list."
+ (let (ignore
+ (walk-data
+ (function
+ (lambda (data options selected)
+ ;; Collect ignored elements or objects into IGNORE-LIST.
+ (mapc
+ (lambda (el)
+ (if (org-export--skip-p el options selected) (push el ignore)
+ (let ((type (org-element-type el)))
+ (if (and (eq (plist-get info :with-archived-trees) 'headline)
+ (eq (org-element-type el) 'headline)
+ (org-element-property :archivedp el))
+ ;; If headline is archived but tree below has
+ ;; to be skipped, add it to ignore list.
+ (mapc (lambda (e) (push e ignore))
+ (org-element-contents el))
+ ;; Move into recursive objects/elements.
+ (when (or (eq type 'org-data)
+ (memq type org-element-greater-elements)
+ (memq type org-element-recursive-objects)
+ (eq type 'paragraph))
+ (funcall walk-data el options selected))))))
+ (org-element-contents data))))))
+ ;; Main call. First find trees containing a select tag, if any.
+ (funcall walk-data data options (org-export--selected-trees data options))
+ ;; Return value.
+ ignore))
-;;;; Properties Management
-
-;; This is mostly done with the help of two functions. On the one
-;; hand `org-export-update-info' is used to keep up-to-date local
-;; information while walking the nested list representing the parsed
-;; document. On the other end, `org-export-set-property' handles
-;; properties modifications according to their type (persistent or
-;; local).
-
-;; As exceptions, `:code-refs' and `:total-loc' properties are updated
-;; with `org-export-handle-code' function.
-
-(defun org-export-update-info (blob info recursep)
- "Update export options depending on context.
-
-BLOB is the element or object being parsed. INFO is the plist
-holding the export options.
-
-When RECURSEP is non-nil, assume the following element or object
-will be inside the current one.
-
-The following properties are updated:
-`footnote-seen-labels' List of already parsed footnote
- labels (string list)
-`genealogy' List of current element's parents
- (symbol list).
-`inherited-properties' List of inherited properties from
- parent headlines (plist).
-`parent-properties' List of last element's properties
- (plist).
-`previous-element' Previous element's type (symbol).
-`previous-object' Previous object's type (symbol).
-
-Return the property list."
- (let* ((type (and (not (stringp blob)) (car blob))))
- (cond
- ;; Case 1: We're moving into a recursive blob.
- (recursep
- (org-combine-plists
- info
- `(:genealogy ,(cons type (plist-get info :genealogy))
- :previous-element nil
- :previous-object nil
- :parent-properties
- ,(if (memq type org-element-all-elements)
- (nth 1 blob)
- (plist-get info :parent-properties))
- :inherited-properties
- ,(if (eq type 'headline)
- (org-combine-plists
- (plist-get info :inherited-properties) (nth 1 blob))
- (plist-get info :inherited-properties)))
- ;; Add persistent properties.
- org-export-persistent-properties))
- ;; Case 2: No recursion.
- (t
- ;; At a footnote reference: mark its label as seen, if not
- ;; already the case.
- (when (eq type 'footnote-reference)
- (let ((label (org-element-get-property :label blob))
- (seen-labels (plist-get org-export-persistent-properties
- :footnote-seen-labels)))
- ;; Store anonymous footnotes (nil label) without checking if
- ;; another anonymous footnote was seen before.
- (unless (and label (member label seen-labels))
- (setq info (org-export-set-property
- info :footnote-seen-labels (push label seen-labels))))))
- ;; Set `:previous-element' or `:previous-object' according to
- ;; BLOB.
- (setq info (cond ((not type)
- (org-export-set-property
- info :previous-object 'plain-text))
- ((memq type org-element-all-elements)
- (org-export-set-property info :previous-element type))
- (t (org-export-set-property info :previous-object type))))
- ;; Return updated value.
- info))))
-
-(defun org-export-set-property (info prop value)
- "Set property PROP to VALUE in plist INFO.
-Return the new plist."
- (when (memq prop org-export-persistent-properties-list)
- (setq org-export-persistent-properties
- (plist-put org-export-persistent-properties prop value)))
- (plist-put info prop value))
+(defun org-export--selected-trees (data info)
+ "Return list of headlines containing a select tag in their tree.
+DATA is parsed data as returned by `org-element-parse-buffer'.
+INFO is a plist holding export options."
+ (let (selected-trees
+ (walk-data
+ (function
+ (lambda (data genealogy)
+ (case (org-element-type data)
+ (org-data
+ (funcall walk-data (org-element-contents data) genealogy))
+ (headline
+ (let ((tags (org-element-property :tags headline)))
+ (if (and tags
+ (loop for tag in (plist-get info :select-tags)
+ thereis (string-match
+ (format ":%s:" tag) tags)))
+ ;; When a select tag is found, mark as acceptable
+ ;; full genealogy and every headline within the
+ ;; tree.
+ (setq selected-trees
+ (append
+ (cons data genealogy)
+ (org-element-map data 'headline 'identity)
+ selected-trees))
+ ;; Else, continue searching in tree, recursively.
+ (funcall walk-data data (cons data genealogy))))))))))
+ (funcall walk-data data nil) selected-trees))
+
+(defun org-export--skip-p (blob options select-tags)
+ "Non-nil when element or object BLOB should be skipped during export.
+OPTIONS is the plist holding export options."
+ (case (org-element-type blob)
+ ;; Check headline.
+ (headline
+ (let ((with-tasks (plist-get options :with-tasks))
+ (todo (org-element-property :todo-keyword blob))
+ (todo-type (org-element-property :todo-type blob))
+ (archived (plist-get options :with-archived-trees))
+ (tag-list (let ((tags (org-element-property :tags blob)))
+ (and tags (org-split-string tags ":")))))
+ (or
+ ;; Ignore subtrees with an exclude tag.
+ (loop for k in (plist-get options :exclude-tags)
+ thereis (member k tag-list))
+ ;; Ignore subtrees without a select tag, when such tag is
+ ;; found in the buffer.
+ (member blob select-tags)
+ ;; Ignore commented sub-trees.
+ (org-element-property :commentedp blob)
+ ;; Ignore archived subtrees if `:with-archived-trees' is nil.
+ (and (not archived) (org-element-property :archivedp blob))
+ ;; Ignore tasks, if specified by `:with-tasks' property.
+ (and todo
+ (or (not with-tasks)
+ (and (memq with-tasks '(todo done))
+ (not (eq todo-type with-tasks)))
+ (and (consp with-tasks) (not (member todo with-tasks))))))))
+ ;; Check time-stamp.
+ (time-stamp (not (plist-get options :with-timestamps)))
+ ;; Check drawer.
+ (drawer
+ (or (not (plist-get options :with-drawers))
+ (and (consp (plist-get options :with-drawers))
+ (not (member (org-element-property :drawer-name blob)
+ (plist-get options :with-drawers))))))))
\f
@@ -1373,11 +1459,12 @@ (defun org-export-set-property (info prop value)
;; `org-export-secondary-string' is provided for that specific task.
;; Internally, three functions handle the filtering of objects and
-;; elements during the export. More precisely, `org-export-skip-p'
-;; determines if the considered object or element should be ignored
-;; altogether, `org-export-interpret-p' tells which elements or
-;; objects should be seen as real Org syntax and `org-export-expand'
-;; transforms the others back into their original shape.
+;; elements during the export. In particular,
+;; `org-export-ignore-element' mark an element or object so future
+;; parse tree traversals skip it, `org-export-interpret-p' tells which
+;; elements or objects should be seen as real Org syntax and
+;; `org-export-expand' transforms the others back into their original
+;; shape.
(defun org-export-data (data backend info)
"Convert DATA to a string into BACKEND format.
@@ -1396,35 +1483,32 @@ (defun org-export-data (data backend info)
;; BLOB can be an element, an object, a string, or nil.
(lambda (blob)
(cond
- ((not blob) nil) ((equal blob "") nil)
+ ((not blob) nil)
;; BLOB is a string. Check if the optional transcoder for plain
;; text exists, and call it in that case. Otherwise, simply
;; return string. Also update INFO and call
;; `org-export-filter-plain-text-functions'.
((stringp blob)
- (setq info (org-export-update-info blob info nil))
(let ((transcoder (intern (format "org-%s-plain-text" backend))))
(org-export-filter-apply-functions
- org-export-filter-plain-text-functions
+ (plist-get info :filter-plain-text)
(if (fboundp transcoder) (funcall transcoder blob info) blob)
- backend)))
+ backend info)))
;; BLOB is an element or an object.
(t
- (let* ((type (if (stringp blob) 'plain-text (car blob)))
+ (let* ((type (org-element-type blob))
;; 1. Determine the appropriate TRANSCODER.
(transcoder
(cond
;; 1.0 A full Org document is inserted.
((eq type 'org-data) 'identity)
;; 1.1. BLOB should be ignored.
- ((org-export-skip-p blob info) nil)
+ ((member blob (plist-get info :ignore-list)) nil)
;; 1.2. BLOB shouldn't be transcoded. Interpret it
;; back into Org syntax.
- ((not (org-export-interpret-p blob info))
- 'org-export-expand)
+ ((not (org-export-interpret-p blob info)) 'org-export-expand)
;; 1.3. Else apply naming convention.
- (t (let ((trans (intern
- (format "org-%s-%s" backend type))))
+ (t (let ((trans (intern (format "org-%s-%s" backend type))))
(and (fboundp trans) trans)))))
;; 2. Compute CONTENTS of BLOB.
(contents
@@ -1432,12 +1516,10 @@ (defun org-export-data (data backend info)
;; Case 0. No transcoder defined: ignore BLOB.
((not transcoder) nil)
;; Case 1. Transparently export an Org document.
- ((eq type 'org-data)
- (org-export-data blob backend info))
+ ((eq type 'org-data) (org-export-data blob backend info))
;; Case 2. For a recursive object.
((memq type org-element-recursive-objects)
- (org-export-data
- blob backend (org-export-update-info blob info t)))
+ (org-export-data blob backend info))
;; Case 3. For a recursive element.
((memq type org-element-greater-elements)
;; Ignore contents of an archived tree
@@ -1445,10 +1527,9 @@ (defun org-export-data (data backend info)
(unless (and
(eq type 'headline)
(eq (plist-get info :with-archived-trees) 'headline)
- (org-element-get-property :archivedp blob))
+ (org-element-property :archivedp blob))
(org-element-normalize-string
- (org-export-data
- blob backend (org-export-update-info blob info t)))))
+ (org-export-data blob backend info))))
;; Case 4. For a paragraph.
((eq type 'paragraph)
(let ((paragraph
@@ -1458,13 +1539,11 @@ (defun org-export-data (data backend info)
;; a footnote definition, ignore first line's
;; indentation: there is none and it might be
;; misleading.
- (and (not (plist-get info :previous-element))
- (let ((parent (car (plist-get info :genealogy))))
- (memq parent '(footnote-definition item)))))))
- (org-export-data
- paragraph
- backend
- (org-export-update-info blob info t))))))
+ (and (not (org-export-get-previous-element blob info))
+ (let ((parent (org-export-get-parent blob info)))
+ (memq (org-element-type parent)
+ '(footnote-definition item)))))))
+ (org-export-data paragraph backend info)))))
;; 3. Transcode BLOB into RESULTS string.
(results (cond
((not transcoder) nil)
@@ -1473,26 +1552,27 @@ (defun org-export-data (data backend info)
`(org-data nil ,(funcall transcoder blob contents))
backend info))
(t (funcall transcoder blob contents info)))))
- ;; 4. Discard nil results. Otherwise, update INFO, append
- ;; the same white space between elements or objects as in
- ;; the original buffer, and call appropriate filters.
- (when results
- (setq info (org-export-update-info blob info nil))
- ;; No filter for a full document.
- (if (eq type 'org-data)
- results
- (org-export-filter-apply-functions
- (eval (intern (format "org-export-filter-%s-functions" type)))
- (if (memq type org-element-all-elements)
- (concat
- (org-element-normalize-string results)
- (make-string (org-element-get-property :post-blank blob) 10))
- (concat
- results
- (make-string
- (org-element-get-property :post-blank blob) 32)))
- backend)))))))
- (org-element-get-contents data) ""))
+ ;; 4. Return results.
+ (cond
+ ((not results) nil)
+ ;; No filter for a full document.
+ ((eq type 'org-data) results)
+ ;; Otherwise, update INFO, append the same white space
+ ;; between elements or objects as in the original buffer,
+ ;; and call appropriate filters.
+ (t
+ (let ((results
+ (org-export-filter-apply-functions
+ (plist-get info (intern (format ":filter-%s" type)))
+ (let ((post-blank (org-element-property :post-blank blob)))
+ (if (memq type org-element-all-elements)
+ (concat (org-element-normalize-string results)
+ (make-string post-blank ?\n))
+ (concat results (make-string post-blank ? ))))
+ backend info)))
+ ;; Eventually return string.
+ results)))))))
+ (org-element-contents data) ""))
(defun org-export-secondary-string (secondary backend info)
"Convert SECONDARY string into BACKEND format.
@@ -1500,74 +1580,19 @@ (defun org-export-secondary-string (secondary backend info)
SECONDARY is a nested list as returned by
`org-element-parse-secondary-string'.
-BACKEND is a symbol among supported exporters.
-
-INFO is a plist holding export options and also used as
-a communication channel between elements when walking the nested
-list. See `org-export-update-info' function for more
-details.
+BACKEND is a symbol among supported exporters. INFO is a plist
+used as a communication channel.
Return transcoded string."
;; Make SECONDARY acceptable for `org-export-data'.
(let ((s (if (listp secondary) secondary (list secondary))))
(org-export-data `(org-data nil ,@s) backend (copy-sequence info))))
-(defun org-export-skip-p (blob info)
- "Non-nil when element or object BLOB should be skipped during export.
-INFO is the plist holding export options."
- ;; Check headline.
- (unless (stringp blob)
- (case (car blob)
- ('headline
- (let ((with-tasks (plist-get info :with-tasks))
- (todo (org-element-get-property :todo-keyword blob))
- (todo-type (org-element-get-property :todo-type blob))
- (archived (plist-get info :with-archived-trees))
- (tag-list (let ((tags (org-element-get-property :tags blob)))
- (and tags (org-split-string tags ":")))))
- (or
- ;; Ignore subtrees with an exclude tag.
- (loop for k in (plist-get info :exclude-tags)
- thereis (member k tag-list))
- ;; Ignore subtrees without a select tag, when such tag is found
- ;; in the buffer.
- (and (plist-get info :use-select-tags)
- (loop for k in (plist-get info :select-tags)
- never (member k tag-list)))
- ;; Ignore commented sub-trees.
- (org-element-get-property :commentedp blob)
- ;; Ignore archived subtrees if `:with-archived-trees' is nil.
- (and (not archived) (org-element-get-property :archivedp blob))
- ;; Ignore tasks, if specified by `:with-tasks' property.
- (and todo (not with-tasks))
- (and todo
- (memq with-tasks '(todo done))
- (not (eq todo-type with-tasks)))
- (and todo
- (consp with-tasks)
- (not (member todo with-tasks))))))
- ;; Check time-stamp.
- ('time-stamp (not (plist-get info :with-timestamps)))
- ;; Check drawer.
- ('drawer
- (or (not (plist-get info :with-drawers))
- (and (consp (plist-get info :with-drawers))
- (not (member (org-element-get-property :drawer-name blob)
- (plist-get info :with-drawers))))))
- ;; Check export snippet.
- ('export-snippet
- (let* ((raw-back-end (org-element-get-property :back-end blob))
- (true-back-end
- (or (cdr (assoc raw-back-end org-export-snippet-translation-alist))
- raw-back-end)))
- (not (string= (symbol-name (plist-get info :back-end))
- true-back-end)))))))
-
(defun org-export-interpret-p (blob info)
"Non-nil if element or object BLOB should be interpreted as Org syntax.
Check is done according to export options INFO, stored as
a plist."
- (case (car blob)
+ (case (org-element-type blob)
;; ... entities...
(entity (plist-get info :with-entities))
;; ... emphasis...
@@ -1581,7 +1606,7 @@ (defun org-export-interpret-p (blob info)
((subscript superscript)
(let ((sub/super-p (plist-get info :with-sub-superscript)))
(if (eq sub/super-p '{})
- (org-element-get-property :use-brackets-p blob)
+ (org-element-property :use-brackets-p blob)
sub/super-p)))
;; ... tables...
(table (plist-get info :with-tables))
@@ -1591,8 +1616,15 @@ (defsubst org-export-expand (blob contents)
"Expand a parsed element or object to its original state.
BLOB is either an element or an object. CONTENTS is its
contents, as a string or nil."
- (funcall
- (intern (format "org-element-%s-interpreter" (car blob))) blob contents))
+ (funcall (intern (format "org-element-%s-interpreter" (org-element-type blob)))
+ blob contents))
+
+(defun org-export-ignore-element (element info)
+ "Add ELEMENT to `:ignore-list' in INFO.
+
+Any element in `:ignore-list' will be skipped when using
+`org-element-map'. INFO is modified by side effects."
+ (plist-put info :ignore-list (cons element (plist-get info :ignore-list))))
\f
@@ -1605,7 +1637,8 @@ (defsubst org-export-expand (blob contents)
;; Every set is back-end agnostic. Although, a filter is always
;; called, in addition to the string it applies to, with the back-end
;; used as argument, so it's easy enough for the end-user to add
-;; back-end specific filters in the set.
+;; back-end specific filters in the set. The communication channel,
+;; as a plist, is required as the third argument.
;; Filters sets are defined below. There are of four types:
@@ -1621,298 +1654,375 @@ (defsubst org-export-expand (blob contents)
;; All filters sets are applied through
;; `org-export-filter-apply-functions' function. Filters in a set are
-;; applied in reverse order, that is in the order of consing. It
-;; allows developers to be reasonably sure that their filters will be
-;; applied first.
+;; applied in a LIFO fashion. It allows developers to be sure that
+;; their filters will be applied first.
+
+;; Filters properties are installed in communication channel just
+;; before parsing, with `org-export-install-filters' function.
;;;; Special Filters
(defvar org-export-filter-parse-tree-functions nil
"Filter, or list of filters, applied to the parsed tree.
-Each filter is called with two arguments: the parse tree, as
-returned by `org-element-parse-buffer', and the back-end as
-a symbol. It must return the modified parse tree to transcode.")
+Each filter is called with three arguments: the parse tree, as
+returned by `org-element-parse-buffer', the back-end, as
+a symbol, and the communication channel, as a plist. It must
+return the modified parse tree to transcode.")
(defvar org-export-filter-final-output-functions nil
"Filter, or list of filters, applied to the transcoded string.
-Each filter is called with two arguments: the full transcoded
-string, and the back-end as a symbol. It must return a string
-that will be used as the final export output.")
+Each filter is called with three arguments: the full transcoded
+string, the back-end, as a symbol, and the communication channel,
+as a plist. It must return a string that will be used as the
+final export output.")
(defvar org-export-filter-plain-text-functions nil
"Filter, or list of filters, applied to plain text.
-Each filter is called with two arguments: a string which contains
-no Org syntax, and the back-end as a symbol. It must return
-a string or nil.")
+Each filter is called with three arguments: a string which
+contains no Org syntax, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
;;;; Elements Filters
(defvar org-export-filter-center-block-functions nil
- "Filter, or list of filters, applied to a transcoded center block.
-Each filter is called with two arguments: the transcoded center
-block, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded center block.
+Each filter is called with three arguments: the transcoded center
+block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-drawer-functions nil
- "Filter, or list of filters, applied to a transcoded drawer.
-Each filter is called with two arguments: the transcoded drawer,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded drawer.
+Each filter is called with three arguments: the transcoded
+drawer, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-dynamic-block-functions nil
- "Filter, or list of filters, applied to a transcoded dynamic-block.
-Each filter is called with two arguments: the transcoded
-dynamic-block, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded dynamic-block.
+Each filter is called with three arguments: the transcoded
+dynamic-block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-headline-functions nil
- "Filter, or list of filters, applied to a transcoded headline.
-Each filter is called with two arguments: the transcoded
-headline, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded headline.
+Each filter is called with three arguments: the transcoded
+headline, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-inlinetask-functions nil
- "Filter, or list of filters, applied to a transcoded inlinetask.
-Each filter is called with two arguments: the transcoded
-inlinetask, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded inlinetask.
+Each filter is called with three arguments: the transcoded
+inlinetask, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-plain-list-functions nil
- "Filter, or list of filters, applied to a transcoded plain-list.
-Each filter is called with two arguments: the transcoded
-plain-list, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded plain-list.
+Each filter is called with three arguments: the transcoded
+plain-list, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-item-functions nil
- "Filter, or list of filters, applied to a transcoded item.
-Each filter is called with two arguments: the transcoded item, as
-a string, and the back-end, as a symbol. It must return a string
-or nil.")
+ "List of functions applied to a transcoded item.
+Each filter is called with three arguments: the transcoded item,
+as a string, the back-end, as a symbol, and the communication
+channel, as a plist. It must return a string or nil.")
(defvar org-export-filter-comment-functions nil
- "Filter, or list of filters, applied to a transcoded comment.
-Each filter is called with two arguments: the transcoded comment,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded comment.
+Each filter is called with three arguments: the transcoded
+comment, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-comment-block-functions nil
- "Filter, or list of filters, applied to a transcoded comment-comment.
-Each filter is called with two arguments: the transcoded
-comment-block, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded comment-comment.
+Each filter is called with three arguments: the transcoded
+comment-block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-example-block-functions nil
- "Filter, or list of filters, applied to a transcoded example-block.
-Each filter is called with two arguments: the transcoded
-example-block, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded example-block.
+Each filter is called with three arguments: the transcoded
+example-block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-export-block-functions nil
- "Filter, or list of filters, applied to a transcoded export-block.
-Each filter is called with two arguments: the transcoded
-export-block, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded export-block.
+Each filter is called with three arguments: the transcoded
+export-block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-fixed-width-functions nil
- "Filter, or list of filters, applied to a transcoded fixed-width.
-Each filter is called with two arguments: the transcoded
-fixed-width, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded fixed-width.
+Each filter is called with three arguments: the transcoded
+fixed-width, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-footnote-definition-functions nil
- "Filter, or list of filters, applied to a transcoded footnote-definition.
-Each filter is called with two arguments: the transcoded
-footnote-definition, as a string, and the back-end, as a symbol.
-It must return a string or nil.")
+ "List of functions applied to a transcoded footnote-definition.
+Each filter is called with three arguments: the transcoded
+footnote-definition, as a string, the back-end, as a symbol, and
+the communication channel, as a plist. It must return a string
+or nil.")
(defvar org-export-filter-horizontal-rule-functions nil
- "Filter, or list of filters, applied to a transcoded horizontal-rule.
-Each filter is called with two arguments: the transcoded
-horizontal-rule, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded horizontal-rule.
+Each filter is called with three arguments: the transcoded
+horizontal-rule, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-keyword-functions nil
- "Filter, or list of filters, applied to a transcoded keyword.
-Each filter is called with two arguments: the transcoded keyword,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded keyword.
+Each filter is called with three arguments: the transcoded
+keyword, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-latex-environment-functions nil
- "Filter, or list of filters, applied to a transcoded latex-environment.
-Each filter is called with two arguments: the transcoded
-latex-environment, as a string, and the back-end, as a symbol.
-It must return a string or nil.")
+ "List of functions applied to a transcoded latex-environment.
+Each filter is called with three arguments: the transcoded
+latex-environment, as a string, the back-end, as a symbol, and
+the communication channel, as a plist. It must return a string
+or nil.")
(defvar org-export-filter-babel-call-functions nil
- "Filter, or list of filters, applied to a transcoded babel-call.
-Each filter is called with two arguments: the transcoded
-babel-call, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded babel-call.
+Each filter is called with three arguments: the transcoded
+babel-call, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-paragraph-functions nil
- "Filter, or list of filters, applied to a transcoded paragraph.
-Each filter is called with two arguments: the transcoded
-paragraph, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded paragraph.
+Each filter is called with three arguments: the transcoded
+paragraph, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-property-drawer-functions nil
- "Filter, or list of filters, applied to a transcoded property-drawer.
-Each filter is called with two arguments: the transcoded
-property-drawer, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded property-drawer.
+Each filter is called with three arguments: the transcoded
+property-drawer, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-quote-block-functions nil
- "Filter, or list of filters, applied to a transcoded quote block.
-Each filter is called with two arguments: the transcoded quote
-block, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded quote block.
+Each filter is called with three arguments: the transcoded quote
+block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-quote-section-functions nil
- "Filter, or list of filters, applied to a transcoded quote-section.
-Each filter is called with two arguments: the transcoded
-quote-section, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded quote-section.
+Each filter is called with three arguments: the transcoded
+quote-section, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
+
+(defvar org-export-filter-section-functions nil
+ "List of functions applied to a transcoded section.
+Each filter is called with three arguments: the transcoded
+section, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-special-block-functions nil
- "Filter, or list of filters, applied to a transcoded special block.
-Each filter is called with two arguments: the transcoded special
-block, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded special block.
+Each filter is called with three arguments: the transcoded
+special block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-src-block-functions nil
- "Filter, or list of filters, applied to a transcoded src-block.
-Each filter is called with two arguments: the transcoded
-src-block, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded src-block.
+Each filter is called with three arguments: the transcoded
+src-block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-table-functions nil
- "Filter, or list of filters, applied to a transcoded table.
-Each filter is called with two arguments: the transcoded table,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded table.
+Each filter is called with three arguments: the transcoded table,
+as a string, the back-end, as a symbol, and the communication
+channel, as a plist. It must return a string or nil.")
(defvar org-export-filter-verse-block-functions nil
- "Filter, or list of filters, applied to a transcoded verse block.
-Each filter is called with two arguments: the transcoded verse
-block, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded verse block.
+Each filter is called with three arguments: the transcoded verse
+block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
;;;; Objects Filters
(defvar org-export-filter-emphasis-functions nil
- "Filter, or list of filters, applied to a transcoded emphasis.
-Each filter is called with two arguments: the transcoded
-emphasis, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded emphasis.
+Each filter is called with three arguments: the transcoded
+emphasis, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-entity-functions nil
- "Filter, or list of filters, applied to a transcoded entity.
-Each filter is called with two arguments: the transcoded entity,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded entity.
+Each filter is called with three arguments: the transcoded
+entity, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-export-snippet-functions nil
- "Filter, or list of filters, applied to a transcoded export-snippet.
-Each filter is called with two arguments: the transcoded
-export-snippet, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded export-snippet.
+Each filter is called with three arguments: the transcoded
+export-snippet, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-footnote-reference-functions nil
- "Filter, or list of filters, applied to a transcoded footnote-reference.
-Each filter is called with two arguments: the transcoded
-footnote-reference, as a string, and the back-end, as a symbol.
-It must return a string or nil.")
+ "List of functions applied to a transcoded footnote-reference.
+Each filter is called with three arguments: the transcoded
+footnote-reference, as a string, the back-end, as a symbol, and
+the communication channel, as a plist. It must return a string
+or nil.")
(defvar org-export-filter-inline-babel-call-functions nil
- "Filter, or list of filters, applied to a transcoded inline-babel-call.
-Each filter is called with two arguments: the transcoded
-inline-babel-call, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded inline-babel-call.
+Each filter is called with three arguments: the transcoded
+inline-babel-call, as a string, the back-end, as a symbol, and
+the communication channel, as a plist. It must return a string
+or nil.")
(defvar org-export-filter-inline-src-block-functions nil
- "Filter, or list of filters, applied to a transcoded inline-src-block.
-Each filter is called with two arguments: the transcoded
-inline-src-block, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded inline-src-block.
+Each filter is called with three arguments: the transcoded
+inline-src-block, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-latex-fragment-functions nil
- "Filter, or list of filters, applied to a transcoded latex-fragment.
-Each filter is called with two arguments: the transcoded
-latex-fragment, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded latex-fragment.
+Each filter is called with three arguments: the transcoded
+latex-fragment, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-line-break-functions nil
- "Filter, or list of filters, applied to a transcoded line-break.
-Each filter is called with two arguments: the transcoded
-line-break, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded line-break.
+Each filter is called with three arguments: the transcoded
+line-break, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-link-functions nil
- "Filter, or list of filters, applied to a transcoded link.
-Each filter is called with two arguments: the transcoded link, as
-a string, and the back-end, as a symbol. It must return a string
-or nil.")
+ "List of functions applied to a transcoded link.
+Each filter is called with three arguments: the transcoded link,
+as a string, the back-end, as a symbol, and the communication
+channel, as a plist. It must return a string or nil.")
(defvar org-export-filter-macro-functions nil
- "Filter, or list of filters, applied to a transcoded macro.
-Each filter is called with two arguments: the transcoded macro,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded macro.
+Each filter is called with three arguments: the transcoded macro,
+as a string, the back-end, as a symbol, and the communication
+channel, as a plist. It must return a string or nil.")
(defvar org-export-filter-radio-target-functions nil
- "Filter, or list of filters, applied to a transcoded radio-target.
-Each filter is called with two arguments: the transcoded
-radio-target, as a string, and the back-end, as a symbol. It
-must return a string or nil.")
+ "List of functions applied to a transcoded radio-target.
+Each filter is called with three arguments: the transcoded
+radio-target, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-statistics-cookie-functions nil
- "Filter, or list of filters, applied to a transcoded statistics-cookie.
-Each filter is called with two arguments: the transcoded
-statistics-cookie, as a string, and the back-end, as a symbol.
-It must return a string or nil.")
+ "List of functions applied to a transcoded statistics-cookie.
+Each filter is called with three arguments: the transcoded
+statistics-cookie, as a string, the back-end, as a symbol, and
+the communication channel, as a plist. It must return a string
+or nil.")
(defvar org-export-filter-subscript-functions nil
- "Filter, or list of filters, applied to a transcoded subscript.
-Each filter is called with two arguments: the transcoded
-subscript, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded subscript.
+Each filter is called with three arguments: the transcoded
+subscript, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-superscript-functions nil
- "Filter, or list of filters, applied to a transcoded superscript.
-Each filter is called with two arguments: the transcoded
-superscript, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded superscript.
+Each filter is called with three arguments: the transcoded
+superscript, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-target-functions nil
- "Filter, or list of filters, applied to a transcoded target.
-Each filter is called with two arguments: the transcoded target,
-as a string, and the back-end, as a symbol. It must return
-a string or nil.")
+ "List of functions applied to a transcoded target.
+Each filter is called with three arguments: the transcoded
+target, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-time-stamp-functions nil
- "Filter, or list of filters, applied to a transcoded time-stamp.
-Each filter is called with two arguments: the transcoded
-time-stamp, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
+ "List of functions applied to a transcoded time-stamp.
+Each filter is called with three arguments: the transcoded
+time-stamp, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
(defvar org-export-filter-verbatim-functions nil
- "Filter, or list of filters, applied to a transcoded verbatim.
-Each filter is called with two arguments: the transcoded
-verbatim, as a string, and the back-end, as a symbol. It must
-return a string or nil.")
-
-(defun org-export-filter-apply-functions (filters value backend)
- "Call every function in FILTERS with arguments VALUE and BACKEND.
-Functions are called in reverse order, to be reasonably sure that
-developer-specified filters, if any, are called first."
- ;; Ensure FILTERS is a list.
- (let ((filters (if (listp filters) (reverse filters) (list filters))))
- (loop for filter in filters
- if (not value) return nil else
- do (setq value (funcall filter value backend))))
+ "List of functions applied to a transcoded verbatim.
+Each filter is called with three arguments: the transcoded
+verbatim, as a string, the back-end, as a symbol, and the
+communication channel, as a plist. It must return a string or
+nil.")
+
+(defun org-export-filter-apply-functions (filters value backend info)
+ "Call every function in FILTERS with arguments VALUE, BACKEND and INFO.
+Functions are called in a LIFO fashion, to be sure that developer
+specified filters, if any, are called first."
+ (loop for filter in filters
+ if (not value) return nil else
+ do (setq value (funcall filter value backend info)))
value)
+(defun org-export-install-filters (backend info)
+ "Install filters properties in communication channel.
+
+BACKEND is a symbol specifying which back-end specific filters to
+install, if any. INFO is a plist containing the current
+communication channel.
+
+Return the updated communication channel."
+ (let (plist)
+ ;; Install user defined filters with `org-export-filters-alist'.
+ (mapc (lambda (p)
+ (setq plist (plist-put plist (car p) (eval (cdr p)))))
+ org-export-filters-alist)
+ ;; Prepend back-end specific filters to that list.
+ (let ((back-end-filters (intern (format "org-%s-filters-alist" backend))))
+ (when (boundp back-end-filters)
+ (mapc (lambda (p)
+ ;; Single values get consed, lists are prepended.
+ (let ((key (car p)) (value (cdr p)))
+ (when value
+ (setq plist
+ (plist-put
+ plist key
+ (if (atom value) (cons value (plist-get plist key))
+ (append value (plist-get plist key))))))))
+ (eval back-end-filters))))
+ ;; Return new communication channel.
+ (org-combine-plists info plist)))
+
\f
;;; Core functions
@@ -1921,13 +2031,27 @@ (defun org-export-filter-apply-functions (filters value backend)
;; its derivatives, `org-export-to-buffer' and `org-export-to-file'.
;; They differ only by the way they output the resulting code.
+;; `org-export-output-file-name' is an auxiliary function meant to be
+;; used with `org-export-to-file'. With a given extension, it tries
+;; to provide a canonical file name to write export output to.
+
;; Note that `org-export-as' doesn't really parse the current buffer,
;; but a copy of it (with the same buffer-local variables and
-;; visibility), where Babel blocks are executed, if appropriate.
+;; visibility), where include keywords are expanded and Babel blocks
+;; are executed, if appropriate.
;; `org-export-with-current-buffer-copy' macro prepares that copy.
-(defun org-export-as (backend
- &optional subtreep visible-only body-only ext-plist)
+;; File inclusion is taken care of by
+;; `org-export-expand-include-keyword' and
+;; `org-export-prepare-file-contents'. Structure wise, including
+;; a whole Org file in a buffer often makes little sense. For
+;; example, if the file contains an headline and the include keyword
+;; was within an item, the item should contain the headline. That's
+;; why file inclusion should be done before any structure can be
+;; associated to the file, that is before parsing.
+
+(defun org-export-as
+ (backend &optional subtreep visible-only body-only ext-plist noexpand)
"Transcode current Org buffer into BACKEND code.
If narrowing is active in the current buffer, only transcode its
@@ -1945,59 +2069,67 @@ (defun org-export-as (backend
When optional argument BODY-ONLY is non-nil, only return body
code, without preamble nor postamble.
-EXT-PLIST, when provided, is a property list with external
-parameters overriding Org default settings, but still inferior to
-file-local settings.
+Optional argument EXT-PLIST, when provided, is a property list
+with external parameters overriding Org default settings, but
+still inferior to file-local settings.
+
+Optional argument NOEXPAND, when non-nil, prevents included files
+to be expanded and Babel code to be executed.
Return code as a string."
(save-excursion
(save-restriction
;; Narrow buffer to an appropriate region for parsing.
- (when (org-region-active-p)
- (narrow-to-region (region-beginning) (region-end)))
- (goto-char (point-min))
- (when subtreep
- (unless (org-at-heading-p)
- (org-with-limited-levels (outline-next-heading)))
- (let ((end (save-excursion (org-end-of-subtree t)))
- (begin (progn (forward-line)
- (org-skip-whitespace)
- (point-at-bol))))
- (narrow-to-region begin end)))
- ;; Retrieve export options (INFO) and parsed tree (RAW-DATA).
+ (cond ((org-region-active-p)
+ (narrow-to-region (region-beginning) (region-end)))
+ (subtreep (org-narrow-to-subtree)))
+ ;; Retrieve export options (INFO) and parsed tree (RAW-DATA),
+ ;; Then options can be completed with tree properties. Note:
;; Buffer isn't parsed directly. Instead, a temporary copy is
- ;; created, where all code blocks are evaluated. RAW-DATA is
- ;; the parsed tree of the buffer resulting from that process.
- ;; Eventually call `org-export-filter-parse-tree-functions'..
- (let ((info (org-export-collect-options backend subtreep ext-plist))
- (raw-data (org-export-filter-apply-functions
- org-export-filter-parse-tree-functions
- (org-export-with-current-buffer-copy
- (org-export-blocks-preprocess)
- (org-element-parse-buffer nil visible-only))
- backend)))
- ;; Initialize the communication system and combine it to INFO.
+ ;; created, where include keywords are expanded and code blocks
+ ;; are evaluated. RAW-DATA is the parsed tree of the buffer
+ ;; resulting from that process. Eventually call
+ ;; `org-export-filter-parse-tree-functions'.
+ (goto-char (point-min))
+ (let ((info (org-export-get-environment backend subtreep ext-plist)))
+ ;; Remove subtree's headline from contents if subtree mode is
+ ;; activated.
+ (when subtreep (forward-line) (narrow-to-region (point) (point-max)))
+ ;; Install filters in communication channel.
+ (setq info (org-export-install-filters backend info))
+ (let ((raw-data
+ (org-export-filter-apply-functions
+ (plist-get info :filter-parse-tree)
+ ;; If NOEXPAND is non-nil, simply parse current
+ ;; visible part of buffer.
+ (if noexpand (org-element-parse-buffer nil visible-only)
+ (org-export-with-current-buffer-copy
+ (org-export-expand-include-keyword)
+ (let ((org-current-export-file (current-buffer)))
+ (org-export-blocks-preprocess))
+ (org-element-parse-buffer nil visible-only)))
+ backend info)))
+ ;; Complete communication channel with tree properties.
(setq info
(org-combine-plists
info
- (org-export-initialize-persistent-properties
- raw-data info backend)))
- ;; Now transcode RAW-DATA. Also call
+ (org-export-collect-tree-properties raw-data info backend)))
+ ;; Transcode RAW-DATA. Also call
;; `org-export-filter-final-output-functions'.
- (let ((body (org-element-normalize-string
- (org-export-data raw-data backend info)))
- (template (intern (format "org-%s-template" backend))))
- (if (and (not body-only) (fboundp template))
- (org-trim
- (org-export-filter-apply-functions
- org-export-filter-final-output-functions
- (funcall template body info)
- backend))
- (org-export-filter-apply-functions
- org-export-filter-final-output-functions body backend)))))))
-
-(defun org-export-to-buffer (backend buffer &optional subtreep visible-only
- body-only ext-plist)
+ (let* ((body (org-element-normalize-string
+ (org-export-data raw-data backend info)))
+ (template (intern (format "org-%s-template" backend)))
+ (output (org-export-filter-apply-functions
+ (plist-get info :filter-final-output)
+ (if (or (not (fboundp template)) body-only) body
+ (funcall template body info))
+ backend info)))
+ ;; Maybe add final OUTPUT to kill ring before returning it.
+ (when org-export-copy-to-kill-ring (org-kill-new output))
+ output))))))
+
+(defun org-export-to-buffer
+ (backend buffer &optional subtreep visible-only body-only ext-plist noexpand)
"Call `org-export-as' with output to a specified buffer.
BACKEND is the back-end used for transcoding, as a symbol.
@@ -2005,11 +2137,13 @@ (defun org-export-to-buffer (backend buffer &optional subtreep visible-only
BUFFER is the output buffer. If it already exists, it will be
erased first, otherwise, it will be created.
-Arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY and EXT-PLIST are
-similar to those used in `org-export-as', which see.
+Optional arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY, EXT-PLIST
+and NOEXPAND are similar to those used in `org-export-as', which
+see.
Return buffer."
- (let ((out (org-export-as backend subtreep visible-only body-only ext-plist))
+ (let ((out (org-export-as
+ backend subtreep visible-only body-only ext-plist noexpand))
(buffer (get-buffer-create buffer)))
(with-current-buffer buffer
(erase-buffer)
@@ -2017,41 +2151,77 @@ (defun org-export-to-buffer (backend buffer &optional subtreep visible-only
(goto-char (point-min)))
buffer))
-(defun org-export-to-file (backend filename &optional post-process subtreep
- visible-only body-only ext-plist)
+(defun org-export-to-file
+ (backend file &optional subtreep visible-only body-only ext-plist noexpand)
"Call `org-export-as' with output to a specified file.
-BACKEND is the back-end used for transcoding, as a symbol.
-
-FILENAME is the output file name. If it already exists, it will
-be erased first, unless it isn't writable, in which case an error
-will be returned. Otherwise, the file will be created.
+BACKEND is the back-end used for transcoding, as a symbol. FILE
+is the name of the output file, as a string.
-Optional argument POST-PROCESS, when non-nil, is a function
-applied to the output file. It expects one argument: the file
-name, as a string. It can be used to call shell commands on that
-file, display a specific buffer, etc.
-
-Optional arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY and
-EXT-PLIST are similar to those used in `org-export-as', which
+Optional arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY, EXT-PLIST
+and NOEXPAND are similar to those used in `org-export-as', which
see.
-Return file name."
- ;; Checks for file and directory permissions.
- (cond
- ((not (file-exists-p filename))
- (let ((dir (or (file-name-directory filename) default-directory)))
- (unless (file-writable-p dir) (error "Output directory not writable"))))
- ((not (file-writable-p filename)) (error "Output file not writable")))
- ;; All checks passed: insert contents to a temporary buffer and
- ;; write it to the specified file.
- (let ((out (org-export-as backend subtreep visible-only body-only ext-plist)))
+Return output file's name."
+ ;; Checks for FILE permissions. `write-file' would do the same, but
+ ;; we'd rather avoid needless transcoding of parse tree.
+ (unless (file-writable-p file) (error "Output file not writable"))
+ ;; Insert contents to a temporary buffer and write it to FILE.
+ (let ((out (org-export-as
+ backend subtreep visible-only body-only ext-plist noexpand)))
(with-temp-buffer
(insert out)
- (write-file filename)))
- (when post-process (funcall post-process filename))
- ;; Return value.
- filename)
+ (let ((coding-system-for-write org-export-coding-system))
+ (write-file file))))
+ ;; Return full path.
+ file)
+
+(defun org-export-output-file-name (extension &optional subtreep pub-dir)
+ "Return output file's name according to buffer specifications.
+
+EXTENSION is a string representing the output file extension,
+with the leading dot.
+
+With a non-nil optional argument SUBTREEP, try to determine
+output file's name by looking for \"EXPORT_FILE_NAME\" property
+of subtree at point.
+
+When optional argument PUB-DIR is set, use it as the publishing
+directory.
+
+Return file name as a string, or nil if it couldn't be
+determined."
+ (let ((base-name
+ ;; File name may come from EXPORT_FILE_NAME subtree property,
+ ;; assuming point is at beginning of said sub-tree.
+ (file-name-sans-extension
+ (or (and subtreep
+ (org-entry-get
+ (save-excursion
+ (ignore-errors
+ (org-back-to-heading (not visible-only)) (point)))
+ "EXPORT_FILE_NAME" t))
+ ;; File name may be extracted from buffer's associated
+ ;; file, if any.
+ (buffer-file-name (buffer-base-buffer))
+ ;; Can't determine file name on our own: Ask user.
+ (let ((read-file-name-function
+ (and org-completion-use-ido 'ido-read-file-name)))
+ (read-file-name
+ "Output file: " pub-dir nil nil nil
+ (lambda (name)
+ (string= (file-name-extension name t) extension))))))))
+ ;; Build file name. Enforce EXTENSION over whatever user may have
+ ;; come up with. PUB-DIR, if defined, always has precedence over
+ ;; any provided path.
+ (cond
+ (pub-dir
+ (concat (file-name-as-directory pub-dir)
+ (file-name-nondirectory base-name)
+ extension))
+ ((string= (file-name-nondirectory base-name) base-name)
+ (concat (file-name-as-directory ".") base-name extension))
+ (t (concat base-name extension)))))
(defmacro org-export-with-current-buffer-copy (&rest body)
"Apply BODY in a copy of the current buffer.
@@ -2069,7 +2239,8 @@ (defmacro org-export-with-current-buffer-copy (&rest body)
(with-temp-buffer
(let ((buffer-invisibility-spec nil))
(org-clone-local-variables
- ,original-buffer "^\\(org-\\|orgtbl-\\|major-mode$\\)")
+ ,original-buffer
+ "^\\(org-\\|orgtbl-\\|major-mode$\\|outline-\\(regexp\\|level\\)$\\)")
(insert ,buffer-string)
(mapc (lambda (ov)
(move-overlay
@@ -2082,6 +2253,160 @@ (defmacro org-export-with-current-buffer-copy (&rest body)
(progn ,@body))))))
(def-edebug-spec org-export-with-current-buffer-copy (body))
+(defun org-export-expand-include-keyword (&optional included dir)
+ "Expand every include keyword in buffer.
+Optional argument INCLUDED is a list of included file names along
+with their line restriction, when appropriate. It is used to
+avoid infinite recursion. Optional argument DIR is the current
+working directory. It is used to properly resolve relative
+paths."
+ (let ((case-fold-search t))
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t]*#\\+INCLUDE: \\(.*\\)" nil t)
+ (when (eq (org-element-type (save-match-data (org-element-at-point)))
+ 'keyword)
+ (beginning-of-line)
+ ;; Extract arguments from keyword's value.
+ (let* ((value (match-string 1))
+ (ind (org-get-indentation))
+ (file (and (string-match "^\"\\(\\S-+\\)\"" value)
+ (prog1 (expand-file-name (match-string 1 value) dir)
+ (setq value (replace-match "" nil nil value)))))
+ (lines
+ (and (string-match
+ ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\"" value)
+ (prog1 (match-string 1 value)
+ (setq value (replace-match "" nil nil value)))))
+ (env (cond ((string-match "\\<example\\>" value) 'example)
+ ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
+ (match-string 1 value))))
+ ;; Minimal level of included file defaults to the child
+ ;; level of the current headline, if any, or one. It
+ ;; only applies is the file is meant to be included as
+ ;; an Org one.
+ (minlevel
+ (and (not env)
+ (if (string-match ":minlevel +\\([0-9]+\\)" value)
+ (prog1 (string-to-number (match-string 1 value))
+ (setq value (replace-match "" nil nil value)))
+ (let ((cur (org-current-level)))
+ (if cur (1+ (org-reduced-level cur)) 1))))))
+ ;; Remove keyword.
+ (delete-region (point) (progn (forward-line) (point)))
+ (cond
+ ((not (file-readable-p file)) (error "Cannot include file %s" file))
+ ;; Check if files has already been parsed. Look after
+ ;; inclusion lines too, as different parts of the same file
+ ;; can be included too.
+ ((member (list file lines) included)
+ (error "Recursive file inclusion: %s" file))
+ (t
+ (cond
+ ((eq env 'example)
+ (insert
+ (let ((ind-str (make-string ind ? ))
+ (contents
+ ;; Protect sensitive contents with commas.
+ (replace-regexp-in-string
+ "\\(^\\)\\([*]\\|[ \t]*#\\+\\)" ","
+ (org-export-prepare-file-contents file lines)
+ nil nil 1)))
+ (format "%s#+BEGIN_EXAMPLE\n%s%s#+END_EXAMPLE\n"
+ ind-str contents ind-str))))
+ ((stringp env)
+ (insert
+ (let ((ind-str (make-string ind ? ))
+ (contents
+ ;; Protect sensitive contents with commas.
+ (replace-regexp-in-string
+ (if (string= env "org") "\\(^\\)\\(.\\)"
+ "\\(^\\)\\([*]\\|[ \t]*#\\+\\)") ","
+ (org-export-prepare-file-contents file lines)
+ nil nil 1)))
+ (format "%s#+BEGIN_SRC %s\n%s%s#+END_SRC\n"
+ ind-str env contents ind-str))))
+ (t
+ (insert
+ (with-temp-buffer
+ (org-mode)
+ (insert
+ (org-export-prepare-file-contents file lines ind minlevel))
+ (org-export-expand-include-keyword
+ (cons (list file lines) included)
+ (file-name-directory file))
+ (buffer-string))))))))))))
+
+(defun org-export-prepare-file-contents (file &optional lines ind minlevel)
+ "Prepare the contents of FILE for inclusion and return them as a string.
+
+When optional argument LINES is a string specifying a range of
+lines, include only those lines.
+
+Optional argument IND, when non-nil, is an integer specifying the
+global indentation of returned contents. Since its purpose is to
+allow an included file to stay in the same environment it was
+created \(i.e. a list item), it doesn't apply past the first
+headline encountered.
+
+Optional argument MINLEVEL, when non-nil, is an integer
+specifying the level that any top-level headline in the included
+file should have."
+ (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)))
+ ;; Remove blank lines at beginning and end of contents. The logic
+ ;; behind that removal is that blank lines around include keyword
+ ;; override blank lines in included file.
+ (goto-char (point-min))
+ (org-skip-whitespace)
+ (beginning-of-line)
+ (delete-region (point-min) (point))
+ (goto-char (point-max))
+ (skip-chars-backward " \r\t\n")
+ (forward-line)
+ (delete-region (point) (point-max))
+ ;; If IND is set, preserve indentation of include keyword until
+ ;; the first headline encountered.
+ (when ind
+ (unless (eq major-mode 'org-mode) (org-mode))
+ (goto-char (point-min))
+ (let ((ind-str (make-string ind ? )))
+ (while (not (or (eobp) (looking-at org-outline-regexp-bol)))
+ ;; Do not move footnote definitions out of column 0.
+ (unless (and (looking-at org-footnote-definition-re)
+ (eq (org-element-type (org-element-at-point))
+ 'footnote-definition))
+ (insert ind-str))
+ (forward-line))))
+ ;; When MINLEVEL is specified, compute minimal level for headlines
+ ;; in the file (CUR-MIN), and remove stars to each headline so
+ ;; that headlines with minimal level have a level of MINLEVEL.
+ (when minlevel
+ (unless (eq major-mode 'org-mode) (org-mode))
+ (let ((levels (org-map-entries
+ (lambda () (org-reduced-level (org-current-level))))))
+ (when levels
+ (let ((offset (- minlevel (apply 'min levels))))
+ (unless (zerop offset)
+ (when org-odd-levels-only (setq offset (* offset 2)))
+ ;; Only change stars, don't bother moving whole
+ ;; sections.
+ (org-map-entries
+ (lambda () (if (< offset 0) (delete-char (abs offset))
+ (insert (make-string offset ?*))))))))))
+ (buffer-string)))
\f
;;; Tools For Back-Ends
@@ -2090,9 +2415,27 @@ (defmacro org-export-with-current-buffer-copy (&rest body)
;; function general enough to have its use across many back-ends
;; should be added here.
-;; As of now, functions operating on footnotes, headlines, include
-;; keywords, links, macros, references, src-blocks, tables and tables
-;; of contents are implemented.
+;; As of now, functions operating on footnotes, headlines, links,
+;; macros, references, src-blocks, tables and tables of contents are
+;; implemented.
+
+;;;; For Export Snippets
+
+;; Every export snippet is transmitted to the back-end. Though, the
+;; latter will only retain one type of export-snippet, ignoring
+;; others, based on the former's target back-end. The function
+;; `org-export-snippet-backend' returns that back-end for a given
+;; export-snippet.
+
+(defun org-export-snippet-backend (export-snippet)
+ "Return EXPORT-SNIPPET targeted back-end as a symbol.
+Translation, with `org-export-snippet-translation-alist', is
+applied."
+ (let ((back-end (org-element-property :back-end export-snippet)))
+ (intern
+ (or (cdr (assoc back-end org-export-snippet-translation-alist))
+ back-end))))
+
;;;; For Footnotes
@@ -2116,32 +2459,71 @@ (defun org-export-collect-footnote-definitions (data info)
INFO is the plist used as a communication channel.
Definitions are sorted by order of references. They either
-appear as Org data \(transcoded with `org-export-data'\) or as
-a secondary string for inlined footnotes \(transcoded with
-`org-export-secondary-string'\). Unreferenced definitions are
+appear as Org data (transcoded with `org-export-data') or as
+a secondary string for inlined footnotes (transcoded with
+`org-export-secondary-string'). Unreferenced definitions are
ignored."
- (org-element-map
- data 'footnote-reference
- (lambda (footnote local)
- (when (org-export-footnote-first-reference-p footnote local)
- (list (org-export-get-footnote-number footnote local)
- (org-element-get-property :label footnote)
- (org-export-get-footnote-definition footnote local))))
- info))
+ (let (num-alist
+ (collect-fn
+ (function
+ (lambda (data)
+ ;; Collect footnote number, label and definition in DATA.
+ (org-element-map
+ data 'footnote-reference
+ (lambda (fn)
+ (when (org-export-footnote-first-reference-p fn info)
+ (let ((def (org-export-get-footnote-definition fn info)))
+ (push
+ (list (org-export-get-footnote-number fn info)
+ (org-element-property :label fn)
+ def)
+ num-alist)
+ ;; Also search in definition for nested footnotes.
+ (when (eq (org-element-property :type fn) 'standard)
+ (funcall collect-fn def)))))
+ ;; Don't enter footnote definitions since it will happen
+ ;; when their first reference is found.
+ info nil 'footnote-definition)))))
+ (funcall collect-fn (plist-get info :parse-tree))
+ (reverse num-alist)))
(defun org-export-footnote-first-reference-p (footnote-reference info)
"Non-nil when a footnote reference is the first one for its label.
FOOTNOTE-REFERENCE is the footnote reference being considered.
INFO is the plist used as a communication channel."
- (let ((label (org-element-get-property :label footnote-reference)))
- (not (and label (member label (plist-get info :footnote-seen-labels))))))
+ (let ((label (org-element-property :label footnote-reference)))
+ ;; Anonymous footnotes are always a first reference.
+ (if (not label) t
+ ;; Otherwise, return the first footnote with the same LABEL and
+ ;; test if it is equal to FOOTNOTE-REFERENCE.
+ (let ((search-refs
+ (function
+ (lambda (data)
+ (org-element-map
+ data 'footnote-reference
+ (lambda (fn)
+ (cond
+ ((string= (org-element-property :label fn) label)
+ (throw 'exit fn))
+ ;; If FN isn't inlined, be sure to traverse its
+ ;; definition before resuming search. See
+ ;; comments in `org-export-get-footnote-number'
+ ;; for more information.
+ ((eq (org-element-property :type fn) 'standard)
+ (funcall search-refs
+ (org-export-get-footnote-definition fn info)))))
+ ;; Don't enter footnote definitions since it will
+ ;; happen when their first reference is found.
+ info 'first-match 'footnote-definition)))))
+ (equal (catch 'exit (funcall search-refs (plist-get info :parse-tree)))
+ footnote-reference)))))
(defun org-export-get-footnote-definition (footnote-reference info)
"Return definition of FOOTNOTE-REFERENCE as parsed data.
INFO is the plist used as a communication channel."
- (let ((label (org-element-get-property :label footnote-reference)))
- (or (org-element-get-property :inline-definition footnote-reference)
+ (let ((label (org-element-property :label footnote-reference)))
+ (or (org-element-property :inline-definition footnote-reference)
(cdr (assoc label (plist-get info :footnote-definition-alist))))))
(defun org-export-get-footnote-number (footnote info)
@@ -2149,23 +2531,46 @@ (defun org-export-get-footnote-number (footnote info)
FOOTNOTE is either a footnote reference or a footnote definition.
INFO is the plist used as a communication channel."
- (let ((label (org-element-get-property :label footnote)))
- (if (eq (car footnote) 'footnote-definition)
- ;; If a footnote definition was provided, first search for
- ;; a relative footnote reference, as only footnote references
- ;; can determine the associated ordinal.
- (org-element-map
- (plist-get info :parse-tree) 'footnote-reference
- (lambda (foot-ref local)
- (when (string= (org-element-get-property :label foot-ref) label)
- (let* ((all-seen (plist-get info :footnote-seen-labels))
- (seenp (and label (member label all-seen))))
- (if seenp (length seenp) (1+ (length all-seen))))))
- info 'first-match)
- (let* ((all-seen (plist-get info :footnote-seen-labels))
- ;; Anonymous footnotes are always new footnotes.
- (seenp (and label (member label all-seen))))
- (if seenp (length seenp) (1+ (length all-seen)))))))
+ (let ((label (org-element-property :label footnote))
+ seen-refs
+ (search-ref
+ (function
+ (lambda (data)
+ ;; Search footnote references through DATA, filling
+ ;; SEEN-REFS along the way.
+ (org-element-map
+ data 'footnote-reference
+ (lambda (fn)
+ (let ((fn-lbl (org-element-property :label fn)))
+ (cond
+ ;; Anonymous footnote match: return number.
+ ((and (not fn-lbl) (equal fn footnote))
+ (throw 'exit (1+ (length seen-refs))))
+ ;; Labels match: return number.
+ ((and label (string= label fn-lbl))
+ (throw 'exit (1+ (length seen-refs))))
+ ;; Anonymous footnote: it's always a new one. Also,
+ ;; be sure to return nil from the `cond' so
+ ;; `first-match' doesn't get us out of the loop.
+ ((not fn-lbl) (push 'inline seen-refs) nil)
+ ;; Label not seen so far: add it so SEEN-REFS.
+ ;;
+ ;; Also search for subsequent references in footnote
+ ;; definition so numbering following reading logic.
+ ;; Note that we don't have to care about inline
+ ;; definitions, since `org-element-map' already
+ ;; traverse them at the right time.
+ ;;
+ ;; Once again, return nil to stay in the loop.
+ ((not (member fn-lbl seen-refs))
+ (push fn-lbl seen-refs)
+ (funcall search-ref
+ (org-export-get-footnote-definition fn info))
+ nil))))
+ ;; Don't enter footnote definitions since it will happen
+ ;; when their first reference is found.
+ info 'first-match 'footnote-definition)))))
+ (catch 'exit (funcall search-ref (plist-get info :parse-tree)))))
;;;; For Headlines
@@ -2177,21 +2582,42 @@ (defun org-export-get-footnote-number (footnote info)
;; headline, while `org-export-number-to-roman' allows to convert it
;; to roman numbers.
-;; `org-export-first-sibling-p' and `org-export-last-sibling-p' are
-;; two useful predicates when it comes to fulfill the
-;; `:headline-levels' property.
+;; `org-export-low-level-p', `org-export-first-sibling-p' and
+;; `org-export-last-sibling-p' are three useful predicates when it
+;; comes to fulfill the `:headline-levels' property.
(defun org-export-get-relative-level (headline info)
"Return HEADLINE relative level within current parsed tree.
INFO is a plist holding contextual information."
- (+ (org-element-get-property :level headline)
+ (+ (org-element-property :level headline)
(or (plist-get info :headline-offset) 0)))
+(defun org-export-low-level-p (headline info)
+ "Non-nil when HEADLINE is considered as low level.
+
+INFO is a plist used as a communication channel.
+
+A low level headlines has a relative level greater than
+`:headline-levels' property value.
+
+Return value is the difference between HEADLINE relative level
+and the last level being considered as high enough, or nil."
+ (let ((limit (plist-get info :headline-levels)))
+ (when (wholenump limit)
+ (let ((level (org-export-get-relative-level headline info)))
+ (and (> level limit) (- level limit))))))
+
(defun org-export-get-headline-number (headline info)
"Return HEADLINE numbering as a list of numbers.
INFO is a plist holding contextual information."
- (cdr (assq (org-element-get-property :begin headline)
- (plist-get info :headline-numbering))))
+ (cdr (assoc headline (plist-get info :headline-numbering))))
+
+(defun org-export-numbered-headline-p (headline info)
+ "Return a non-nil value if HEADLINE element should be numbered.
+INFO is a plist used as a communication channel."
+ (let ((sec-num (plist-get info :section-numbers))
+ (level (org-export-get-relative-level headline info)))
+ (if (wholenump sec-num) (<= level sec-num) sec-num)))
(defun org-export-number-to-roman (n)
"Convert integer N into a roman numeral."
@@ -2212,123 +2638,13 @@ (defun org-export-number-to-roman (n)
(defun org-export-first-sibling-p (headline info)
"Non-nil when HEADLINE is the first sibling in its sub-tree.
INFO is the plist used as a communication channel."
- (not (eq (plist-get info :previous-element) 'headline)))
+ (not (eq (org-element-type (org-export-get-previous-element headline info))
+ 'headline)))
(defun org-export-last-sibling-p (headline info)
"Non-nil when HEADLINE is the last sibling in its sub-tree.
INFO is the plist used as a communication channel."
- (= (org-element-get-property :end headline)
- (or (plist-get (plist-get info :parent-properties) :end)
- (plist-get info :point-max))))
-
-
-;;;; For Include Keywords
-
-;; This section provides a tool to properly handle insertion of files
-;; during export: `org-export-included-files'. It recursively
-;; transcodes a file specfied by an include keyword.
-
-;; It uses two helper functions: `org-export-get-file-contents'
-;; returns contents of a file according to parameters specified in the
-;; keyword while `org-export-parse-included-file' parses the file
-;; specified by it.
-
-(defun org-export-included-file (keyword backend info)
- "Transcode file specified with include KEYWORD.
-
-KEYWORD is the include keyword element transcoded. BACKEND is
-the language back-end used for transcoding. INFO is the plist
-used as a communication channel.
-
-This function updates `:included-files' and `:headline-offset'
-properties.
-
-Return the transcoded string."
- (let ((data (org-export-parse-included-file keyword info))
- (file (let ((value (org-element-get-property :value keyword)))
- (and (string-match "^\"\\(\\S-+\\)\"" value)
- (match-string 1 value)))))
- (org-element-normalize-string
- (org-export-data
- data backend
- (org-combine-plists
- info
- ;; Store full path of already included files to avoid
- ;; recursive file inclusion.
- `(:included-files
- ,(cons (expand-file-name file) (plist-get info :included-files))
- ;; Ensure that a top-level headline in the included
- ;; file becomes a direct child of the current headline
- ;; in the buffer.
- :headline-offset
- ,(- (+ (plist-get (plist-get info :inherited-properties) :level)
- (plist-get info :headline-offset))
- (1- (org-export-get-min-level data info)))))))))
-
-(defun org-export-get-file-contents (file &optional lines)
- "Get the contents of FILE and return them as a string.
-When optional argument LINES is a string specifying a range of
-lines, include only those lines."
- (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)))
- (buffer-string)))
-
-(defun org-export-parse-included-file (keyword info)
- "Parse file specified by include KEYWORD.
-
-KEYWORD is the include keyword element transcoded. BACKEND is the
-language back-end used for transcoding. INFO is the plist used as
-a communication channel.
-
-Return the parsed tree."
- (let* ((value (org-element-get-property :value keyword))
- (file (and (string-match "^\"\\(\\S-+\\)\"" value)
- (prog1 (match-string 1 value)
- (setq value (replace-match "" nil nil value)))))
- (lines (and (string-match
- ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\"" value)
- (prog1 (match-string 1 value)
- (setq value (replace-match "" nil nil value)))))
- (env (cond ((string-match "\\<example\\>" value) "example")
- ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
- (match-string 1 value)))))
- (cond
- ((or (not file)
- (not (file-exists-p file))
- (not (file-readable-p file)))
- (format "Cannot include file %s" file))
- ((and (not env)
- (member (expand-file-name file) (plist-get info :included-files)))
- (error "Recursive file inclusion: %S" file))
- (t (let ((raw (org-element-normalize-string
- (org-export-get-file-contents
- (expand-file-name file) lines))))
- ;; If environment isn't specified, Insert file in
- ;; a temporary buffer and parse it as Org syntax.
- ;; Otherwise, build the element representing the file.
- (cond
- ((not env)
- (with-temp-buffer
- (insert raw) (org-mode) (org-element-parse-buffer)))
- ((string= "example" env)
- `(org-data nil (example-block (:value ,raw :post-blank 0))))
- (t
- `(org-data
- nil
- (src-block (:value ,raw :language ,env :post-blank 0))))))))))
+ (not (org-export-get-next-element headline info)))
;;;; For Links
@@ -2346,10 +2662,18 @@ (defun org-export-parse-included-file (keyword info)
;; (i.e. links with "fuzzy" as type) within the parsed tree, and
;; returns an appropriate unique identifier when found, or nil.
+;; `org-export-resolve-id-link' returns the first headline with
+;; specified id or custom-id in parse tree, or nil when none was
+;; found.
+
+;; `org-export-resolve-coderef' associates a reference to a line
+;; number in the element it belongs, or returns the reference itself
+;; when the element isn't numbered.
+
(defun org-export-solidify-link-text (s)
- "Take link text and make a safe target out of it."
+ "Take link text S and make a safe target out of it."
(save-match-data
- (mapconcat 'identity (org-split-string s "[^a-zA-Z0-9_\\.-]+") "-")))
+ (mapconcat 'identity (org-split-string s "[^a-zA-Z0-9_.-]+") "-")))
(defun org-export-get-coderef-format (path desc)
"Return format string for code reference link.
@@ -2360,72 +2684,142 @@ (defun org-export-get-coderef-format (path desc)
((string= desc "") "%s")
(t desc))))
-(defun org-export-inline-image-p (link &optional extensions)
+(defun org-export-inline-image-p (link &optional rules)
"Non-nil if LINK object points to an inline image.
-When non-nil, optional argument EXTENSIONS is a list of valid
-extensions for image files, as strings. Otherwise, a default
-list is provided \(cf. `org-image-file-name-regexp'\)."
- (and (not (org-element-get-contents link))
- (string= (org-element-get-property :type link) "file")
- (org-file-image-p
- (expand-file-name (org-element-get-property :path link))
- extensions)))
+Optional argument is a set of RULES defining inline images. It
+is an alist where associations have the following shape:
+
+ \(TYPE . REGEXP)
+
+Applying a rule means apply REGEXP against LINK's path when its
+type is TYPE. The function will return a non-nil value if any of
+the provided rules is non-nil. The default rule is
+`org-export-default-inline-image-rule'.
+
+This only applies to links without a description."
+ (and (not (org-element-contents link))
+ (let ((case-fold-search t)
+ (rules (or rules org-export-default-inline-image-rule)))
+ (some
+ (lambda (rule)
+ (and (string= (org-element-property :type link) (car rule))
+ (string-match (cdr rule)
+ (org-element-property :path link))))
+ rules))))
(defun org-export-resolve-fuzzy-link (link info)
- "Return an unique identifier for LINK destination.
+ "Return LINK destination.
INFO is a plist holding contextual information.
-Return value can be a string, an buffer position, or nil:
+Return value can be an object, an element, or nil:
-- If LINK path exactly matches any target, return its name as the
- identifier.
+- If LINK path matches a target object (i.e. <<path>>) or
+ element (i.e. \"#+target: path\"), return it.
-- If LINK path exactly matches any headline name, return
- headline's beginning position as the identifier. If more than
- one headline share that name, priority will be given to the one
- with the closest common ancestor, if any, or the first one in
- the parse tree otherwise.
+- If LINK path exactly matches the name affiliated keyword
+ \(i.e. #+name: path) of an element, return that element.
+
+- If LINK path exactly matches any headline name, return that
+ element. If more than one headline share that name, priority
+ will be given to the one with the closest common ancestor, if
+ any, or the first one in the parse tree otherwise.
- Otherwise, return nil.
Assume LINK type is \"fuzzy\"."
- (let ((path (org-element-get-property :path link)))
- (if (member path (plist-get info :target-list))
- ;; Link points to a target: return its name as a string.
- path
- ;; Link either points to an headline or nothing. Try to find
- ;; the source, with priority given to headlines with the closest
- ;; common ancestor. If such candidate is found, return its
- ;; beginning position as an unique identifier, otherwise return
- ;; nil.
- (let* ((head-alist (plist-get info :headline-alist))
- (link-begin (org-element-get-property :begin link))
- (link-end (org-element-get-property :end link))
- ;; Store candidates as a list of cons cells holding their
- ;; beginning and ending position.
- (cands (loop for head in head-alist
- when (string= (car head) path)
- collect (cons (nth 1 head) (nth 2 head)))))
- (cond
- ;; No candidate: return nil.
- ((not cands) nil)
- ;; If one or more candidates share common ancestors with
- ;; LINK, return beginning position of the first one matching
- ;; the closer ancestor shared.
- ((let ((ancestors (loop for head in head-alist
- when (and (> link-begin (nth 1 head))
- (<= link-end (nth 2 head)))
- collect (cons (nth 1 head) (nth 2 head)))))
- (loop named main for ancestor in (nreverse ancestors) do
- (loop for candidate in cands
- when (and (>= (car candidate) (car ancestor))
- (<= (cdr candidate) (cdr ancestor)))
- do (return-from main (car candidate))))))
- ;; No candidate have a common ancestor with link: First match
- ;; will do. Return its beginning position.
- (t (caar cands)))))))
+ (let ((path (org-element-property :path link)))
+ (cond
+ ;; First try to find a matching "<<path>>" unless user specified
+ ;; he was looking for an headline (path starts with a *
+ ;; character).
+ ((and (not (eq (substring path 0 1) ?*))
+ (loop for target in (plist-get info :target-list)
+ when (string= (org-element-property :value target) path)
+ return target)))
+ ;; Then try to find an element with a matching "#+name: path"
+ ;; affiliated keyword.
+ ((and (not (eq (substring path 0 1) ?*))
+ (org-element-map
+ (plist-get info :parse-tree) org-element-all-elements
+ (lambda (el)
+ (when (string= (org-element-property :name el) path) el))
+ info 'first-match)))
+ ;; Last case: link either points to an headline or to
+ ;; nothingness. Try to find the source, with priority given to
+ ;; headlines with the closest common ancestor. If such candidate
+ ;; is found, return its beginning position as an unique
+ ;; identifier, otherwise return nil.
+ (t
+ (let ((find-headline
+ (function
+ ;; Return first headline whose `:raw-value' property
+ ;; is NAME in parse tree DATA, or nil.
+ (lambda (name data)
+ (org-element-map
+ data 'headline
+ (lambda (headline)
+ (when (string=
+ (org-element-property :raw-value headline)
+ name)
+ headline))
+ info 'first-match)))))
+ ;; Search among headlines sharing an ancestor with link,
+ ;; from closest to farthest.
+ (or (catch 'exit
+ (mapc
+ (lambda (parent)
+ (when (eq (org-element-type parent) 'headline)
+ (let ((foundp (funcall find-headline path parent)))
+ (when foundp (throw 'exit foundp)))))
+ (org-export-get-genealogy link info)) nil)
+ ;; No match with a common ancestor: try the full parse-tree.
+ (funcall find-headline path (plist-get info :parse-tree))))))))
+
+(defun org-export-resolve-id-link (link info)
+ "Return headline referenced as LINK destination.
+
+INFO is a plist used as a communication channel.
+
+Return value can be an headline element or nil. Assume LINK type
+is either \"id\" or \"custom-id\"."
+ (let ((id (org-element-property :path link)))
+ (org-element-map
+ (plist-get info :parse-tree) 'headline
+ (lambda (headline)
+ (when (or (string= (org-element-property :id headline) id)
+ (string= (org-element-property :custom-id headline) id))
+ headline))
+ info 'first-match)))
+
+(defun org-export-resolve-coderef (ref info)
+ "Resolve a code reference REF.
+
+INFO is a plist used as a communication channel.
+
+Return associated line number in source code, or REF itself,
+depending on src-block or example element's switches."
+ (org-element-map
+ (plist-get info :parse-tree) '(example-block src-block)
+ (lambda (el)
+ (with-temp-buffer
+ (insert (org-trim (org-element-property :value el)))
+ (let* ((label-fmt (regexp-quote
+ (or (org-element-property :label-fmt el)
+ org-coderef-label-format)))
+ (ref-re
+ (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
+ (replace-regexp-in-string "%s" ref label-fmt nil t))))
+ ;; Element containing REF is found. Resolve it to either
+ ;; a label or a line number, as needed.
+ (when (re-search-backward ref-re nil t)
+ (cond
+ ((org-element-property :use-labels el) ref)
+ ((eq (org-element-property :number-lines el) 'continued)
+ (+ (org-export-get-loc el info) (line-number-at-pos)))
+ (t (line-number-at-pos)))))))
+ info 'first-match))
;;;; For Macros
@@ -2435,9 +2829,17 @@ (defun org-export-resolve-fuzzy-link (link info)
(defun org-export-expand-macro (macro info)
"Expand MACRO and return it as a string.
INFO is a plist holding export options."
- (let* ((key (org-element-get-property :key macro))
- (args (org-element-get-property :args macro))
- (value (plist-get info (intern (format ":macro-%s" key)))))
+ (let* ((key (org-element-property :key macro))
+ (args (org-element-property :args macro))
+ ;; User's macros are stored in the communication channel with
+ ;; a ":macro-" prefix. If it's a string leave it as-is.
+ ;; Otherwise, it's a secondary string that needs to be
+ ;; expanded recursively.
+ (value
+ (let ((val (plist-get info (intern (format ":macro-%s" key)))))
+ (if (stringp val) val
+ (org-export-secondary-string
+ val (plist-get info :back-end) info)))))
;; Replace arguments in VALUE.
(let ((s 0) n)
(while (string-match "\\$\\([0-9]+\\)" value s)
@@ -2448,8 +2850,8 @@ (defun org-export-expand-macro (macro info)
;; VALUE starts with "(eval": it is a s-exp, `eval' it.
(when (string-match "\\`(eval\\>" value)
(setq value (eval (read value))))
- ;; Return expanded string.
- (format "%s" value)))
+ ;; Return string.
+ (format "%s" (or value ""))))
;;;; For References
@@ -2457,164 +2859,245 @@ (defun org-export-expand-macro (macro info)
;; `org-export-get-ordinal' associates a sequence number to any object
;; or element.
-(defun org-export-get-ordinal (element info &optional within-section predicate)
+(defun org-export-get-ordinal (element info &optional types predicate)
"Return ordinal number of an element or object.
ELEMENT is the element or object considered. INFO is the plist
used as a communication channel.
-When optional argument WITHIN-SECTION is non-nil, narrow counting
-to the section containing ELEMENT.
+Optional argument TYPES, when non-nil, is a list of element or
+object types, as symbols, that should also be counted in.
+Otherwise, only provided element's type is considered.
Optional argument PREDICATE is a function returning a non-nil
value if the current element or object should be counted in. It
-accepts one argument: the element or object being considered.
-This argument allows to count only a certain type of objects,
-like inline images, which are a subset of links \(in that case,
-`org-export-inline-image-p' might be an useful predicate\)."
- (let ((counter 0)
- (type (car element))
- ;; Determine if search should apply to current section, in
- ;; which case it should be retrieved first, or to full parse
- ;; tree. As a special case, an element or object without
- ;; a parent headline will also trigger a full search,
- ;; notwithstanding WITHIN-SECTION value.
- (data
- (let ((parse-tree (plist-get info :parse-tree)))
- (if within-section
- (let ((parent (plist-get (plist-get info :inherited-properties)
- :begin)))
- (if (not parent) parse-tree
- (org-element-map
- parse-tree 'headline
- (lambda (el local)
- (when (= (org-element-get-property :begin el) parent) el))
- info 'first-match)))
- parse-tree))))
- ;; Increment counter until ELEMENT is found again.
+accepts two arguments: the element or object being considered and
+the plist used as a communication channel. This allows to count
+only a certain type of objects (i.e. inline images).
+
+Return value is a list of numbers if ELEMENT is an headline or an
+item. It is nil for keywords. It represents the footnote number
+for footnote definitions and footnote references. If ELEMENT is
+a target, return the same value as if ELEMENT was the closest
+table, item or headline containing the target. In any other
+case, return the sequence number of ELEMENT among elements or
+objects of the same type."
+ ;; A target keyword, representing an invisible target, never has
+ ;; a sequence number.
+ (unless (eq (org-element-type element) 'keyword)
+ ;; Ordinal of a target object refer to the ordinal of the closest
+ ;; table, item, or headline containing the object.
+ (when (eq (org-element-type element) 'target)
+ (setq element
+ (loop for parent in (org-export-get-genealogy element info)
+ when
+ (memq
+ (org-element-type parent)
+ '(footnote-definition footnote-reference headline item
+ table))
+ return parent)))
+ (case (org-element-type element)
+ ;; Special case 1: An headline returns its number as a list.
+ (headline (org-export-get-headline-number element info))
+ ;; Special case 2: An item returns its number as a list.
+ (item (let ((struct (org-element-property :structure element)))
+ (org-list-get-item-number
+ (org-element-property :begin element)
+ struct
+ (org-list-prevs-alist struct)
+ (org-list-parents-alist struct))))
+ ((footnote definition footnote-reference)
+ (org-export-get-footnote-number element info))
+ (otherwise
+ (let ((counter 0))
+ ;; Increment counter until ELEMENT is found again.
+ (org-element-map
+ (plist-get info :parse-tree) (or types (org-element-type element))
+ (lambda (el)
+ (cond
+ ((equal element el) (1+ counter))
+ ((not predicate) (incf counter) nil)
+ ((funcall predicate el info) (incf counter) nil)))
+ info 'first-match))))))
+
+
+;;;; For Src-Blocks
+
+;; `org-export-get-loc' counts number of code lines accumulated in
+;; src-block or example-block elements with a "+n" switch until
+;; a given element, excluded. Note: "-n" switches reset that count.
+
+;; `org-export-unravel-code' extracts source code (along with a code
+;; references alist) from an `element-block' or `src-block' type
+;; element.
+
+;; `org-export-format-code' applies a formatting function to each line
+;; of code, providing relative line number and code reference when
+;; appropriate. Since it doesn't access the original element from
+;; which the source code is coming, it expects from the code calling
+;; it to know if lines should be numbered and if code references
+;; should appear.
+
+;; Eventually, `org-export-format-code-default' is a higher-level
+;; function (it makes use of the two previous functions) which handles
+;; line numbering and code references inclusion, and returns source
+;; code in a format suitable for plain text or verbatim output.
+
+(defun org-export-get-loc (element info)
+ "Return accumulated lines of code up to ELEMENT.
+
+INFO is the plist used as a communication channel.
+
+ELEMENT is excluded from count."
+ (let ((loc 0))
(org-element-map
- data type
- (lambda (el local)
+ (plist-get info :parse-tree)
+ `(src-block example-block ,(org-element-type element))
+ (lambda (el)
(cond
- ((and (functionp predicate) (funcall predicate el)))
- ((equal element el) (1+ counter))
- (t (incf counter) nil)))
- info 'first-match)))
+ ;; ELEMENT is reached: Quit the loop.
+ ((equal el element) t)
+ ;; Only count lines from src-block and example-block elements
+ ;; with a "+n" or "-n" switch. A "-n" switch resets counter.
+ ((not (memq (org-element-type el) '(src-block example-block))) nil)
+ ((let ((linums (org-element-property :number-lines el)))
+ (when linums
+ ;; Accumulate locs or reset them.
+ (let ((lines (org-count-lines
+ (org-trim (org-element-property :value el)))))
+ (setq loc (if (eq linums 'new) lines (+ loc lines))))))
+ ;; Return nil to stay in the loop.
+ nil)))
+ info 'first-match)
+ ;; Return value.
+ loc))
+(defun org-export-unravel-code (element)
+ "Clean source code and extract references out of it.
-;;;; For Src-Blocks
+ELEMENT has either a `src-block' an `example-block' type.
-;; `org-export-handle-code' takes care of line numbering and reference
-;; cleaning in source code, when appropriate. It also updates global
-;; LOC count (`:total-loc' property) and code references alist
-;; (`:code-refs' property).
-
-(defun org-export-handle-code (code switches info
- &optional language num-fmt ref-fmt)
- "Handle line numbers and code references in CODE.
-
-CODE is the string to process. SWITCHES is the option string
-determining which changes will be applied to CODE. INFO is the
-plist used as a communication channel during export.
-
-Optional argument LANGUAGE, when non-nil, is a string specifying
-code's language.
-
-If optional argument NUM-FMT is a string, it will be used as
-a format string for numbers at beginning of each line.
-
-If optional argument REF-FMT is a string, it will be used as
-a format string for each line of code containing a reference.
-
-Update the following INFO properties by side-effect: `:total-loc'
-and `:code-refs'.
-
-Return new code as a string."
- (let* ((switches (or switches ""))
- (numberp (string-match "[-+]n\\>" switches))
- (continuep (string-match "\\+n\\>" switches))
- (total-LOC (if (and numberp (not continuep))
- 0
- (or (plist-get info :total-loc) 0)))
- (preserve-indent-p (or org-src-preserve-indentation
- (string-match "-i\\>" switches)))
- (replace-labels (when (string-match "-r\\>" switches)
- (if (string-match "-k\\>" switches) 'keep t)))
+Return a cons cell whose CAR is the source code, cleaned from any
+reference and protective comma and CDR is an alist between
+relative line number (integer) and name of code reference on that
+line (string)."
+ (let* ((line 0) refs
;; Get code and clean it. Remove blank lines at its
;; beginning and end. Also remove protective commas.
(code (let ((c (replace-regexp-in-string
"\\`\\([ \t]*\n\\)+" ""
(replace-regexp-in-string
- "\\(:?[ \t]*\n\\)*[ \t]*\\'" "\n" code))))
+ "\\(:?[ \t]*\n\\)*[ \t]*\\'" "\n"
+ (org-element-property :value element)))))
;; If appropriate, remove global indentation.
- (unless preserve-indent-p (setq c (org-remove-indentation c)))
+ (unless (or org-src-preserve-indentation
+ (org-element-property :preserve-indent element))
+ (setq c (org-remove-indentation c)))
;; Free up the protected lines. Note: Org blocks
;; have commas at the beginning or every line.
- (if (string= language "org")
+ (if (string= (org-element-property :language element) "org")
(replace-regexp-in-string "^," "" c)
(replace-regexp-in-string
"^\\(,\\)\\(:?\\*\\|[ \t]*#\\+\\)" "" c nil nil 1))))
- ;; Split code to process it line by line.
- (code-lines (org-split-string code "\n"))
- ;; Ensure line numbers will be correctly padded before
- ;; applying the format string.
- (num-fmt (format (if (stringp num-fmt) num-fmt "%s: ")
- (format "%%%ds"
- (length (number-to-string
- (+ (length code-lines)
- total-LOC))))))
;; Get format used for references.
- (label-fmt (or (and (string-match "-l +\"\\([^\"\n]+\\)\"" switches)
- (match-string 1 switches))
- org-coderef-label-format))
+ (label-fmt (regexp-quote
+ (or (org-element-property :label-fmt element)
+ org-coderef-label-format)))
;; Build a regexp matching a loc with a reference.
- (with-ref-re (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)\\)[ \t]*$"
- (replace-regexp-in-string
- "%s" "\\([-a-zA-Z0-9_ ]+\\)" label-fmt nil t)))
- coderefs)
+ (with-ref-re
+ (format "^.*?\\S-.*?\\([ \t]*\\(%s\\)[ \t]*\\)$"
+ (replace-regexp-in-string
+ "%s" "\\([-a-zA-Z0-9_ ]+\\)" label-fmt nil t))))
+ ;; Return value.
+ (cons
+ ;; Code with references removed.
+ (org-element-normalize-string
+ (mapconcat
+ (lambda (loc)
+ (incf line)
+ (if (not (string-match with-ref-re loc)) loc
+ ;; Ref line: remove ref, and signal its position in REFS.
+ (push (cons line (match-string 3 loc)) refs)
+ (replace-match "" nil nil loc 1)))
+ (org-split-string code "\n") "\n"))
+ ;; Reference alist.
+ refs)))
+
+(defun org-export-format-code (code fun &optional num-lines ref-alist)
+ "Format CODE by applying FUN line-wise and return it.
+
+CODE is a string representing the code to format. FUN is
+a function. It must accept three arguments: a line of
+code (string), the current line number (integer) or nil and the
+reference associated to the current line (string) or nil.
+
+Optional argument NUM-LINES can be an integer representing the
+number of code lines accumulated until the current code. Line
+numbers passed to FUN will take it into account. If it is nil,
+FUN's second argument will always be nil. This number can be
+obtained with `org-export-get-loc' function.
+
+Optional argument REF-ALIST can be an alist between relative line
+number (i.e. ignoring NUM-LINES) and the name of the code
+reference on it. If it is nil, FUN's third argument will always
+be nil. It can be obtained through the use of
+`org-export-unravel-code' function."
+ (let ((--locs (org-split-string code "\n"))
+ (--line 0))
(org-element-normalize-string
- (mapconcat (lambda (loc)
- ;; Maybe add line number to current line of code
- ;; (LOC).
- (when numberp
- (setq loc (concat (format num-fmt (incf total-LOC)) loc)))
- ;; Take action if at a ref line.
- (when (string-match with-ref-re loc)
- (let ((ref (match-string 3 loc)))
- (setq loc
- (cond
- ;; Option "-k": don't remove labels. Use
- ;; numbers for references when lines are
- ;; numbered, use labels otherwise.
- ((eq replace-labels 'keep)
- (let ((full-ref (format "(%s)" ref)))
- (push (cons ref (if numberp total-LOC full-ref))
- coderefs)
- (replace-match full-ref nil nil loc 2))
- (replace-match (format "(%s)" ref) nil nil loc 2))
- ;; Option "-r" without "-k": remove labels.
- ;; Use numbers for references when lines are
- ;; numbered, use labels otherwise.
- (replace-labels
- (push (cons ref (if numberp total-LOC ref))
- coderefs)
- (replace-match "" nil nil loc 1))
- ;; Else: don't remove labels and don't use
- ;; numbers for references.
- (t
- (let ((full-ref (format "(%s)" ref)))
- (push (cons ref full-ref) coderefs)
- (replace-match full-ref nil nil loc 2)))))))
- ;; If REF-FMT is defined, apply it to current LOC.
- (when (stringp ref-fmt) (setq loc (format ref-fmt loc)))
- ;; Update by side-effect communication channel.
- ;; Return updated LOC.
- (setq info (org-export-set-property
- (org-export-set-property
- info :code-refs coderefs)
- :total-loc total-LOC))
- loc)
- code-lines "\n"))))
+ (mapconcat
+ (lambda (--loc)
+ (incf --line)
+ (let ((--ref (cdr (assq --line ref-alist))))
+ (funcall fun --loc (and num-lines (+ num-lines --line)) --ref)))
+ --locs "\n"))))
+
+(defun org-export-format-code-default (element info)
+ "Return source code from ELEMENT, formatted in a standard way.
+
+ELEMENT is either a `src-block' or `example-block' element. INFO
+is a plist used as a communication channel.
+
+This function takes care of line numbering and code references
+inclusion. Line numbers, when applicable, appear at the
+beginning of the line, separated from the code by two white
+spaces. Code references, on the other hand, appear flushed to
+the right, separated by six white spaces from the widest line of
+code."
+ ;; Extract code and references.
+ (let* ((code-info (org-export-unravel-code element))
+ (code (car code-info))
+ (code-lines (org-split-string code "\n"))
+ (refs (and (org-element-property :retain-labels element)
+ (cdr code-info)))
+ ;; Handle line numbering.
+ (num-start (case (org-element-property :number-lines element)
+ (continued (org-export-get-loc element info))
+ (new 0)))
+ (num-fmt
+ (and num-start
+ (format "%%%ds "
+ (length (number-to-string
+ (+ (length code-lines) num-start))))))
+ ;; Prepare references display, if required. Any reference
+ ;; should start six columns after the widest line of code,
+ ;; wrapped with parenthesis.
+ (max-width
+ (+ (apply 'max (mapcar 'length code-lines))
+ (if (not num-start) 0 (length (format num-fmt num-start))))))
+ (org-export-format-code
+ code
+ (lambda (loc line-num ref)
+ (let ((number-str (and num-fmt (format num-fmt line-num))))
+ (concat
+ number-str
+ loc
+ (and ref
+ (concat (make-string
+ (- (+ 6 max-width)
+ (+ (length loc) (length number-str))) ? )
+ (format "(%s)" ref))))))
+ num-start refs)))
;;;; For Tables
@@ -2649,7 +3132,6 @@ (defun org-export-table-format-info (table)
(mapc (lambda (row)
(if (string-match "^[ \t]*|[-+]+|[ \t]*$" row)
(incf row-group)
- (push row-group rowgroups)
;; Determine if a special column is present by looking
;; for special markers in the first column. More
;; accurately, the first column is considered special
@@ -2658,8 +3140,8 @@ (defun org-export-table-format-info (table)
(setq special-column-p
(cond
((not special-column-p) nil)
- ((string-match "^[ \t]*| *\\\\?\\([\#!$*_^]\\) *|"
- row) 'special)
+ ((string-match "^[ \t]*| *\\\\?\\([/#!$*_^]\\) *|" row)
+ 'special)
((string-match "^[ \t]*| +|" row) special-column-p))))
(cond
;; Read forced alignment and width information, if any,
@@ -2667,10 +3149,13 @@ (defun org-export-table-format-info (table)
((org-table-cookie-line-p row)
(let ((col 0))
(mapc (lambda (field)
- (when (string-match "<\\([lrc]\\)\\([0-9]+\\)?>" field)
- (aset align col (match-string 1 field))
- (aset width col (let ((w (match-string 2 field)))
- (and w (string-to-number w)))))
+ (when (string-match
+ "<\\([lrc]\\)?\\([0-9]+\\)?>" field)
+ (let ((align-data (match-string 1 field)))
+ (when align-data (aset align col align-data)))
+ (let ((w-data (match-string 2 field)))
+ (when w-data
+ (aset width col (string-to-number w-data)))))
(incf col))
(org-split-string row "[ \t]*|[ \t]*"))))
;; Read column groups information.
@@ -2682,7 +3167,9 @@ (defun org-export-table-format-info (table)
((string= ">" field) 'end)
((string= "<>" field) 'start-end)))
(incf col))
- (org-split-string row "[ \t]*|[ \t]*"))))))
+ (org-split-string row "[ \t]*|[ \t]*"))))
+ ;; Contents line.
+ (t (push row-group rowgroups))))
(org-split-string table "\n"))
;; Return plist.
(list :alignment align
@@ -2706,7 +3193,7 @@ (defun org-export-clean-table (table specialp)
((org-table-colgroup-line-p row) nil)
((org-table-cookie-line-p row) nil)
;; Ignore rows starting with a special marker.
- ((string-match "^[ \t]*| *[!_^/] *|" row) nil)
+ ((string-match "^[ \t]*| *[!_^/$] *|" row) nil)
;; Remove special column.
((and specialp
(or (string-match "^\\([ \t]*\\)|-+\\+" row)
@@ -2731,6 +3218,8 @@ (defun org-export-clean-table (table specialp)
(defun org-export-collect-headlines (info &optional n)
"Collect headlines in order to build a table of contents.
+INFO is a plist used as a communication channel.
+
When non-nil, optional argument N must be an integer. It
specifies the depth of the table of contents.
@@ -2738,70 +3227,353 @@ (defun org-export-collect-headlines (info &optional n)
(org-element-map
(plist-get info :parse-tree)
'headline
- (lambda (headline local)
+ (lambda (headline)
;; Strip contents from HEADLINE.
- (let ((relative-level (org-export-get-relative-level headline local)))
+ (let ((relative-level (org-export-get-relative-level headline info)))
(unless (and n (> relative-level n)) headline)))
info))
-(defun org-export-collect-elements (type backend info)
- "Collect named elements of type TYPE.
+(defun org-export-collect-elements (type info &optional predicate)
+ "Collect referenceable elements of a determined type.
-Only elements with a caption or a name are collected.
+TYPE can be a symbol or a list of symbols specifying element
+types to search. Only elements with a caption or a name are
+collected.
-BACKEND is the back-end used to transcode their caption or name.
-INFO is a plist holding export options.
+INFO is a plist used as a communication channel.
-Return an alist where key is entry's name and value an unique
-identifier that might be used for internal links."
- (org-element-map
- (plist-get info :parse-tree)
- type
- (lambda (element info)
- (let ((entry
- (cond
- ((org-element-get-property :caption element)
- (org-export-secondary-string
- (org-element-get-property :caption element) backend info))
- ((org-element-get-property :name element)
- (org-export-secondary-string
- (org-element-get-property :name element) backend info)))))
- ;; Skip elements with neither a caption nor a name.
- (when entry (cons entry (org-element-get-property :begin element)))))
- info))
+When non-nil, optional argument PREDICATE is a function accepting
+one argument, an element of type TYPE. It returns a non-nil
+value when that element should be collected.
-(defun org-export-collect-tables (backend info)
+Return a list of all elements found, in order of appearance."
+ (org-element-map
+ (plist-get info :parse-tree) type
+ (lambda (element)
+ (and (or (org-element-property :caption element)
+ (org-element-property :name element))
+ (or (not predicate) (funcall predicate element))
+ element)) info))
+
+(defun org-export-collect-tables (info)
"Build a list of tables.
-BACKEND is the back-end used to transcode table's name. INFO is
-a plist holding export options.
+INFO is a plist used as a communication channel.
-Return an alist where key is the caption of the table and value
-an unique identifier that might be used for internal links."
- (org-export-collect-elements 'table backend info))
+Return a list of table elements with a caption or a name
+affiliated keyword."
+ (org-export-collect-elements 'table info))
-(defun org-export-collect-figures (backend info)
+(defun org-export-collect-figures (info predicate)
"Build a list of figures.
-A figure is a paragraph type element with a caption or a name.
+INFO is a plist used as a communication channel. PREDICATE is
+a function which accepts one argument: a paragraph element and
+whose return value is non-nil when that element should be
+collected.
-BACKEND is the back-end used to transcode headline's name. INFO
-is a plist holding export options.
+A figure is a paragraph type element, with a caption or a name,
+verifying PREDICATE. The latter has to be provided since
+a \"figure\" is a vague concept that may depend on back-end.
-Return an alist where key is the caption of the figure and value
-an unique indentifier that might be used for internal links."
- (org-export-collect-elements 'paragraph backend info))
+Return a list of elements recognized as figures."
+ (org-export-collect-elements 'paragraph info predicate))
-(defun org-export-collect-listings (backend info)
+(defun org-export-collect-listings (info)
"Build a list of src blocks.
-BACKEND is the back-end used to transcode src block's name. INFO
-is a plist holding export options.
+INFO is a plist used as a communication channel.
+
+Return a list of src-block elements with a caption or a name
+affiliated keyword."
+ (org-export-collect-elements 'src-block info))
+
+
+;;;; Topology
+
+;; Here are various functions to retrieve information about the
+;; neighbourhood of a given element or object. Neighbours of interest
+;; are direct parent (`org-export-get-parent'), parent headline
+;; (`org-export-get-parent-headline'), parent paragraph
+;; (`org-export-get-parent-paragraph'), previous element or object
+;; (`org-export-get-previous-element') and next element or object
+;; (`org-export-get-next-element').
+
+;; All of these functions are just a specific use of the more generic
+;; `org-export-get-genealogy', which returns the genealogy relative to
+;; the element or object.
+
+(defun org-export-get-genealogy (blob info)
+ "Return genealogy relative to a given element or object.
+BLOB is the element or object being considered. INFO is a plist
+used as a communication channel."
+ (let* ((type (org-element-type blob))
+ (end (org-element-property :end blob))
+ (walk-data
+ (lambda (data genealogy)
+ ;; Walk DATA, looking for BLOB. GENEALOGY is the list of
+ ;; parents of all elements in DATA.
+ (mapc
+ (lambda (el)
+ (cond
+ ((stringp el) nil)
+ ((equal el blob) (throw 'exit genealogy))
+ ((>= (org-element-property :end el) end)
+ ;; If BLOB is an object and EL contains a secondary
+ ;; string, be sure to check it.
+ (when (memq type org-element-all-objects)
+ (let ((sec-prop
+ (cdr (assq (org-element-type el)
+ org-element-secondary-value-alist))))
+ (when sec-prop
+ (funcall
+ walk-data
+ (cons 'org-data
+ (cons nil (org-element-property sec-prop el)))
+ (cons el genealogy)))))
+ (funcall walk-data el (cons el genealogy)))))
+ (org-element-contents data)))))
+ (catch 'exit (funcall walk-data (plist-get info :parse-tree) nil) nil)))
+
+(defun org-export-get-parent (blob info)
+ "Return BLOB parent or nil.
+BLOB is the element or object considered. INFO is a plist used
+as a communication channel."
+ (car (org-export-get-genealogy blob info)))
+
+(defun org-export-get-parent-headline (blob info)
+ "Return closest parent headline or nil.
+
+BLOB is the element or object being considered. INFO is a plist
+used as a communication channel."
+ (catch 'exit
+ (mapc
+ (lambda (el) (when (eq (org-element-type el) 'headline) (throw 'exit el)))
+ (org-export-get-genealogy blob info))
+ nil))
+
+(defun org-export-get-parent-paragraph (object info)
+ "Return parent paragraph or nil.
+
+INFO is a plist used as a communication channel.
+
+Optional argument OBJECT, when provided, is the object to consider.
+Otherwise, return the paragraph containing current object.
+
+This is useful for objects, which share attributes with the
+paragraph containing them."
+ (catch 'exit
+ (mapc
+ (lambda (el) (when (eq (org-element-type el) 'paragraph) (throw 'exit el)))
+ (org-export-get-genealogy object info))
+ nil))
+
+(defun org-export-get-previous-element (blob info)
+ "Return previous element or object.
+
+BLOB is an element or object. INFO is a plist used as
+a communication channel.
+
+Return previous element or object, a string, or nil."
+ (let ((parent (org-export-get-parent blob info)))
+ (cadr (member blob (reverse (org-element-contents parent))))))
+
+(defun org-export-get-next-element (blob info)
+ "Return next element or object.
+
+BLOB is an element or object. INFO is a plist used as
+a communication channel.
+
+Return next element or object, a string, or nil."
+ (let ((parent (org-export-get-parent blob info)))
+ (cadr (member blob (org-element-contents parent)))))
+
-Return an alist where key is the caption of the src block and
-value an unique indentifier that might be used for internal
-links."
- (org-export-collect-elements 'src-block backend info))
+\f
+;;; The Dispatcher
+
+;; `org-export-dispatch' is the standard interactive way to start an
+;; export process. It uses `org-export-dispatch-ui' as a subroutine
+;; for its interface. Most commons back-ends should have an entry in
+;; it.
+
+(defun org-export-dispatch ()
+ "Export dispatcher for Org mode.
+
+It provides an access to common export related tasks in a buffer.
+Its interface comes in two flavours: standard and expert. While
+both share the same set of bindings, only the former displays the
+valid keys associations. Set `org-export-dispatch-use-expert-ui'
+to switch to one or the other.
+
+Return an error if key pressed has no associated command."
+ (interactive)
+ (let* ((input (org-export-dispatch-ui
+ (if (listp org-export-initial-scope) org-export-initial-scope
+ (list org-export-initial-scope))
+ org-export-dispatch-use-expert-ui))
+ (raw-key (car input))
+ (optns (cdr input)))
+ ;; Translate "C-a", "C-b"... into "a", "b"... Then take action
+ ;; depending on user's key pressed.
+ (case (if (< raw-key 27) (+ raw-key 96) raw-key)
+ ;; Allow to quit with "q" key.
+ (?q nil)
+ ;; Export with `e-ascii' back-end.
+ ((?A ?N ?U)
+ (let ((outbuf
+ (org-export-to-buffer
+ 'e-ascii "*Org E-ASCII Export*"
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns)
+ `(:ascii-charset
+ ,(case raw-key (?A 'ascii) (?N 'latin1) (t 'utf-8))))))
+ (with-current-buffer outbuf (text-mode))
+ (when org-export-show-temporary-export-buffer
+ (switch-to-buffer-other-window outbuf))))
+ ((?a ?n ?u)
+ (org-e-ascii-export-to-ascii
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns)
+ `(:ascii-charset ,(case raw-key (?a 'ascii) (?n 'latin1) (t 'utf-8)))))
+ ;; Export with `e-latex' back-end.
+ (?L
+ (let ((outbuf
+ (org-export-to-buffer
+ 'e-latex "*Org E-LaTeX Export*"
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns))))
+ (with-current-buffer outbuf (latex-mode))
+ (when org-export-show-temporary-export-buffer
+ (switch-to-buffer-other-window outbuf))))
+ (?l (org-e-latex-export-to-latex
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns)))
+ (?p (org-e-latex-export-to-pdf
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns)))
+ (?d (org-open-file
+ (org-e-latex-export-to-pdf
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns))))
+ ;; Export with `e-html' back-end.
+ (?H
+ (let ((outbuf
+ (org-export-to-buffer
+ 'e-html "*Org E-HTML Export*"
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns))))
+ ;; set major mode
+ (with-current-buffer outbuf
+ (if (featurep 'nxhtml-mode) (nxhtml-mode) (nxml-mode)))
+ (when org-export-show-temporary-export-buffer
+ (switch-to-buffer-other-window outbuf))))
+ (?h (org-e-html-export-to-html
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns)))
+ (?b (org-open-file
+ (org-e-html-export-to-html
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns))))
+ ;; Export with `e-odt' back-end.
+ (?o (org-e-odt-export-to-odt
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns)))
+ (?O (org-open-file
+ (org-e-odt-export-to-odt
+ (memq 'subtree optns) (memq 'visible optns) (memq 'body optns))))
+ ;; Publishing facilities
+ (?F (org-e-publish-current-file (memq 'force optns)))
+ (?P (org-e-publish-current-project (memq 'force optns)))
+ (?X (let ((project
+ (assoc (org-icompleting-read
+ "Publish project: " org-e-publish-project-alist nil t)
+ org-e-publish-project-alist)))
+ (org-e-publish project (memq 'force optns))))
+ (?E (org-e-publish-all (memq 'force optns)))
+ ;; Undefined command.
+ (t (error "No command associated with key %s"
+ (char-to-string raw-key))))))
+
+(defun org-export-dispatch-ui (options expertp)
+ "Handle interface for `org-export-dispatch'.
+
+OPTIONS is a list containing current interactive options set for
+export. It can contain any of the following symbols:
+`body' toggles a body-only export
+`subtree' restricts export to current subtree
+`visible' restricts export to visible part of buffer.
+`force' force publishing files.
+
+EXPERTP, when non-nil, triggers expert UI. In that case, no help
+buffer is provided, but indications about currently active
+options are given in the prompt. Moreover, \[?] allows to switch
+back to standard interface.
+
+Return value is a list with key pressed as CAR and a list of
+final interactive export options as CDR."
+ (let ((help
+ (format "---- (Options) -------------------------------------------
+
+\[1] Body only: %s [2] Export scope: %s
+\[3] Visible only: %s [4] Force publishing: %s
+
+
+--- (ASCII/Latin-1/UTF-8 Export) -------------------------
+
+\[a/n/u] to TXT file [A/N/U] to temporary buffer
+
+--- (HTML Export) ----------------------------------------
+
+\[h] to HTML file [b] ... and open it
+\[H] to temporary buffer
+
+--- (LaTeX Export) ---------------------------------------
+
+\[l] to TEX file [L] to temporary buffer
+\[p] to PDF file [d] ... and open it
+
+--- (ODF Export) -----------------------------------------
+
+\[o] to ODT file [O] ... and open it
+
+--- (Publish) --------------------------------------------
+
+\[F] current file [P] current project
+\[X] a project [E] every project"
+ (if (memq 'body options) "On " "Off")
+ (if (memq 'subtree options) "Subtree" "Buffer ")
+ (if (memq 'visible options) "On " "Off")
+ (if (memq 'force options) "On " "Off")))
+ (standard-prompt "Export command: ")
+ (expert-prompt (format "Export command (%s%s%s%s): "
+ (if (memq 'body options) "b" "-")
+ (if (memq 'subtree options) "s" "-")
+ (if (memq 'visible options) "v" "-")
+ (if (memq 'force options) "f" "-")))
+ (handle-keypress
+ (function
+ ;; Read a character from command input, toggling interactive
+ ;; options when applicable. PROMPT is the displayed prompt,
+ ;; as a string.
+ (lambda (prompt)
+ (let ((key (read-char-exclusive prompt)))
+ (cond
+ ;; Ignore non-standard characters (i.e. "M-a").
+ ((not (characterp key)) (org-export-dispatch-ui options expertp))
+ ;; Help key: Switch back to standard interface if
+ ;; expert UI was active.
+ ((eq key ??) (org-export-dispatch-ui options nil))
+ ;; Toggle export options.
+ ((memq key '(?1 ?2 ?3 ?4))
+ (org-export-dispatch-ui
+ (let ((option (case key (?1 'body) (?2 'subtree) (?3 'visible)
+ (?4 'force))))
+ (if (memq option options) (remq option options)
+ (cons option options)))
+ expertp))
+ ;; Action selected: Send key and options back to
+ ;; `org-export-dispatch'.
+ (t (cons key options))))))))
+ ;; With expert UI, just read key with a fancy prompt. In standard
+ ;; UI, display an intrusive help buffer.
+ (if expertp (funcall handle-keypress expert-prompt)
+ (save-window-excursion
+ (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*"))
+ (funcall handle-keypress standard-prompt)))))
(provide 'org-export)
diff --git a/contrib/lisp/org-interactive-query.el b/contrib/lisp/org-interactive-query.el
index 6bf40f8..ab6669b 100644
--- a/contrib/lisp/org-interactive-query.el
+++ b/contrib/lisp/org-interactive-query.el
@@ -6,7 +6,7 @@
;; Version: 1.0
;; Keywords: org, wp
;;
-;; This file is not part of GNU Emacs.
+;; This file is not part of GNU Emacs.
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
;; / add a keyword as a positive selection criterion
;; \ add a keyword as a newgative selection criterion
;; = clear a keyword from the selection string
-;; ;
+;; ;
(require 'org)
@@ -39,7 +39,7 @@
(org-defkey org-agenda-mode-map "/" 'org-agenda-query-and-cmd)
(org-defkey org-agenda-mode-map ";" 'org-agenda-query-or-cmd)
(org-defkey org-agenda-mode-map "\\" 'org-agenda-query-not-cmd)
-
+
;;; Agenda interactive query manipulation
(defcustom org-agenda-query-selection-single-key t
@@ -283,7 +283,7 @@ (defun org-agenda-query-merge-todo-key (alist entry)
(defun org-agenda-query-generic-cmd (op)
"Activate query manipulation with OP as initial operator."
(let ((q (org-agenda-query-selection org-agenda-query-string op
- org-tag-alist
+ org-tag-alist
(org-agenda-query-global-todo-keys))))
(when q
(setq org-agenda-query-string q)
diff --git a/contrib/lisp/org-invoice.el b/contrib/lisp/org-invoice.el
index ca25711..c951d4e 100644
--- a/contrib/lisp/org-invoice.el
+++ b/contrib/lisp/org-invoice.el
@@ -181,7 +181,7 @@ (defun org-invoice-level-min-max (ls)
(when (or (not min) (< level min)) (setq min level))
(when (> level max) (setq max level))))
(cons (or min 0) max)))
-
+
(defun org-invoice-collapse-list (ls)
"Reorganize the given list by dates."
(let ((min-max (org-invoice-level-min-max ls)) new)
@@ -214,7 +214,7 @@ (defun org-invoice-collapse-list (ls)
(+ price (cdr (assoc 'price (car bucket)))))
(nconc bucket (list info))))))
(nreverse new)))
-
+
(defun org-invoice-info-to-table (info)
"Create a single org table row from the given info alist."
(let ((title (cdr (assoc 'title info)))
@@ -223,19 +223,19 @@ (defun org-invoice-info-to-table (info)
(price (cdr (assoc 'price info)))
(with-price (plist-get org-invoice-table-params :price)))
(unless total
- (setq
+ (setq
org-invoice-total-time (+ org-invoice-total-time work)
org-invoice-total-price (+ org-invoice-total-price price)))
(setq total (and total (org-minutes-to-hh:mm-string total)))
(setq work (and work (org-minutes-to-hh:mm-string work)))
- (insert-before-markers
+ (insert-before-markers
(concat "|" title
(cond
(total (concat "|" total))
(work (concat "|" work)))
(and with-price price (concat "|" (format "%.2f" price)))
"|" "\n"))))
-
+
(defun org-invoice-list-to-table (ls)
"Convert a list of heading info to an org table"
(let ((with-price (plist-get org-invoice-table-params :price))
@@ -243,7 +243,7 @@ (defun org-invoice-list-to-table (ls)
(with-header (plist-get org-invoice-table-params :headers))
(org-invoice-total-time 0)
(org-invoice-total-price 0))
- (insert-before-markers
+ (insert-before-markers
(concat "| Task / Date | Time" (and with-price "| Price") "|\n"))
(dolist (info ls)
(insert-before-markers "|-\n")
@@ -268,9 +268,9 @@ (defun org-invoice-collect-invoice-data ()
(org-clock-sum)
(run-hook-with-args 'org-invoice-start-hook)
(cons org-invoice-current-invoice
- (org-invoice-collapse-list
+ (org-invoice-collapse-list
(org-map-entries 'org-invoice-heading-info t 'tree 'archive))))))
-
+
(defun org-dblock-write:invoice (params)
"Function called by OrgMode to write the invoice dblock. To
create an invoice dblock you can use the `org-invoice-report'
@@ -397,5 +397,5 @@ (defun org-invoice-report (&optional jump)
(if report (goto-char report)
(org-create-dblock (list :name "invoice")))
(org-update-dblock)))
-
+
(provide 'org-invoice)
diff --git a/contrib/lisp/org-mac-iCal.el b/contrib/lisp/org-mac-iCal.el
index 5d29d4b..0fdc95f 100644
--- a/contrib/lisp/org-mac-iCal.el
+++ b/contrib/lisp/org-mac-iCal.el
@@ -101,7 +101,7 @@ (defun org-mac-iCal ()
(shell-command "sw_vers" (current-buffer))
(when (re-search-backward "10\\.[567]" nil t)
(omi-concat-leopard-ics all-calendars)))
-
+
;; move all caldav ics files to the same place as local ics files
(mapc
(lambda (x)
@@ -111,7 +111,7 @@ (defun org-mac-iCal ()
(concat "~/Library/Calendars/" y)))
(directory-files x nil ".*ics$")))
caldav-folders)
-
+
;; check calendar has contents and import
(setq import-calendars (directory-files "~/Library/Calendars" 1 ".*ics$"))
(mapc
@@ -181,7 +181,7 @@ (defun omi-import-ics (string)
(* (/ org-mac-iCal-range 2) 30))
(delete-region startEntry endEntry)))
(goto-char (point-max))))
- (while
+ (while
(re-search-forward "^END:VEVENT$" nil t)
(delete-blank-lines))
(goto-line 1)
diff --git a/contrib/lisp/org-mac-link-grabber.el b/contrib/lisp/org-mac-link-grabber.el
index 1644fc4..b422bfb 100644
--- a/contrib/lisp/org-mac-link-grabber.el
+++ b/contrib/lisp/org-mac-link-grabber.el
@@ -2,7 +2,7 @@
;;; application and insert them as links into org-mode documents
;;
;; Copyright (c) 2010-2012 Free Software Foundation, Inc.
-;;
+;;
;; Author: Anthony Lander <anthony.lander@gmail.com>
;; Version: 1.0.1
;; Keywords: org, mac, hyperlink
@@ -52,7 +52,7 @@
;; add (require 'org-mac-link-grabber) to your .emacs, and optionally
;; bind a key to activate the link grabber menu, like this:
;;
-;; (add-hook 'org-mode-hook (lambda ()
+;; (add-hook 'org-mode-hook (lambda ()
;; (define-key org-mode-map (kbd "C-c g") 'omlg-grab-link)))
;;
;;
@@ -161,7 +161,7 @@ (defun omlg-grab-link ()
(when (and active (eq input key))
(call-interactively grab-function))))
descriptors)))
-
+
(defalias 'omgl-grab-link 'omlg-grab-link
"Renamed, and this alias will be obsolete next revision.")
@@ -344,7 +344,7 @@ (defun as-mac-safari-get-frontmost-url ()
" return theUrl & \"::split::\" & theName & \"\n\"\n"
"end tell\n"))))
(car (split-string result "[\r\n]+" t))))
-
+
(defun org-mac-safari-get-frontmost-url ()
(interactive)
(message "Applescript: Getting Safari url...")
@@ -361,7 +361,7 @@ (defun org-mac-safari-get-frontmost-url ()
(defun org-mac-safari-insert-frontmost-url ()
(interactive)
(insert (org-mac-safari-get-frontmost-url)))
-
+
\f
;;
;;
diff --git a/contrib/lisp/org-mairix.el b/contrib/lisp/org-mairix.el
index 11e4e70..367a866 100644
--- a/contrib/lisp/org-mairix.el
+++ b/contrib/lisp/org-mairix.el
@@ -207,7 +207,7 @@ (defgroup org-mairix-mutt nil
:group 'org-mairix)
(defcustom org-mairix-mutt-display-command
- "xterm -title 'mairix search: %search%' -e 'unset COLUMNS; mutt -f
+ "xterm -title 'mairix search: %search%' -e 'unset COLUMNS; mutt -f
~/mail/mairix -e \"push <display-message>\"' &"
"Command to execute to display mairix search results via mutt within
an xterm.
@@ -244,7 +244,7 @@ (defcustom org-mairix-gnus-results-group "nnmaildir:mairix"
:group 'org-mairix-gnus
:type 'string)
-(defcustom org-mairix-gnus-select-display-group-function
+(defcustom org-mairix-gnus-select-display-group-function
'org-mairix-gnus-select-display-group-function-gg
"Hook to call to select the group that contains the matching articles.
We should not need this, it is owed to a problem of gnus that people were
@@ -285,7 +285,7 @@ (defun org-mairix-gnus-display-results (search args)
If you can improve this, please do!"
(if (not (equal (substring search 0 2) "m:" ))
- (error "org-mairix-gnus-display-results: display of search other than
+ (error "org-mairix-gnus-display-results: display of search other than
message-id not implemented yet"))
(setq message-id (substring search 2 nil))
(require 'gnus)
diff --git a/contrib/lisp/org-mime.el b/contrib/lisp/org-mime.el
index 72bdd68..b9d9f37 100644
--- a/contrib/lisp/org-mime.el
+++ b/contrib/lisp/org-mime.el
@@ -43,13 +43,13 @@
;;
;; you might want to bind this to a key with something like the
;; following message-mode binding
-;;
+;;
;; (add-hook 'message-mode-hook
;; (lambda ()
;; (local-set-key "\C-c\M-o" 'org-mime-htmlize)))
;;
;; and the following org-mode binding
-;;
+;;
;; (add-hook 'org-mode-hook
;; (lambda ()
;; (local-set-key "\C-c\M-o" 'org-mime-org-buffer-htmlize)))
diff --git a/contrib/lisp/org-mtags.el b/contrib/lisp/org-mtags.el
index 4178cde..cbae721 100644
--- a/contrib/lisp/org-mtags.el
+++ b/contrib/lisp/org-mtags.el
@@ -254,4 +254,3 @@ (defun org-mtags-fontify-tags (limit)
(provide 'org-mtags)
;;; org-mtags.el ends here
-
diff --git a/contrib/lisp/org-notmuch.el b/contrib/lisp/org-notmuch.el
index 11e06b8..25f6ab6 100644
--- a/contrib/lisp/org-notmuch.el
+++ b/contrib/lisp/org-notmuch.el
@@ -32,7 +32,7 @@
;; Links have one the following form
;; notmuch:<search terms>
-;; notmuch-search:<search terms>.
+;; notmuch-search:<search terms>.
;; The first form open the queries in notmuch-show mode, whereas the
;; second link open it in notmuch-search mode. Note that queries are
@@ -61,13 +61,13 @@ (defun org-notmuch-store-link ()
(setq link (org-make-link "notmuch:" "id:" message-id))
(org-add-link-props :link link :description desc)
link)))
-
+
(defun org-notmuch-open (path)
"Follow a notmuch message link specified by PATH."
(org-notmuch-follow-link path))
(defun org-notmuch-follow-link (search)
- "Follow a notmuch link to SEARCH.
+ "Follow a notmuch link to SEARCH.
Can link to more than one message, if so all matching messages are shown."
(require 'notmuch)
@@ -82,10 +82,10 @@ (defun org-notmuch-follow-link (search)
(defun org-notmuch-search-store-link ()
"Store a link to a notmuch search or message."
(when (eq major-mode 'notmuch-search-mode)
- (let ((link (org-make-link "notmuch-search:"
+ (let ((link (org-make-link "notmuch-search:"
(org-link-escape notmuch-search-query-string)))
(desc (concat "Notmuch search: " notmuch-search-query-string)))
- (org-store-link-props :type "notmuch-search"
+ (org-store-link-props :type "notmuch-search"
:link link
:description desc)
link)))
diff --git a/contrib/lisp/org-panel.el b/contrib/lisp/org-panel.el
index a6117ce..3ffdfaf 100644
--- a/contrib/lisp/org-panel.el
+++ b/contrib/lisp/org-panel.el
@@ -639,5 +639,3 @@ (defun orgpan-minor-post-command ()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; org-panel.el ends here
-
-
diff --git a/contrib/lisp/org-registry.el b/contrib/lisp/org-registry.el
index 3b43ce2..c1a1c6c 100644
--- a/contrib/lisp/org-registry.el
+++ b/contrib/lisp/org-registry.el
@@ -145,15 +145,15 @@ (defun org-registry-display-files (files link)
(defun org-registry-assoc-all (link &optional registry)
"Return all associated entries of LINK in the registry."
- (org-registry-find-all
+ (org-registry-find-all
(lambda (entry) (string= link (car entry)))
registry))
(defun org-registry-find-all (test &optional registry)
"Return all entries satisfying `test' in the registry."
- (delq nil
- (mapcar
- (lambda (x) (and (funcall test x) x))
+ (delq nil
+ (mapcar
+ (lambda (x) (and (funcall test x) x))
(or registry org-registry-alist))))
;;;###autoload
diff --git a/contrib/lisp/org-screen.el b/contrib/lisp/org-screen.el
index ba74267..a517b4b 100644
--- a/contrib/lisp/org-screen.el
+++ b/contrib/lisp/org-screen.el
@@ -40,7 +40,7 @@
;; associated with that task, go to the end of your item and type:
;;
;; M-x org-screen
-;;
+;;
;; This will prompt you for a name of a screen session. Type in a
;; name and it will insert a link into your org file at your current
;; location.
@@ -79,10 +79,10 @@ (defun org-screen-helper (name arg)
;; Pick the name of the new buffer.
(let ((term-ansi-buffer-name
- (generate-new-buffer-name
+ (generate-new-buffer-name
(org-screen-buffer-name name))))
(setq term-ansi-buffer-name
- (term-ansi-make-term
+ (term-ansi-make-term
term-ansi-buffer-name org-screen-program-name nil arg name))
(set-buffer term-ansi-buffer-name)
(term-mode)
@@ -104,5 +104,5 @@ (defun org-screen-goto (name)
'("screen" . "elisp:(org-screen-goto \"%s\")"))
(setq org-link-abbrev-alist
'(("screen" . "elisp:(org-screen-goto \"%s\")"))))
-
+
(provide 'org-screen)
diff --git a/contrib/lisp/org-static-mathjax.el b/contrib/lisp/org-static-mathjax.el
index 6a9f0ec..29f2cfe 100644
--- a/contrib/lisp/org-static-mathjax.el
+++ b/contrib/lisp/org-static-mathjax.el
@@ -86,7 +86,7 @@ (defun org-static-mathjax-hook-installer ()
(set 'org-static-mathjax-mathjax-path
(car (read-from-string
(substring mathjax-options (match-end 0))))))))
- (add-hook 'after-save-hook
+ (add-hook 'after-save-hook
'org-static-mathjax-process
nil t)))))
@@ -117,20 +117,20 @@ (defun org-static-mathjax-process ()
(set symbol (eval (car (read-from-string
(substring options (match-end 0))))))))
'(embed-fonts output-file-name))
-
+
; debug
(when org-static-mathjax-debug
(message "output file name, embed-fonts")
(print output-file-name)
(print embed-fonts))
-
+
; open (temporary) input file, copy contents there, replace MathJax path with local installation
(with-temp-buffer
(insert html-code)
(goto-char 1)
(replace-regexp mathjax-oldpath mathjax-newpath)
(write-file input-file-name))
-
+
; prepare argument list for call-process
(let ((call-process-args (list org-static-mathjax-xulrunner-path
nil nil nil
@@ -146,10 +146,10 @@ (defun org-static-mathjax-process ()
(if (not embed-fonts)
(progn
(add-to-list 'call-process-args "--final-mathjax-url" t)
- (add-to-list 'call-process-args
+ (add-to-list 'call-process-args
(file-name-directory org-static-mathjax-mathjax-path)
t)))
-
+
; debug
(when org-static-mathjax-debug
(print call-process-args))
diff --git a/contrib/lisp/org-sudoku.el b/contrib/lisp/org-sudoku.el
index 768729c..bf9a699 100644
--- a/contrib/lisp/org-sudoku.el
+++ b/contrib/lisp/org-sudoku.el
@@ -1,5 +1,5 @@
;;; org-sudoku.el --- Greate and solve SUDOKU games in Org tables
-;; Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp, games
@@ -126,7 +126,7 @@ (defun org-sudoku-solve-field ()
(setq game (org-sudoku-solve-game game))
(if game
(progn
- (org-table-put i j (number-to-string
+ (org-table-put i j (number-to-string
(nth 1 (assoc (cons i j) game)))
'align)
(org-table-goto-line i)
@@ -139,7 +139,7 @@ (defun org-sudoku-get-game ()
"Interpret table at point as sudoku game and read it.
A game structure is returned."
(let (b e g i j game)
-
+
(org-table-goto-line 1)
(org-table-goto-column 1)
(setq b (point))
diff --git a/contrib/lisp/org-toc.el b/contrib/lisp/org-toc.el
index 1c9752b..3f37cb8 100644
--- a/contrib/lisp/org-toc.el
+++ b/contrib/lisp/org-toc.el
@@ -278,7 +278,7 @@ (defun org-toc-show (&optional depth position)
;;; Navigation functions:
(defun org-toc-goto (&optional jump cycle)
"From Org TOC buffer, follow the targeted subtree in the Org window.
-If JUMP is non-nil, go to the base buffer.
+If JUMP is non-nil, go to the base buffer.
If JUMP is 'delete, go to the base buffer and delete other windows.
If CYCLE is non-nil, cycle the targeted subtree in the Org window."
(interactive)
@@ -459,15 +459,15 @@ (defun org-toc-get-headlines-status ()
(defun org-toc-help ()
"Display a quick help message in the echo-area for `org-toc-mode'."
(interactive)
- (let ((st-start 0)
+ (let ((st-start 0)
(help-message
"\[space\] show heading \[1-4\] hide headlines below this level
\[TAB\] jump to heading \[f\] toggle follow mode (currently %s)
\[return\] jump and delete others windows \[i\] toggle info mode (currently %s)
\[S-TAB\] cycle subtree (in Org) \[S\] toggle show subtree mode (currently %s)
-\[C-S-TAB\] global cycle (in Org) \[r\] toggle recenter mode (currently %s)
+\[C-S-TAB\] global cycle (in Org) \[r\] toggle recenter mode (currently %s)
\[:\] cycle subtree (in TOC) \[c\] toggle column view (currently %s)
-\[n/p\] next/previous heading \[s\] save TOC configuration
+\[n/p\] next/previous heading \[s\] save TOC configuration
\[q\] quit the TOC \[g\] restore last TOC configuration"))
(while (string-match "\\[[^]]+\\]" help-message st-start)
(add-text-properties (match-beginning 0)
diff --git a/contrib/lisp/org-wikinodes.el b/contrib/lisp/org-wikinodes.el
index a5a5b19..87cc174 100644
--- a/contrib/lisp/org-wikinodes.el
+++ b/contrib/lisp/org-wikinodes.el
@@ -174,7 +174,7 @@ (defun org-wikinodes-follow-link (target)
(message "New Wiki target `%s' created in current buffer"
target))))))
-;;; The target cache
+;;; The target cache
(defvar org-wikinodes-directory-targets-cache nil)
@@ -206,7 +206,7 @@ (defun org-wikinodes-get-targets ()
(while (re-search-forward re nil t)
(push (org-match-string-no-properties 4) targets))))
(nreverse targets)))
-
+
(defun org-wikinodes-get-links-for-directory (dir)
"Return an alist that connects wiki links to files in directory DIR."
(let ((files (directory-files dir nil "\\`[^.#].*\\.org\\'"))
@@ -328,7 +328,7 @@ (defun org-wikinodes-add-to-font-lock-keywords ()
(setcdr m (cons '(org-wikinodes-activate-links) (cdr m)))
(message
"Failed to add wikinodes to `org-font-lock-extra-keywords'."))))
-
+
(add-hook 'org-font-lock-set-keywords-hook
'org-wikinodes-add-to-font-lock-keywords)
diff --git a/contrib/lisp/org2rem.el b/contrib/lisp/org2rem.el
index 7fa9dd9..d54eff3 100644
--- a/contrib/lisp/org2rem.el
+++ b/contrib/lisp/org2rem.el
@@ -402,7 +402,7 @@ (defun org-print-remind-entries (&optional combine)
(insert sexp "\n"))))
;; (princ (org-diary-to-rem-string sexp-buffer))
(kill-buffer sexp-buffer))
-
+
(when org-remind-include-todo
(setq prefix "TODO-")
(goto-char (point-min))
@@ -450,7 +450,7 @@ (defun org-print-remind-entries (&optional combine)
(if dos diff-days 0)
(if dos 0 diff-days))
1000)))
-
+
(if (and (numberp org-rem-aw) (> org-rem-aw 0))
(setq remind-aw (+ (or remind-aw 0) org-rem-aw)))
@@ -470,7 +470,7 @@ (defun org-print-remind-entries (&optional combine)
(and due (setq due (org-rem-ts-to-remind-date-type due)))
(and start (setq start (org-rem-ts-to-remind-date-type start)))
(and remind-ew (setq remind-ew (org-rem-ts-to-remind-date-type remind-ew)))
-
+
(if (string-match org-bracket-link-regexp hd)
(setq hd (replace-match (if (match-end 3) (match-string 3 hd)
(match-string 1 hd))
diff --git a/contrib/lisp/test-org-export-preproc.el b/contrib/lisp/test-org-export-preproc.el
index b03da70..66c342f 100644
--- a/contrib/lisp/test-org-export-preproc.el
+++ b/contrib/lisp/test-org-export-preproc.el
@@ -36,4 +36,3 @@ (defun test-preproc ()
(org-pop-to-buffer-same-window "*preproc-temp*")
(point-max)
(insert string))))
-
diff --git a/contrib/scripts/StartOzServer.oz b/contrib/scripts/StartOzServer.oz
index 56940a3..9d41e83 100644
--- a/contrib/scripts/StartOzServer.oz
+++ b/contrib/scripts/StartOzServer.oz
@@ -1,5 +1,5 @@
%%% *************************************************************
-%%% Copyright (C) 2009 Torsten Anders (www.torsten-anders.de)
+%%% Copyright (C) 2009-2012 Torsten Anders (www.torsten-anders.de)
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License
%%% as published by the Free Software Foundation; either version 2
diff --git a/contrib/scripts/org2hpda b/contrib/scripts/org2hpda
index 6b308f3..b59b6a3 100755
--- a/contrib/scripts/org2hpda
+++ b/contrib/scripts/org2hpda
@@ -1,5 +1,5 @@
# org2hpda - a small utility to generate hipster pda style printouts from org mode
-# Copyright (C) 2007 Christian Egli
+# Copyright (C) 2007-2012 Christian Egli
#
# Version: 0.6
#
diff --git a/doc/org.texi b/doc/org.texi
index 3a1a77d..d8ebef5 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -5,7 +5,7 @@
@settitle The Org Manual
@set VERSION 7.8.05
-@set DATE mars 2012
+@set DATE March 2012
@c Use proper quote and backtick for code sections in PDF output
@c Cf. Texinfo manual 14.2
@@ -265,7 +265,7 @@
@copying
This manual is for Org version @value{VERSION}.
-Copyright @copyright{} 2004-2011 Free Software Foundation, Inc.
+Copyright @copyright{} 2004-2012 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -717,6 +717,7 @@
* rownames:: Handle row names in tables
* shebang:: Make tangled files executable
* eval:: Limit evaluation of specific code blocks
+* wrap:: Mark source block evaluation results
Miscellaneous
@@ -1080,7 +1081,7 @@ @section Feedback
@node Conventions, , Feedback, Introduction
@section Typesetting conventions used in this manual
-Org uses three types of keywords: TODO keywords, tags, and property
+Org uses three types of keywords: TODO keywords, tags and property
names. In this manual we use the following conventions:
@table @code
@@ -1098,7 +1099,14 @@ @section Typesetting conventions used in this manual
special meaning are written with all capitals.
@end table
-The manual lists both the keys and the corresponding commands for accessing
+Moreover, Org uses @i{option keywords} (like @code{#+TITLE} to set the title)
+and @i{environment keywords} (like @code{#+BEGIN_HTML} to start a @code{HTML}
+environment). They are written in uppercase in the manual to enhance its
+readability, but you can use lowercase in your Org files@footnote{Easy
+templates insert lowercase keywords and Babel dynamically inserts
+@code{#+results}.}
+
+The manual lists both the keys and the corresponding commands for accessing a
functionality. Org mode often uses the same key for different functions,
depending on context. The command that is bound to such keys has a generic
name, like @code{org-metaright}. In the manual we will, wherever possible,
@@ -1158,7 +1166,8 @@ @section Headlines
start with one or more stars, on the left margin@footnote{See the variables
@code{org-special-ctrl-a/e}, @code{org-special-ctrl-k}, and
@code{org-ctrl-k-protect-subtree} to configure special behavior of @kbd{C-a},
-@kbd{C-e}, and @kbd{C-k} in headlines.}. For example:
+@kbd{C-e}, and @kbd{C-k} in headlines.} @footnote{Clocking only works with
+headings indented less then 30 stars.}. For example:
@example
* Top level headline
@@ -1428,7 +1437,7 @@ @section Structure editing
@code{org-clone-subtree-with-time-shift}.
@orgcmd{C-c C-w,org-refile}
Refile entry or region to a different location. @xref{Refiling notes}.
-@orgcmd{C-c ^,org-sort-entries-or-items}
+@orgcmd{C-c ^,org-sort}
Sort same-level entries. When there is an active region, all entries in the
region will be sorted. Otherwise the children of the current headline are
sorted. The command prompts for the sorting method, which can be
@@ -1755,11 +1764,13 @@ @section Drawers
@cindex visibility cycling, drawers
@vindex org-drawers
+@cindex org-insert-drawer
+@kindex C-c C-x d
Sometimes you want to keep information associated with an entry, but you
normally don't want to see it. For this, Org mode has @emph{drawers}.
Drawers need to be configured with the variable
-@code{org-drawers}@footnote{You can define drawers on a per-file basis
-with a line like @code{#+DRAWERS: HIDDEN PROPERTIES STATE}}. Drawers
+@code{org-drawers}@footnote{You can define additional drawers on a
+per-file basis with a line like @code{#+DRAWERS: HIDDEN STATE}}. Drawers
look like this:
@example
@@ -1771,6 +1782,13 @@ @section Drawers
After the drawer.
@end example
+You can interactively insert drawers at point by calling
+@code{org-insert-drawer}, which is bound to @key{C-c C-x d}. With an active
+region, this command will put the region inside the drawer. With a prefix
+argument, this command calls @code{org-insert-property-drawer} and add a
+property drawer right below the current headline. Completion over drawer
+keywords is also possible using @key{M-TAB}.
+
Visibility cycling (@pxref{Visibility cycling}) on the headline will hide and
show the entry, but keep the drawer collapsed to a single line. In order to
look inside the drawer, you need to move the cursor to the drawer line and
@@ -3225,6 +3243,8 @@ @section External links
vm:folder @r{VM folder link}
vm:folder#id @r{VM message link}
vm://myself@@some.where.org/folder#id @r{VM on remote machine}
+vm-imap:account:folder @r{VM IMAP folder link}
+vm-imap:account:folder#id @r{VM IMAP message link}
wl:folder @r{WANDERLUST folder link}
wl:folder#id @r{WANDERLUST message link}
mhe:folder @r{MH-E folder link}
@@ -4063,9 +4083,11 @@ @subsection Tracking TODO state changes
headline as an itemized list, newest first@footnote{See the variable
@code{org-log-states-order-reversed}}. When taking a lot of notes, you might
want to get the notes out of the way into a drawer (@pxref{Drawers}).
-Customize the variable @code{org-log-into-drawer} to get this
-behavior---the recommended drawer for this is called @code{LOGBOOK}. You can
-also overrule the setting of this variable for a subtree by setting a
+Customize the variable @code{org-log-into-drawer} to get this behavior---the
+recommended drawer for this is called @code{LOGBOOK}@footnote{Note that the
+@code{LOGBOOK} drawer is unfolded when pressing @key{SPC} in the agenda to
+show an entry---use @key{C-u SPC} to keep it folded here}. You can also
+overrule the setting of this variable for a subtree by setting a
@code{LOG_INTO_DRAWER} property.
Since it is normally too much to record a note for every state, Org mode
@@ -4870,8 +4892,8 @@ @section Property syntax
@orgcmd{C-c C-x p,org-set-property}
Set a property. This prompts for a property name and a value. If
necessary, the property drawer is created as well.
-@item M-x org-insert-property-drawer
-@findex org-insert-property-drawer
+@item C-u M-x org-insert-drawer
+@cindex org-insert-drawer
Insert a property drawer into the current entry. The drawer will be
inserted early in the entry, but after the lines with planning
information like deadlines.
@@ -5896,12 +5918,14 @@ @section Clocking work time
@cindex time clocking
Org mode allows you to clock the time you spend on specific tasks in a
-project. When you start working on an item, you can start the clock.
-When you stop working on that task, or when you mark the task done, the
-clock is stopped and the corresponding time interval is recorded. It
-also computes the total time spent on each subtree of a project. And it
-remembers a history or tasks recently clocked, to that you can jump quickly
-between a number of tasks absorbing your time.
+project. When you start working on an item, you can start the clock. When
+you stop working on that task, or when you mark the task done, the clock is
+stopped and the corresponding time interval is recorded. It also computes
+the total time spent on each subtree@footnote{Clocking only works if all
+headings are indented with less than 30 stars. This is a hardcoded
+limitation of `lmax' in `org-clock-sum'.} of a project. And it remembers a
+history or tasks recently clocked, to that you can jump quickly between a
+number of tasks absorbing your time.
To save the clock history across Emacs sessions, use
@lisp
@@ -6680,21 +6704,21 @@ @subsubsection Template expansion
@vindex org-from-is-user-regexp
@smallexample
-Link type | Available keywords
-------------------------+----------------------------------------------
-bbdb | %:name %:company
-irc | %:server %:port %:nick
-vm, wl, mh, mew, rmail | %:type %:subject %:message-id
- | %:from %:fromname %:fromaddress
- | %:to %:toname %:toaddress
- | %:date @r{(message date header field)}
- | %:date-timestamp @r{(date as active timestamp)}
- | %:date-timestamp-inactive @r{(date as inactive timestamp)}
- | %:fromto @r{(either "to NAME" or "from NAME")@footnote{This will always be the other, not the user. See the variable @code{org-from-is-user-regexp}.}}
-gnus | %:group, @r{for messages also all email fields}
-w3, w3m | %:url
-info | %:file %:node
-calendar | %:date
+Link type | Available keywords
+---------------------------------+----------------------------------------------
+bbdb | %:name %:company
+irc | %:server %:port %:nick
+vm, vm-imap, wl, mh, mew, rmail | %:type %:subject %:message-id
+ | %:from %:fromname %:fromaddress
+ | %:to %:toname %:toaddress
+ | %:date @r{(message date header field)}
+ | %:date-timestamp @r{(date as active timestamp)}
+ | %:date-timestamp-inactive @r{(date as inactive timestamp)}
+ | %:fromto @r{(either "to NAME" or "from NAME")@footnote{This will always be the other, not the user. See the variable @code{org-from-is-user-regexp}.}}
+gnus | %:group, @r{for messages also all email fields}
+w3, w3m | %:url
+info | %:file %:node
+calendar | %:date
@end smallexample
@noindent
@@ -9020,7 +9044,7 @@ @section Images and Tables
@example
#+CAPTION: This is the caption for the next table (or link)
-#+LABEL: tbl:basic-data
+#+LABEL: tab:basic-data
| ... | ...|
|-----|----|
@end example
@@ -9634,7 +9658,7 @@ @section Export options
@cindex #+EXPORT_SELECT_TAGS
@cindex #+EXPORT_EXCLUDE_TAGS
@cindex #+XSLT
-@cindex #+LATEX_HEADER
+@cindex #+LaTeX_HEADER
@vindex user-full-name
@vindex user-mail-address
@vindex org-export-default-language
@@ -9654,7 +9678,7 @@ @section Export options
@r{You need to confirm using these, or configure @code{org-export-allow-BIND}}
#+LINK_UP: the ``up'' link of an exported page
#+LINK_HOME: the ``home'' link of an exported page
-#+LATEX_HEADER: extra line(s) for the @LaTeX{} header, like \usepackage@{xyz@}
+#+LaTeX_HEADER: extra line(s) for the @LaTeX{} header, like \usepackage@{xyz@}
#+EXPORT_SELECT_TAGS: Tags that select a tree for export
#+EXPORT_EXCLUDE_TAGS: Tags that exclude a tree from export
#+XSLT: the XSLT stylesheet used by DocBook exporter to generate FO file
@@ -10326,11 +10350,11 @@ @subsection Header and sectioning structure
@vindex org-export-latex-classes
@vindex org-export-latex-default-packages-alist
@vindex org-export-latex-packages-alist
-@cindex #+LATEX_HEADER
-@cindex #+LATEX_CLASS
-@cindex #+LATEX_CLASS_OPTIONS
-@cindex property, LATEX_CLASS
-@cindex property, LATEX_CLASS_OPTIONS
+@cindex #+LaTeX_HEADER
+@cindex #+LaTeX_CLASS
+@cindex #+LaTeX_CLASS_OPTIONS
+@cindex property, LaTeX_CLASS
+@cindex property, LaTeX_CLASS_OPTIONS
You can change this globally by setting a different value for
@code{org-export-latex-default-class} or locally by adding an option like
@code{#+LaTeX_CLASS: myclass} in your file, or with a @code{:LaTeX_CLASS:}
@@ -10340,11 +10364,22 @@ @subsection Header and sectioning structure
@code{org-export-latex-default-packages-alist} and
@code{org-export-latex-packages-alist} are spliced.}, and allows you to
define the sectioning structure for each class. You can also define your own
-classes there. @code{#+LaTeX_CLASS_OPTIONS} or a @code{LaTeX_CLASS_OPTIONS}
-property can specify the options for the @code{\documentclass} macro. You
-can also use @code{#+LATEX_HEADER: \usepackage@{xyz@}} to add lines to the
-header. See the docstring of @code{org-export-latex-classes} for more
-information.
+classes there. @code{#+LaTeX_CLASS_OPTIONS} or a @code{:LaTeX_CLASS_OPTIONS:}
+property can specify the options for the @code{\documentclass} macro. The
+options to documentclass have to be provided, as expected by @LaTeX{}, within
+square brackets. You can also use @code{#+LaTeX_HEADER: \usepackage@{xyz@}}
+to add lines to the header. See the docstring of
+@code{org-export-latex-classes} for more information. An example is shown
+below.
+
+@example
+#+LaTeX_CLASS: article
+#+LaTeX_CLASS_OPTIONS: [a4paper]
+#+LaTeX_HEADER: \usepackage@{xyz@}
+
+* Headline 1
+ some text
+@end example
@node Quoting @LaTeX{} code, Tables in @LaTeX{} export, Header and sectioning, @LaTeX{} and PDF export
@subsection Quoting @LaTeX{} code
@@ -10428,9 +10463,7 @@ @subsection Images in @LaTeX{} export
this option can be used with tables as well@footnote{One can also take
advantage of this option to pass other, unrelated options into the figure or
table environment. For an example see the section ``Exporting org files'' in
-@url{http://orgmode.org/worg/org-hacks.html}}. For example the
-@code{#+ATTR_LaTeX:} line below is exported as the @code{figure} environment
-below it.
+@url{http://orgmode.org/worg/org-hacks.html}}.
If you would like to let text flow around the image, add the word @samp{wrap}
to the @code{#+ATTR_LaTeX:} line, which will make the figure occupy the left
@@ -10517,7 +10550,7 @@ @subsection Beamer class export
Frames will automatically receive a @code{fragile} option if they contain
source code that uses the verbatim environment. Special @file{beamer}
specific code can be inserted using @code{#+BEAMER:} and
-@code{#+BEGIN_beamer...#+end_beamer} constructs, similar to other export
+@code{#+BEGIN_BEAMER...#+END_BEAMER} constructs, similar to other export
backends, but with the difference that @code{#+LaTeX:} stuff will be included
in the presentation as well.
@@ -12280,7 +12313,7 @@ @subsection Generating an index
@end multitable
The file will be created when first publishing a project with the
-@code{:makeindex} set. The file only contains a statement @code{#+include:
+@code{:makeindex} set. The file only contains a statement @code{#+INCLUDE:
"theindex.inc"}. You can then build around this include statement by adding
a title, style information, etc.
@@ -12668,10 +12701,10 @@ @section Evaluating code blocks
begins by default with @code{#+RESULTS} and optionally a cache identifier
and/or the name of the evaluated code block. The default value of
@code{#+RESULTS} can be changed with the customizable variable
-@code{org-babel-results-keyword}.
+@code{org-babel-results-keyword}.
By default, the evaluation facility is only enabled for Lisp code blocks
-specified as @code{emacs-lisp}. However, source code blocks in many languages
+specified as @code{emacs-lisp}. However, source code blocks in many languages
can be evaluated within Org mode (see @ref{Languages} for a list of supported
languages and @ref{Structure of code blocks} for information on the syntax
used to define a code block).
@@ -12685,8 +12718,8 @@ @section Evaluating code blocks
its results into the Org mode buffer.
@cindex #+CALL
-It is also possible to evaluate named code blocks from anywhere in an
-Org mode buffer or an Org mode table. Live code blocks located in the current
+It is also possible to evaluate named code blocks from anywhere in an Org
+mode buffer or an Org mode table. Live code blocks located in the current
Org mode buffer or in the ``Library of Babel'' (see @ref{Library of Babel})
can be executed. Named code blocks can be executed with a separate
@code{#+CALL:} line or inline within a block of text.
@@ -12980,7 +13013,7 @@ @subsection Using header arguments
(message "data1:%S, data2:%S" data1 data2)
#+END_SRC
- #+results:
+ #+RESULTS:
: data1:1, data2:2
@end example
@@ -12992,7 +13025,7 @@ @subsection Using header arguments
(message "data:%S" data)
#+END_SRC
- #+results: named-block
+ #+RESULTS: named-block
: data:2
@end example
@@ -13050,6 +13083,7 @@ @subsection Specific header arguments
* rownames:: Handle row names in tables
* shebang:: Make tangled files executable
* eval:: Limit evaluation of specific code blocks
+* wrap:: Mark source block evaluation results
@end menu
Additional header arguments are defined on a language-specific basis, see
@@ -13064,7 +13098,7 @@ @subsubsection @code{:var}
case, variables require a default value when they are declared.
The values passed to arguments can either be literal values, references, or
-Emacs Lisp code (see @ref{var, Emacs Lisp evaluation of variables}). References
+Emacs Lisp code (see @ref{var, Emacs Lisp evaluation of variables}). References
include anything in the Org mode file that takes a @code{#+NAME:},
@code{#+TBLNAME:}, or @code{#+RESULTS:} line. This includes tables, lists,
@code{#+BEGIN_EXAMPLE} blocks, other code blocks, and the results of other
@@ -13103,7 +13137,7 @@ @subsubsection @code{:var}
(length table)
#+END_SRC
-#+results: table-length
+#+RESULTS: table-length
: 4
@end example
@@ -13122,7 +13156,7 @@ @subsubsection @code{:var}
(print x)
#+END_SRC
-#+results:
+#+RESULTS:
| simple | list |
@end example
@@ -13135,7 +13169,7 @@ @subsubsection @code{:var}
(* 2 length)
#+END_SRC
-#+results:
+#+RESULTS:
: 8
@end example
@@ -13150,7 +13184,7 @@ @subsubsection @code{:var}
(* 2 input)
#+END_SRC
-#+results: double
+#+RESULTS: double
: 16
#+NAME: squared
@@ -13158,7 +13192,7 @@ @subsubsection @code{:var}
(* input input)
#+END_SRC
-#+results: squared
+#+RESULTS: squared
: 4
@end example
@@ -13177,7 +13211,7 @@ @subsubsection @code{:var}
(concatenate 'string x " for you.")
#+END_SRC
-#+results: read-literal-example
+#+RESULTS: read-literal-example
: A literal example
: on two lines for you.
@@ -13219,7 +13253,7 @@ @subsubsection @code{:var}
data
#+END_SRC
-#+results:
+#+RESULTS:
: a
@end example
@@ -13240,7 +13274,7 @@ @subsubsection @code{:var}
data
#+END_SRC
-#+results:
+#+RESULTS:
| 2 | b |
| 3 | c |
| 4 | d |
@@ -13262,7 +13296,7 @@ @subsubsection @code{:var}
data
#+END_SRC
-#+results:
+#+RESULTS:
| 1 | 2 | 3 | 4 |
@end example
@@ -13282,7 +13316,7 @@ @subsubsection @code{:var}
data
#+END_SRC
-#+results:
+#+RESULTS:
| 11 | 14 | 17 |
@end example
@@ -13315,7 +13349,7 @@ @subsubsection @code{:var}
$data
#+END_SRC
-#+results:
+#+RESULTS:
: (a b c)
@end example
@@ -13381,10 +13415,10 @@ @subsubsection @code{:results}
into the buffer. If the results look like a table they will be aligned as
such by Org mode. E.g., @code{:results value raw}.
@item @code{html}
-Results are assumed to be HTML and will be enclosed in a @code{begin_html}
+Results are assumed to be HTML and will be enclosed in a @code{BEGIN_HTML}
block. E.g., @code{:results value html}.
@item @code{latex}
-Results assumed to be @LaTeX{} and are enclosed in a @code{begin_latex} block.
+Results assumed to be @LaTeX{} and are enclosed in a @code{BEGIN_LaTeX} block.
E.g., @code{:results value latex}.
@item @code{code}
Result are assumed to be parsable code and are enclosed in a code block.
@@ -13617,21 +13651,34 @@ @subsubsection @code{:session}
@node noweb, noweb-ref, session, Specific header arguments
@subsubsection @code{:noweb}
-The @code{:noweb} header argument controls expansion of ``noweb'' style (see
-@ref{Noweb reference syntax}) references in a code block. This header
-argument can have one of three values: @code{yes}, @code{no}, or @code{tangle}.
+The @code{:noweb} header argument controls expansion of ``noweb'' syntax
+references (see @ref{Noweb reference syntax}) when the code block is
+evaluated, tangled, or exported. The @code{:noweb} header argument can have
+one of the five values: @code{no}, @code{yes}, @code{tangle}, or
+@code{no-export} @code{strip-export}.
@itemize @bullet
-@item @code{yes}
-All ``noweb'' syntax references in the body of the code block will be
-expanded before the block is evaluated, tangled or exported.
@item @code{no}
-The default. No ``noweb'' syntax specific action is taken when the code
-block is evaluated, tangled or exported.
+The default. ``Noweb'' syntax references in the body of the code block will
+not be expanded before the code block is evaluated, tangled or exported.
+@item @code{yes}
+``Noweb'' syntax references in the body of the code block will be
+expanded before the code block is evaluated, tangled or exported.
@item @code{tangle}
-All ``noweb'' syntax references in the body of the code block will be
-expanded before the block is tangled, however ``noweb'' references will not
-be expanded when the block is evaluated or exported.
+``Noweb'' syntax references in the body of the code block will be expanded
+before the code block is tangled. However, ``noweb'' syntax references will
+not be expanded when the code block is evaluated or exported.
+@item @code{no-export}
+``Noweb'' syntax references in the body of the code block will be expanded
+before the block is evaluated or tangled. However, ``noweb'' syntax
+references will not be expanded when the code block is exported.
+@item @code{strip-export}
+``Noweb'' syntax references in the body of the code block will be expanded
+before the block is evaluated or tangled. However, ``noweb'' syntax
+references will not be removed when the code block is exported.
+@item @code{eval}
+``Noweb'' syntax references in the body of the code block will only be
+expanded before the block is evaluated.
@end itemize
@subsubheading Noweb prefix lines
@@ -13732,7 +13779,7 @@ @subsubsection @code{:cache}
@item @code{yes}
Every time the code block is run a SHA1 hash of the code and arguments
passed to the block will be generated. This hash is packed into the
-@code{#+results:} line and will be checked on subsequent
+@code{#+RESULTS:} line and will be checked on subsequent
executions of the code block. If the code block has not
changed since the last time it was evaluated, it will not be re-evaluated.
@end itemize
@@ -13749,7 +13796,7 @@ @subsubsection @code{:cache}
runif(1)
#+END_SRC
- #+results[a2a72cd647ad44515fab62e144796432793d68e1]: random
+ #+RESULTS[a2a72cd647ad44515fab62e144796432793d68e1]: random
0.4659510825295
#+NAME: caller
@@ -13757,7 +13804,7 @@ @subsubsection @code{:cache}
x
#+END_SRC
- #+results[bec9c8724e397d5df3b696502df3ed7892fc4f5f]: caller
+ #+RESULTS[bec9c8724e397d5df3b696502df3ed7892fc4f5f]: caller
0.254227238707244
@end example
@@ -13801,7 +13848,7 @@ @subsubsection @code{:hlines}
return tab
#+END_SRC
-#+results: echo-table
+#+RESULTS: echo-table
| a | b | c |
| d | e | f |
| g | h | i |
@@ -13823,7 +13870,7 @@ @subsubsection @code{:hlines}
return tab
#+END_SRC
-#+results: echo-table
+#+RESULTS: echo-table
| a | b | c |
|---+---+---|
| d | e | f |
@@ -13861,7 +13908,7 @@ @subsubsection @code{:colnames}
return [[val + '*' for val in row] for row in tab]
#+END_SRC
-#+results: echo-table-again
+#+RESULTS: echo-table-again
| a |
|----|
| b* |
@@ -13904,7 +13951,7 @@ @subsubsection @code{:rownames}
return [[val + 10 for val in row] for row in tab]
#+END_SRC
-#+results: echo-table-once-again
+#+RESULTS: echo-table-once-again
| one | 11 | 12 | 13 | 14 | 15 |
| two | 16 | 17 | 18 | 19 | 20 |
@end example
@@ -13922,7 +13969,7 @@ @subsubsection @code{:shebang}
first line of any tangled file holding the code block, and the file
permissions of the tangled file are set to make it executable.
-@node eval, , shebang, Specific header arguments
+@node eval, wrap, shebang, Specific header arguments
@subsubsection @code{:eval}
The @code{:eval} header argument can be used to limit the evaluation of
specific code blocks. The @code{:eval} header argument can be useful for
@@ -13947,6 +13994,14 @@ @subsubsection @code{:eval}
of the @code{org-confirm-babel-evaluate} variable see @ref{Code evaluation
security}.
+@node wrap, , eval, Specific header arguments
+@subsubsection @code{:wrap}
+The @code{:wrap} header argument is used to mark the results of source block
+evaluation. The header argument can be passed a string that will be appended
+to @code{#+BEGIN_} and @code{#+END_}, which will then be used to wrap the
+results. If not string is specified then the results will be wrapped in a
+@code{#+BEGIN/END_RESULTS} block.
+
@node Results of evaluation, Noweb reference syntax, Header arguments, Working With Source Code
@section Results of evaluation
@cindex code block, results of evaluation
@@ -14016,7 +14071,7 @@ @subsubsection @code{:results output}
print "bye"
#+END_SRC
-#+results:
+#+RESULTS:
: hello
: bye
@end example
@@ -14029,7 +14084,7 @@ @subsubsection @code{:results output}
print "bye"
#+END_SRC
-#+results:
+#+RESULTS:
: hello
: 2
: bye
@@ -14320,19 +14375,19 @@ @section Easy Templates
The following template selectors are currently supported.
@multitable @columnfractions 0.1 0.9
-@item @kbd{s} @tab @code{#+begin_src ... #+end_src}
-@item @kbd{e} @tab @code{#+begin_example ... #+end_example}
-@item @kbd{q} @tab @code{#+begin_quote ... #+end_quote}
-@item @kbd{v} @tab @code{#+begin_verse ... #+end_verse}
-@item @kbd{c} @tab @code{#+begin_center ... #+end_center}
-@item @kbd{l} @tab @code{#+begin_latex ... #+end_latex}
-@item @kbd{L} @tab @code{#+latex:}
-@item @kbd{h} @tab @code{#+begin_html ... #+end_html}
-@item @kbd{H} @tab @code{#+html:}
-@item @kbd{a} @tab @code{#+begin_ascii ... #+end_ascii}
-@item @kbd{A} @tab @code{#+ascii:}
-@item @kbd{i} @tab @code{#+index:} line
-@item @kbd{I} @tab @code{#+include:} line
+@item @kbd{s} @tab @code{#+BEGIN_SRC ... #+END_SRC}
+@item @kbd{e} @tab @code{#+BEGIN_EXAMPLE ... #+END_EXAMPLE}
+@item @kbd{q} @tab @code{#+BEGIN_QUOTE ... #+END_QUOTE}
+@item @kbd{v} @tab @code{#+BEGIN_VERSE ... #+END_VERSE}
+@item @kbd{c} @tab @code{#+BEGIN_CENTER ... #+END_CENTER}
+@item @kbd{l} @tab @code{#+BEGIN_LaTeX ... #+END_LaTeX}
+@item @kbd{L} @tab @code{#+LaTeX:}
+@item @kbd{h} @tab @code{#+BEGIN_HTML ... #+END_HTML}
+@item @kbd{H} @tab @code{#+HTML:}
+@item @kbd{a} @tab @code{#+BEGIN_ASCII ... #+END_ASCII}
+@item @kbd{A} @tab @code{#+ASCII:}
+@item @kbd{i} @tab @code{#+INDEX:} line
+@item @kbd{I} @tab @code{#+INCLUDE:} line
@end multitable
For example, on an empty line, typing "<e" and then pressing TAB, will expand
@@ -14426,7 +14481,7 @@ @section Customization
@cindex options, for customization
@cindex variables, for customization
-There are more than 180 variables that can be used to customize
+There are more than 500 variables that can be used to customize
Org. For the sake of compactness of the manual, I am not
describing the variables here. A structured overview of customization
variables is available with @kbd{M-x org-customize}. Or select
@@ -14477,8 +14532,8 @@ @section Summary of in-buffer settings
top-level entries.
@item #+DRAWERS: NAME1 .....
@vindex org-drawers
-Set the file-local set of drawers. The corresponding global variable is
-@code{org-drawers}.
+Set the file-local set of additional drawers. The corresponding global
+variable is @code{org-drawers}.
@item #+LINK: linkword replace
@vindex org-link-abbrev-alist
These lines (several are allowed) specify link abbreviations.
@@ -14689,7 +14744,7 @@ @section Summary of in-buffer settings
@item #+TITLE:, #+AUTHOR:, #+EMAIL:, #+LANGUAGE:, #+TEXT:, #+DATE:,
@itemx #+OPTIONS:, #+BIND:, #+XSLT:,
@itemx #+DESCRIPTION:, #+KEYWORDS:,
-@itemx #+LATEX_HEADER:, #+STYLE:, #+LINK_UP:, #+LINK_HOME:,
+@itemx #+LaTeX_HEADER:, #+STYLE:, #+LINK_UP:, #+LINK_HOME:,
@itemx #+EXPORT_SELECT_TAGS:, #+EXPORT_EXCLUDE_TAGS:
These lines provide settings for exporting files. For more details see
@ref{Export options}.
@@ -15966,6 +16021,7 @@ @section Using the property API
`special' or `standard', only get that subclass.
@end defun
@vindex org-use-property-inheritance
+@findex org-insert-property-drawer
@defun org-entry-get pom property &optional inherit
Get value of PROPERTY for entry at point-or-marker POM. By default,
this only looks at properties defined locally in the entry. If INHERIT
@@ -15988,7 +16044,7 @@ @section Using the property API
@end defun
@defun org-insert-property-drawer
-Insert a property drawer at point.
+Insert a property drawer for the current entry. Also
@end defun
@defun org-entry-put-multivalued-property pom property &rest values
@@ -16141,13 +16197,16 @@ @section Using the mapping API
@cindex iPhone
@cindex MobileOrg
-@uref{http://mobileorg.ncogni.to/, MobileOrg} is an application for the
-@i{iPhone/iPod Touch} series of devices, developed by Richard Moreland.
-@i{MobileOrg} offers offline viewing and capture support for an Org mode
-system rooted on a ``real'' computer. It does also allow you to record
-changes to existing entries. Android users should check out
+@i{MobileOrg} is the name of the mobile companion app for Org mode, currently
+available for iOS and for Android. @i{MobileOrg} offers offline viewing and
+capture support for an Org mode system rooted on a ``real'' computer. It
+does also allow you to record changes to existing entries.
+The @uref{http://mobileorg.ncogni.to/, iOS implementation} for the
+@i{iPhone/iPod Touch/iPad} series of devices, was developed by Richard
+Moreland. Android users should check out
@uref{http://wiki.github.com/matburt/mobileorg-android/, MobileOrg Android}
-by Matt Jones.
+by Matt Jones. The two implementations are not identical but offer similar
+features.
This appendix describes the support Org has for creating agenda views in a
format that can be displayed by @i{MobileOrg}, and for integrating notes
@@ -16312,7 +16371,7 @@ @section Pulling from MobileOrg
integrated into the core by now), including the @LaTeX{} exporter and the plain
list parser. His support during the early days, when he basically acted as
co-maintainer, was central to the success of this project. Bastien also
-invented Worg, helped establishing the Web presence of Org, and sponsors
+invented Worg, helped establishing the Web presence of Org, and sponsored
hosting costs for the orgmode.org website.
@item Eric Schulte and Dan Davison
Eric and Dan are jointly responsible for the Org-babel system, which turns
diff --git a/doc/orgcard.tex b/doc/orgcard.tex
index 487a7f1..25f5434 100644
--- a/doc/orgcard.tex
+++ b/doc/orgcard.tex
@@ -17,7 +17,7 @@
\pdflayout=(0l)
% Nothing else needs to be changed below this line.
-% Copyright (C) 1987, 1993, 1996-1997, 2001-2011
+% Copyright (C) 1987, 1993, 1996-1997, 2001-2012
% Free Software Foundation, Inc.
% This file is part of GNU Emacs.
diff --git a/doc/orgguide.texi b/doc/orgguide.texi
index 00a1dae..d596d89 100644
--- a/doc/orgguide.texi
+++ b/doc/orgguide.texi
@@ -4,7 +4,7 @@
@settitle The compact Org-mode Guide
@set VERSION 7.8.05
-@set DATE mars 2012
+@set DATE March 2012
@c Use proper quote and backtick for code sections in PDF output
@c Cf. Texinfo manual 14.2
@@ -40,7 +40,7 @@
@end macro
@copying
-Copyright @copyright{} 2010 Free Software Foundation
+Copyright @copyright{} 2010-2012 Free Software Foundation
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -1906,7 +1906,7 @@ @section Commands in the agenda buffer
@c
@itemx @key{TAB}
Go to the original location of the item in another window. Under Emacs
-22, @kbd{mouse-1} will also works for this.
+22, @kbd{mouse-1} will also work for this.
@c
@itemx @key{RET}
Go to the original location of the item and delete other windows.
@@ -2409,8 +2409,8 @@ @section DocBook export
Export as DocBook file.
@end table
-Similarly to the HTML exporter, you can use @code{#+DocBook:} and
-@code{#+BEGIN_DocBook ... #+END_DocBook} construct to add verbatim @LaTeX{}
+Similarly to the HTML exporter, you can use @code{#+DOCBOOK:} and
+@code{#+BEGIN_DOCBOOK ... #+END_DOCBOOK} construct to add verbatim @LaTeX{}
code.
@node iCalendar export, , DocBook export, Exporting
@@ -2492,10 +2492,10 @@ @section iCalendar export
The structure of code blocks is as follows:
@example
-#+srcname: <name>
-#+begin_src <language> <switches> <header arguments>
+#+NAME: <name>
+#+BEGIN_SRC <language> <switches> <header arguments>
<body>
-#+end_src
+#+END_SRC
@end example
Where @code{<name>} is a string used to name the code block,
@@ -2520,11 +2520,11 @@ @section iCalendar export
manual. The following shows a code block and its results.
@example
-#+begin_src emacs-lisp
+#+BEGIN_SRC emacs-lisp
(+ 1 2 3 4)
-#+end_src
+#+END_SRC
-#+results:
+#+RESULTS:
: 10
@end example
@@ -2663,10 +2663,17 @@ @section A cleaner outline view
@node MobileOrg, , Clean view, Miscellaneous
@section MobileOrg
-@i{MobileOrg} is an application originally developed for the @i{iPhone/iPod
-Touch} series of devices, developed by Richard Moreland. There is also an
-independent implementation for Android devices, by Matt Jones.
-For details, see the Org-mode manual.
+@i{MobileOrg} is the name of the mobile companion app for Org mode, currently
+available for iOS and for Android. @i{MobileOrg} offers offline viewing and
+capture support for an Org mode system rooted on a ``real'' computer. It
+does also allow you to record changes to existing entries.
+
+The @uref{http://mobileorg.ncogni.to/, iOS implementation} for the
+@i{iPhone/iPod Touch/iPad} series of devices, was developed by Richard
+Moreland. Android users should check out
+@uref{http://wiki.github.com/matburt/mobileorg-android/, MobileOrg Android}
+by Matt Jones. The two implementations are not identical but offer similar
+features.
@seealso{
@uref{http://orgmode.org/manual/Miscellaneous.html#Miscellaneous, Chapter 15
diff --git a/doc/pdflayout.sty b/doc/pdflayout.sty
index e16babc..1b421a1 100644
--- a/doc/pdflayout.sty
+++ b/doc/pdflayout.sty
@@ -1,4 +1,4 @@
-% Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+% Copyright (C) 2007-2012 Free Software Foundation, Inc.
% This file is part of GNU Emacs.
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index 067dad1..9631275 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -3,11 +3,11 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2011-08-15.20}
+\def\texinfoversion{2012-01-03.18}
%
% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-% 2007, 2008 Free Software Foundation, Inc.
+% 2007, 2008-2012 Free Software Foundation, Inc.
%
% This texinfo.tex file is free software: you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
diff --git a/lisp/ob-awk.el b/lisp/ob-awk.el
index ded8ee4..682d802 100644
--- a/lisp/ob-awk.el
+++ b/lisp/ob-awk.el
@@ -24,9 +24,9 @@
;;; Commentary:
;; Babel's awk can use special header argument:
-;;
+;;
;; - :in-file takes a path to a file of data to be processed by awk
-;;
+;;
;; - :stdin takes an Org-mode data or code block reference, the value
;; of which will be passed to the awk process through STDIN
diff --git a/lisp/ob-ditaa.el b/lisp/ob-ditaa.el
index 57ae4b9..ae7794b 100644
--- a/lisp/ob-ditaa.el
+++ b/lisp/ob-ditaa.el
@@ -34,15 +34,28 @@
;; 3) we are adding the "file" and "cmdline" header arguments
;;
;; 4) there are no variables (at least for now)
+;;
+;; 5) it depends on a variable defined in org-exp-blocks (namely
+;; `org-ditaa-jar-path') so be sure you have org-exp-blocks loaded
;;; Code:
(require 'ob)
+(defvar org-ditaa-jar-path) ;; provided by org-exp-blocks
+
(defvar org-babel-default-header-args:ditaa
- '((:results . "file") (:exports . "results") (:java . "-Dfile.encoding=UTF-8"))
+ '((:results . "file")
+ (:exports . "results")
+ (:java . "-Dfile.encoding=UTF-8"))
"Default arguments for evaluating a ditaa source block.")
-(defvar org-ditaa-jar-path)
+(defcustom org-ditaa-jar-option "-jar"
+ "Option for the ditaa jar file.
+Do not leave leading or trailing spaces in this string."
+ :group 'org-babel
+ :version "24.1"
+ :type 'string)
+
(defun org-babel-execute:ditaa (body params)
"Execute a block of Ditaa code with org-babel.
This function is called by `org-babel-execute-src-block'."
@@ -55,7 +68,7 @@ (defun org-babel-execute:ditaa (body params)
(cmdline (cdr (assoc :cmdline params)))
(java (cdr (assoc :java params)))
(in-file (org-babel-temp-file "ditaa-"))
- (cmd (concat "java " java " -jar "
+ (cmd (concat "java " java " " org-ditaa-jar-option " "
(shell-quote-argument
(expand-file-name org-ditaa-jar-path))
" " cmdline
diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el
index 181f1be..2299dd4 100644
--- a/lisp/ob-exp.el
+++ b/lisp/ob-exp.el
@@ -43,31 +43,37 @@ (defcustom org-export-babel-evaluate t
When set to nil no code will be evaluated as part of the export
process."
:group 'org-babel
+ :version "24.1"
:type 'boolean)
(put 'org-export-babel-evaluate 'safe-local-variable (lambda (x) (eq x nil)))
+(defun org-babel-exp-get-export-buffer ()
+ "Return the current export buffer if possible."
+ (cond
+ ((bufferp org-current-export-file) org-current-export-file)
+ (org-current-export-file (get-file-buffer org-current-export-file))
+ ('otherwise
+ (error "Requested export buffer when `org-current-export-file' is nil"))))
+
(defmacro org-babel-exp-in-export-file (lang &rest body)
(declare (indent 1))
`(let* ((lang-headers (intern (concat "org-babel-default-header-args:" ,lang)))
(heading (nth 4 (ignore-errors (org-heading-components))))
- (link (when org-current-export-file
- (org-make-link-string
- (if heading
- (concat org-current-export-file "::" heading)
- org-current-export-file))))
- (export-buffer (current-buffer)) results)
- (when link
+ (export-buffer (current-buffer))
+ (original-buffer (org-babel-exp-get-export-buffer)) results)
+ (when original-buffer
;; resolve parameters in the original file so that
;; headline and file-wide parameters are included, attempt
;; to go to the same heading in the original file
- (set-buffer (get-file-buffer org-current-export-file))
+ (set-buffer original-buffer)
(save-restriction
- (condition-case nil
- (let ((org-link-search-inhibit-query t))
- (org-open-link-from-string link))
- (error (when heading
- (goto-char (point-min))
- (re-search-forward (regexp-quote heading) nil t))))
+ (when heading
+ (condition-case nil
+ (let ((org-link-search-inhibit-query t))
+ (org-link-search heading))
+ (error (when heading
+ (goto-char (point-min))
+ (re-search-forward (regexp-quote heading) nil t)))))
(setq results ,@body))
(set-buffer export-buffer)
results)))
@@ -109,13 +115,32 @@ (defun org-babel-exp-src-block (body &rest headers)
(setf hash (org-babel-sha1-hash info)))
;; expand noweb references in the original file
(setf (nth 1 info)
- (if (and (cdr (assoc :noweb (nth 2 info)))
- (string= "yes" (cdr (assoc :noweb (nth 2 info)))))
- (org-babel-expand-noweb-references
- info (get-file-buffer org-current-export-file))
- (nth 1 info)))
+ (if (string= "strip-export" (cdr (assoc :noweb (nth 2 info))))
+ (replace-regexp-in-string
+ (org-babel-noweb-wrap) "" (nth 1 info))
+ (if (org-babel-noweb-p (nth 2 info) :export)
+ (org-babel-expand-noweb-references
+ info (org-babel-exp-get-export-buffer))
+ (nth 1 info))))
(org-babel-exp-do-export info 'block hash)))))
+(defcustom org-babel-exp-call-line-template
+ ""
+ "Template used to export call lines.
+This template may be customized to include the call line name
+with any export markup. The template is filled out using
+`org-fill-template', and the following %keys may be used.
+
+ line --- call line
+
+An example value would be \"\\n: call: %line\" to export the call line
+wrapped in a verbatim environment.
+
+Note: the results are inserted separately after the contents of
+this template."
+ :group 'org-babel
+ :type 'string)
+
(defvar org-babel-default-lob-header-args)
(defun org-babel-exp-non-block-elements (start end)
"Process inline source and call lines between START and END for export."
@@ -146,7 +171,7 @@ (defun org-babel-exp-non-block-elements (start end)
(if (and (cdr (assoc :noweb params))
(string= "yes" (cdr (assoc :noweb params))))
(org-babel-expand-noweb-references
- info (get-file-buffer org-current-export-file))
+ info (org-babel-exp-get-export-buffer))
(nth 1 info)))
(let ((code-replacement (save-match-data
(org-babel-exp-do-export
@@ -162,22 +187,24 @@ (defun org-babel-exp-non-block-elements (start end)
(inlinep (match-string 11))
(inline-start (match-end 11))
(inline-end (match-end 0))
- (rep (let ((lob-info (org-babel-lob-get-info)))
- (save-match-data
- (org-babel-exp-do-export
- (list "emacs-lisp" "results"
- (org-babel-merge-params
- org-babel-default-header-args
- org-babel-default-lob-header-args
- (org-babel-params-from-properties)
- (org-babel-parse-header-arguments
- (org-babel-clean-text-properties
- (concat ":var results="
- (mapconcat #'identity
- (butlast lob-info)
- " ")))))
- "" nil (car (last lob-info)))
- 'lob)))))
+ (results (save-match-data
+ (org-babel-exp-do-export
+ (list "emacs-lisp" "results"
+ (org-babel-merge-params
+ org-babel-default-header-args
+ org-babel-default-lob-header-args
+ (org-babel-params-from-properties)
+ (org-babel-parse-header-arguments
+ (org-babel-clean-text-properties
+ (concat ":var results="
+ (mapconcat #'identity
+ (butlast lob-info)
+ " ")))))
+ "" nil (car (last lob-info)))
+ 'lob)))
+ (rep (org-fill-template
+ org-babel-exp-call-line-template
+ `(("line" . ,(nth 0 lob-info))))))
(if inlinep
(save-excursion
(goto-char inline-start)
@@ -212,13 +239,37 @@ (defun org-babel-exp-do-export (info type &optional hash)
('both (org-babel-exp-results info type nil hash)
(org-babel-exp-code info)))))
+(defcustom org-babel-exp-code-template
+ "#+BEGIN_SRC %lang%flags\n%body\n#+END_SRC"
+ "Template used to export the body of code blocks.
+This template may be customized to include additional information
+such as the code block name, or the values of particular header
+arguments. The template is filled out using `org-fill-template',
+and the following %keys may be used.
+
+ lang ------ the language of the code block
+ name ------ the name of the code block
+ body ------ the body of the code block
+ flags ----- the flags passed to the code block
+
+In addition to the keys mentioned above, every header argument
+defined for the code block may be used as a key and will be
+replaced with its value."
+ :group 'org-babel
+ :type 'string)
+
(defun org-babel-exp-code (info)
"Return the original code block formatted for export."
(org-fill-template
- "#+BEGIN_SRC %lang%flags\n%body\n#+END_SRC"
+ org-babel-exp-code-template
`(("lang" . ,(nth 0 info))
+ ("body" . ,(nth 1 info))
+ ,@(mapcar (lambda (pair)
+ (cons (substring (symbol-name (car pair)) 1)
+ (format "%S" (cdr pair))))
+ (nth 2 info))
("flags" . ,((lambda (f) (when f (concat " " f))) (nth 3 info)))
- ("body" . ,(nth 1 info)))))
+ ("name" . ,(or (nth 4 info) "")))))
(defun org-babel-exp-results (info type &optional silent hash)
"Evaluate and return the results of the current code block for export.
@@ -229,7 +280,8 @@ (defun org-babel-exp-results (info type &optional silent hash)
(when (and org-export-babel-evaluate
(not (and hash (equal hash (org-babel-current-result-hash)))))
(let ((lang (nth 0 info))
- (body (nth 1 info)))
+ (body (nth 1 info))
+ (info (copy-sequence info)))
;; skip code blocks which we can't evaluate
(when (fboundp (intern (concat "org-babel-execute:" lang)))
(org-babel-eval-wipe-error-buffer)
diff --git a/lisp/ob-gnuplot.el b/lisp/ob-gnuplot.el
index 0cdef4e..5d07366 100644
--- a/lisp/ob-gnuplot.el
+++ b/lisp/ob-gnuplot.el
@@ -34,7 +34,7 @@
;;; Requirements:
;; - gnuplot :: http://www.gnuplot.info/
-;;
+;;
;; - gnuplot-mode :: http://cars9.uchicago.edu/~ravel/software/gnuplot-mode.html
;;; Code:
diff --git a/lisp/ob-haskell.el b/lisp/ob-haskell.el
index b04c3b0..53c5532 100644
--- a/lisp/ob-haskell.el
+++ b/lisp/ob-haskell.el
@@ -79,7 +79,7 @@ (defun org-babel-execute:haskell (body params)
(cdr (member org-babel-haskell-eoe
(reverse (mapcar #'org-babel-trim raw)))))))
(org-babel-reassemble-table
- (cond
+ (cond
((equal result-type 'output)
(mapconcat #'identity (reverse (cdr results)) "\n"))
((equal result-type 'value)
diff --git a/lisp/ob-js.el b/lisp/ob-js.el
index bbb7aa0..893bc7b 100644
--- a/lisp/ob-js.el
+++ b/lisp/ob-js.el
@@ -55,6 +55,7 @@ (defvar org-babel-js-eoe "org-babel-js-eoe"
(defcustom org-babel-js-cmd "node"
"Name of command used to evaluate js blocks."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defvar org-babel-js-function-wrapper
diff --git a/lisp/ob-lilypond.el b/lisp/ob-lilypond.el
index 1f412fd..0e9b0c6 100644
--- a/lisp/ob-lilypond.el
+++ b/lisp/ob-lilypond.el
@@ -3,7 +3,7 @@
;; Copyright (C) 2010-2012 Free Software Foundation, Inc.
;; Author: Martyn Jago
-;; Keywords: babel language, literate programming
+;; Keywords: babel language, literate programming, music score
;; Homepage: https://github.com/mjago/ob-lilypond
;; This file is part of GNU Emacs.
@@ -23,10 +23,14 @@
;;; Commentary:
-;; Installation / usage info, and examples are available at
-;; https://github.com/mjago/ob-lilypond
+;; Installation, ob-lilypond documentation, and examples are available at
+;; http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-lilypond.html
+;;
+;; Lilypond documentation can be found at
+;; http://lilypond.org/manuals.html
;;; Code:
+
(require 'ob)
(require 'ob-eval)
(require 'ob-tangle)
@@ -37,9 +41,11 @@ (defalias 'lilypond-mode 'LilyPond-mode)
(add-to-list 'org-babel-tangle-lang-exts '("LilyPond" . "ly"))
(defvar org-babel-default-header-args:lilypond '()
- "Default header arguments for js code blocks.")
+ "Default header arguments for lilypond code blocks.
+NOTE: The arguments are determined at lilypond compile time.
+See (ly-set-header-args)")
-(defconst ly-version "0.3"
+(defconst ly-version "7.6"
"The version number of the file ob-lilypond.el.")
(defvar ly-compile-post-tangle t
@@ -86,6 +92,10 @@ (defvar ly-gen-html nil
"HTML generation can be turned on by default by setting
LY-GEN-HTML to t")
+(defvar ly-gen-pdf nil
+"PDF generation can be turned on by default by setting
+LY-GEN-PDF to t")
+
(defvar ly-use-eps nil
"You can force the compiler to use the EPS backend by setting
LY-USE-EPS to t")
@@ -114,7 +124,7 @@ (defun org-babel-expand-body:lilypond (body params)
body))))
vars)
body))
-
+
(defun org-babel-execute:lilypond (body params)
"This function is called by `org-babel-execute-src-block'.
Depending on whether we are in arrange mode either:
@@ -138,7 +148,7 @@ (defun ly-tangle ()
(defun ly-process-basic (body params)
"Execute a lilypond block in basic mode"
-
+
(let* ((result-params (cdr (assoc :result-params params)))
(out-file (cdr (assoc :file params)))
(cmdline (or (cdr (assoc :cmdline params))
@@ -147,7 +157,7 @@ (defun ly-process-basic (body params)
(with-temp-file in-file
(insert (org-babel-expand-body:generic body params)))
-
+
(org-babel-eval
(concat
(ly-determine-ly-path)
@@ -177,7 +187,7 @@ (defun ly-execute-tangled-ly ()
(ly-temp-file (ly-switch-extension
(buffer-file-name) ".ly")))
(if (file-exists-p ly-tangled-file)
- (progn
+ (progn
(when (file-exists-p ly-temp-file)
(delete-file ly-temp-file))
(rename-file ly-tangled-file
@@ -203,18 +213,20 @@ (defun ly-compile-lilyfile (file-name &optional test)
(arg-2 nil) ;infile
(arg-3 "*lilypond*") ;buffer
(arg-4 t) ;display
- (arg-5 (if ly-gen-png "--png" "")) ;&rest...
- (arg-6 (if ly-gen-html "--html" ""))
- (arg-7 (if ly-use-eps "-dbackend=eps" ""))
- (arg-8 (if ly-gen-svg "-dbackend=svg" ""))
- (arg-9 (concat "--output=" (file-name-sans-extension file-name)))
- (arg-10 file-name))
+ (arg-4 t) ;display
+ (arg-5 (if ly-gen-png "--png" "")) ;&rest...
+ (arg-6 (if ly-gen-html "--html" ""))
+ (arg-7 (if ly-gen-pdf "--pdf" ""))
+ (arg-8 (if ly-use-eps "-dbackend=eps" ""))
+ (arg-9 (if ly-gen-svg "-dbackend=svg" ""))
+ (arg-10 (concat "--output=" (file-name-sans-extension file-name)))
+ (arg-11 file-name))
(if test
- `(,arg-1 ,arg-2 ,arg-3 ,arg-4 ,arg-5
- ,arg-6 ,arg-7 ,arg-8 ,arg-9 ,arg-10)
+ `(,arg-1 ,arg-2 ,arg-3 ,arg-4 ,arg-5 ,arg-6
+ ,arg-7 ,arg-8 ,arg-9 ,arg-10 ,arg-11)
(call-process
- arg-1 arg-2 arg-3 arg-4 arg-5
- arg-6 arg-7 arg-8 arg-9 arg-10))))
+ arg-1 arg-2 arg-3 arg-4 arg-5 arg-6
+ arg-7 arg-8 arg-9 arg-10 arg-11))))
(defun ly-check-for-compile-error (file-name &optional test)
"Check for compile error.
@@ -243,7 +255,7 @@ (defun ly-mark-error-line (file-name line)
"Mark the erroneous lines in the lilypond org buffer.
FILE-NAME is full path to lilypond file.
LINE is the erroneous line"
-
+
(switch-to-buffer-other-window
(concat (file-name-nondirectory
(ly-switch-extension file-name ".org"))))
@@ -256,7 +268,7 @@ (defun ly-mark-error-line (file-name line)
(set-mark (point))
(goto-char (- (point) (length line))))
(goto-char temp))))
-
+
(defun ly-parse-line-num (&optional buffer)
"Extract error line number."
@@ -284,7 +296,7 @@ (defun ly-parse-error-line (file-name lineNo)
"Extract the erroneous line from the tangled .ly file
FILE-NAME is full path to lilypond file.
LINENO is the number of the erroneous line"
-
+
(with-temp-buffer
(insert-file-contents (ly-switch-extension file-name ".ly")
nil nil nil t)
@@ -294,12 +306,12 @@ (defun ly-parse-error-line (file-name lineNo)
(forward-line (- lineNo 1))
(buffer-substring (point) (point-at-eol)))
nil)))
-
+
(defun ly-attempt-to-open-pdf (file-name &optional test)
"Attempt to display the generated pdf file
FILE-NAME is full path to lilypond file
If TEST is non-nil, the shell command is returned and is not run"
-
+
(when ly-display-pdf-post-tangle
(let ((pdf-file (ly-switch-extension file-name ".pdf")))
(if (file-exists-p pdf-file)
@@ -307,8 +319,12 @@ (defun ly-attempt-to-open-pdf (file-name &optional test)
(concat (ly-determine-pdf-path) " " pdf-file)))
(if test
cmd-string
- (shell-command cmd-string)))
- (message "No pdf file generated so can't display!")))))
+ (start-process
+ "\"Audition pdf\""
+ "*lilypond*"
+ (ly-determine-pdf-path)
+ pdf-file)))
+ (message "No pdf file generated so can't display!")))))
(defun ly-attempt-to-play-midi (file-name &optional test)
"Attempt to play the generated MIDI file
@@ -322,7 +338,11 @@ (defun ly-attempt-to-play-midi (file-name &optional test)
(concat (ly-determine-midi-path) " " midi-file)))
(if test
cmd-string
- (shell-command cmd-string)))
+ (start-process
+ "\"Audition midi\""
+ "*lilypond*"
+ (ly-determine-midi-path)
+ midi-file)))
(message "No midi file generated so can't play!")))))
(defun ly-determine-ly-path (&optional test)
@@ -340,7 +360,7 @@ (defun ly-determine-ly-path (&optional test)
(defun ly-determine-pdf-path (&optional test)
"Return correct path to pdf viewer depending on OS
If TEST is non-nil, it contains a simulation of the OS for test purposes"
-
+
(let ((sys-type
(or test system-type)))
(cond ((string= sys-type "darwin")
@@ -352,7 +372,7 @@ (defun ly-determine-pdf-path (&optional test)
(defun ly-determine-midi-path (&optional test)
"Return correct path to midi player depending on OS
If TEST is non-nil, it contains a simulation of the OS for test purposes"
-
+
(let ((sys-type
(or test test system-type)))
(cond ((string= sys-type "darwin")
@@ -360,10 +380,10 @@ (defun ly-determine-midi-path (&optional test)
((string= sys-type "win32")
ly-win32-midi-path)
(t ly-nix-midi-path))))
-
+
(defun ly-toggle-midi-play ()
"Toggle whether midi will be played following a successful compilation"
-
+
(interactive)
(setq ly-play-midi-post-tangle
(not ly-play-midi-post-tangle))
@@ -373,7 +393,7 @@ (defun ly-toggle-midi-play ()
(defun ly-toggle-pdf-display ()
"Toggle whether pdf will be displayed following a successful compilation"
-
+
(interactive)
(setq ly-display-pdf-post-tangle
(not ly-display-pdf-post-tangle))
@@ -399,6 +419,15 @@ (defun ly-toggle-html-generation ()
(message (concat "HTML generation has been "
(if ly-gen-html "ENABLED." "DISABLED."))))
+(defun ly-toggle-pdf-generation ()
+ "Toggle whether pdf will be generated by compilation"
+
+ (interactive)
+ (setq ly-gen-pdf
+ (not ly-gen-pdf))
+ (message (concat "PDF generation has been "
+ (if ly-gen-pdf "ENABLED." "DISABLED."))))
+
(defun ly-toggle-arrange-mode ()
"Toggle whether in Arrange mode or Basic mode"
@@ -428,6 +457,7 @@ (defun ly-get-header-args (mode)
'((:tangle . "yes")
(:noweb . "yes")
(:results . "silent")
+ (:cache . "yes")
(:comments . "yes")))
(t
'((:results . "file")
@@ -441,6 +471,4 @@ (defun ly-set-header-args (mode)
(provide 'ob-lilypond)
-
-
;;; ob-lilypond.el ends here
diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el
index 2e45787..a0ec1b7 100644
--- a/lisp/ob-lisp.el
+++ b/lisp/ob-lisp.el
@@ -49,6 +49,7 @@ (defcustom org-babel-lisp-dir-fmt
For example a value of \"(progn ;; %s\\n %%s)\" would ignore the
current directory string."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defun org-babel-expand-body:lisp (body params)
diff --git a/lisp/ob-lob.el b/lisp/ob-lob.el
index eff2737..6abb313 100644
--- a/lisp/ob-lob.el
+++ b/lisp/ob-lob.el
@@ -39,6 +39,7 @@ (defcustom org-babel-lob-files '()
"Files used to populate the `org-babel-library-of-babel'.
To add files to this list use the `org-babel-lob-ingest' command."
:group 'org-babel
+ :version "24.1"
:type 'list)
(defvar org-babel-default-lob-header-args '((:exports . "results"))
@@ -104,7 +105,7 @@ (defun org-babel-lob-get-info ()
(beginning-of-line 1)
(when (looking-at org-babel-lob-one-liner-regexp)
(append
- (mapcar #'org-babel-clean-text-properties
+ (mapcar #'org-babel-clean-text-properties
(list
(format "%s%s(%s)%s"
(nonempty 3 12)
@@ -115,7 +116,7 @@ (defun org-babel-lob-get-info ()
(nonempty 9 18)))
(list (length (if (= (length (match-string 12)) 0)
(match-string 2) (match-string 11))))))))))
-
+
(defun org-babel-lob-execute (info)
"Execute the lob call specified by INFO."
(let ((params (org-babel-process-params
diff --git a/lisp/ob-ocaml.el b/lisp/ob-ocaml.el
index 6b4c54d..8d61ff3 100644
--- a/lisp/ob-ocaml.el
+++ b/lisp/ob-ocaml.el
@@ -98,7 +98,7 @@ (defun org-babel-variable-assignments:ocaml (params)
(lambda (pair) (format "let %s = %s;;" (car pair)
(org-babel-ocaml-elisp-to-ocaml (cdr pair))))
(mapcar #'cdr (org-babel-get-header params :var))))
-
+
(defun org-babel-ocaml-elisp-to-ocaml (val)
"Return a string of ocaml code which evaluates to VAL."
(if (listp val)
diff --git a/lisp/ob-picolisp.el b/lisp/ob-picolisp.el
index 04fcad5..7f4e468 100644
--- a/lisp/ob-picolisp.el
+++ b/lisp/ob-picolisp.el
@@ -45,10 +45,10 @@
;; PicoLisp _is_ an object-oriented database with a Prolog-based query
;; language implemented in PicoLisp (Pilog). Database objects are
-;; first-class members of the language.
+;; first-class members of the language.
;; PicoLisp is an extremely productive framework for the development
-;; of interactive web-applications (on top of a database).
+;; of interactive web-applications (on top of a database).
;;; Requirements:
@@ -76,6 +76,7 @@ (defvar org-babel-picolisp-eoe "org-babel-picolisp-eoe"
(defcustom org-babel-picolisp-cmd "pil"
"Name of command used to evaluate picolisp blocks."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defun org-babel-expand-body:picolisp (body params &optional processed-params)
@@ -96,7 +97,7 @@ (defun org-babel-expand-body:picolisp (body params &optional processed-params)
(defun org-babel-execute:picolisp (body params)
"Execute a block of Picolisp code with org-babel. This function is
- called by `org-babel-execute-src-block'"
+ called by `org-babel-execute-src-block'"
(message "executing Picolisp source code block")
(let* (
;; name of the session or "none"
@@ -119,7 +120,7 @@ (defun org-babel-execute:picolisp (body params)
((member "value" result-params)
(format "(out \"/dev/null\" %s)" full-body))
(t full-body))))
-
+
((lambda (result)
(if (or (member "verbatim" result-params)
(member "scalar" result-params)
diff --git a/lisp/ob-plantuml.el b/lisp/ob-plantuml.el
index da70052..55729eb 100644
--- a/lisp/ob-plantuml.el
+++ b/lisp/ob-plantuml.el
@@ -44,6 +44,7 @@ (defvar org-babel-default-header-args:plantuml
(defcustom org-plantuml-jar-path nil
"Path to the plantuml.jar file."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defun org-babel-execute:plantuml (body params)
diff --git a/lisp/ob-ref.el b/lisp/ob-ref.el
index bd9e389..cde594e 100644
--- a/lisp/ob-ref.el
+++ b/lisp/ob-ref.el
@@ -60,7 +60,7 @@
(declare-function org-narrow-to-subtree "org" ())
(declare-function org-id-find-id-in-file "org-id" (id file &optional markerp))
(declare-function org-show-context "org" (&optional key))
-(declare-function org-pop-to-buffer-same-window
+(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
(defvar org-babel-ref-split-regexp
diff --git a/lisp/ob-ruby.el b/lisp/ob-ruby.el
index 8f7e44e..19cce58 100644
--- a/lisp/ob-ruby.el
+++ b/lisp/ob-ruby.el
@@ -28,10 +28,10 @@
;;; Requirements:
;; - ruby and irb executables :: http://www.ruby-lang.org/
-;;
+;;
;; - ruby-mode :: Can be installed through ELPA, or from
;; http://github.com/eschulte/rinari/raw/master/util/ruby-mode.el
-;;
+;;
;; - inf-ruby mode :: Can be installed through ELPA, or from
;; http://github.com/eschulte/rinari/raw/master/util/inf-ruby.el
diff --git a/lisp/ob-scheme.el b/lisp/ob-scheme.el
index 4bcde94..e1f7657 100644
--- a/lisp/ob-scheme.el
+++ b/lisp/ob-scheme.el
@@ -54,6 +54,7 @@ (defvar org-babel-scheme-eoe "org-babel-scheme-eoe"
(defcustom org-babel-scheme-cmd "guile"
"Name of command used to evaluate scheme blocks."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defun org-babel-expand-body:scheme (body params)
diff --git a/lisp/ob-sh.el b/lisp/ob-sh.el
index 6f4cb4f..1fbac1d 100644
--- a/lisp/ob-sh.el
+++ b/lisp/ob-sh.el
@@ -56,14 +56,13 @@ (defun org-babel-execute:sh (body params)
This function is called by `org-babel-execute-src-block'."
(let* ((session (org-babel-sh-initiate-session
(cdr (assoc :session params))))
- (result-params (cdr (assoc :result-params params)))
(stdin ((lambda (stdin) (when stdin (org-babel-sh-var-to-string
(org-babel-ref-resolve stdin))))
(cdr (assoc :stdin params))))
(full-body (org-babel-expand-body:generic
body params (org-babel-variable-assignments:sh params))))
(org-babel-reassemble-table
- (org-babel-sh-evaluate session full-body result-params stdin)
+ (org-babel-sh-evaluate session full-body params stdin)
(org-babel-pick-name
(cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
(org-babel-pick-name
@@ -134,29 +133,38 @@ (defvar org-babel-sh-eoe-indicator "echo 'org_babel_sh_eoe'"
(defvar org-babel-sh-eoe-output "org_babel_sh_eoe"
"String to indicate that evaluation has completed.")
-(defun org-babel-sh-evaluate (session body &optional result-params stdin)
+(defun org-babel-sh-evaluate (session body &optional params stdin)
"Pass BODY to the Shell process in BUFFER.
If RESULT-TYPE equals 'output then return a list of the outputs
of the statements in BODY, if RESULT-TYPE equals 'value then
return the value of the last statement in BODY."
((lambda (results)
(when results
- (if (or (member "scalar" result-params)
- (member "verbatim" result-params)
- (member "output" result-params))
- results
- (let ((tmp-file (org-babel-temp-file "sh-")))
- (with-temp-file tmp-file (insert results))
- (org-babel-import-elisp-from-file tmp-file)))))
+ (let ((result-params (cdr (assoc :result-params params))))
+ (if (or (member "scalar" result-params)
+ (member "verbatim" result-params)
+ (member "output" result-params))
+ results
+ (let ((tmp-file (org-babel-temp-file "sh-")))
+ (with-temp-file tmp-file (insert results))
+ (org-babel-import-elisp-from-file tmp-file))))))
(cond
(stdin ; external shell script w/STDIN
(let ((script-file (org-babel-temp-file "sh-script-"))
- (stdin-file (org-babel-temp-file "sh-stdin-")))
- (with-temp-file script-file (insert body))
+ (stdin-file (org-babel-temp-file "sh-stdin-"))
+ (shebang (cdr (assoc :shebang params)))
+ (padline (not (string= "no" (cdr (assoc :padline params))))))
+ (with-temp-file script-file
+ (when shebang (insert (concat shebang "\n")))
+ (when padline (insert "\n"))
+ (insert body))
+ (set-file-modes script-file #o755)
(with-temp-file stdin-file (insert stdin))
(with-temp-buffer
(call-process-shell-command
- (format "%s %s" org-babel-sh-command script-file)
+ (if shebang
+ script-file
+ (format "%s %s" org-babel-sh-command script-file))
stdin-file
(current-buffer))
(buffer-string))))
@@ -182,7 +190,17 @@ (defun org-babel-sh-evaluate (session body &optional result-params stdin)
(list org-babel-sh-eoe-indicator))))
2)) "\n"))
('otherwise ; external shell script
- (org-babel-eval org-babel-sh-command (org-babel-trim body))))))
+ (if (cdr (assoc :shebang params))
+ (let ((script-file (org-babel-temp-file "sh-script-"))
+ (shebang (cdr (assoc :shebang params)))
+ (padline (not (string= "no" (cdr (assoc :padline params))))))
+ (with-temp-file script-file
+ (when shebang (insert (concat shebang "\n")))
+ (when padline (insert "\n"))
+ (insert body))
+ (set-file-modes script-file #o755)
+ (org-babel-eval script-file ""))
+ (org-babel-eval org-babel-sh-command (org-babel-trim body)))))))
(defun org-babel-sh-strip-weird-long-prompt (string)
"Remove prompt cruft from a string of shell output."
diff --git a/lisp/ob-sql.el b/lisp/ob-sql.el
index 56fbdae..20fbad3 100644
--- a/lisp/ob-sql.el
+++ b/lisp/ob-sql.el
@@ -40,7 +40,7 @@
;; - add more useful header arguments (user, passwd, database, etc...)
;; - support for more engines (currently only supports mysql)
;; - what's a reasonable way to drop table data into SQL?
-;;
+;;
;;; Code:
(require 'ob)
@@ -70,6 +70,10 @@ (defun org-babel-execute:sql (body params)
(org-babel-temp-file "sql-out-")))
(header-delim "")
(command (case (intern engine)
+ ('monetdb (format "mclient -f tab %s < %s > %s"
+ (or cmdline "")
+ (org-babel-process-file-name in-file)
+ (org-babel-process-file-name out-file)))
('msosql (format "osql %s -s \"\t\" -i %s -o %s"
(or cmdline "")
(org-babel-process-file-name in-file)
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index 5e498ab..2af033c 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -47,6 +47,7 @@ (defcustom org-babel-tangle-lang-exts
written in this language. If no entry is found in this list,
then the name of the language is used."
:group 'org-babel-tangle
+ :version "24.1"
:type '(repeat
(cons
(string "Language name")
@@ -55,16 +56,19 @@ (defcustom org-babel-tangle-lang-exts
(defcustom org-babel-post-tangle-hook nil
"Hook run in code files tangled by `org-babel-tangle'."
:group 'org-babel
+ :version "24.1"
:type 'hook)
(defcustom org-babel-pre-tangle-hook '(save-buffer)
"Hook run at the beginning of `org-babel-tangle'."
:group 'org-babel
+ :version "24.1"
:type 'hook)
(defcustom org-babel-tangle-body-hook nil
"Hook run over the contents of each code block body."
:group 'org-babel
+ :version "24.1"
:type 'hook)
(defcustom org-babel-tangle-comment-format-beg "[[%link][%source-name]]"
@@ -79,6 +83,7 @@ (defcustom org-babel-tangle-comment-format-beg "[[%link][%source-name]]"
Whether or not comments are inserted during tangling is
controlled by the :comments header argument."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defcustom org-babel-tangle-comment-format-end "%source-name ends here"
@@ -93,6 +98,7 @@ (defcustom org-babel-tangle-comment-format-end "%source-name ends here"
Whether or not comments are inserted during tangling is
controlled by the :comments header argument."
:group 'org-babel
+ :version "24.1"
:type 'string)
(defcustom org-babel-process-comment-text #'org-babel-trim
@@ -101,6 +107,7 @@ (defcustom org-babel-process-comment-text #'org-babel-trim
should take a single string argument and return a string
result. The default value is `org-babel-trim'."
:group 'org-babel
+ :version "24.1"
:type 'function)
(defun org-babel-find-file-noselect-refresh (file)
@@ -283,7 +290,7 @@ (defun org-babel-tangle-clean ()
(interactive)
(goto-char (point-min))
(while (or (re-search-forward "\\[\\[file:.*\\]\\[.*\\]\\]" nil t)
- (re-search-forward "<<[^[:space:]]*>>" nil t))
+ (re-search-forward (org-babel-noweb-wrap) nil t))
(delete-region (save-excursion (beginning-of-line 1) (point))
(save-excursion (end-of-line 1) (forward-char 1) (point)))))
@@ -344,11 +351,7 @@ (defun org-babel-tangle-collect-blocks (&optional language)
body params
(and (fboundp assignments-cmd)
(funcall assignments-cmd params))))))
- (if (and (cdr (assoc :noweb params)) ;; expand noweb refs
- (let ((nowebs (split-string
- (cdr (assoc :noweb params)))))
- (or (member "yes" nowebs)
- (member "tangle" nowebs))))
+ (if (org-babel-noweb-p params :tangle)
(org-babel-expand-noweb-references info)
(nth 1 info)))))
(comment
diff --git a/lisp/ob.el b/lisp/ob.el
index 9205a20..531cd16 100644
--- a/lisp/ob.el
+++ b/lisp/ob.el
@@ -33,6 +33,8 @@ (defvar org-src-lang-modes)
(defvar org-babel-library-of-babel)
(declare-function show-all "outline" ())
(declare-function org-reduce "org" (CL-FUNC CL-SEQ &rest CL-KEYS))
+(declare-function org-mark-ring-push "org" (&optional pos buffer))
+(declare-function org-strip-protective-commas "org" (beg end))
(declare-function tramp-compat-make-temp-file "tramp-compat"
(filename &optional dir-flag))
(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
@@ -57,6 +59,7 @@ (defvar org-babel-library-of-babel)
(declare-function org-cycle "org" (&optional arg))
(declare-function org-uniquify "org" (list))
(declare-function org-current-level "org" ())
+(declare-function org-strip-protective-commas "org" (beg end))
(declare-function org-table-import "org-table" (file arg))
(declare-function org-add-hook "org-compat"
(hook function &optional append local))
@@ -104,6 +107,7 @@ (defcustom org-confirm-babel-evaluate t
`org-babel-no-eval-on-ctrl-c-ctrl-c' variable can be used to
remove code block execution from the C-c C-c keybinding."
:group 'org-babel
+ :version "24.1"
:type '(choice boolean function))
;; don't allow this variable to be changed through file settings
(put 'org-confirm-babel-evaluate 'safe-local-variable (lambda (x) (eq x t)))
@@ -111,6 +115,7 @@ (defcustom org-confirm-babel-evaluate t
(defcustom org-babel-no-eval-on-ctrl-c-ctrl-c nil
"Remove code block evaluation from the C-c C-c key binding."
:group 'org-babel
+ :version "24.1"
:type 'boolean)
(defcustom org-babel-results-keyword "RESULTS"
@@ -120,6 +125,23 @@ (defcustom org-babel-results-keyword "RESULTS"
:group 'org-babel
:type 'string)
+(defcustom org-babel-noweb-wrap-start "<<"
+ "String used to begin a noweb reference in a code block.
+See also `org-babel-noweb-wrap-end'."
+ :group 'org-babel
+ :type 'string)
+
+(defcustom org-babel-noweb-wrap-end ">>"
+ "String used to end a noweb reference in a code block.
+See also `org-babel-noweb-wrap-start'."
+ :group 'org-babel
+ :type 'string)
+
+(defun org-babel-noweb-wrap (&optional regexp)
+ (concat org-babel-noweb-wrap-start
+ (or regexp "\\([^ \t\n].+?[^ \t]\\|[^ \t\n]\\)")
+ org-babel-noweb-wrap-end))
+
(defvar org-babel-src-name-regexp
"^[ \t]*#\\+name:[ \t]*"
"Regular expression used to match a source name line.")
@@ -381,7 +403,7 @@ (defconst org-babel-common-header-args-w-values
(mkdirp . ((yes no)))
(no-expand)
(noeval)
- (noweb . ((yes no tangle)))
+ (noweb . ((yes no tangle no-export strip-export)))
(noweb-ref . :any)
(noweb-sep . :any)
(padline . ((yes no)))
@@ -394,7 +416,8 @@ (defconst org-babel-common-header-args-w-values
(session . :any)
(shebang . :any)
(tangle . ((tangle yes no :any)))
- (var . :any)))
+ (var . :any)
+ (wrap . :any)))
(defconst org-babel-header-arg-names
(mapcar #'car org-babel-common-header-args-w-values)
@@ -492,12 +515,9 @@ (defun org-babel-execute-src-block (&optional arg info params)
(new-hash (when cache? (org-babel-sha1-hash info)))
(old-hash (when cache? (org-babel-current-result-hash)))
(body (setf (nth 1 info)
- (let ((noweb (cdr (assoc :noweb params))))
- (if (and noweb
- (or (string= "yes" noweb)
- (string= "tangle" noweb)))
- (org-babel-expand-noweb-references info)
- (nth 1 info)))))
+ (if (org-babel-noweb-p params :eval)
+ (org-babel-expand-noweb-references info)
+ (nth 1 info))))
(dir (cdr (assoc :dir params)))
(default-directory
(or (and dir (file-name-as-directory dir)) default-directory))
@@ -571,8 +591,7 @@ (defun org-babel-expand-src-block (&optional arg info params)
(lambda (el1 el2) (string< (symbol-name (car el1))
(symbol-name (car el2)))))))
(body (setf (nth 1 info)
- (if (and (cdr (assoc :noweb params))
- (string= "yes" (cdr (assoc :noweb params))))
+ (if (org-babel-noweb-p params :eval)
(org-babel-expand-noweb-references info) (nth 1 info))))
(expand-cmd (intern (concat "org-babel-expand-body:" lang)))
(assignments-cmd (intern (concat "org-babel-variable-assignments:"
@@ -669,8 +688,7 @@ (defun org-babel-load-in-session (&optional arg info)
(lang (nth 0 info))
(params (nth 2 info))
(body (setf (nth 1 info)
- (if (and (cdr (assoc :noweb params))
- (string= "yes" (cdr (assoc :noweb params))))
+ (if (org-babel-noweb-p params :eval)
(org-babel-expand-noweb-references info)
(nth 1 info))))
(session (cdr (assoc :session params)))
@@ -1442,13 +1460,35 @@ (defun org-babel-goto-src-block-head ()
(defun org-babel-goto-named-src-block (name)
"Go to a named source-code block."
(interactive
- (let ((completion-ignore-case t))
- (list (org-icompleting-read "source-block name: "
- (org-babel-src-block-names) nil t))))
+ (let ((completion-ignore-case t)
+ (under-point (thing-at-point 'line)))
+ (list (org-icompleting-read
+ "source-block name: " (org-babel-src-block-names) nil t
+ (cond
+ ;; noweb
+ ((string-match (org-babel-noweb-wrap) under-point)
+ (let ((block-name (match-string 1 under-point)))
+ (string-match "[^(]*" block-name)
+ (match-string 0 block-name)))
+ ;; #+call:
+ ((string-match org-babel-lob-one-liner-regexp under-point)
+ (let ((source-info (car (org-babel-lob-get-info))))
+ (if (string-match "^\\([^\\[]+?\\)\\(\\[.*\\]\\)?(" source-info)
+ (let ((source-name (match-string 1 source-info)))
+ source-name))))
+ ;; #+results:
+ ((string-match (concat "#\\+" org-babel-results-keyword
+ "\\:\s+\\([^\\(]*\\)") under-point)
+ (match-string 1 under-point))
+ ;; symbol-at-point
+ ((and (thing-at-point 'symbol))
+ (org-babel-find-named-block (thing-at-point 'symbol))
+ (thing-at-point 'symbol))
+ (""))))))
(let ((point (org-babel-find-named-block name)))
(if point
;; taken from `org-open-at-point'
- (progn (goto-char point) (org-show-context))
+ (progn (org-mark-ring-push) (goto-char point) (org-show-context))
(message "source-code block '%s' not found in this buffer" name))))
(defun org-babel-find-named-block (name)
@@ -1874,6 +1914,9 @@ (defun org-babel-insert-result
(setq end (point-marker))
;; possibly wrap result
(cond
+ ((assoc :wrap (nth 2 info))
+ (let ((name (or (cdr (assoc :wrap (nth 2 info))) "RESULTS")))
+ (wrap (concat "#+BEGIN_" name) (concat "#+END_" name))))
((member "html" result-params)
(wrap "#+BEGIN_HTML" "#+END_HTML"))
((member "latex" result-params)
@@ -1925,11 +1968,10 @@ (defun org-babel-result-end ()
(progn (re-search-forward (concat "^" (match-string 1) ":END:"))
(forward-char 1) (point)))
(t
- (let ((case-fold-search t)
- (blocks-re (regexp-opt
- (list "latex" "html" "example" "src" "result" "org"))))
- (if (looking-at (concat "[ \t]*#\\+begin_" blocks-re))
- (progn (re-search-forward (concat "[ \t]*#\\+end_" blocks-re) nil t)
+ (let ((case-fold-search t))
+ (if (looking-at (concat "[ \t]*#\\+begin_\\([^ \t\n\r]+\\)"))
+ (progn (re-search-forward (concat "[ \t]*#\\+end_" (match-string 1))
+ nil t)
(forward-char 1))
(while (looking-at "[ \t]*\\(: \\|\\[\\[\\)")
(forward-line 1))))
@@ -2073,8 +2115,11 @@ (defun org-babel-merge-params (&rest plists)
(:tangle ;; take the latest -- always overwrite
(setq tangle (or (list (cdr pair)) tangle)))
(:noweb
- (setq noweb (e-merge '(("yes" "no" "tangle")) noweb
- (split-string (or (cdr pair) "")))))
+ (setq noweb (e-merge
+ '(("yes" "no" "tangle" "no-export"
+ "strip-export" "eval"))
+ noweb
+ (split-string (or (cdr pair) "")))))
(:cache
(setq cache (e-merge '(("yes" "no")) cache
(split-string (or (cdr pair) "")))))
@@ -2106,6 +2151,20 @@ (defvar *org-babel-use-quick-and-dirty-noweb-expansion* nil
not properly allow code blocks to inherit the \":noweb-ref\"
header argument from buffer or subtree wide properties.")
+(defun org-babel-noweb-p (params context)
+ "Check if PARAMS require expansion in CONTEXT.
+CONTEXT may be one of :tangle, :export or :eval."
+ (flet ((intersect (as bs)
+ (when as
+ (if (member (car as) bs)
+ (car as)
+ (intersect (cdr as) bs)))))
+ (intersect (case context
+ (:tangle '("yes" "tangle" "no-export" "strip-export"))
+ (:eval '("yes" "no-export" "strip-export" "eval"))
+ (:export '("yes")))
+ (split-string (or (cdr (assoc :noweb params)) "")))))
+
(defun org-babel-expand-noweb-references (&optional info parent-buffer)
"Expand Noweb references in the body of the current source code block.
@@ -2153,8 +2212,7 @@ (defun org-babel-expand-noweb-references (&optional info parent-buffer)
(with-temp-buffer
(insert body) (goto-char (point-min))
(setq index (point))
- (while (and (re-search-forward "<<\\([^ \t\n].+?[^ \t\n]\\|[^ \t\n]\\)>>"
- nil t))
+ (while (and (re-search-forward (org-babel-noweb-wrap) nil t))
(save-match-data (setf source-name (match-string 1)))
(save-match-data (setq evaluate (string-match "\(.*\)" source-name)))
(save-match-data
@@ -2226,7 +2284,7 @@ (defun org-babel-expand-noweb-references (&optional info parent-buffer)
;; possibly raise an error if named block doesn't exist
(if (member lang org-babel-noweb-error-langs)
(error "%s" (concat
- "<<" source-name ">> "
+ (org-babel-noweb-wrap source-name)
"could not be resolved (see "
"`org-babel-noweb-error-langs')"))
"")))
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 25f9b8c..1b033e8 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -247,7 +247,9 @@ (defconst org-sorting-choice
;; Keep custom values for `org-agenda-filter-preset' compatible with
;; the new variable `org-agenda-tag-filter-preset'.
-(defvaralias 'org-agenda-filter-preset 'org-agenda-tag-filter-preset)
+(if (fboundp 'defvaralias)
+ (defvaralias 'org-agenda-filter-preset 'org-agenda-tag-filter-preset)
+ (defvaralias 'org-agenda-filter 'org-agenda-tag-filter))
(defconst org-agenda-custom-commands-local-options
`(repeat :tag "Local settings for this command. Remember to quote values"
@@ -647,6 +649,7 @@ (defcustom org-agenda-todo-ignore-timestamp nil
to make his option also apply to the tags-todo list."
:group 'org-agenda-skip
:group 'org-agenda-todo-list
+ :version "24.1"
:type '(choice
(const :tag "Ignore future timestamp todos" future)
(const :tag "Ignore past or present timestamp todos" past)
@@ -794,6 +797,7 @@ (defcustom org-agenda-skip-deadline-prewarning-if-scheduled nil
because you will take care of it on the day when scheduled."
:group 'org-agenda-skip
:group 'org-agenda-daily/weekly
+ :version "24.1"
:type '(choice
(const :tag "Alwas show prewarning" nil)
(const :tag "Remove prewarning if entry is scheduled" t)
@@ -858,6 +862,7 @@ (defcustom org-agenda-menu-show-matcher t
Setting it to nil is good if matcher strings are very long and/or if
you want to use two-column display (see `org-agenda-menu-two-column')."
:group 'org-agenda
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-menu-two-column nil
@@ -865,6 +870,7 @@ (defcustom org-agenda-menu-two-column nil
If you use this, you probably want to set `org-agenda-menu-show-matcher'
to nil."
:group 'org-agenda
+ :version "24.1"
:type 'boolean)
(defcustom org-finalize-agenda-hook nil
@@ -888,6 +894,7 @@ (defcustom org-agenda-follow-indirect nil
"Non-nil means `org-agenda-follow-mode' displays only the
current item's tree, in an indirect buffer."
:group 'org-agenda
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-show-outline-path t
@@ -1040,11 +1047,13 @@ (defcustom org-agenda-time-leading-zero nil
"Non-nil means use leading zero for military times in agenda.
For example, 9:30am would become 09:30 rather than 9:30."
:group 'org-agenda-daily/weekly
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-timegrid-use-ampm nil
"When set, show AM/PM style timestamps on the timegrid."
:group 'org-agenda
+ :version "24.1"
:type 'boolean)
(defun org-agenda-time-of-day-to-ampm (time)
@@ -1092,6 +1101,7 @@ (defcustom org-agenda-move-date-from-past-immediately-to-today t
to today. WHen nil, just move one day forward even if the date stays
in the past."
:group 'org-agenda-daily/weekly
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-include-diary nil
@@ -1104,6 +1114,7 @@ (defcustom org-agenda-include-deadlines t
"If non-nil, include entries within their deadline warning period.
Custom commands can set this variable in the options section."
:group 'org-agenda-daily/weekly
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-repeating-timestamp-show-all t
@@ -1179,6 +1190,7 @@ (defcustom org-agenda-clock-consistency-checks
:short-face face for clock intervals that are too short"
:group 'org-agenda-daily/weekly
:group 'org-clock
+ :version "24.1"
:type 'plist)
(defcustom org-agenda-log-mode-add-notes t
@@ -1237,6 +1249,7 @@ (defcustom org-agenda-search-view-always-boolean nil
is a regexp marked with braces like \"{abc}\", this will also switch to
boolean search."
:group 'org-agenda-search-view
+ :version "24.1"
:type 'boolean)
(if (fboundp 'defvaralias)
@@ -1247,6 +1260,7 @@ (defcustom org-agenda-search-view-force-full-words nil
"Non-nil means, search words must be matches as complete words.
When nil, they may also match part of a word."
:group 'org-agenda-search-view
+ :version "24.1"
:type 'boolean)
(defgroup org-agenda-time-grid nil
@@ -1310,12 +1324,14 @@ (defcustom org-agenda-time-grid
(defcustom org-agenda-show-current-time-in-grid t
"Non-nil means show the current time in the time grid."
:group 'org-agenda-time-grid
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-current-time-string
"now - - - - - - - - - - - - - - - - - - - - - - - - -"
"The string for the current time marker in the agenda."
:group 'org-agenda-time-grid
+ :version "24.1"
:type 'string)
(defgroup org-agenda-sorting nil
@@ -1526,6 +1542,7 @@ (defcustom org-agenda-inactive-leader "["
"Text preceding item pulled into the agenda by inactive time stamps.
These entries are added to the agenda when pressing \"[\"."
:group 'org-agenda-line-format
+ :version "24.1"
:type '(list
(string :tag "Scheduled today ")
(string :tag "Scheduled previously")))
@@ -1564,6 +1581,7 @@ (defcustom org-agenda-remove-timeranges-from-blocks nil
"Non-nil means remove time ranges specifications in agenda
items that span on several days."
:group 'org-agenda-line-format
+ :version "24.1"
:type 'boolean)
(defcustom org-agenda-default-appointment-duration nil
@@ -1645,6 +1663,7 @@ (defcustom org-agenda-day-face-function nil
returns a face, or nil if does not want to specify a face and let
the normal rules apply."
:group 'org-agenda-line-format
+ :version "24.1"
:type 'function)
(defcustom org-agenda-category-icon-alist nil
@@ -1677,6 +1696,7 @@ (defcustom org-agenda-category-icon-alist nil
(\"Emacs\" '(space . (:width (16))))"
:group 'org-agenda-line-format
+ :version "24.1"
:type '(alist :key-type (string :tag "Regexp matching category")
:value-type (choice (list :tag "Icon"
(string :tag "File or data")
@@ -1739,6 +1759,7 @@ (defcustom org-agenda-bulk-custom-functions nil
the custom function `set-category' on the selected entries.
Note that functions in this alist don't need to be quoted."
:type 'alist
+ :version "24.1"
:group 'org-agenda)
(eval-when-compile
@@ -1768,7 +1789,7 @@ (defun org-add-agenda-custom-command (entry)
(setcdr ass (cdr entry))
(push entry org-agenda-custom-commands))))
-;;; Define the Org-agenda-mode
+;;; Define the org-agenda-mode
(defvar org-agenda-mode-map (make-sparse-keymap)
"Keymap for `org-agenda-mode'.")
@@ -4375,7 +4396,7 @@ (defun org-agenda-list-stuck-projects (&rest ignore)
;;; Diary integration
(defvar org-disable-agenda-to-diary nil) ;Dynamically-scoped param.
-(defvar list-diary-entries-hook)
+(defvar diary-list-entries-hook)
(defvar diary-time-regexp)
(defun org-get-entries-from-diary (date)
"Get the (Emacs Calendar) diary entries for DATE."
@@ -4384,8 +4405,8 @@ (defun org-get-entries-from-diary (date)
(diary-display-hook '(fancy-diary-display))
(diary-display-function 'fancy-diary-display)
(pop-up-frames nil)
- (list-diary-entries-hook
- (cons 'org-diary-default-entry list-diary-entries-hook))
+ (diary-list-entries-hook
+ (cons 'org-diary-default-entry diary-list-entries-hook))
(diary-file-name-prefix-function nil) ; turn this feature off
(diary-modify-entry-list-string-function 'org-modify-diary-entry-string)
entries
@@ -6190,8 +6211,9 @@ (defun org-agenda-redo ()
(recenter window-line)))
(defvar org-global-tags-completion-table nil)
+(defvar org-agenda-filtered-by-category nil)
(defvar org-agenda-filter-form nil)
-
+(defvar org-agenda-filtered-by-category nil)
(defun org-agenda-filter-by-category (strip)
"Keep only those lines in the agenda buffer that have a specific category.
The category is that of the current line."
@@ -6369,10 +6391,9 @@ (defun org-agenda-compare-effort (op value)
(funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0))
value))))
-(defvar org-agenda-filtered-by-category nil)
(defun org-agenda-filter-apply (filter type)
"Set FILTER as the new agenda filter and apply it."
- (let (tags)
+ (let (tags cat)
(if (eq type 'tag)
(setq org-agenda-tag-filter filter)
(setq org-agenda-category-filter filter
@@ -7150,10 +7171,13 @@ (defun org-agenda-show (&optional full-entry)
(select-window win)))
(defvar org-agenda-show-window nil)
-(defun org-agenda-show-and-scroll-up ()
+(defun org-agenda-show-and-scroll-up (&optional arg)
"Display the Org-mode file which contains the item at point.
-When called repeatedly, scroll the window that is displaying the buffer."
- (interactive)
+When called repeatedly, scroll the window that is displaying the buffer.
+With a \\[universal-argument] prefix, use `org-show-entry' instead of
+`show-subtree' to display the item, so that drawers and logbooks stay
+folded."
+ (interactive "P")
(let ((win (selected-window)))
(if (and (window-live-p org-agenda-show-window)
(eq this-command last-command))
@@ -7161,7 +7185,7 @@ (defun org-agenda-show-and-scroll-up ()
(select-window org-agenda-show-window)
(ignore-errors (scroll-up)))
(org-agenda-goto t)
- (show-subtree)
+ (if arg (org-show-entry) (show-subtree))
(setq org-agenda-show-window (selected-window)))
(select-window win)))
@@ -7996,6 +8020,7 @@ (defcustom org-agenda-insert-diary-strategy 'date-tree
(defcustom org-agenda-insert-diary-extract-time nil
"Non-nil means extract any time specification from the diary entry."
:group 'org-agenda
+ :version "24.1"
:type 'boolean)
(defun org-agenda-add-entry-to-org-agenda-diary-file (type text &optional d1 d2)
diff --git a/lisp/org-archive.el b/lisp/org-archive.el
index 4137e2c..db3b825 100644
--- a/lisp/org-archive.el
+++ b/lisp/org-archive.el
@@ -43,6 +43,7 @@ (defcustom org-archive-default-command 'org-archive-subtree
(defcustom org-archive-reversed-order nil
"Non-nil means make the tree first child under the archive heading, not last."
:group 'org-archive
+ :version "24.1"
:type 'boolean)
(defcustom org-archive-sibling-heading "Archive"
@@ -72,6 +73,7 @@ (defcustom org-archive-stamp-time t
(defcustom org-archive-subtree-add-inherited-tags 'infile
"Non-nil means append inherited tags when archiving a subtree."
:group 'org-archive
+ :version "24.1"
:type '(choice
(const :tag "Never" nil)
(const :tag "When archiving a subtree to the same file" infile)
diff --git a/lisp/org-ascii.el b/lisp/org-ascii.el
index c652671..90f39fd 100644
--- a/lisp/org-ascii.el
+++ b/lisp/org-ascii.el
@@ -108,7 +108,7 @@ (defun org-export-as-latin1-to-buffer (&rest args)
(defun org-export-as-utf8 (&rest args)
"Like `org-export-as-ascii', use encoding for special symbols."
(interactive)
- (org-export-as-encoding 'org-export-as-ascii
+ (org-export-as-encoding 'org-export-as-ascii
(org-called-interactively-p 'any)
'utf8 args))
diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 73d0fa4..7ba3d72 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -101,6 +101,7 @@ (defvar org-attach-inherited nil
(defcustom org-attach-store-link-p nil
"Non-nil means store a link to a file when attaching it."
:group 'org-attach
+ :version "24.1"
:type '(choice
(const :tag "Don't store link" nil)
(const :tag "Link to origin location" t)
diff --git a/lisp/org-bbdb.el b/lisp/org-bbdb.el
index 49b9cf7..7fddbb2 100644
--- a/lisp/org-bbdb.el
+++ b/lisp/org-bbdb.el
@@ -120,6 +120,7 @@
(declare-function diary-ordinal-suffix "diary-lib" (n))
(defvar date) ;; dynamically scoped from Org
+(defvar name) ;; dynamically scoped from Org
;; Customization
diff --git a/lisp/org-beamer.el b/lisp/org-beamer.el
index 28b79a0..575967b 100644
--- a/lisp/org-beamer.el
+++ b/lisp/org-beamer.el
@@ -43,6 +43,7 @@ (defgroup org-beamer nil
(defcustom org-beamer-use-parts nil
""
:group 'org-beamer
+ :version "24.1"
:type 'boolean)
(defcustom org-beamer-frame-level 1
@@ -52,6 +53,7 @@ (defcustom org-beamer-frame-level 1
You can set this to 4 as well, if you at the same time set
`org-beamer-use-parts' to make the top levels `\part'."
:group 'org-beamer
+ :version "24.1"
:type '(choice
(const :tag "Frames need a BEAMER_env property" nil)
(integer :tag "Specific level makes a frame")))
@@ -60,12 +62,14 @@ (defcustom org-beamer-frame-default-options ""
"Default options string to use for frames, should contains the [brackets].
And example for this is \"[allowframebreaks]\"."
:group 'org-beamer
+ :version "24.1"
:type '(string :tag "[options]"))
(defcustom org-beamer-column-view-format
"%45ITEM %10BEAMER_env(Env) %10BEAMER_envargs(Env Args) %4BEAMER_col(Col) %8BEAMER_extra(Extra)"
"Default column view format that should be used to fill the template."
:group 'org-beamer
+ :version "24.1"
:type '(choice
(const :tag "Do not insert Beamer column view format" nil)
(string :tag "Beamer column view format")))
@@ -76,6 +80,7 @@ (defcustom org-beamer-themes
When a beamer template is filled, this will be the default for
BEAMER_HEADER_EXTRA, which will be inserted just before \\begin{document}."
:group 'org-beamer
+ :version "24.1"
:type '(choice
(const :tag "Do not insert Beamer themes" nil)
(string :tag "Beamer themes")))
@@ -102,6 +107,7 @@ (defconst org-beamer-environments-default
("theorem" "t" "\\begin{theorem}%a%U%x" "\\end{theorem}")
("definition" "d" "\\begin{definition}%a%U%x" "\\end{definition}")
("example" "e" "\\begin{example}%a%U%x" "\\end{example}")
+ ("exampleblock" "E" "\\begin{exampleblock}%a{%h}%x" "\\end{exampleblock}")
("proof" "p" "\\begin{proof}%a%U%x" "\\end{proof}")
("beamercolorbox" "o" "\\begin{beamercolorbox}%o{%h}%x" "\\end{beamercolorbox}")
("normal" "h" "%h" "") ; Emit the heading as normal text
@@ -142,6 +148,7 @@ (defcustom org-beamer-environments-extra nil
close The closing string of the environment."
:group 'org-beamer
+ :version "24.1"
:type '(repeat
(list
(string :tag "Environment")
@@ -402,6 +409,7 @@ (defun org-beamer-amend-header ()
(defcustom org-beamer-fragile-re "\\\\\\(verb\\|lstinline\\)\\|^[ \t]*\\\\begin{\\(verbatim\\|lstlisting\\|minted\\)}"
"If this regexp matches in a frame, the frame is marked as fragile."
:group 'org-beamer
+ :version "24.1"
:type 'regexp)
(defface org-beamer-tag '((t (:box (:line-width 1 :color grey40))))
@@ -511,6 +519,7 @@ (defun org-beamer-auto-fragile-frames ()
(defcustom org-beamer-outline-frame-title "Outline"
"Default title of a frame containing an outline."
:group 'org-beamer
+ :version "24.1"
:type '(string :tag "Outline frame title")
)
@@ -519,6 +528,7 @@ (defcustom org-beamer-outline-frame-options nil
You might want to put e.g. [allowframebreaks=0.9] here. Remember to
include square brackets."
:group 'org-beamer
+ :version "24.1"
:type '(string :tag "Outline frame options")
)
diff --git a/lisp/org-bibtex.el b/lisp/org-bibtex.el
index 17cdbc2..cebd6ca 100644
--- a/lisp/org-bibtex.el
+++ b/lisp/org-bibtex.el
@@ -216,12 +216,14 @@ (defvar *org-bibtex-entries* nil
(defcustom org-bibtex-autogen-keys nil
"Set to a truth value to use `bibtex-generate-autokey' to generate keys."
:group 'org-bibtex
+ :version "24.1"
:type 'boolean)
(defcustom org-bibtex-prefix nil
"Optional prefix for all bibtex property names.
For example setting to 'BIB_' would allow interoperability with fireforg."
:group 'org-bibtex
+ :version "24.1"
:type 'string)
(defcustom org-bibtex-treat-headline-as-title t
@@ -230,6 +232,7 @@ (defcustom org-bibtex-treat-headline-as-title t
the property. If this value is t, `org-bibtex-check' will ignore
a missing title field."
:group 'org-bibtex
+ :version "24.1"
:type 'boolean)
(defcustom org-bibtex-export-arbitrary-fields nil
@@ -238,6 +241,7 @@ (defcustom org-bibtex-export-arbitrary-fields nil
ensure that other org-properties, such as CATEGORY or LOGGING are
not placed in the exported bibtex entry."
:group 'org-bibtex
+ :version "24.1"
:type 'boolean)
(defcustom org-bibtex-key-property "CUSTOM_ID"
@@ -247,11 +251,13 @@ (defcustom org-bibtex-key-property "CUSTOM_ID"
to enable global links, but only with great caution, as global
IDs must be unique."
:group 'org-bibtex
+ :version "24.1"
:type 'string)
(defcustom org-bibtex-tags nil
"List of tag(s) that should be added to new bib entries."
:group 'org-bibtex
+ :version "24.1"
:type '(repeat :tag "Tag" (string)))
(defcustom org-bibtex-tags-are-keywords nil
@@ -266,17 +272,20 @@ (defcustom org-bibtex-tags-are-keywords nil
defined in `org-bibtex-tags' or `org-bibtex-no-export-tags' will
not be exported."
:group 'org-bibtex
+ :version "24.1"
:type 'boolean)
(defcustom org-bibtex-no-export-tags nil
"List of tag(s) that should not be converted to keywords.
This variable is relevant only if `org-bibtex-export-tags-as-keywords` is t."
:group 'org-bibtex
+ :version "24.1"
:type '(repeat :tag "Tag" (string)))
(defcustom org-bibtex-type-property-name "btype"
"Property in which to store bibtex entry type (e.g., article)."
:group 'org-bibtex
+ :version "24.1"
:type 'string)
\f
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 0fd8003..e3bd9f7 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -56,7 +56,7 @@
(date &optional keep-restriction))
(declare-function org-table-get-specials "org-table" ())
(declare-function org-table-goto-line "org-table" (N))
-(declare-function org-pop-to-buffer-same-window "org-compat"
+(declare-function org-pop-to-buffer-same-window "org-compat"
(&optional buffer-or-name norecord label))
(defvar org-remember-default-headline)
@@ -262,6 +262,7 @@ (defcustom org-capture-templates nil
info | %:type %:file %:node
calendar | %:type %:date"
:group 'org-capture
+ :version "24.1"
:type
'(repeat
(choice :value ("" "" entry (file "~/org/notes.org") "")
@@ -336,12 +337,21 @@ (defcustom org-capture-before-finalize-hook nil
The capture buffer is still current when this hook runs and it is
widened to the entire buffer."
:group 'org-capture
+ :version "24.1"
:type 'hook)
(defcustom org-capture-after-finalize-hook nil
"Hook that is run right after a capture process is finalized.
Suitable for window cleanup"
:group 'org-capture
+ :version "24.1"
+ :type 'hook)
+
+(defcustom org-capture-prepare-finalize-hook nil
+ "Hook that is run before the finalization starts.
+The capture buffer is current and still narrowed."
+ :group 'org-capture
+ :version "24.1"
:type 'hook)
;;; The property list for keeping information about the capture process
@@ -527,6 +537,8 @@ (defun org-capture-finalize (&optional stay-with-capture)
(buffer-base-buffer (current-buffer)))
(error "This does not seem to be a capture buffer for Org-mode"))
+ (run-hooks 'org-capture-prepare-finalize-hook)
+
;; Did we start the clock in this capture buffer?
(when (and org-capture-clock-was-started
org-clock-marker (marker-buffer org-clock-marker)
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index 591f59c..46d9af8 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -226,6 +226,7 @@ (defcustom org-task-overrun-text nil
When this is a string, it is prepended to the clock string as an indication,
also using the face `org-mode-line-clock-overrun'."
:group 'org-clock
+ :version "24.1"
:type '(choice
(const :tag "Just mark the time string" nil)
(string :tag "Text to prepend")))
@@ -267,12 +268,14 @@ (defcustom org-clocktable-defaults
:formatter nil)
"Default properties for clock tables."
:group 'org-clock
+ :version "24.1"
:type 'plist)
(defcustom org-clock-clocktable-formatter 'org-clocktable-write-default
"Function to turn clocking data into a table.
For more information, see `org-clocktable-write-default'."
:group 'org-clocktable
+ :version "24.1"
:type 'function)
;; FIXME: translate es and nl last string "Clock summary at"
@@ -283,6 +286,7 @@ (defcustom org-clock-clocktable-language-setup
("nl" "Bestand" "N" "Tijdstip" "Hoofding" "Duur" "ALLES" "Totale duur" "Bestandstijd" "Clock summary at"))
"Terms used in clocktable, translated to different languages."
:group 'org-clocktable
+ :version "24.1"
:type 'alist)
(defcustom org-clock-clocktable-default-properties '(:maxlevel 2 :scope file)
@@ -310,11 +314,13 @@ (defcustom org-clock-auto-clock-resolution 'when-no-clock-is-running
(defcustom org-clock-report-include-clocking-task nil
"When non-nil, include the current clocking task time in clock reports."
:group 'org-clock
+ :version "24.1"
:type 'boolean)
(defcustom org-clock-resolve-expert nil
"Non-nil means do not show the splash buffer with the clock resolver."
:group 'org-clock
+ :version "24.1"
:type 'boolean)
(defvar org-clock-in-prepare-hook nil
@@ -1387,7 +1393,8 @@ (defun org-clock-out (&optional fail-quietly at-time)
(message (concat "Clock stopped at %s after HH:MM = " org-time-clocksum-format "%s") te h m
(if remove " => LINE REMOVED" ""))
(run-hooks 'org-clock-out-hook)
- (org-clock-delete-current))))))
+ (unless (org-clocking-p)
+ (org-clock-delete-current)))))))
(add-hook 'org-clock-out-hook 'org-clock-remove-empty-clock-drawer)
@@ -1989,7 +1996,7 @@ (defun org-clocktable-shift (dir n)
(encode-time 0 0 0 (+ d n) m y))))
((and wp (string-match "w\\|W" wp) mw (> (length wp) 0))
(require 'cal-iso)
- (setq date (calendar-gregorian-from-absolute
+ (setq date (calendar-gregorian-from-absolute
(calendar-absolute-from-iso (list (+ mw n) 1 y))))
(setq ins (format-time-string
"%G-W%V"
@@ -2006,7 +2013,7 @@ (defun org-clocktable-shift (dir n)
(setq mw 5
y (- y 1))
())
- (setq date (calendar-gregorian-from-absolute
+ (setq date (calendar-gregorian-from-absolute
(calendar-absolute-from-iso (org-quarter-to-date (+ mw n) y))))
(setq ins (format-time-string
(concatenate 'string (number-to-string y) "-Q" (number-to-string (+ mw n)))
@@ -2456,7 +2463,9 @@ (defun org-clock-get-table-data (file params)
(org-clock-sum ts te
(unless (null matcher)
(lambda ()
- (let ((tags-list (org-get-tags-at)))
+ (let* ((tags-list (org-get-tags-at))
+ (org-scanner-tags tags-list)
+ (org-trust-scanner-tags t))
(eval matcher)))))
(goto-char (point-min))
(setq st t)
@@ -2631,4 +2640,3 @@ (defun org-clock-persistence-insinuate ()
(provide 'org-clock)
;;; org-clock.el ends here
-
diff --git a/lisp/org-crypt.el b/lisp/org-crypt.el
index f3e63b0..f60c61e 100644
--- a/lisp/org-crypt.el
+++ b/lisp/org-crypt.el
@@ -76,21 +76,21 @@
(defgroup org-crypt nil
"Org Crypt"
- :tag "Org Crypt"
+ :tag "Org Crypt"
:group 'org)
(defcustom org-crypt-tag-matcher "crypt"
"The tag matcher used to find headings whose contents should be encrypted.
See the \"Match syntax\" section of the org manual for more details."
- :type 'string
+ :type 'string
:group 'org-crypt)
(defcustom org-crypt-key ""
"The default key to use when encrypting the contents of a heading.
This setting can also be overridden in the CRYPTKEY property."
- :type 'string
+ :type 'string
:group 'org-crypt)
(defcustom org-crypt-disable-auto-save 'ask
@@ -111,6 +111,7 @@ (defcustom org-crypt-disable-auto-save 'ask
NOTE: This only works for entries which have a tag
that matches `org-crypt-tag-matcher'."
:group 'org-crypt
+ :version "24.1"
:type '(choice (const :tag "Always" t)
(const :tag "Never" nil)
(const :tag "Ask" ask)
diff --git a/lisp/org-ctags.el b/lisp/org-ctags.el
index ea94d41..42e2687 100644
--- a/lisp/org-ctags.el
+++ b/lisp/org-ctags.el
@@ -162,6 +162,7 @@ (defcustom org-ctags-path-to-ctags
(t "ctags-exuberant"))
"Full path to the ctags executable file."
:group 'org-ctags
+ :version "24.1"
:type 'file)
(defcustom org-ctags-open-link-functions
@@ -170,6 +171,7 @@ (defcustom org-ctags-open-link-functions
org-ctags-ask-append-topic)
"List of functions to be prepended to ORG-OPEN-LINK-FUNCTIONS when ORG-CTAGS is active."
:group 'org-ctags
+ :version "24.1"
:type 'hook
:options '(org-ctags-find-tag
org-ctags-ask-rebuild-tags-file-then-find-tag
@@ -191,6 +193,7 @@ (defcustom org-ctags-new-topic-template
The following patterns are replaced in the string:
`%t' - replaced with the capitalized title of the hyperlink"
:group 'org-ctags
+ :version "24.1"
:type 'string)
diff --git a/lisp/org-docbook.el b/lisp/org-docbook.el
index 499ab5d..5dfc160 100644
--- a/lisp/org-docbook.el
+++ b/lisp/org-docbook.el
@@ -150,6 +150,7 @@ (defcustom org-export-docbook-footnote-id-prefix "fn-"
(defcustom org-export-docbook-footnote-separator "<superscript>, </superscript>"
"Text used to separate footnotes."
:group 'org-export-docbook
+ :version "24.1"
:type 'string)
(defcustom org-export-docbook-emphasis-alist
@@ -195,6 +196,7 @@ (defcustom org-export-docbook-xslt-stylesheet nil
Object (FO) files. You can use either `fo/docbook.xsl' that
comes with DocBook, or any customization layer you may have."
:group 'org-export-docbook
+ :version "24.1"
:type 'string)
(defcustom org-export-docbook-xslt-proc-command nil
diff --git a/lisp/org-entities.el b/lisp/org-entities.el
index fe3c528..8b5b3f3 100644
--- a/lisp/org-entities.el
+++ b/lisp/org-entities.el
@@ -44,6 +44,7 @@ (defcustom org-entities-ascii-explanatory nil
For example, this will replace \"\\nsup\" with \"[not a superset of]\"
in backends where the corresponding character is not available."
:group 'org-entities
+ :version "24.1"
:type 'boolean)
(defcustom org-entities-user nil
@@ -68,6 +69,7 @@ (defcustom org-entities-user nil
If you define new entities here that require specific LaTeX packages to be
loaded, add these packages to `org-export-latex-packages-alist'."
:group 'org-entities
+ :version "24.1"
:type '(repeat
(list
(string :tag "name ")
diff --git a/lisp/org-eshell.el b/lisp/org-eshell.el
index de6f9fb..f572095 100644
--- a/lisp/org-eshell.el
+++ b/lisp/org-eshell.el
@@ -45,7 +45,7 @@ (defun org-eshell-open (link)
(if (get-buffer eshell-buffer-name)
(org-pop-to-buffer-same-window eshell-buffer-name)
(eshell))
- (end-of-buffer)
+ (goto-char (point-max))
(eshell-kill-input)
(insert command)
(eshell-send-input)))
diff --git a/lisp/org-exp-blocks.el b/lisp/org-exp-blocks.el
index 020eefb..78eaa15 100644
--- a/lisp/org-exp-blocks.el
+++ b/lisp/org-exp-blocks.el
@@ -135,6 +135,7 @@ (defcustom org-export-blocks-witheld
(defcustom org-export-blocks-postblock-hook nil
"Run after blocks have been processed with `org-export-blocks-preprocess'."
:group 'org-export-general
+ :version "24.1"
:type 'hook)
(defun org-export-blocks-html-quote (body &optional open close)
@@ -224,7 +225,7 @@ (defun org-export-blocks-preprocess ()
;;--------------------------------------------------------------------------------
;; ditaa: create images from ASCII art using the ditaa utility
-(defvar org-ditaa-jar-path (expand-file-name
+(defcustom org-ditaa-jar-path (expand-file-name
"ditaa.jar"
(file-name-as-directory
(expand-file-name
@@ -233,7 +234,9 @@ (defvar org-ditaa-jar-path (expand-file-name
(expand-file-name
"../contrib"
(file-name-directory (or load-file-name buffer-file-name)))))))
- "Path to the ditaa jar executable.")
+ "Path to the ditaa jar executable."
+ :group 'org-babel
+ :type 'string)
(defvar org-export-current-backend) ; dynamically bound in org-exp.el
(defun org-export-blocks-format-ditaa (body &rest headers)
diff --git a/lisp/org-exp.el b/lisp/org-exp.el
index a2f0cfc..fef6c33 100644
--- a/lisp/org-exp.el
+++ b/lisp/org-exp.el
@@ -98,6 +98,7 @@ (defcustom org-export-kill-product-buffer-when-displayed nil
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
@@ -120,6 +121,7 @@ (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)))
@@ -229,6 +231,7 @@ (defcustom org-export-default-language "en"
(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 ""
@@ -326,6 +329,7 @@ (defcustom org-export-with-tasks t
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)
@@ -376,6 +380,7 @@ (defcustom org-export-email-info 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
@@ -603,6 +608,7 @@ (defcustom org-export-table-remove-empty-lines t
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
diff --git a/lisp/org-faces.el b/lisp/org-faces.el
index e71ce23..481d662 100644
--- a/lisp/org-faces.el
+++ b/lisp/org-faces.el
@@ -351,6 +351,7 @@ (defcustom org-faces-easy-properties
color."
:group 'org-faces
:group 'org-todo
+ :version "24.1"
:type '(repeat
(cons (choice (const todo) (const tag) (const priority))
(choice (const :foreground) (const :background)))))
@@ -547,6 +548,7 @@ (defcustom org-fontify-quote-and-verse-blocks nil
When nil, format these as normal Org. This is the default, because the
content of these blocks will still be treated as Org syntax."
:group 'org-faces
+ :version "24.1"
:type 'boolean)
(defface org-clock-overlay ;; copied from secondary-selection
@@ -732,6 +734,7 @@ (defcustom org-cycle-level-faces t
level org-n-level-faces"
:group 'org-appearance
:group 'org-faces
+ :version "24.1"
:type 'boolean)
(defface org-latex-and-export-specials
diff --git a/lisp/org-feed.el b/lisp/org-feed.el
index f5186aa..6901ffa 100644
--- a/lisp/org-feed.el
+++ b/lisp/org-feed.el
@@ -80,7 +80,7 @@
;; that received the input of the feed. You should add FEEDSTATUS
;; to your list of drawers in the files that receive feed input:
;;
-;; #+DRAWERS: PROPERTIES LOGBOOK FEEDSTATUS
+;; #+DRAWERS: PROPERTIES CLOCK LOGBOOK RESULTS FEEDSTATUS
;;
;; Acknowledgments
;; ---------------
--git a/lisp/org-footnote.el b/lisp/org-footnote.el
index 196dd99..3be853e 100644
--- a/lisp/org-footnote.el
+++ b/lisp/org-footnote.el
@@ -57,6 +57,7 @@
(declare-function org-mark-ring-push "org" (&optional pos buffer))
(declare-function org-show-context "org" (&optional key))
(declare-function org-trim "org" (s))
+(declare-function org-skip-whitespace "org" ())
(declare-function outline-next-heading "outline")
(defvar org-outline-regexp-bol) ; defined in org.el
diff --git a/lisp/org-freemind.el b/lisp/org-freemind.el
index 8b77400..3b94d92 100644
--- a/lisp/org-freemind.el
+++ b/lisp/org-freemind.el
@@ -414,6 +414,7 @@ (defcustom org-freemind-node-css-style
;; with this setting now, but not before??? Was this perhaps a java
;; bug or is it a windows xp bug (some resource gets exhausted if you
;; use sticky keys which I do).
+ :version "24.1"
:group 'org-freemind)
(defun org-freemind-org-text-to-freemind-subnode/note (node-name start end drawers-regexp)
diff --git a/lisp/org-gnus.el b/lisp/org-gnus.el
index 2a3f946..5b855c2 100644
--- a/lisp/org-gnus.el
+++ b/lisp/org-gnus.el
@@ -62,6 +62,7 @@ (defcustom org-gnus-nnimap-query-article-no-from-file nil
So if following a link to a Gnus article takes ages, try setting
this variable to `t'."
:group 'org-link-store
+ :version "24.1"
:type 'boolean)
@@ -175,7 +176,7 @@ (defun org-gnus-store-link ()
(setq to (or to (gnus-fetch-original-field "To"))
newsgroups (gnus-fetch-original-field "Newsgroups")
x-no-archive (gnus-fetch-original-field "x-no-archive")))
- (org-store-link-props :type "gnus" :from from :subject subject
+ (org-store-link-props :type "gnus" :from from :subject subject
:message-id message-id :group group :to to)
(when date
(org-add-link-props :date date :date-timestamp date-ts
diff --git a/lisp/org-habit.el b/lisp/org-habit.el
index be0efff..4274aae 100644
--- a/lisp/org-habit.el
+++ b/lisp/org-habit.el
@@ -70,11 +70,13 @@ (defcustom org-habit-show-habits-only-for-today t
(defcustom org-habit-today-glyph ?!
"Glyph character used to identify today."
:group 'org-habit
+ :version "24.1"
:type 'character)
(defcustom org-habit-completed-glyph ?*
"Glyph character used to show completed days on which a task was done."
:group 'org-habit
+ :version "24.1"
:type 'character)
(defface org-habit-clear-face
diff --git a/lisp/org-html.el b/lisp/org-html.el
index 69d88fe..5cecc44 100644
--- a/lisp/org-html.el
+++ b/lisp/org-html.el
@@ -64,6 +64,7 @@ (defcustom org-export-html-footnote-format "<sup>%s</sup>"
(defcustom org-export-html-footnote-separator "<sup>, </sup>"
"Text used to separate footnotes."
:group 'org-export-html
+ :version "24.1"
:type 'string)
(defcustom org-export-html-coding-system nil
@@ -252,6 +253,7 @@ (defcustom org-export-html-mathjax-options
#+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\""
:group 'org-export-html
+ :version "24.1"
:type '(list :greedy t
(list :tag "path (the path from where to load MathJax.js)"
(const :format " " path) (string))
@@ -335,6 +337,7 @@ (defcustom org-export-html-mathjax-template
</script>"
"The MathJax setup for XHTML files."
:group 'org-export-html
+ :version "24.1"
:type 'string)
(defcustom org-export-html-tag-class-prefix ""
@@ -361,6 +364,7 @@ (defcustom org-export-html-headline-anchor-format "<a name=\"%s\" id=\"%s\"></a>
to the headline (e.g. \"sec-2\"). When set to `nil', don't insert
HTML anchors in headlines."
:group 'org-export-html
+ :version "24.1"
:type 'string)
(defcustom org-export-html-preamble t
@@ -392,6 +396,7 @@ (defcustom org-export-html-preamble-format '(("en" ""))
If you need to use a \"%\" character, you need to escape it
like that: \"%%\"."
:group 'org-export-html
+ :version "24.1"
:type 'string)
(defcustom org-export-html-postamble 'auto
@@ -432,6 +437,7 @@ (defcustom org-export-html-postamble-format
If you need to use a \"%\" character, you need to escape it
like that: \"%%\"."
:group 'org-export-html
+ :version "24.1"
:type 'string)
(defcustom org-export-html-home/up-format
@@ -548,6 +554,7 @@ (defcustom org-export-html-table-align-individual-fields t
is ignored by some browsers (like Firefox, Safari). Opera does it right
though."
:group 'org-export-tables
+ :version "24.1"
:type 'boolean)
(defcustom org-export-html-table-use-header-tags-for-first-column nil
@@ -578,6 +585,7 @@ (defcustom org-export-html-protect-char-alist
(">" . ">"))
"Alist of characters to be converted by `org-html-protect'."
:group 'org-export-html
+ :version "24.1"
:type '(repeat (cons (string :tag "Character")
(string :tag "HTML equivalent"))))
@@ -639,6 +647,7 @@ (defcustom org-export-html-divs '("preamble" "content" "postamble")
DIV, the second one for the content DIV and the third one for the
postamble DIV."
:group 'org-export-html
+ :version "24.1"
:type '(list
(string :tag " Div for the preamble:")
(string :tag " Div for the content:")
diff --git a/lisp/org-icalendar.el b/lisp/org-icalendar.el
index 29f6c74..d73a619 100644
--- a/lisp/org-icalendar.el
+++ b/lisp/org-icalendar.el
@@ -54,6 +54,7 @@ (defcustom org-icalendar-alarm-time 0
- The alarm will go off N minutes before the event
- only a DISPLAY action is defined."
:group 'org-export-icalendar
+ :version "24.1"
:type 'integer)
(defcustom org-icalendar-combined-name "OrgMode"
@@ -64,6 +65,7 @@ (defcustom org-icalendar-combined-name "OrgMode"
(defcustom org-icalendar-combined-description nil
"Calendar description for the combined iCalendar (all agenda files)."
:group 'org-export-icalendar
+ :version "24.1"
:type 'string)
(defcustom org-icalendar-use-plain-timestamp t
@@ -74,6 +76,7 @@ (defcustom org-icalendar-use-plain-timestamp t
(defcustom org-icalendar-honor-noexport-tag nil
"Non-nil means don't export entries with a tag in `org-export-exclude-tags'."
:group 'org-export-icalendar
+ :version "24.1"
:type 'boolean)
(defcustom org-icalendar-use-deadline '(event-if-not-todo todo-due)
@@ -213,6 +216,7 @@ (defcustom org-icalendar-date-time-format
- \":%Y%m%dT%H%M%SZ\" for time expressed in Universal Time"
:group 'org-export-icalendar
+ :version "24.1"
:type '(choice
(const :tag "Local time" ":%Y%m%dT%H%M%S")
(const :tag "Explicit local time" ";TZID=%Z:%Y%m%dT%H%M%S")
diff --git a/lisp/org-id.el b/lisp/org-id.el
index 0b829d6..55e826f 100644
--- a/lisp/org-id.el
+++ b/lisp/org-id.el
@@ -73,7 +73,7 @@
(require 'org)
(declare-function message-make-fqdn "message" ())
-(declare-function org-pop-to-buffer-same-window
+(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
;;; Customization
@@ -641,7 +641,3 @@ (defun org-id-open (id)
(provide 'org-id)
;;; org-id.el ends here
-
-
-
-
diff --git a/lisp/org-indent.el b/lisp/org-indent.el
index 99a7584..056c22b 100644
--- a/lisp/org-indent.el
+++ b/lisp/org-indent.el
@@ -45,6 +45,7 @@
(declare-function org-inlinetask-get-task-level "org-inlinetask" ())
(declare-function org-inlinetask-in-task-p "org-inlinetask" ())
(declare-function org-list-item-body-column "org-list" (item))
+(defvar org-inlinetask-show-first-star)
(defgroup org-indent nil
"Options concerning dynamic virtual outline indentation."
@@ -293,8 +294,10 @@ (defsubst org-indent-set-line-properties (l w h)
(let ((stars (aref org-indent-stars
(min l org-indent-max-levels))))
(and stars
- (concat org-indent-inlinetask-first-star
- (substring stars 1)))))
+ (if (org-bound-and-true-p org-inlinetask-show-first-star)
+ (concat org-indent-inlinetask-first-star
+ (substring stars 1))
+ stars))))
(h (aref org-indent-stars
(min l org-indent-max-levels)))
(t (aref org-indent-strings
diff --git a/lisp/org-inlinetask.el b/lisp/org-inlinetask.el
index a14e404..dbb9b22 100644
--- a/lisp/org-inlinetask.el
+++ b/lisp/org-inlinetask.el
@@ -90,6 +90,9 @@ (defgroup org-inlinetask nil
(defcustom org-inlinetask-min-level 15
"Minimum level a headline must have before it is treated as an inline task.
+Don't set it to something higher than `29' or clocking will break since this
+is the hardcoded maximum number of stars `org-clock-sum' will work with.
+
It is strongly recommended that you set `org-cycle-max-level' not at all,
or to a number smaller than this one. In fact, when `org-cycle-max-level' is
not set, it will be assumed to be one less than the value of smaller than
@@ -99,6 +102,12 @@ (defcustom org-inlinetask-min-level 15
(const :tag "Off" nil)
(integer)))
+(defcustom org-inlinetask-show-first-star nil
+ "Non-nil means display the first star of an inline task as additional marker.
+When nil, the first star is not shown."
+ :tag "Org Inline Tasks"
+ :group 'org-structure)
+
(defcustom org-inlinetask-export t
"Non-nil means export inline tasks.
When nil, they will not be exported."
@@ -173,6 +182,7 @@ (defcustom org-inlinetask-default-state nil
This should be the state `org-inlinetask-insert-task' should use by
default, or nil of no state should be assigned."
:group 'org-inlinetask
+ :version "24.1"
:type '(choice
(const :tag "No state" nil)
(string :tag "Specific state")))
@@ -431,9 +441,12 @@ (defun org-inlinetask-fontify (limit)
'org-hide
'org-warning)))
(while (re-search-forward re limit t)
- (add-text-properties (match-beginning 1) (match-end 1)
- `(face ,start-face font-lock-fontified t))
- (add-text-properties (match-beginning 2) (match-end 2)
+ (if org-inlinetask-show-first-star
+ (add-text-properties (match-beginning 1) (match-end 1)
+ `(face ,start-face font-lock-fontified t)))
+ (add-text-properties (match-beginning
+ (if org-inlinetask-show-first-star 2 1))
+ (match-end 2)
'(face org-hide font-lock-fontified t))
(add-text-properties (match-beginning 3) (match-end 3)
'(face org-inlinetask font-lock-fontified t)))))
@@ -451,7 +464,7 @@ (defun org-inlinetask-toggle-visibility ()
((= end start))
;; Inlinetask was folded: expand it.
((get-char-property (1+ start) 'invisible)
- (outline-flag-region start end nil))
+ (org-show-entry))
(t (outline-flag-region start end t)))))
(defun org-inlinetask-remove-END-maybe ()
diff --git a/lisp/org-irc.el b/lisp/org-irc.el
index 0dd0512..1074283 100644
--- a/lisp/org-irc.el
+++ b/lisp/org-irc.el
@@ -59,7 +59,7 @@
(declare-function erc-server-buffer "erc" ())
(declare-function erc-get-server-nickname-list "erc" ())
(declare-function erc-cmd-JOIN "erc" (channel &optional key))
-(declare-function org-pop-to-buffer-same-window
+(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
(defvar org-irc-client 'erc
diff --git a/lisp/org-latex.el b/lisp/org-latex.el
index 6d46501..03664b4 100644
--- a/lisp/org-latex.el
+++ b/lisp/org-latex.el
@@ -218,6 +218,7 @@ (defcustom org-export-latex-inputenc-alist nil
will cause \\usepackage[utf8x]{inputenc} to be used for buffers that
are written as utf8 files."
:group 'org-export-latex
+ :version "24.1"
:type '(repeat
(cons
(string :tag "Derived from buffer")
@@ -283,6 +284,7 @@ (defcustom org-export-latex-todo-keyword-markup "\\textbf{%s}"
(defcustom org-export-latex-tag-markup "\\textbf{%s}"
"Markup for tags, as a printf format."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-timestamp-markup "\\textit{%s}"
@@ -293,6 +295,7 @@ (defcustom org-export-latex-timestamp-markup "\\textit{%s}"
(defcustom org-export-latex-timestamp-inactive-markup "\\textit{%s}"
"A printf format string to be applied to inactive time stamps."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-timestamp-keyword-markup "\\texttt{%s}"
@@ -302,11 +305,12 @@ (defcustom org-export-latex-timestamp-keyword-markup "\\texttt{%s}"
(defcustom org-export-latex-href-format "\\href{%s}{%s}"
"A printf format string to be applied to href links.
-The format must contain either two %s instances or just one.
-If it contains two %s instances, the first will be filled with
+The format must contain either two %s instances or just one.
+If it contains two %s instances, the first will be filled with
the link, the second with the link description. If it contains
only one, the %s will be filled with the link."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-hyperref-format "\\hyperref[%s]{%s}"
@@ -314,11 +318,13 @@ (defcustom org-export-latex-hyperref-format "\\hyperref[%s]{%s}"
The format must contain one or two %s instances. The first one
will be filled with the link, the second with its description."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-footnote-separator "\\textsuperscript{,}\\,"
"Text used to separate footnotes."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-quotes
@@ -336,6 +342,7 @@ (defcustom org-export-latex-quotes
for allowed characters before/after the quote, the second
string defines the replacement string for this quote."
:group 'org-export-latex
+ :version "24.1"
:type '(list
(cons :tag "Opening quote"
(string :tag "Regexp for char before")
@@ -361,6 +368,7 @@ (defcustom org-export-latex-table-caption-above t
"When non-nil, the caption is set above the table. When nil,
the caption is set below the table."
:group 'org-export-latex
+ :version "24.1"
:type 'boolean)
(defcustom org-export-latex-tables-column-borders nil
@@ -478,6 +486,7 @@ (defcustom org-export-latex-listings-w-names t
`org-export-latex-listings' variable) can be named in the style
of noweb."
:group 'org-export-latex
+ :version "24.1"
:type 'boolean)
(defcustom org-export-latex-minted-langs
@@ -499,6 +508,7 @@ (defcustom org-export-latex-minted-langs
pygmentize -L lexers
"
:group 'org-export-latex
+ :version "24.1"
:type '(repeat
(list
(symbol :tag "Major mode ")
@@ -522,6 +532,7 @@ (defcustom org-export-latex-listings-options nil
Note that the same options will be applied to blocks of all
languages."
:group 'org-export-latex
+ :version "24.1"
:type '(repeat
(list
(string :tag "Listings option name ")
@@ -545,6 +556,7 @@ (defcustom org-export-latex-minted-options nil
as the start of the minted environment. Note that the same
options will be applied to blocks of all languages."
:group 'org-export-latex
+ :version "24.1"
:type '(repeat
(list
(string :tag "Minted option name ")
@@ -586,11 +598,13 @@ (defcustom org-export-latex-image-default-option "width=.9\\linewidth"
(defcustom org-latex-default-figure-position "htb"
"Default position for latex figures."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-tabular-environment "tabular"
"Default environment used to build tables."
:group 'org-export-latex
+ :version "24.1"
:type 'string)
(defcustom org-export-latex-inline-image-extensions
@@ -667,6 +681,7 @@ (defcustom org-export-pdf-logfiles
'("aux" "idx" "log" "out" "toc" "nav" "snm" "vrb")
"The list of file extensions to consider as LaTeX logfiles."
:group 'org-export-pdf
+ :version "24.1"
:type '(repeat (string :tag "Extension")))
(defcustom org-export-pdf-remove-logfiles t
@@ -2227,7 +2242,7 @@ (defun org-export-latex-links ()
;; a LaTeX issue, but we here implement a work-around anyway.
(setq path (org-export-latex-protect-amp path)
desc (org-export-latex-protect-amp desc)))
- (insert
+ (insert
(if (string-match "%s.*%s" org-export-latex-href-format)
(format org-export-latex-href-format path desc)
(format org-export-latex-href-format path))))
diff --git a/lisp/org-list.el b/lisp/org-list.el
index 2caecff..b865aed 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -215,6 +215,7 @@ (defcustom org-alphabetical-lists nil
26 items will fallback to standard numbering. Alphabetical
counters like \"[@c]\" will be recognized."
:group 'org-plain-lists
+ :version "24.1"
:type 'boolean)
(defcustom org-list-two-spaces-after-bullet-regexp nil
@@ -258,6 +259,7 @@ (defcustom org-list-automatic-rules '((bullet . t)
outdenting a list whose bullet is * to column 0 will
change that bullet to \"-\"."
:group 'org-plain-lists
+ :version "24.1"
:type '(alist :tag "Sets of rules"
:key-type
(choice
@@ -277,6 +279,7 @@ (defcustom org-list-use-circular-motion nil
\\[org-move-item-down], \\[org-next-item] and
\\[org-previous-item]."
:group 'org-plain-lists
+ :version "24.1"
:type 'boolean)
(defvar org-checkbox-statistics-hook nil
@@ -306,6 +309,7 @@ (defcustom org-list-indent-offset 0
By setting this to a small number, usually 1 or 2, one can more
clearly distinguish sub-items in a list."
:group 'org-plain-lists
+ :version "24.1"
:type 'integer)
(defcustom org-list-radio-list-templates
@@ -710,15 +714,15 @@ (defun org-list-struct ()
;; equally indented than BEG-CELL's cdr. Also, store ending
;; position of items in END-LST-2.
(catch 'exit
- (while t
- (let ((ind (+ (or (get-text-property (point) 'original-indentation) 0)
+ (while t
+ (let ((ind (+ (or (get-text-property (point) 'original-indentation) 0)
(org-get-indentation))))
- (cond
- ((>= (point) lim-down)
+ (cond
+ ((>= (point) lim-down)
;; At downward limit: this is de facto the end of the
;; list. Save point as an ending position, and jump to
;; part 3.
- (throw 'exit
+ (throw 'exit
(push (cons 0 (funcall end-before-blank)) end-lst-2)))
;; At a verbatim block, move to its end. Point is at bol
;; and 'org-example property is set by whole lines:
@@ -1015,6 +1019,41 @@ (defun org-list-get-list-type (item struct prevs)
((string-match "[[:alnum:]]" (org-list-get-bullet first struct)) 'ordered)
(t 'unordered))))
+(defun org-list-get-item-number (item struct prevs parents)
+ "Return ITEM's sequence number.
+
+STRUCT is the list structure. PREVS is the alist of previous
+items, as returned by `org-list-prevs-alist'. PARENTS is the
+alist of ancestors, as returned by `org-list-parents-alist'.
+
+Return value is a list of integers. Counters have an impact on
+that value."
+ (let ((get-relative-number
+ (function
+ (lambda (item struct prevs)
+ ;; Return relative sequence number of ITEM in the sub-list
+ ;; it belongs. STRUCT is the list structure. PREVS is
+ ;; the alist of previous items.
+ (let ((seq 0) (pos item) counter)
+ (while (and (not (setq counter (org-list-get-counter pos struct)))
+ (setq pos (org-list-get-prev-item pos struct prevs)))
+ (incf seq))
+ (if (not counter) (1+ seq)
+ (cond
+ ((string-match "[A-Za-z]" counter)
+ (+ (- (string-to-char (upcase (match-string 0 counter))) 64)
+ seq))
+ ((string-match "[0-9]+" counter)
+ (+ (string-to-number (match-string 0 counter)) seq))
+ (t (1+ seq)))))))))
+ ;; Cons each parent relative number into return value (OUT).
+ (let ((out (list (funcall get-relative-number item struct prevs)))
+ (parent item))
+ (while (setq parent (org-list-get-parent parent struct parents))
+ (push (funcall get-relative-number parent struct prevs) out))
+ ;; Return value.
+ out)))
+
\f
;;; Searching
@@ -1239,9 +1278,8 @@ (defun org-list-insert-item (pos struct prevs &optional checkbox after-bullet)
(insert body item-sep)
;; 5. Add new item to STRUCT.
(mapc (lambda (e)
- (let ((p (car e))
- (end (nth 6 e)))
- (cond
+ (let ((p (car e)) (end (nth 6 e)))
+ (cond
;; Before inserted item, positions don't change but
;; an item ending after insertion has its end shifted
;; by SIZE-OFFSET.
@@ -2129,6 +2167,18 @@ (defun org-insert-item (&optional checkbox)
(goto-char (match-end 0))
t)))))
+(defun org-mark-list ()
+ "Mark the current list.
+If this is a sublist, only mark the sublist."
+ (interactive)
+ (let* ((item (org-list-get-item-begin))
+ (struct (org-list-struct))
+ (prevs (org-list-prevs-alist struct))
+ (lbeg (org-list-get-list-begin item struct prevs))
+ (lend (org-list-get-list-end item struct prevs)))
+ (push-mark lend nil t)
+ (goto-char lbeg)))
+
(defun org-list-repair ()
"Fix indentation, bullets and checkboxes is the list at point."
(interactive)
diff --git a/lisp/org-mks.el b/lisp/org-mks.el
index 71405de..95223ef 100644
--- a/lisp/org-mks.el
+++ b/lisp/org-mks.el
@@ -24,7 +24,7 @@
;;; Commentary:
-;;
+;;
;;; Code:
diff --git a/lisp/org-mobile.el b/lisp/org-mobile.el
index cc935a3..48253f7 100644
--- a/lisp/org-mobile.el
+++ b/lisp/org-mobile.el
@@ -37,7 +37,7 @@
(eval-when-compile (require 'cl))
-(declare-function org-pop-to-buffer-same-window
+(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
(defgroup org-mobile nil
@@ -68,6 +68,7 @@ (defcustom org-mobile-files '(org-agenda-files)
(defcustom org-mobile-files-exclude-regexp ""
"A regexp to exclude files from `org-mobile-files'."
:group 'org-mobile
+ :version "24.1"
:type 'regexp)
(defcustom org-mobile-directory ""
@@ -84,6 +85,7 @@ (defcustom org-mobile-use-encryption nil
application. Before turning this on, check of MobileOrg does already
support it - at the time of this writing it did not yet."
:group 'org-mobile
+ :version "24.1"
:type 'boolean)
(defcustom org-mobile-encryption-tempfile "~/orgtmpcrypt"
@@ -91,6 +93,7 @@ (defcustom org-mobile-encryption-tempfile "~/orgtmpcrypt"
This must be local file on your local machine (not on the WebDAV server).
You might want to put this file into a directory where only you have access."
:group 'org-mobile
+ :version "24.1"
:type 'directory)
(defcustom org-mobile-encryption-password ""
@@ -111,6 +114,7 @@ (defcustom org-mobile-encryption-password ""
this variable empty - Org will then ask for the password once per Emacs
session."
:group 'org-mobile
+ :version "24.1"
:type '(string :tag "Password"))
(defvar org-mobile-encryption-password-session nil)
@@ -150,6 +154,7 @@ (defcustom org-mobile-agendas 'all
all the custom agendas and the default ones
list a list of selection key(s) as string."
:group 'org-mobile
+ :version "24.1"
:type '(choice
(const :tag "Default Agendas" default)
(const :tag "Custom Agendas" custom)
@@ -272,7 +277,7 @@ (defun org-mobile-files-alist ()
(t nil)))
org-mobile-files)))
(files (delete
- nil
+ nil
(mapcar (lambda (f)
(unless (and (not (string= org-mobile-files-exclude-regexp ""))
(string-match org-mobile-files-exclude-regexp f))
@@ -295,6 +300,8 @@ (defun org-mobile-files-alist ()
(push (cons file link-name) rtn)))
(nreverse rtn)))
+(defvar org-agenda-filter)
+
;;;###autoload
(defun org-mobile-push ()
"Push the current state of Org affairs to the WebDAV directory.
@@ -303,7 +310,7 @@ (defun org-mobile-push ()
(interactive)
(let ((a-buffer (get-buffer org-agenda-buffer-name)))
(let ((org-agenda-buffer-name "*SUMO*")
- (org-agenda-filter org-agenda-filter)
+ (org-agenda-tag-filter org-agenda-tag-filter)
(org-agenda-redo-command org-agenda-redo-command))
(save-excursion
(save-window-excursion
@@ -499,7 +506,7 @@ (defun org-mobile-copy-agenda-files ()
org-mobile-directory))
(save-excursion
(setq buf (find-file file))
- (when (and (= (point-min) (point-max)))
+ (when (and (= (point-min) (point-max)))
(insert "\n")
(save-buffer)
(when org-mobile-use-encryption
@@ -1099,4 +1106,3 @@ (defun org-mobile-bodies-same-p (a b)
(provide 'org-mobile)
;;; org-mobile.el ends here
-
diff --git a/lisp/org-pcomplete.el b/lisp/org-pcomplete.el
index 7538dac..7a4dc0d 100644
--- a/lisp/org-pcomplete.el
+++ b/lisp/org-pcomplete.el
@@ -50,6 +50,9 @@ (defgroup org-complete nil
:tag "Org"
:group 'org)
+(defvar org-drawer-regexp)
+(defvar org-property-re)
+
(defun org-thing-at-point ()
"Examine the thing at point and let the caller know what it is.
The return value is a string naming the thing at point."
@@ -84,8 +87,16 @@ (defun org-thing-at-point ()
(equal (char-after (point-at-bol)) ?*))
(cons "tag" nil))
((and (equal (char-before beg1) ?:)
- (not (equal (char-after (point-at-bol)) ?*)))
+ (not (equal (char-after (point-at-bol)) ?*))
+ (save-excursion
+ (move-beginning-of-line 1)
+ (skip-chars-backward "[ \t\n]")
+ (or (looking-back org-drawer-regexp)
+ (looking-back org-property-re))))
(cons "prop" nil))
+ ((and (equal (char-before beg1) ?:)
+ (not (equal (char-after (point-at-bol)) ?*)))
+ (cons "drawer" nil))
(t nil))))
(defun org-command-at-point ()
@@ -146,7 +157,7 @@ (defun pcomplete/org-mode/file-option ()
(org-split-string (org-get-current-options) "\n"))
org-additional-option-like-keywords)))))
(substring pcomplete-stub 2)))
-
+
(defvar org-startup-options)
(defun pcomplete/org-mode/file-option/startup ()
"Complete arguments for the #+STARTUP file option."
@@ -239,6 +250,25 @@ (defun pcomplete/org-mode/prop ()
lst))
(substring pcomplete-stub 1)))
+(defvar org-drawers)
+
+(defun pcomplete/org-mode/drawer ()
+ "Complete a drawer name."
+ (let ((spc (save-excursion
+ (move-beginning-of-line 1)
+ (looking-at "^\\([ \t]*\\):")
+ (match-string 1)))
+ (cpllist (mapcar (lambda (x) (concat x ": ")) org-drawers)))
+ (pcomplete-here cpllist
+ (substring pcomplete-stub 1)
+ (unless (or (not (delete
+ nil
+ (mapcar (lambda(x)
+ (string-match (substring pcomplete-stub 1) x))
+ cpllist)))
+ (looking-at "[ \t]*\n.*:END:"))
+ (save-excursion (insert "\n" spc ":END:"))))))
+
(defun pcomplete/org-mode/block-option/src ()
"Complete the arguments of a begin_src block.
Complete a language in the first field, the header arguments and switches."
diff --git a/lisp/org-publish.el b/lisp/org-publish.el
index 057edd7..3590cba 100644
--- a/lisp/org-publish.el
+++ b/lisp/org-publish.el
@@ -248,6 +248,7 @@ (defcustom org-publish-sitemap-sort-files 'alphabetically
You can overwrite this default per project in your
`org-publish-project-alist', using `:sitemap-sort-files'."
:group 'org-publish
+ :version "24.1"
:type 'symbol)
(defcustom org-publish-sitemap-sort-folders 'first
@@ -260,6 +261,7 @@ (defcustom org-publish-sitemap-sort-folders 'first
You can overwrite this default per project in your
`org-publish-project-alist', using `:sitemap-sort-folders'."
:group 'org-publish
+ :version "24.1"
:type 'symbol)
(defcustom org-publish-sitemap-sort-ignore-case nil
@@ -268,12 +270,14 @@ (defcustom org-publish-sitemap-sort-ignore-case nil
You can overwrite this default per project in your
`org-publish-project-alist', using `:sitemap-ignore-case'."
:group 'org-publish
+ :version "24.1"
:type 'boolean)
(defcustom org-publish-sitemap-date-format "%Y-%m-%d"
"Format for `format-time-string' which is used to print a date
in the sitemap."
:group 'org-publish
+ :version "24.1"
:type 'string)
(defcustom org-publish-sitemap-file-entry-format "%t"
@@ -284,6 +288,7 @@ (defcustom org-publish-sitemap-file-entry-format "%t"
%a is the author.
%d is the date formatted using `org-publish-sitemap-date-format'."
:group 'org-publish
+ :version "24.1"
:type 'string)
@@ -368,7 +373,7 @@ (defun org-publish-remove-all-timestamps ()
(declare-function org-publish-delete-dups "org-publish" (list))
(declare-function find-lisp-find-files "find-lisp" (directory regexp))
-(declare-function org-pop-to-buffer-same-window
+(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1031,7 +1036,7 @@ (defun org-publish-index-generate-theindex (directory)
(setq ibuffer (find-file-noselect index-file))
(with-current-buffer ibuffer
(erase-buffer)
- (insert "\n\n#+include: \"theindex.inc\"\n\n")
+ (insert "\n\n#+INCLUDE: \"theindex.inc\"\n\n")
(save-buffer))
(kill-buffer ibuffer)))))
@@ -1127,7 +1132,7 @@ (defun org-publish-cache-file-needs-publishing (filename &optional pub-dir pub-f
(let ((ctime (org-publish-cache-ctime-of-src filename)))
(or (< pstamp ctime)
(when included-files-ctime
- (not (null (delq nil (mapcar (lambda(ct) (< ctime ct))
+ (not (null (delq nil (mapcar (lambda(ct) (< ctime ct))
included-files-ctime))))))))))
(defun org-publish-cache-set-file-property (filename property value &optional project-name)
diff --git a/lisp/org-remember.el b/lisp/org-remember.el
index 854562f..65e92ba 100644
--- a/lisp/org-remember.el
+++ b/lisp/org-remember.el
@@ -39,7 +39,7 @@
(declare-function remember "remember" (&optional initial))
(declare-function remember-buffer-desc "remember" ())
(declare-function remember-finalize "remember" ())
-(declare-function org-pop-to-buffer-same-window
+(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
(defvar remember-save-after-remembering)
@@ -1152,4 +1152,3 @@ (defun org-require-remember ()
(provide 'org-remember)
;;; org-remember.el ends here
-
diff --git a/lisp/org-special-blocks.el b/lisp/org-special-blocks.el
index fca5dd6..fc882a3 100644
--- a/lisp/org-special-blocks.el
+++ b/lisp/org-special-blocks.el
@@ -51,7 +51,7 @@ (defvar org-export-current-backend) ; dynamically bound in org-exp.el
(defun org-special-blocks-make-special-cookies ()
"Adds special cookies when #+begin_foo and #+end_foo tokens are
seen. This is run after a few special cases are taken care of."
- (when (or (eq org-export-current-backend 'html)
+ (when (or (eq org-export-current-backend 'html)
(eq org-export-current-backend 'latex))
(goto-char (point-min))
(while (re-search-forward "^[ \t]*#\\+\\(begin\\|end\\)_\\(.*\\)$" nil t)
diff --git a/lisp/org-src.el b/lisp/org-src.el
index 87fb4f0..e975d97 100644
--- a/lisp/org-src.el
+++ b/lisp/org-src.el
@@ -41,6 +41,7 @@
(declare-function org-at-table.el-p "org" ())
(declare-function org-get-indentation "org" (&optional line))
(declare-function org-switch-to-buffer-other-window "org" (&rest args))
+(declare-function org-strip-protective-commas "org" (beg end))
(declare-function org-pop-to-buffer-same-window
"org-compat" (&optional buffer-or-name norecord label))
@@ -172,6 +173,7 @@ (defcustom org-src-lang-modes
(defvar org-src-mode-map (make-sparse-keymap))
(define-key org-src-mode-map "\C-c'" 'org-edit-src-exit)
+(define-key org-src-mode-map "\C-x\C-s" 'org-edit-src-save)
(defvar org-edit-src-force-single-line nil)
(defvar org-edit-src-from-org-mode nil)
@@ -326,6 +328,7 @@ (defun org-edit-src-code (&optional context code edit-buffer-name)
(if org-src-preserve-indentation col (max 0 (- col total-nindent))))
(org-src-mode)
(set-buffer-modified-p nil)
+ (setq buffer-file-name nil)
(and org-edit-src-persistent-message
(org-set-local 'header-line-format msg))
(let ((edit-prep-func (intern (concat "org-babel-edit-prep:" lang))))
@@ -671,21 +674,33 @@ (defun org-edit-src-exit (&optional context)
(set-window-configuration org-edit-src-saved-temp-window-config)
(setq org-edit-src-saved-temp-window-config nil))))
+(defmacro org-src-in-org-buffer (&rest body)
+ `(let ((p (point)) (m (mark)) (ul buffer-undo-list) msg)
+ (save-window-excursion
+ (org-edit-src-exit 'save)
+ ,@body
+ (setq msg (current-message))
+ (if (eq org-src-window-setup 'other-frame)
+ (let ((org-src-window-setup 'current-window))
+ (org-edit-src-code 'save))
+ (org-edit-src-code 'save)))
+ (setq buffer-undo-list ul)
+ (push-mark m 'nomessage)
+ (goto-char (min p (point-max)))
+ (message (or msg ""))))
+(def-edebug-spec org-src-in-org-buffer (body))
+
(defun org-edit-src-save ()
"Save parent buffer with current state source-code buffer."
(interactive)
- (let ((p (point)) (m (mark)) msg)
- (save-window-excursion
- (org-edit-src-exit 'save)
- (save-buffer)
- (setq msg (current-message))
- (if (eq org-src-window-setup 'other-frame)
- (let ((org-src-window-setup 'current-window))
- (org-edit-src-code 'save))
- (org-edit-src-code 'save)))
- (push-mark m 'nomessage)
- (goto-char (min p (point-max)))
- (message (or msg ""))))
+ (org-src-in-org-buffer (save-buffer)))
+
+(declare-function org-babel-tangle "ob-tangle" (&optional only-this-block target-file lang))
+
+(defun org-src-tangle (arg)
+ "Tangle the parent buffer."
+ (interactive)
+ (org-src-in-org-buffer (org-babel-tangle arg)))
(defun org-src-mode-configure-edit-buffer ()
(when (org-bound-and-true-p org-edit-src-from-org-mode)
@@ -759,6 +774,7 @@ (defcustom org-src-tab-acts-natively nil
"If non-nil, the effect of TAB in a code block is as if it were
issued in the language major mode buffer."
:type 'boolean
+ :version "24.1"
:group 'org-babel)
(defun org-src-native-tab-command-maybe ()
diff --git a/lisp/org-table.el b/lisp/org-table.el
index d9e9c30..39cddab 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -169,11 +169,13 @@ (defcustom org-table-exit-follow-field-mode-when-leaving-table t
except maybe locally in a special file that has mostly tables with long
fields."
:group 'org-table
+ :version "24.1"
:type 'boolean)
(defcustom org-table-fix-formulas-confirm nil
"Whether the user should confirm when Org fixes formulas."
:group 'org-table-editing
+ :version "24.1"
:type '(choice
(const :tag "with yes-or-no" yes-or-no-p)
(const :tag "with y-or-n" y-or-n-p)
@@ -236,6 +238,7 @@ (defcustom org-table-duration-custom-format 'hours
'days, and the output will be a fraction of seconds, minutes or
days."
:group 'org-table-calculation
+ :version "24.1"
:type '(choice (symbol :tag "Seconds" 'seconds)
(symbol :tag "Minutes" 'minutes)
(symbol :tag "Hours " 'hours)
@@ -247,6 +250,7 @@ (defcustom org-table-formula-field-format "%s"
characters. Beware that modifying the display can prevent the
field from being used in another formula."
:group 'org-table-settings
+ :version "24.1"
:type 'string)
(defcustom org-table-formula-evaluate-inline t
@@ -2436,7 +2440,7 @@ (defun org-table-eval-formula (&optional arg equation
(modes (copy-sequence org-calc-default-modes))
(numbers nil) ; was a variable, now fixed default
(keep-empty nil)
- n form form0 formrpl formrg bw fmt x ev orig c lispp literal
+ n form form0 formrpl formrg bw fmt x ev orig c lispp literal
duration duration-output-format)
;; Parse the format string. Since we have a lot of modes, this is
;; a lot of work. However, I think calc still uses most of the time.
@@ -2461,7 +2465,7 @@ (defun org-table-eval-formula (&optional arg equation
duration-output-format nil
fmt (replace-match "" t t fmt)))
(if (string-match "t" fmt)
- (setq duration t
+ (setq duration t
duration-output-format org-table-duration-custom-format
numbers t
fmt (replace-match "" t t fmt)))
@@ -2529,7 +2533,7 @@ (defun org-table-eval-formula (&optional arg equation
;; Insert complex ranges
(while (and (string-match org-table-range-regexp form)
(> (length (match-string 0 form)) 1))
- (setq formrg (save-match-data
+ (setq formrg (save-match-data
(org-table-get-range (match-string 0 form) nil n0)))
(setq formrpl
(save-match-data
@@ -4759,4 +4763,3 @@ (defun org-table-get-remote-range (name-or-id form)
(provide 'org-table)
;;; org-table.el ends here
-
diff --git a/lisp/org-taskjuggler.el b/lisp/org-taskjuggler.el
index 56b6f05..4409013 100644
--- a/lisp/org-taskjuggler.el
+++ b/lisp/org-taskjuggler.el
@@ -166,28 +166,33 @@ (defgroup org-export-taskjuggler nil
(defcustom org-export-taskjuggler-extension ".tjp"
"Extension of TaskJuggler files."
:group 'org-export-taskjuggler
+ :version "24.1"
:type 'string)
(defcustom org-export-taskjuggler-project-tag "taskjuggler_project"
"Tag, property or todo used to find the tree containing all
the tasks for the project."
:group 'org-export-taskjuggler
+ :version "24.1"
:type 'string)
(defcustom org-export-taskjuggler-resource-tag "taskjuggler_resource"
"Tag, property or todo used to find the tree containing all the
resources for the project."
:group 'org-export-taskjuggler
+ :version "24.1"
:type 'string)
(defcustom org-export-taskjuggler-target-version 2.4
"Which version of TaskJuggler the exporter is targeting."
:group 'org-export-taskjuggler
+ :version "24.1"
:type 'number)
(defcustom org-export-taskjuggler-default-project-version "1.0"
"Default version string for the project."
:group 'org-export-taskjuggler
+ :version "24.1"
:type 'string)
(defcustom org-export-taskjuggler-default-project-duration 280
@@ -195,6 +200,7 @@ (defcustom org-export-taskjuggler-default-project-duration 280
in the root node of the task tree, i.e. the tree that has been marked
with `org-export-taskjuggler-project-tag'"
:group 'org-export-taskjuggler
+ :version "24.1"
:type 'integer)
(defcustom org-export-taskjuggler-default-reports
@@ -214,6 +220,7 @@ (defcustom org-export-taskjuggler-default-reports
}")
"Default reports for the project."
:group 'org-export-taskjuggler
+ :version "24.1"
:type '(repeat (string :tag "Report")))
(defcustom org-export-taskjuggler-default-global-properties
@@ -230,6 +237,7 @@ (defcustom org-export-taskjuggler-default-global-properties
The global properties are inserted after the project declaration
but before any resource and task declarations."
:group 'org-export-taskjuggler
+ :version "24.1"
:type '(string :tag "Preamble"))
;;; Hooks
@@ -355,8 +363,8 @@ (defun org-taskjuggler-components ()
(let* ((props (org-entry-properties))
(components (org-heading-components))
(level (nth 1 components))
- (headline
- (replace-regexp-in-string
+ (headline
+ (replace-regexp-in-string
"\"" "\\\"" (nth 4 components) t t)) ; quote double quotes in headlines
(parent-ordered (org-taskjuggler-parent-is-ordered-p)))
(push (cons "level" level) props)
@@ -406,10 +414,10 @@ (defun org-taskjuggler-compute-task-leafiness (tasks)
(successor (car (cdr tasks))))
(cond
;; if a task has no successors it is a leaf
- ((null successor)
+ ((null successor)
(push (cons (cons "leaf-node" t) task) new-list))
;; if the successor has a lower level than task it is a leaf
- ((<= (cdr (assoc "level" successor)) (cdr (assoc "level" task)))
+ ((<= (cdr (assoc "level" successor)) (cdr (assoc "level" task)))
(push (cons (cons "leaf-node" t) task) new-list))
;; otherwise examine the rest of the tasks
(t (push task new-list))))
diff --git a/lisp/org-timer.el b/lisp/org-timer.el
index 44a53ad..a3bde0f 100644
--- a/lisp/org-timer.el
+++ b/lisp/org-timer.el
@@ -53,6 +53,7 @@ (defcustom org-timer-default-timer 0
"The default timer when a timer is set.
When 0, the user is prompted for a value."
:group 'org-time
+ :version "24.1"
:type 'number)
(defvar org-timer-start-hook nil
diff --git a/lisp/org-vm.el b/lisp/org-vm.el
index b6975ff..1698749 100644
--- a/lisp/org-vm.el
+++ b/lisp/org-vm.el
@@ -6,6 +6,10 @@
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;;
+;; Support for IMAP folders added
+;; by Konrad Hinsen <konrad dot hinsen at fastmail dot net>
+;; Requires VM 8.2.0a or later.
+;;
;; This file is part of GNU Emacs.
;;
;; GNU Emacs is free software: you can redistribute it and/or modify
@@ -42,11 +46,17 @@
(declare-function vm-su-message-id "ext:vm-summary" (m))
(declare-function vm-su-subject "ext:vm-summary" (m))
(declare-function vm-summarize "ext:vm-summary" (&optional display raise))
+(declare-function vm-imap-folder-p "ext:vm-save" ())
+(declare-function vm-imap-find-spec-for-buffer "ext:vm-imap" (buffer))
+(declare-function vm-imap-folder-for-spec "ext:vm-imap" (spec))
+(declare-function vm-imap-parse-spec-to-list "ext:vm-imap" (spec))
+(declare-function vm-imap-spec-for-account "ext:vm-imap" (account))
(defvar vm-message-pointer)
(defvar vm-folder-directory)
;; Install the link type
(org-add-link-type "vm" 'org-vm-open)
+(org-add-link-type "vm-imap" 'org-vm-imap-open)
(add-hook 'org-store-link-functions 'org-vm-store-link)
;; Implementation
@@ -61,11 +71,11 @@ (defun org-vm-store-link ()
(save-excursion
(vm-select-folder-buffer)
(let* ((message (car vm-message-pointer))
- (folder buffer-file-name)
- (subject (vm-su-subject message))
+ (subject (vm-su-subject message))
(to (vm-get-header-contents message "To"))
(from (vm-get-header-contents message "From"))
- (message-id (vm-su-message-id message))
+ (message-id (vm-su-message-id message))
+ (link-type (if (vm-imap-folder-p) "vm-imap" "vm"))
(date (vm-get-header-contents message "Date"))
(date-ts (and date (format-time-string
(org-time-stamp-format t)
@@ -73,20 +83,24 @@ (defun org-vm-store-link ()
(date-ts-ia (and date (format-time-string
(org-time-stamp-format t t)
(date-to-time date))))
- desc link)
- (org-store-link-props :type "vm" :from from :to to :subject subject
+ folder desc link)
+ (if (vm-imap-folder-p)
+ (let ((spec (vm-imap-find-spec-for-buffer (current-buffer))))
+ (setq folder (vm-imap-folder-for-spec spec)))
+ (progn
+ (setq folder (abbreviate-file-name buffer-file-name))
+ (if (and vm-folder-directory
+ (string-match (concat "^" (regexp-quote vm-folder-directory))
+ folder))
+ (setq folder (replace-match "" t t folder)))))
+ (setq message-id (org-remove-angle-brackets message-id))
+ (org-store-link-props :type link-type :from from :to to :subject subject
:message-id message-id)
(when date
(org-add-link-props :date date :date-timestamp date-ts
:date-timestamp-inactive date-ts-ia))
- (setq message-id (org-remove-angle-brackets message-id))
- (setq folder (abbreviate-file-name folder))
- (if (and vm-folder-directory
- (string-match (concat "^" (regexp-quote vm-folder-directory))
- folder))
- (setq folder (replace-match "" t t folder)))
(setq desc (org-email-link-description))
- (setq link (org-make-link "vm:" folder "#" message-id))
+ (setq link (org-make-link (concat link-type ":") folder "#" message-id))
(org-add-link-props :link link :description desc)
link))))
@@ -121,21 +135,46 @@ (defun org-vm-follow-link (&optional folder article readonly)
(setq folder (format "/%s@%s:%s" user host file))))))
(when folder
(funcall (cdr (assq 'vm org-link-frame-setup)) folder readonly)
- (sit-for 0.1)
(when article
- (require 'vm-search)
- (vm-select-folder-buffer)
- (widen)
- (let ((case-fold-search t))
- (goto-char (point-min))
- (if (not (re-search-forward
- (concat "^" "message-id: *" (regexp-quote article))))
- (error "Could not find the specified message in this folder"))
- (vm-isearch-update)
- (vm-isearch-narrow)
- (vm-preview-current-message)
- (vm-summarize)))))
+ (org-vm-select-message (org-add-angle-brackets article)))))
+
+(defun org-vm-imap-open (path)
+ "Follow a VM link to an IMAP folder"
+ (require 'vm-imap)
+ (when (string-match "\\([^:]+\\):\\([^#]+\\)#?\\(.+\\)?" path)
+ (let* ((account-name (match-string 1 path))
+ (mailbox-name (match-string 2 path))
+ (message-id (match-string 3 path))
+ (account-spec (vm-imap-parse-spec-to-list
+ (vm-imap-spec-for-account account-name)))
+ (mailbox-spec (mapconcat 'identity
+ (append (butlast account-spec 4)
+ (cons mailbox-name
+ (last account-spec 3)))
+ ":")))
+ (funcall (cdr (assq 'vm-imap org-link-frame-setup))
+ mailbox-spec)
+ (when message-id
+ (org-vm-select-message (org-add-angle-brackets message-id))))))
+
+(defun org-vm-select-message (message-id)
+ "Go to the message with message-id in the current folder."
+ (require 'vm-search)
+ (sit-for 0.1)
+ (vm-select-folder-buffer)
+ (widen)
+ (let ((case-fold-search t))
+ (goto-char (point-min))
+ (if (not (re-search-forward
+ (concat "^" "message-id: *" (regexp-quote message-id))))
+ (error "Could not find the specified message in this folder"))
+ (vm-isearch-update)
+ (vm-isearch-narrow)
+ (vm-preview-current-message)
+ (vm-summarize)))
(provide 'org-vm)
+
+
;;; org-vm.el ends here
diff --git a/lisp/org-wl.el b/lisp/org-wl.el
index 6d23706..8a79ec0 100644
--- a/lisp/org-wl.el
+++ b/lisp/org-wl.el
@@ -46,11 +46,13 @@ (defcustom org-wl-link-to-refile-destination t
(defcustom org-wl-link-remove-filter nil
"Remove filter condition if message is filter folder."
:group 'org-wl
+ :version "24.1"
:type 'boolean)
(defcustom org-wl-shimbun-prefer-web-links nil
"If non-nil create web links for shimbun messages."
:group 'org-wl
+ :version "24.1"
:type 'boolean)
(defcustom org-wl-nntp-prefer-web-links nil
@@ -58,16 +60,19 @@ (defcustom org-wl-nntp-prefer-web-links nil
When folder name contains string \"gmane\" link to gmane,
googlegroups otherwise."
:type 'boolean
+ :version "24.1"
:group 'org-wl)
(defcustom org-wl-disable-folder-check t
"Disable check for new messages when open a link."
:type 'boolean
+ :version "24.1"
:group 'org-wl)
(defcustom org-wl-namazu-default-index nil
"Default namazu search index."
:type 'directory
+ :version "24.1"
:group 'org-wl)
;; Declare external functions and variables
diff --git a/lisp/org.el b/lisp/org.el
index 04c5c62..c22c39d 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1,4 +1,5 @@
;;; org.el --- Outline-based notes management and organizer
+
;; Carstens outline-mode for keeping track of everything.
;; Copyright (C) 2004-2012 Free Software Foundation, Inc.
;;
@@ -75,6 +76,7 @@ (defvar org-table-formula-constants-local nil
(require 'gnus-sum))
(require 'calendar)
+(require 'format-spec)
;; Emacs 22 calendar compatibility: Make sure the new variables are available
(when (fboundp 'defvaralias)
@@ -151,6 +153,7 @@ (defcustom org-babel-load-languages '((emacs-lisp . t))
requirements) is loaded."
:group 'org-babel
:set 'org-babel-do-load-languages
+ :version "24.1"
:type '(alist :tag "Babel Languages"
:key-type
(choice
@@ -167,9 +170,10 @@ (defcustom org-babel-load-languages '((emacs-lisp . t))
(const :tag "Fortran" fortran)
(const :tag "Gnuplot" gnuplot)
(const :tag "Haskell" haskell)
+ (const :tag "IO" io)
(const :tag "Java" java)
(const :tag "Javascript" js)
- (const :tag "Latex" latex)
+ (const :tag "LaTeX" latex)
(const :tag "Ledger" ledger)
(const :tag "Lilypond" lilypond)
(const :tag "Maxima" maxima)
@@ -184,6 +188,7 @@ (defcustom org-babel-load-languages '((emacs-lisp . t))
(const :tag "Python" python)
(const :tag "Ruby" ruby)
(const :tag "Sass" sass)
+ (const :tag "Scala" scala)
(const :tag "Scheme" scheme)
(const :tag "Screen" screen)
(const :tag "Shell Script" sh)
@@ -199,6 +204,7 @@ (defcustom org-clone-delete-id nil
Otherwise they inherit the ID property with a new unique
identifier."
:type 'boolean
+ :version "24.1"
:group 'org-id)
;;; Version
@@ -258,6 +264,7 @@ (defcustom org-load-hook nil
(defcustom org-log-buffer-setup-hook nil
"Hook that is run after an Org log buffer is created."
:group 'org
+ :version "24.1"
:type 'hook)
(defvar org-modules) ; defined below
@@ -427,6 +434,7 @@ (defcustom org-loop-over-headlines-in-active-region nil
(const :tag "All headlines in active region" t)
(const :tag "In active region, headlines at the same level than the first one" 'start-level)
(string :tag "Tags/Property/Todo matcher"))
+ :version "24.1"
:group 'org-todo
:group 'org-archive)
@@ -495,6 +503,7 @@ (defcustom org-use-sub-superscripts t
This option can also be set with the +OPTIONS line, e.g. \"^:nil\"."
:group 'org-startup
:group 'org-export-translation
+ :version "24.1"
:type '(choice
(const :tag "Always interpret" t)
(const :tag "Only with braces" {})
@@ -511,6 +520,7 @@ (defcustom org-startup-with-beamer-mode nil
#+STARTUP: beamer"
:group 'org-startup
+ :version "24.1"
:type 'boolean)
(defcustom org-startup-align-all-tables nil
@@ -531,6 +541,7 @@ (defcustom org-startup-with-inline-images nil
#+STARTUP: inlineimages
#+STARTUP: noinlineimages"
:group 'org-startup
+ :version "24.1"
:type 'boolean)
(defcustom org-insert-mode-line-in-empty-file nil
@@ -1015,23 +1026,25 @@ (defcustom org-special-ctrl-a/e nil
"Non-nil means `C-a' and `C-e' behave specially in headlines and items.
When t, `C-a' will bring back the cursor to the beginning of the
-headline text, i.e. after the stars and after a possible TODO keyword.
-In an item, this will be the position after the bullet.
-When the cursor is already at that position, another `C-a' will bring
-it to the beginning of the line.
-
-`C-e' will jump to the end of the headline, ignoring the presence of tags
-in the headline. A second `C-e' will then jump to the true end of the
-line, after any tags. This also means that, when this variable is
-non-nil, `C-e' also will never jump beyond the end of the heading of a
-folded section, i.e. not after the ellipses.
-
-When set to the symbol `reversed', the first `C-a' or `C-e' works normally,
-going to the true line boundary first. Only a directly following, identical
-keypress will bring the cursor to the special positions.
-
-This may also be a cons cell where the behavior for `C-a' and `C-e' is
-set separately."
+headline text, i.e. after the stars and after a possible TODO
+keyword. In an item, this will be the position after bullet and
+check-box, if any. When the cursor is already at that position,
+another `C-a' will bring it to the beginning of the line.
+
+`C-e' will jump to the end of the headline, ignoring the presence
+of tags in the headline. A second `C-e' will then jump to the
+true end of the line, after any tags. This also means that, when
+this variable is non-nil, `C-e' also will never jump beyond the
+end of the heading of a folded section, i.e. not after the
+ellipses.
+
+When set to the symbol `reversed', the first `C-a' or `C-e' works
+normally, going to the true line boundary first. Only a directly
+following, identical keypress will bring the cursor to the
+special positions.
+
+This may also be a cons cell where the behavior for `C-a' and
+`C-e' is set separately."
:group 'org-edit-structure
:type '(choice
(const :tag "off" nil)
@@ -1068,6 +1081,7 @@ (defcustom org-ctrl-k-protect-subtree nil
Any other non-nil value will result in a query to the user, if it is
OK to kill that hidden subtree. When nil, kill without remorse."
:group 'org-edit-structure
+ :version "24.1"
:type '(choice
(const :tag "Do not protect hidden subtrees" nil)
(const :tag "Protect hidden subtrees with a security query" t)
@@ -1088,6 +1102,7 @@ (defcustom org-catch-invisible-edits nil
allows insertion and backward-delete right before ellipses.
FIXME: maybe in this case we should not even show?"
:group 'org-edit-structure
+ :version "24.1"
:type '(choice
(const :tag "Do not check" nil)
(const :tag "Throw error when trying to edit" error)
@@ -1541,6 +1556,7 @@ (defcustom org-link-search-must-match-exact-headline 'query-to-create
When nil, the link search tries to match a phrase with all words
in the search text."
:group 'org-link-follow
+ :version "24.1"
:type '(choice
(const :tag "Use fuzzy text search" nil)
(const :tag "Match only exact headline" t)
@@ -1549,6 +1565,7 @@ (defcustom org-link-search-must-match-exact-headline 'query-to-create
(defcustom org-link-frame-setup
'((vm . vm-visit-folder-other-frame)
+ (vm-imap . vm-visit-imap-folder-other-frame)
(gnus . org-gnus-no-new-news)
(file . find-file-other-window)
(wl . wl-other-frame))
@@ -1660,6 +1677,7 @@ (defcustom org-confirm-shell-link-function 'yes-or-no-p
(defcustom org-confirm-shell-link-not-regexp ""
"A regexp to skip confirmation for shell links."
:group 'org-link-follow
+ :version "24.1"
:type 'regexp)
(defcustom org-confirm-elisp-link-function 'yes-or-no-p
@@ -1685,6 +1703,7 @@ (defcustom org-confirm-elisp-link-function 'yes-or-no-p
(defcustom org-confirm-elisp-link-not-regexp ""
"A regexp to skip confirmation for Elisp links."
:group 'org-link-follow
+ :version "24.1"
:type 'regexp)
(defconst org-file-apps-defaults-gnu
@@ -1907,6 +1926,7 @@ (defcustom org-log-refile nil
will temporarily be changed to `time'."
:group 'org-refile
:group 'org-progress
+ :version "24.1"
:type '(choice
(const :tag "No logging" nil)
(const :tag "Record timestamp" time)
@@ -1982,6 +2002,7 @@ (defcustom org-refile-use-cache nil
you need to clear the cache manually by pressing `C-0 C-c C-w' or, if you
find that easier, `C-u C-u C-u C-c C-w'."
:group 'org-refile
+ :version "24.1"
:type 'boolean)
(defcustom org-refile-use-outline-path nil
@@ -2037,6 +2058,7 @@ (defcustom org-refile-active-region-within-subtree nil
do so sometimes: in that case, the first line of the region is
converted to a headline before refiling."
:group 'org-refile
+ :version "24.1"
:type 'boolean)
(defgroup org-todo nil
@@ -2513,6 +2535,7 @@ (defcustom org-todo-repeat-to-state nil
in a TODO_TYP set. But you can specify another task here.
alternatively, set the :REPEAT_TO_STATE: property of the entry."
:group 'org-todo
+ :version "24.1"
:type '(choice (const :tag "Head of sequence" nil)
(string :tag "Specific state")))
@@ -2597,6 +2620,7 @@ (defcustom org-get-priority-function nil
The user can set a different function here, which should take a string
as an argument and return the numeric priority."
:group 'org-priorities
+ :version "24.1"
:type 'function)
(defgroup org-time nil
@@ -2738,6 +2762,7 @@ (defcustom org-agenda-jump-prefer-future 'org-read-date-prefer-future
This may t or nil, or the symbol `org-read-date-prefer-future'."
:group 'org-agenda
:group 'org-time
+ :version "24.1"
:type '(choice
(const :tag "Use org-read-date-prefer-future"
org-read-date-prefer-future)
@@ -2772,6 +2797,7 @@ (defcustom org-read-date-force-compatible-dates t
A workaround for this problem is to use diary sexp dates for time
stamps outside of this range."
:group 'org-time
+ :version "24.1"
:type 'boolean)
(defcustom org-read-date-display-live t
@@ -2819,6 +2845,7 @@ (defcustom org-use-effective-time nil
\"effective time\" of any timestamps between midnight and 8am will be
23:59 of the previous day."
:group 'boolean
+ :version "24.1"
:type 'integer)
(defcustom org-edit-timestamp-down-means-later nil
@@ -2892,6 +2919,7 @@ (defcustom org-complete-tags-always-offer-all-agenda-tags nil
'org-complete-tags-always-offer-all-agenda-tags)
t)))"
:group 'org-tags
+ :version "24.1"
:type 'boolean)
(defvar org-file-tags nil
@@ -3060,6 +3088,7 @@ (defcustom org-properties-postprocess-alist nil
(org-entry-get (point) \"Effort\"))))
(org-minutes-to-hh:mm-string (- effort clocksum))))))"
:group 'org-properties
+ :version "24.1"
:type 'alist)
(defcustom org-use-property-inheritance nil
@@ -3331,7 +3360,9 @@ (defcustom org-format-latex-signal-error t
"Non-nil means signal an error when image creation of LaTeX snippets fails.
When nil, just push out a message."
:group 'org-latex
+ :version "24.1"
:type 'boolean)
+
(defcustom org-latex-to-mathml-jar-file nil
"Value of\"%j\" in `org-latex-to-mathml-convert-command'.
Use this to specify additional executable file say a jar file.
@@ -3339,6 +3370,7 @@ (defcustom org-latex-to-mathml-jar-file nil
When using MathToWeb as the converter, specify the full-path to
your mathtoweb.jar file."
:group 'org-latex
+ :version "24.1"
:type '(choice
(const :tag "None" nil)
(file :tag "JAR file" :must-match t)))
@@ -3356,6 +3388,7 @@ (defcustom org-latex-to-mathml-convert-command nil
When using MathToWeb as the converter, set this to
\"java -jar %j -unicode -force -df %o %I\"."
:group 'org-latex
+ :version "24.1"
:type '(choice
(const :tag "None" nil)
(string :tag "\nShell command")))
@@ -3465,6 +3498,7 @@ (defcustom org-export-latex-default-packages-alist
:group 'org-export-latex
:set 'org-set-packages-alist
:get 'org-get-packages-alist
+ :version "24.1"
:type '(repeat
(choice
(list :tag "options/package pair"
@@ -3530,6 +3564,7 @@ (defcustom org-hidden-keywords nil
For example, a value '(title) for this list will make the document's title
appear in the buffer without the initial #+TITLE: keyword."
:group 'org-appearance
+ :version "24.1"
:type '(set (const :tag "#+AUTHOR" author)
(const :tag "#+DATE" date)
(const :tag "#+EMAIL" email)
@@ -3570,11 +3605,13 @@ (defcustom org-pretty-entities nil
"Non-nil means show entities as UTF8 characters.
When nil, the \\name form remains in the buffer."
:group 'org-appearance
+ :version "24.1"
:type 'boolean)
(defcustom org-pretty-entities-include-sub-superscripts t
"Non-nil means, pretty entity display includes formatting sub/superscripts."
:group 'org-appearance
+ :version "24.1"
:type 'boolean)
(defvar org-emph-re nil
@@ -4544,7 +4581,7 @@ (defun org-set-regexps-and-options ()
(mapcar (lambda (x) (org-split-string x ":"))
(org-split-string value)))))))
((equal key "DRAWERS")
- (setq drawers (org-split-string value splitre)))
+ (setq drawers (delete-dups (append org-drawers (org-split-string value splitre)))))
((equal key "CONSTANTS")
(setq const (append const (org-split-string value splitre))))
((equal key "STARTUP")
@@ -4894,6 +4931,8 @@ (defconst org-heading-regexp "^\\(\\*+\\)\\(?: +\\(.*?\\)\\)?[ \t]*$"
"Matches an headline, putting stars and text into groups.
Stars are put in group 1 and the trimmed body in group 2.")
+(defvar bidi-paragraph-direction)
+
;;;###autoload
(define-derived-mode org-mode outline-mode "Org"
"Outline-based notes management and organizer, alias
@@ -5355,6 +5394,7 @@ (defun org-activate-code (limit)
(defcustom org-src-fontify-natively nil
"When non-nil, fontify code in code blocks."
:type 'boolean
+ :version "24.1"
:group 'org-appearance
:group 'org-babel)
@@ -6223,34 +6263,36 @@ (defun org-cycle (&optional arg)
(defun org-cycle-internal-global ()
"Do the global cycling action."
- (cond
- ((and (eq last-command this-command)
- (eq org-cycle-global-status 'overview))
- ;; We just created the overview - now do table of contents
- ;; This can be slow in very large buffers, so indicate action
- (run-hook-with-args 'org-pre-cycle-hook 'contents)
- (message "CONTENTS...")
- (org-content)
- (message "CONTENTS...done")
- (setq org-cycle-global-status 'contents)
- (run-hook-with-args 'org-cycle-hook 'contents))
-
- ((and (eq last-command this-command)
- (eq org-cycle-global-status 'contents))
- ;; We just showed the table of contents - now show everything
- (run-hook-with-args 'org-pre-cycle-hook 'all)
- (show-all)
- (message "SHOW ALL")
- (setq org-cycle-global-status 'all)
- (run-hook-with-args 'org-cycle-hook 'all))
+ ;; Hack to avoid display of messages for .org attachments in Gnus
+ (let ((ga (string-match "\\*fontification" (buffer-name))))
+ (cond
+ ((and (eq last-command this-command)
+ (eq org-cycle-global-status 'overview))
+ ;; We just created the overview - now do table of contents
+ ;; This can be slow in very large buffers, so indicate action
+ (run-hook-with-args 'org-pre-cycle-hook 'contents)
+ (unless ga (message "CONTENTS..."))
+ (org-content)
+ (unless ga (message "CONTENTS...done"))
+ (setq org-cycle-global-status 'contents)
+ (run-hook-with-args 'org-cycle-hook 'contents))
+
+ ((and (eq last-command this-command)
+ (eq org-cycle-global-status 'contents))
+ ;; We just showed the table of contents - now show everything
+ (run-hook-with-args 'org-pre-cycle-hook 'all)
+ (show-all)
+ (unless ga (message "SHOW ALL"))
+ (setq org-cycle-global-status 'all)
+ (run-hook-with-args 'org-cycle-hook 'all))
- (t
- ;; Default action: go to overview
- (run-hook-with-args 'org-pre-cycle-hook 'overview)
- (org-overview)
- (message "OVERVIEW")
- (setq org-cycle-global-status 'overview)
- (run-hook-with-args 'org-cycle-hook 'overview))))
+ (t
+ ;; Default action: go to overview
+ (run-hook-with-args 'org-pre-cycle-hook 'overview)
+ (org-overview)
+ (unless ga (message "OVERVIEW"))
+ (setq org-cycle-global-status 'overview)
+ (run-hook-with-args 'org-cycle-hook 'overview)))))
(defun org-cycle-internal-local ()
"Do the local cycling action."
@@ -9861,6 +9903,22 @@ (defun org-link-search (s &optional type avoid-pos stealth)
pos (match-beginning 0))))
;; There is an exact target for this
(goto-char pos))
+ ((save-excursion
+ (goto-char (point-min))
+ (and
+ (re-search-forward
+ (format "^[ \t]*#\\+TARGET: %s" (regexp-quote s0)) nil t)
+ (setq type 'dedicated pos (match-beginning 0))))
+ ;; Found an invisible target.
+ (goto-char pos))
+ ((save-excursion
+ (goto-char (point-min))
+ (and
+ (re-search-forward
+ (format "^[ \t]*#\\+NAME: %s" (regexp-quote s0)) nil t)
+ (setq type 'dedicated pos (match-beginning 0))))
+ ;; Found an element with a matching #+name affiliated keyword.
+ (goto-char pos))
((and (string-match "^(\\(.*\\))$" s0)
(save-excursion
(goto-char (point-min))
@@ -11042,11 +11100,11 @@ (defconst org-additional-option-like-keywords
(defcustom org-structure-template-alist
'(
- ("s" "#+begin_src ?\n\n#+end_src"
+ ("s" "#+BEGIN_SRC ?\n\n#+END_SRC"
"<src lang=\"?\">\n\n</src>")
- ("e" "#+begin_example\n?\n#+end_example"
+ ("e" "#+BEGIN_EXAMPLE\n?\n#+END_EXAMPLE"
"<example>\n?\n</example>")
- ("q" "#+begin_quote\n?\n#+end_quote"
+ ("q" "#+BEGIN_QUOTE\n?\n#+END_QUOTE"
"<quote>\n?\n</quote>")
("v" "#+BEGIN_VERSE\n?\n#+END_VERSE"
"<verse>\n?\n</verse>")
@@ -11054,17 +11112,17 @@ (defcustom org-structure-template-alist
"<center>\n?\n</center>")
("l" "#+BEGIN_LaTeX\n?\n#+END_LaTeX"
"<literal style=\"latex\">\n?\n</literal>")
- ("L" "#+latex: "
+ ("L" "#+LaTeX: "
"<literal style=\"latex\">?</literal>")
- ("h" "#+begin_html\n?\n#+end_html"
+ ("h" "#+BEGIN_HTML\n?\n#+END_HTML"
"<literal style=\"html\">\n?\n</literal>")
- ("H" "#+html: "
+ ("H" "#+HTML: "
"<literal style=\"html\">?</literal>")
- ("a" "#+begin_ascii\n?\n#+end_ascii")
- ("A" "#+ascii: ")
- ("i" "#+index: ?"
- "#+index: ?")
- ("I" "#+include %file ?"
+ ("a" "#+BEGIN_ASCII\n?\n#+END_ASCII")
+ ("A" "#+ASCII: ")
+ ("i" "#+INDEX: ?"
+ "#+INDEX: ?")
+ ("I" "#+INCLUDE %file ?"
"<include file=%file markup=\"?\">")
)
"Structure completion elements.
@@ -11076,8 +11134,7 @@ (defcustom org-structure-template-alist
There are two templates for each key, the first uses the original Org syntax,
the second uses Emacs Muse-like syntax tags. These Muse-like tags become
the default when the /org-mtags.el/ module has been loaded. See also the
-variable `org-mtags-prefer-muse-templates'.
-This is an experimental feature, it is undecided if it is going to stay in."
+variable `org-mtags-prefer-muse-templates'."
:group 'org-completion
:type '(repeat
(string :tag "Key")
@@ -12852,7 +12909,8 @@ (defun org-scan-tags (action matcher &optional todo-only start-level)
;; eval matcher only when the todo condition is OK
(and (or (not todo-only) (member todo org-not-done-keywords))
- (let ((case-fold-search t)) (eval matcher)))
+ (let ((case-fold-search t) (org-trust-scanner-tags t))
+ (eval matcher)))
;; Call the skipper, but return t if it does not skip,
;; so that the `and' form continues evaluating
@@ -12891,8 +12949,7 @@ (defun org-scan-tags (action matcher &optional todo-only start-level)
(make-string (1- level) ?.) "")
(org-get-heading))
category
- tags-list
- )
+ tags-list)
priority (org-get-priority txt))
(goto-char lspos)
(setq marker (org-agenda-new-marker))
@@ -13292,7 +13349,7 @@ (defun org-align-tags-here (to-col)
(defun org-set-tags-command (&optional arg just-align)
"Call the set-tags command for the current entry."
(interactive "P")
- (if (org-at-heading-p)
+ (if (or (org-at-heading-p) (and arg (org-before-first-heading-p)))
(org-set-tags arg just-align)
(save-excursion
(org-back-to-heading t)
@@ -13346,7 +13403,7 @@ (defun org-set-tags (&optional arg just-align)
With prefix ARG, realign all tags in headings in the current buffer."
(interactive "P")
(let* ((re org-outline-regexp-bol)
- (current (org-get-tags-string))
+ (current (unless arg (org-get-tags-string)))
(col (current-column))
(org-setting-tags t)
table current-tags inherited-tags ; computed below when needed
@@ -14418,11 +14475,10 @@ (defun org-property-values (key)
(defun org-insert-property-drawer ()
"Insert a property drawer into the current entry."
- (interactive)
(org-back-to-heading t)
(looking-at org-outline-regexp)
(let ((indent (if org-adapt-indentation
- (- (match-end 0)(match-beginning 0))
+ (- (match-end 0) (match-beginning 0))
0))
(beg (point))
(re (concat "^[ \t]*" org-keyword-time-regexp))
@@ -14456,6 +14512,70 @@ (defun org-insert-property-drawer ()
(hide-entry))
(org-flag-drawer t))))
+(defun org-insert-drawer (&optional arg drawer)
+ "Insert a drawer at point.
+
+Optional argument DRAWER, when non-nil, is a string representing
+drawer's name. Otherwise, the user is prompted for a name.
+
+If a region is active, insert the drawer around that region
+instead.
+
+Point is left between drawer's boundaries."
+ (interactive "P")
+ (let* ((logbook (if (stringp org-log-into-drawer) org-log-into-drawer
+ "LOGBOOK"))
+ ;; SYSTEM-DRAWERS is a list of drawer names that are used
+ ;; internally by Org. They are meant to be inserted
+ ;; automatically.
+ (system-drawers `("CLOCK" ,logbook "PROPERTIES"))
+ ;; Remove system drawers from list. Note: For some reason,
+ ;; `org-completing-read' ignores the predicate while
+ ;; `completing-read' handles it fine.
+ (drawer (if arg "PROPERTIES"
+ (or drawer
+ (completing-read
+ "Drawer: " org-drawers
+ (lambda (d) (not (member d system-drawers))))))))
+ (cond
+ ;; With C-u, fall back on `org-insert-property-drawer'
+ (arg (org-insert-property-drawer))
+ ;; With an active region, insert a drawer at point.
+ ((not (org-region-active-p))
+ (progn
+ (unless (bolp) (insert "\n"))
+ (insert (format ":%s:\n\n:END:\n" drawer))
+ (forward-line -2)))
+ ;; Otherwise, insert the drawer at point
+ (t
+ (let ((rbeg (region-beginning))
+ (rend (copy-marker (region-end))))
+ (unwind-protect
+ (progn
+ (goto-char rbeg)
+ (beginning-of-line)
+ (when (save-excursion
+ (re-search-forward org-outline-regexp-bol rend t))
+ (error "Drawers cannot contain headlines"))
+ ;; Position point at the beginning of the first
+ ;; non-blank line in region. Insert drawer's opening
+ ;; there, then indent it.
+ (org-skip-whitespace)
+ (beginning-of-line)
+ (insert ":" drawer ":\n")
+ (forward-line -1)
+ (indent-for-tab-command)
+ ;; Move point to the beginning of the first blank line
+ ;; after the last non-blank line in region. Insert
+ ;; drawer's closing, then indent it.
+ (goto-char rend)
+ (skip-chars-backward " \r\t\n")
+ (insert "\n:END:")
+ (indent-for-tab-command)
+ (unless (eolp) (insert "\n")))
+ ;; Clear marker, whatever the outcome of insertion is.
+ (set-marker rend nil)))))))
+
(defvar org-property-set-functions-alist nil
"Property set function alist.
Each entry should have the following format:
@@ -14804,11 +14924,11 @@ (defun org-time-stamp (arg &optional inactive)
(insert "--")
(setq time (let ((this-command this-command))
(org-read-date arg 'totime nil nil
- default-time default-input)))
+ default-time default-input inactive)))
(org-insert-time-stamp time (or org-time-was-given arg) inactive))
((org-at-timestamp-p t)
(setq time (let ((this-command this-command))
- (org-read-date arg 'totime nil nil default-time default-input)))
+ (org-read-date arg 'totime nil nil default-time default-input inactive)))
(when (org-at-timestamp-p t) ; just to get the match data
; (setq inactive (eq (char-after (match-beginning 0)) ?\[))
(replace-match "")
@@ -14823,7 +14943,7 @@ (defun org-time-stamp (arg &optional inactive)
(message "Timestamp updated"))
(t
(setq time (let ((this-command this-command))
- (org-read-date arg 'totime nil nil default-time default-input)))
+ (org-read-date arg 'totime nil nil default-time default-input inactive)))
(org-insert-time-stamp time (or org-time-was-given arg) inactive
nil nil (list org-end-time-was-given))))))
@@ -14869,9 +14989,10 @@ (defvar org-read-date-history nil)
(defvar org-read-date-final-answer nil)
(defvar org-read-date-analyze-futurep nil)
(defvar org-read-date-analyze-forced-year nil)
+(defvar org-read-date-inactive)
(defun org-read-date (&optional with-time to-time from-string prompt
- default-time default-input)
+ default-time default-input inactive)
"Read a date, possibly a time, and make things smooth for the user.
The prompt will suggest to enter an ISO date, but you can also enter anything
which will at least partially be understood by `parse-time-string'.
@@ -15020,6 +15141,7 @@ (defun org-read-date (&optional with-time to-time from-string prompt
(unwind-protect
(progn
(use-local-map map)
+ (setq org-read-date-inactive inactive)
(add-hook 'post-command-hook 'org-read-date-display)
(setq org-ans0 (read-string prompt default-input
'org-read-date-history nil))
@@ -15090,7 +15212,9 @@ (defun org-read-date-display ()
(and (boundp 'org-time-was-given) org-time-was-given))
(cdr fmts)
(car fmts)))
- (txt (concat "=> " (format-time-string fmt (apply 'encode-time f)))))
+ (txt (format-time-string fmt (apply 'encode-time f)))
+ (txt (if org-read-date-inactive (concat "[" (substring txt 1 -1) "]") txt))
+ (txt (concat "=> " txt)))
(when (and org-end-time-was-given
(string-match org-plain-time-of-day-regexp txt))
(setq txt (concat (substring txt 0 (match-end 0)) "-"
@@ -16176,6 +16300,7 @@ (defcustom org-effort-durations
For example, if the value of this variable is ((\"hours\" . 60)), then an
effort string \"2hours\" is equivalent to 120 minutes."
:group 'org-agenda
+ :version "24.1"
:type '(alist :key-type (string :tag "Modifier")
:value-type (number :tag "Minutes")))
@@ -16886,6 +17011,8 @@ (defun org-format-latex (prefix &optional dir overlays msg at
(error "Unknown conversion type %s for latex fragments"
processing-type)))))))))
+(declare-function format-spec "format-spec" (format specification))
+
(defun org-create-math-formula (latex-frag &optional mathml-file)
"Convert LATEX-FRAG to MathML and store it in MATHML-FILE.
Use `org-latex-to-mathml-convert-command'. If the conversion is
@@ -17328,6 +17455,7 @@ (defun org-remove-inline-images ()
(org-defkey org-mode-map "\C-c$" 'org-archive-subtree)
(org-defkey org-mode-map "\C-c\C-x\C-s" 'org-advertized-archive-subtree)
(org-defkey org-mode-map "\C-c\C-x\C-a" 'org-archive-subtree-default)
+(org-defkey org-mode-map "\C-c\C-xd" 'org-insert-drawer)
(org-defkey org-mode-map "\C-c\C-xa" 'org-toggle-archive-tag)
(org-defkey org-mode-map "\C-c\C-xA" 'org-archive-to-archive-sibling)
(org-defkey org-mode-map "\C-c\C-xb" 'org-tree-to-indirect-buffer)
@@ -17392,6 +17520,7 @@ (defun org-remove-inline-images ()
(org-defkey org-mode-map "\C-c\C-x\C-mg" 'org-mobile-pull)
(org-defkey org-mode-map "\C-c\C-x\C-mp" 'org-mobile-push)
(org-defkey org-mode-map "\C-c@" 'org-mark-subtree)
+(org-defkey org-mode-map "\C-c\C-@" 'org-mark-list)
(org-defkey org-mode-map [?\C-c (control ?*)] 'org-list-make-subtree)
;;(org-defkey org-mode-map [?\C-c (control ?-)] 'org-list-make-list-from-subtree)
@@ -17563,6 +17692,7 @@ (defcustom org-speed-command-hook
Set `org-use-speed-commands' to non-nil value to enable this
hook. The default setting is `org-speed-command-default-hook'."
:group 'org-structure
+ :version "24.1"
:type 'hook)
(defun org-self-insert-command (N)
@@ -17996,14 +18126,16 @@ (defun org-metaleft (&optional arg)
(t (call-interactively 'backward-word))))
(defun org-metaright (&optional arg)
- "Demote subtree or move table column to right.
-Calls `org-do-demote' or `org-table-move-column', depending on context.
+ "Demote a subtree, a list item or move table column to right.
+In front of a drawer or a block keyword, indent it correctly.
With no specific context, calls the Emacs default `forward-word'.
See the individual commands for more information."
(interactive "P")
(cond
((run-hook-with-args-until-success 'org-metaright-hook))
((org-at-table-p) (call-interactively 'org-table-move-column))
+ ((org-at-drawer-p) (call-interactively 'org-indent-drawer))
+ ((org-at-block-p) (call-interactively 'org-indent-block))
((org-with-limited-levels
(or (org-at-heading-p)
(and (org-region-active-p)
@@ -18526,7 +18658,8 @@ (defun org-return (&optional indent)
See the individual commands for more information."
(interactive)
(cond
- ((bobp) (if indent (newline-and-indent) (newline)))
+ ((or (bobp) (org-in-src-block-p))
+ (if indent (newline-and-indent) (newline)))
((org-at-table-p)
(org-table-justify-field-maybe)
(call-interactively 'org-table-next-row))
@@ -18821,6 +18954,8 @@ (defun org-meta-return (&optional arg)
(interactive "P")
(cond
((run-hook-with-args-until-success 'org-metareturn-hook))
+ ((or (org-at-drawer-p) (org-at-property-p))
+ (newline-and-indent))
((org-at-table-p)
(call-interactively 'org-table-wrap-region))
(t (call-interactively 'org-insert-heading))))
@@ -19547,6 +19682,14 @@ (defun org-uuidgen-p (s)
"Is S an ID created by UUIDGEN?"
(string-match "\\`[0-9a-f]\\{8\\}-[0-9a-f]\\{4\\}-[0-9a-f]\\{4\\}-[0-9a-f]\\{4\\}-[0-9a-f]\\{12\\}\\'" (downcase s)))
+(defun org-in-src-block-p nil
+ "Whether point is in a code source block."
+ (let (ov)
+ (when (setq ov (overlays-at (point)))
+ (memq 'org-block-background
+ (overlay-properties
+ (car ov))))))
+
(defun org-context ()
"Return a list of contexts of the current cursor position.
If several contexts apply, all are returned.
@@ -19565,8 +19708,10 @@ (defun org-context ()
:table in an org-mode table
:table-special on a special filed in a table
:table-table in a table.el table
+:clocktable in a clocktable
+:src-block in a source block
:link on a hyperlink
-:keyword on a keyword: SCHEDULED, DEADLINE, CLOSE,COMMENT, QUOTE.
+:keyword on a keyword: SCHEDULED, DEADLINE, CLOSE, COMMENT, QUOTE.
:target on a <<target>>
:radio-target on a <<<radio-target>>>
:latex-fragment on a LaTeX fragment
@@ -19577,6 +19722,7 @@ (defun org-context ()
and :keyword."
(let* ((f (get-text-property (point) 'face))
(faces (if (listp f) f (list f)))
+ (case-fold-search t)
(p (point)) clist o)
;; First the large context
(cond
@@ -19611,6 +19757,23 @@ (defun org-context ()
(push (list :table-table) clist)))
(goto-char p)
+ ;; New the "medium" contexts: clocktables, source blocks
+ (cond ((org-in-clocktable-p)
+ (push (list :clocktable
+ (and (or (looking-at "#\\+BEGIN: clocktable")
+ (search-backward "#+BEGIN: clocktable" nil t))
+ (match-beginning 0))
+ (and (re-search-forward "#\\+END:?" nil t)
+ (match-end 0))) clist))
+ ((org-in-src-block-p)
+ (push (list :src-block
+ (and (or (looking-at "#\\+BEGIN_SRC")
+ (search-backward "#+BEGIN_SRC" nil t))
+ (match-beginning 0))
+ (and (search-forward "#+END_SRC" nil t)
+ (match-beginning 0))) clist)))
+ (goto-char p)
+
;; Now the small context
(cond
((org-at-timestamp-p)
@@ -20147,6 +20310,47 @@ (defun org-indent-line-function ()
t t))
(org-move-to-column column)))
+(defun org-indent-drawer ()
+ "Indent the drawer at point."
+ (interactive)
+ (let ((p (point))
+ (e (and (save-excursion (re-search-forward ":END:" nil t))
+ (match-end 0)))
+ (folded
+ (save-excursion
+ (end-of-line)
+ (when (overlays-at (point))
+ (member 'invisible (overlay-properties
+ (car (overlays-at (point)))))))))
+ (when folded (org-cycle))
+ (indent-for-tab-command)
+ (while (and (move-beginning-of-line 2) (< (point) e))
+ (indent-for-tab-command))
+ (goto-char p)
+ (when folded (org-cycle)))
+ (message "Drawer at point indented"))
+
+(defun org-indent-block ()
+ "Indent the block at point."
+ (interactive)
+ (let ((p (point))
+ (case-fold-search t)
+ (e (and (save-excursion (re-search-forward "#\\+end_?\\(?:[a-z]+\\)?" nil t))
+ (match-end 0)))
+ (folded
+ (save-excursion
+ (end-of-line)
+ (when (overlays-at (point))
+ (member 'invisible (overlay-properties
+ (car (overlays-at (point)))))))))
+ (when folded (org-cycle))
+ (indent-for-tab-command)
+ (while (and (move-beginning-of-line 2) (< (point) e))
+ (indent-for-tab-command))
+ (goto-char p)
+ (when folded (org-cycle)))
+ (message "Block at point indented"))
+
(defvar org-adaptive-fill-regexp-backup adaptive-fill-regexp
"Variable to store copy of `adaptive-fill-regexp'.
Since `adaptive-fill-regexp' is set to never match, we need to
@@ -20191,10 +20395,11 @@ (defun org-set-autofill-regexps ()
(org-set-local 'fill-paragraph-function 'org-fill-paragraph)
;; Prevent auto-fill from inserting unwanted new items.
(if (boundp 'fill-nobreak-predicate)
- (org-set-local 'fill-nobreak-predicate
- (if (memq 'org-fill-item-nobreak-p fill-nobreak-predicate)
- fill-nobreak-predicate
- (cons 'org-fill-item-nobreak-p fill-nobreak-predicate))))
+ (org-set-local
+ 'fill-nobreak-predicate
+ (org-uniquify
+ (append fill-nobreak-predicate
+ '(org-fill-item-nobreak-p org-fill-line-break-nobreak-p)))))
;; Adaptive filling: To get full control, first make sure that
;; `adaptive-fill-regexp' never matches. Then install our own matcher.
(unless (local-variable-p 'adaptive-fill-regexp (current-buffer))
@@ -20214,6 +20419,13 @@ (defun org-fill-item-nobreak-p ()
"Non-nil when a line break at point would insert a new item."
(and (looking-at (org-item-re)) (org-list-in-valid-context-p)))
+(defun org-fill-line-break-nobreak-p ()
+ "Non-nil when a line break at point would create an Org line break."
+ (save-excursion
+ (skip-chars-backward "[ \t]")
+ (skip-chars-backward "\\\\")
+ (looking-at "\\\\\\\\\\($\\|[^\\\\]\\)")))
+
(defun org-fill-paragraph (&optional justify)
"Re-align a table, pass through to fill-paragraph if no table."
(let ((table-p (org-at-table-p))
@@ -20551,7 +20763,8 @@ (defun org-kill-line (&optional arg)
(if (or (eq org-ctrl-k-protect-subtree 'error)
(not (y-or-n-p "Kill hidden subtree along with headline? ")))
(error "C-k aborted - would kill hidden subtree")))
- (call-interactively 'kill-line))
+ (call-interactively
+ (if visual-line-mode 'kill-visual-line 'kill-line)))
((looking-at (org-re ".*?\\S-\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)[ \t]*$"))
(kill-region (point) (match-beginning 1))
(org-set-tags nil t))
@@ -20706,11 +20919,17 @@ (defun org-at-heading-p (&optional ignored)
(defalias 'org-on-heading-p 'org-at-heading-p)
(defun org-at-drawer-p nil
- "Whether point is at a drawer."
+ "Is cursor at a drawer keyword?"
(save-excursion
(move-beginning-of-line 1)
(looking-at org-drawer-regexp)))
+(defun org-at-block-p nil
+ "Is cursor at a block keyword?"
+ (save-excursion
+ (move-beginning-of-line 1)
+ (looking-at org-block-regexp)))
+
(defun org-point-at-end-of-empty-headline ()
"If point is at the end of an empty headline, return t, else nil.
If the heading only contains a TODO keyword, it is still still considered
diff --git a/testing/examples/babel.org b/testing/examples/babel.org
index c551828..4d89707 100644
--- a/testing/examples/babel.org
+++ b/testing/examples/babel.org
@@ -7,40 +7,70 @@
:END:
#+name: noweb-example
-#+begin_src emacs-lisp
- (message "expanded")
+#+begin_src emacs-lisp :results silent :exports code
+ (message "expanded1")
#+end_src
-#+begin_src emacs-lisp :noweb yes
- ;; noweb-yes-start
- <<noweb-example>>
- ;; noweb-yes-end
+#+name: noweb-example2
+#+begin_src emacs-lisp :results silent
+ (message "expanded2")
#+end_src
-#+begin_src emacs-lisp :noweb no
- ;; noweb-no-start
+#+begin_src emacs-lisp :noweb yes :results silent
+;; noweb-1-yes-start
<<noweb-example>>
- ;; noweb-no-end
#+end_src
-#+begin_src emacs-lisp :noweb tangle
+#+begin_src emacs-lisp :noweb no :results silent
+;; noweb-no-start
+ <<noweb-example1>>
+#+end_src
+
+#+begin_src emacs-lisp :noweb yes :results silent
+;; noweb-2-yes-start
+ <<noweb-example2>>
+#+end_src
+
+#+begin_src emacs-lisp :noweb tangle :results silent
;; noweb-tangle-start
- <<noweb-example>>
- ;; noweb-tangle-end
+ <<noweb-example1>>
+ <<noweb-example2>>
#+end_src
-* elisp forms in header arguments
+* =:noweb= header argument expansion using :exports results
:PROPERTIES:
- :ID: 22d67284-bf14-4cdc-8319-f4bd876829d7
- :var: prop=(+ 2 2)
+ :ID: 8701beb4-13d9-468c-997a-8e63e8b66f8d
:END:
-#+begin_src emacs-lisp
- prop
+#+name: noweb-example
+#+begin_src emacs-lisp :exports results
+ (message "expanded1")
#+end_src
-#+name:
-: 4
+#+name: noweb-example2
+#+begin_src emacs-lisp :exports results
+ (message "expanded2")
+#+end_src
+
+#+begin_src emacs-lisp :noweb yes :exports results
+;; noweb-1-yes-start
+ <<noweb-example>>
+#+end_src
+
+#+begin_src emacs-lisp :noweb no :exports code
+;; noweb-no-start
+ <<noweb-example1>>
+#+end_src
+
+#+begin_src emacs-lisp :noweb yes :exports results
+;; noweb-2-yes-start
+ <<noweb-example2>>
+#+end_src
+
+#+begin_src emacs-lisp :noweb tangle :exports code
+ <<noweb-example1>>
+ <<noweb-example2>>
+#+end_src
* excessive id links on tangling
:PROPERTIES:
@@ -59,42 +89,6 @@
#+begin_src emacs-lisp :tangle no
(message "for tangling")
#+end_src
-* simple variable resolution
- :PROPERTIES:
- :ID: f68821bc-7f49-4389-85b5-914791ee3718
- :END:
-
-#+name: four
-#+begin_src emacs-lisp
- (list 1 2 3 4)
-#+end_src
-
-#+begin_src emacs-lisp :var four=four
- (length four)
-#+end_src
-
-#+name:
-: 4
-
-* multi-line header arguments
- :PROPERTIES:
- :ID: b77c8857-6c76-4ea9-8a61-ddc2648d96c4
- :END:
-
-#+headers: :var letters='(a b c d e f g)
-#+begin_src emacs-lisp :var numbers='(1 2 3 4 5 6 7)
- (map 'list #'list numbers letters)
-#+end_src
-
-#+name:
-| 1 | a |
-| 2 | b |
-| 3 | c |
-| 4 | d |
-| 5 | e |
-| 6 | f |
-| 7 | g |
-
* simple named code block
:PROPERTIES:
:ID: 0d82b52d-1bb9-4916-816b-2c67c8108dbb
@@ -111,7 +105,7 @@
#+name: i-have-a-name
: 42
-* Pascal's Triangle -- export test
+* Pascal's Triangle -- exports both test
:PROPERTIES:
:ID: 92518f2a-a46a-4205-a3ab-bcce1008a4bb
:END:
@@ -202,29 +196,24 @@ Here is one in the middle src_sh{echo 1} of a line.
Here is one at the end of a line. src_sh{echo 2}
src_sh{echo 3} Here is one at the beginning of a line.
-* parsing header arguments
- :PROPERTIES:
- :ID: 7eb0dc6e-1c53-4275-88b3-b22f3113b9c3
- :END:
-
-#+begin_src example-lang :session :results output :var num=9
- the body
-#+end_src
-* conflicting blocks on export
+* mixed blocks with exports both
:PROPERTIES:
:ID: 5daa4d03-e3ea-46b7-b093-62c1b7632df3
:END:
+
#+name: a-list
- a
- b
- c
-#+begin_src emacs-lisp :results wrap :exports both
+#+begin_src emacs-lisp :exports both
"code block results"
#+end_src
-#+begin_src emacs-lisp :var lst=a-list :results list
+
+#+begin_src emacs-lisp :var lst=a-list :results list :exports both
(reverse lst)
#+end_src
+
* using the =:noweb-ref= header argument
:PROPERTIES:
:ID: 54d68d4b-1544-4745-85ab-4f03b3cbd8a0
@@ -282,32 +271,43 @@ this is simple
has length 14
* org-babel-get-inline-src-block-matches
- :PROPERTIES:
+ :PROPERTIES:
:results: silent
:ID: 0D0983D4-DE33-400A-8A05-A225A567BC74
:END:
src_sh{echo "One"} block at start of line
- One spaced block in src_sh{ echo "middle" } of line
+ One spaced block in src_sh{ echo "middle" } of line
src_sh{echo 2} blocks on the src_emacs-lisp{"same"} line
Inline block with src_sh[:results silent]{ echo "parameters" }.
-* returning file names -- interpreted as lists
+* exporting a code block with a name
:PROPERTIES:
- :ID: a73a2ab6-b8b2-4c0e-ae7f-23ad14eab7bc
+ :ID: b02ddd8a-eeb8-42ab-8664-8a759e6f43d9
:END:
-#+begin_src sh :results scalar
- echo "[[file:./cv.cls]]"
+exporting a code block with a name
+#+name: qux
+#+begin_src sh :foo "baz"
+ echo bar
#+end_src
+* noweb no-export and exports both
+ :PROPERTIES:
+ :ID: 8a820f6c-7980-43db-8a24-0710d33729c9
+ :END:
+Weird interaction.
-#+name:
-: [[file:./cv.cls]]
+here is one block
-#+begin_src sh :results raw scalar
- echo "[[file:./cv.cls]]"
-#+end_src
+#+name: noweb-no-export-and-exports-both-1
+#+BEGIN_SRC sh :exports none
+ echo 1
+#+END_SRC
-#+name:
-[[file:./cv.cls]]
+and another
+
+#+BEGIN_SRC sh :noweb no-export :exports both
+ # I am inside the code block
+ <<noweb-no-export-and-exports-both-1>>
+#+END_SRC
* in order evaluation on export
:PROPERTIES:
@@ -335,3 +335,23 @@ Fifth
#+begin_src emacs-lisp
(push 5 *evaluation-collector*)
#+end_src
+* exporting more than just results from a call line
+ :PROPERTIES:
+ :ID: bec63a04-491e-4caa-97f5-108f3020365c
+ :END:
+Here is a call line with more than just the results exported.
+#+call: double(8)
+* strip noweb references on export
+ :PROPERTIES:
+ :ID: 8e7bd234-99b2-4b14-8cd6-53945e409775
+ :END:
+
+#+name: strip-export-1
+#+BEGIN_SRC sh :exports none
+ i="10"
+#+END_SRC
+
+#+BEGIN_SRC sh :noweb strip-export :exports code :results silent
+ <<strip-export-1>>
+ echo "1$i"
+#+END_SRC
diff --git a/testing/examples/normal.org b/testing/examples/normal.org
index af6e4ea..c0d95a4 100644
--- a/testing/examples/normal.org
+++ b/testing/examples/normal.org
@@ -16,3 +16,13 @@ Here are a couple of code blocks.
;; 94839181-184f-4ff4-a72f-94214df6f5ba
(message "I am code")
#+end_src
+* accumulating properties in drawers
+ :PROPERTIES:
+ :var+: bar=2
+ :var: foo=1
+ :ID: 75282ba2-f77a-4309-a970-e87c149fe125
+ :END:
+
+#+begin_src emacs-lisp :results silent
+ (list bar foo)
+#+end_src
diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el
index dfadedb..5b5e0b4 100644
--- a/testing/lisp/test-ob-C.el
+++ b/testing/lisp/test-ob-C.el
@@ -1,5 +1,15 @@
-(require 'ob-C)
-
+;;; test-ob-awk.el --- tests for ob-awk.el
+
+;; Copyright (c) 2010-2012 Sergey Litvinov
+;; Authors: Sergey Litvinov
+
+;; Released under the GNU General Public License version 3
+;; see: http://www.gnu.org/licenses/gpl-3.0.html
+
+;;; Code:
+(unless (featurep 'ob-C)
+ (signal 'missing-test-dependency "Support for C code blocks"))
+
(ert-deftest ob-C/assert ()
(should t))
diff --git a/testing/lisp/test-ob-R.el b/testing/lisp/test-ob-R.el
index 2dfd141..0ebf4d9 100644
--- a/testing/lisp/test-ob-R.el
+++ b/testing/lisp/test-ob-R.el
@@ -1,23 +1,17 @@
;;; test-ob-R.el --- tests for ob-R.el
-;; Copyright (c) 2011 Eric Schulte
+;; Copyright (c) 2011-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
+;;; Code:
(org-test-for-executable "R")
(unless (featurep 'ess)
(signal 'missing-test-dependency "ESS"))
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(require 'ob-R)
+(unless (featurep 'ob-R)
+ (signal 'missing-test-dependency "Support for R code blocks"))
(ert-deftest test-ob-R/simple-session ()
(org-test-with-temp-text
diff --git a/testing/lisp/test-ob-awk.el b/testing/lisp/test-ob-awk.el
index e372fef..d925b7b 100644
--- a/testing/lisp/test-ob-awk.el
+++ b/testing/lisp/test-ob-awk.el
@@ -1,21 +1,15 @@
;;; test-ob-awk.el --- tests for ob-awk.el
-;; Copyright (c) 2010 Sergey Litvinov
+;; Copyright (c) 2010-2012 Sergey Litvinov
;; Authors: Sergey Litvinov
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
+;;; Code:
(org-test-for-executable "awk")
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(require 'ob-awk)
+(unless (featurep 'ob-awk)
+ (signal 'missing-test-dependency "Support for Awk code blocks"))
(ert-deftest ob-awk/input-none ()
"Test with no input file"
diff --git a/testing/lisp/test-ob-emacs-lisp.el b/testing/lisp/test-ob-emacs-lisp.el
index a83e8e9..f262ff7 100644
--- a/testing/lisp/test-ob-emacs-lisp.el
+++ b/testing/lisp/test-ob-emacs-lisp.el
@@ -10,19 +10,7 @@
;; Org-mode tests for ob-emacs-lisp.el live here
-\f
;;; Code:
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
-
(ert-deftest ob-emacs-lisp/commented-last-block-line-no-var ()
(org-test-with-temp-text-in-file "
#+begin_src emacs-lisp
diff --git a/testing/lisp/test-ob-exp.el b/testing/lisp/test-ob-exp.el
index 8899e0d..f86d84a 100644
--- a/testing/lisp/test-ob-exp.el
+++ b/testing/lisp/test-ob-exp.el
@@ -1,6 +1,6 @@
;;; test-ob-exp.el
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
@@ -10,17 +10,7 @@
;; Template test file for Org-mode tests
-\f
;;; Code:
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
(ert-deftest test-ob-exp/org-babel-exp-src-blocks/w-no-headers ()
"Testing export without any headlines in the org-mode file."
(let ((html-file (concat (file-name-sans-extension org-test-no-heading-file)
@@ -65,43 +55,164 @@
(should-not (file-exists-p (concat org-test-link-in-heading-file "::")))
(when (file-exists-p html-file) (delete-file html-file))))
-;; TODO
-;; (ert-deftest ob-exp/noweb-on-export ()
-;; "Noweb header arguments export correctly.
-;; - yes expand on both export and tangle
-;; - no expand on neither export or tangle
-;; - tangle expand on only tangle not export"
-;; (let (html)
-;; (org-test-at-id "eb1f6498-5bd9-45e0-9c56-50717053e7b7"
-;; (org-narrow-to-subtree)
-;; (let ((arg nil)
-;; )
-;; (mapcar (lambda (x)
-;; (should (equal ""
-;; (org-export-as-html nil
-;; nil
-;; nil
-;; 'string))))
-;; '("yes" "no" "tangle"))))))
-
-
-;; TODO Test broken (args-out-of-range 1927 3462)
-;; (ert-deftest ob-exp/exports-both ()
-;; "Test the :exports both header argument.
-;; The code block should create both <pre></pre> and <table></table>
-;; elements in the final html."
-;; (let (html)
-;; (org-test-at-id "92518f2a-a46a-4205-a3ab-bcce1008a4bb"
-;; (org-narrow-to-subtree)
-;; (setq html (org-export-as-html nil nil nil 'string))
-;; (should (string-match "<pre.*>[^\000]*</pre>" html))
-;; (should (string-match "<table.*>[^\000]*</table>" html)))))
-
-;; TODO Test Broken - causes ert to go off into the weeds
-;; (ert-deftest ob-exp/export-subtree ()
-;; (org-test-at-id "5daa4d03-e3ea-46b7-b093-62c1b7632df3"
-;; (org-mark-subtree)
-;; (org-export-as-latex nil)))
+(ert-deftest ob-exp/noweb-on-export ()
+ "Noweb header arguments export correctly.
+- yes expand on both export and tangle
+- no expand on neither export or tangle
+- tangle expand on only tangle not export"
+ (org-test-at-id "eb1f6498-5bd9-45e0-9c56-50717053e7b7"
+ (org-narrow-to-subtree)
+ (let ((exported-html
+ (org-export-as-html nil nil nil 'string 'body-only))
+ (test-point 0))
+
+ (org-test-with-temp-text-in-file
+ exported-html
+
+ ;; check following ouput exists and in order
+ (mapcar (lambda (x)
+ (should (< test-point
+ (re-search-forward
+ x
+ nil t)))
+ (setq test-point (point)))
+ '("<code>:noweb</code> header argument expansion"
+ "message" "expanded1"
+ "message" "expanded2"
+ "noweb-1-yes-start"
+ "message" "expanded1"
+ "noweb-no-start"
+ "<<noweb-example1>>"
+ "noweb-2-yes-start"
+ "message" "expanded2"
+ "noweb-tangle-start"
+ "<<noweb-example1>>"
+ "<<noweb-example2>>"))))))
+
+(ert-deftest ob-exp/noweb-on-export-with-exports-results ()
+ "Noweb header arguments export correctly using :exports results.
+- yes expand on both export and tangle
+- no expand on neither export or tangle
+- tangle expand on only tangle not export"
+ (org-test-at-id "8701beb4-13d9-468c-997a-8e63e8b66f8d"
+ (org-narrow-to-subtree)
+ (let ((exported-html
+ (org-export-as-html nil nil nil 'string 'body-only))
+ (test-point 0))
+
+ (org-test-with-temp-text-in-file
+ exported-html
+
+ ;; check following ouput exists and in order
+ (mapcar (lambda (x)
+ (should (< test-point
+ (re-search-forward
+ x
+ nil t)))
+ (setq test-point (point)))
+ '("<code>:noweb</code> header argument expansion using :exports results"
+ "expanded1"
+ "expanded2"
+ "expanded1"
+ "noweb-no-start"
+ "<<noweb-example1>>"
+ "expanded2"
+ "<<noweb-example1>>"
+ "<<noweb-example2>>"))))))
+
+(ert-deftest ob-exp/exports-both ()
+ "Test the :exports both header argument.
+The code block should create both <pre></pre> and <table></table>
+elements in the final html."
+ (org-test-at-id "92518f2a-a46a-4205-a3ab-bcce1008a4bb"
+ (org-narrow-to-subtree)
+ (let ((exported-html
+ (org-export-as-html nil nil nil 'string 'body-only))
+ (test-point 0))
+ (org-test-with-temp-text-in-file
+ exported-html
+
+ ;; check following ouput exists and in order
+ (mapcar (lambda (x)
+ (should (< test-point
+ (re-search-forward
+ x
+ nil t)))
+ (setq test-point (point)))
+ '( "Pascal's Triangle – exports both test"
+ "<pre"
+ "defun" "pascals-triangle"
+ "if""list""list""let*""prev-triangle"
+ "pascals-triangle""prev-row""car""reverse""prev-triangle"
+ "append""prev-triangle""list""map""list"
+ "append""prev-row""append""prev-row""pascals-triangle"
+ "</pre>"
+ "<table""<tbody>"
+ "<tr>"">1<""</tr>"
+ "<tr>"">1<"">1<""</tr>"
+ "<tr>"">1<"">2<"">1<""</tr>"
+ "<tr>"">1<"">3<"">3<"">1<""</tr>"
+ "<tr>"">1<"">4<"">6<"">4<"">1<""</tr>"
+ "<tr>"">1<"">5<"">10<"">10<"">5<"">1<""</tr>"
+ "</tbody>""</table>"))))))
+
+(ert-deftest ob-exp/mixed-blocks-with-exports-both ()
+ (org-test-at-id "5daa4d03-e3ea-46b7-b093-62c1b7632df3"
+ (org-narrow-to-subtree)
+ (let ((exported-html
+ (org-export-as-html nil nil nil 'string 'body-only))
+ (test-point 0))
+ (org-test-with-temp-text-in-file
+ exported-html
+
+ ;; check following ouput exists and in order
+ (mapcar (lambda (x)
+ (should (< test-point
+ (re-search-forward
+ x
+ nil t)))
+ (setq test-point (point)))
+ '("mixed blocks with exports both"
+ "<ul>"
+ "<li>""a""</li>"
+ "<li>""b""</li>"
+ "<li>""c""</li>"
+ "</ul>"
+ "<pre"
+ "\"code block results\""
+ "</pre>"
+ "<pre class=\"example\">"
+ "code block results"
+ "</pre>"))))))
+
+(ert-deftest ob-exp/export-with-name ()
+ (let ((org-babel-exp-code-template
+ "=%name=\n#+BEGIN_SRC %lang%flags\nbody\n#+END_SRC"))
+ (org-test-at-id "b02ddd8a-eeb8-42ab-8664-8a759e6f43d9"
+ (org-narrow-to-subtree)
+ (let ((ascii (org-export-as-ascii nil nil nil 'string 'body-only)))
+ (should (string-match "qux" ascii))))))
+
+(ert-deftest ob-exp/export-with-header-argument ()
+ (let ((org-babel-exp-code-template
+ "
+| header | value |
+|---------+----------|
+| foo | %foo |
+| results | %results |
+#+BEGIN_SRC %lang%flags\nbody\n#+END_SRC"))
+ (org-test-at-id "b02ddd8a-eeb8-42ab-8664-8a759e6f43d9"
+ (org-narrow-to-subtree)
+ (let ((ascii (org-export-as-ascii nil nil nil 'string 'body-only)))
+ (should (string-match "baz" ascii))
+ (should (string-match "replace" ascii))))))
+
+(ert-deftest ob-exp/noweb-no-export-and-exports-both ()
+ (org-test-at-id "8a820f6c-7980-43db-8a24-0710d33729c9"
+ (org-narrow-to-subtree)
+ (let ((html (org-export-as-html nil nil nil 'string 'body-only)))
+ (should (string-match (regexp-quote "noweb-no-export-and-exports-both-1")
+ html)))))
(ert-deftest ob-exp/evaluate-all-executables-in-order ()
(org-test-at-id "96cc7073-97ec-4556-87cf-1f9bffafd317"
@@ -110,6 +221,49 @@
(org-export-as-ascii nil nil nil 'string)
(should (equal '(5 4 3 2 1) *evaluation-collector*)))))
+(ert-deftest ob-exp/export-call-line-information ()
+ (org-test-at-id "bec63a04-491e-4caa-97f5-108f3020365c"
+ (org-narrow-to-subtree)
+ (let* ((org-babel-exp-call-line-template "\n: call: %line special-token")
+ (html (org-export-as-html nil nil nil 'string t)))
+ (should (string-match "double" html))
+ (should (string-match "16" html))
+ (should (string-match "special-token" html)))))
+
+(ert-deftest ob-exp/noweb-strip-export-ensure-strips ()
+ (org-test-at-id "8e7bd234-99b2-4b14-8cd6-53945e409775"
+ (org-narrow-to-subtree)
+ (org-babel-next-src-block 2)
+ (should (= 110 (org-babel-execute-src-block)))
+ (let ((ascii (org-export-as-ascii nil nil nil 'string t)))
+ (should-not (string-match (regexp-quote "<<strip-export-1>>") ascii))
+ (should-not (string-match (regexp-quote "i=\"10\"") ascii)))))
+
+(ert-deftest ob-exp/export-from-a-temp-buffer ()
+ :expected-result :failed
+ (org-test-with-temp-text
+ "
+#+Title: exporting from a temporary buffer
+
+#+name: foo
+#+BEGIN_SRC emacs-lisp
+ :foo
+#+END_SRC
+
+#+name: bar
+#+BEGIN_SRC emacs-lisp
+ :bar
+#+END_SRC
+
+#+BEGIN_SRC emacs-lisp :var foo=foo :noweb yes :exports results
+ (list foo <<bar>>)
+#+END_SRC
+"
+ (let* ((org-current-export-file (current-buffer))
+ (ascii (org-export-as-ascii nil nil nil 'string)))
+ (should (string-match (regexp-quote (format nil "%S" '(:foo :bar)))
+ ascii)))))
+
(provide 'test-ob-exp)
;;; test-ob-exp.el ends here
diff --git a/testing/lisp/test-ob-fortran.el b/testing/lisp/test-ob-fortran.el
index 8be3287..c18cb64 100644
--- a/testing/lisp/test-ob-fortran.el
+++ b/testing/lisp/test-ob-fortran.el
@@ -1,35 +1,15 @@
;;; test-ob-fortran.el --- tests for ob-fortran.el
-;; Copyright (c) 2010 Sergey Litvinov
+;; Copyright (c) 2010-2012 Sergey Litvinov
;; Authors: Sergey Litvinov
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
+;;; Code:
(org-test-for-executable "gfortran")
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(let ((load-path (cons (expand-file-name
- "langs"
- (expand-file-name
- "babel"
- (expand-file-name
- "contrib"
- (expand-file-name
- ".."
- (expand-file-name
- ".."
- (file-name-directory
- (or load-file-name buffer-file-name)))))))
- load-path)))
-
- (require 'ob-fortran))
+(unless (featurep 'ob-fortran)
+ (signal 'missing-test-dependency "Support for Fortran code blocks"))
(ert-deftest ob-fortran/assert ()
(should t))
@@ -38,15 +18,13 @@
"Test of hello world program."
(org-test-at-id "459384e8-1797-4f11-867e-dde0473ea7cc"
(org-babel-next-src-block)
- (should (equal "Hello world" (org-babel-execute-src-block))))
-)
+ (should (equal "Hello world" (org-babel-execute-src-block)))))
(ert-deftest ob-fortran/fortran-var-program ()
"Test a fortran variable"
(org-test-at-id "459384e8-1797-4f11-867e-dde0473ea7cc"
(org-babel-next-src-block 2)
- (should (= 10 (org-babel-execute-src-block))))
-)
+ (should (= 10 (org-babel-execute-src-block)))))
(ert-deftest ob-fortran/input-var ()
"Test :var"
diff --git a/testing/lisp/test-ob-lilypond.el b/testing/lisp/test-ob-lilypond.el
index 2ca0597..306c48a 100644
--- a/testing/lisp/test-ob-lilypond.el
+++ b/testing/lisp/test-ob-lilypond.el
@@ -1,19 +1,14 @@
;;; test-ob-lilypond.el --- tests for ob-lilypond.el
-;; Copyright (c) 2010 Martyn Jago
+;; Copyright (c) 2010-2012 Martyn Jago
;; Authors: Martyn Jago
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(require 'ob-lilypond)
+;;; Code:
+(unless (featurep 'ob-lilypond)
+ (signal 'missing-test-dependency "Support for Lilypond code blocks"))
(save-excursion
(set-buffer (get-buffer-create "test-ob-lilypond.el"))
@@ -47,10 +42,10 @@
(should (boundp 'ly-version)))
(ert-deftest ob-lilypond/ly-version-command ()
- (should (equal "ob-lilypond version 0.3" (ly-version)))
+ (should (equal "ob-lilypond version 7.6" (ly-version)))
(with-temp-buffer
(ly-version t)
- (should (equal "ob-lilypond version 0.3"
+ (should (equal "ob-lilypond version 7.6"
(buffer-substring (point-min) (point-max))))))
(ert-deftest ob-lilypond/ly-compile-lilyfile ()
@@ -61,6 +56,7 @@
t ;display
,(if ly-gen-png "--png" "") ;&rest...
,(if ly-gen-html "--html" "")
+ ,(if ly-gen-pdf "--pdf" "")
,(if ly-use-eps "-dbackend=eps" "")
,(if ly-gen-svg "-dbackend=svg" "")
"--output=test-file"
@@ -121,6 +117,9 @@
(ert-deftest ob-lilypond/ly-gen-html ()
(should (boundp 'ly-gen-html)))
+(ert-deftest ob-lilypond/ly-gen-html ()
+ (should (boundp 'ly-gen-pdf)))
+
(ert-deftest ob-lilypond/use-eps ()
(should (boundp 'ly-use-eps)))
@@ -301,6 +300,18 @@
(ly-toggle-pdf-display)
(should (not ly-display-pdf-post-tangle))))
+(ert-deftest ob-lilypond/ly-toggle-pdf-generation-toggles-flag ()
+ (if ly-gen-pdf
+ (progn
+ (ly-toggle-pdf-generation)
+ (should (not ly-gen-pdf))
+ (ly-toggle-pdf-generation)
+ (should ly-gen-pdf))
+ (ly-toggle-pdf-generation)
+ (should ly-gen-pdf)
+ (ly-toggle-pdf-generation)
+ (should (not ly-gen-pdf))))
+
(ert-deftest ob-lilypond/ly-toggle-arrange-mode ()
(if ly-arrange-mode
(progn
@@ -353,6 +364,7 @@
(should (equal '((:tangle . "yes")
(:noweb . "yes")
(:results . "silent")
+ (:cache . "yes")
(:comments . "yes"))
(ly-set-header-args t)))
(should (equal '((:results . "file")
@@ -364,6 +376,7 @@
(should (equal '((:tangle . "yes")
(:noweb . "yes")
(:results . "silent")
+ (:cache . "yes")
(:comments . "yes"))
org-babel-default-header-args:lilypond))
(ly-set-header-args nil)
diff --git a/testing/lisp/test-ob-lob.el b/testing/lisp/test-ob-lob.el
index 5d362d8..2cb49ca 100644
--- a/testing/lisp/test-ob-lob.el
+++ b/testing/lisp/test-ob-lob.el
@@ -1,6 +1,6 @@
;;; test-ob-lob.el
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
diff --git a/testing/lisp/test-ob-maxima.el b/testing/lisp/test-ob-maxima.el
index a63908c..4c92af0 100644
--- a/testing/lisp/test-ob-maxima.el
+++ b/testing/lisp/test-ob-maxima.el
@@ -1,35 +1,13 @@
;;; test-ob-maxima.el --- tests for ob-maxima.el
-;; Copyright (c) 2010 Sergey Litvinov
+;; Copyright (c) 2010-2012 Sergey Litvinov
;; Authors: Sergey Litvinov
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
-
(org-test-for-executable "maxima")
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(let ((load-path (cons (expand-file-name
- "langs"
- (expand-file-name
- "babel"
- (expand-file-name
- "contrib"
- (expand-file-name
- ".."
- (expand-file-name
- ".."
- (file-name-directory
- (or load-file-name buffer-file-name)))))))
- load-path)))
-
- (require 'ob-maxima))
+(unless (featurep 'ob-maxima)
+ (signal 'missing-test-dependency "Support for Maxima code blocks"))
(ert-deftest ob-maxima/assert ()
(should t))
diff --git a/testing/lisp/test-ob-octave.el b/testing/lisp/test-ob-octave.el
index 528a94a..e642679 100644
--- a/testing/lisp/test-ob-octave.el
+++ b/testing/lisp/test-ob-octave.el
@@ -1,21 +1,13 @@
;;; test-ob-octave.el --- tests for ob-octave.el
-;; Copyright (c) 2010 Sergey Litvinov
+;; Copyright (c) 2010-2012 Sergey Litvinov
;; Authors: Sergey Litvinov
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
-
(org-test-for-executable "octave")
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(require 'ob-octave)
+(unless (featurep 'ob-octave)
+ (signal 'missing-test-dependency "Support for Octave code blocks"))
(ert-deftest ob-octave/input-none ()
"Number output"
diff --git a/testing/lisp/test-ob-python.el b/testing/lisp/test-ob-python.el
index e2990bc..d6a4133 100644
--- a/testing/lisp/test-ob-python.el
+++ b/testing/lisp/test-ob-python.el
@@ -1,21 +1,15 @@
;;; test-ob-python.el --- tests for ob-python.el
-;; Copyright (c) 2011 Eric Schulte
+;; Copyright (c) 2011-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
+;;; Code:
(org-test-for-executable "python")
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-(require 'ob-python)
+(unless (featurep 'ob-python)
+ (signal 'missing-test-dependency "Support for Python code blocks"))
(ert-deftest test-ob-python/colnames-yes-header-argument ()
(org-test-with-temp-text "#+name: eg
diff --git a/testing/lisp/test-ob-sh.el b/testing/lisp/test-ob-sh.el
index 8ff7081..297c86e 100644
--- a/testing/lisp/test-ob-sh.el
+++ b/testing/lisp/test-ob-sh.el
@@ -1,6 +1,6 @@
;;; test-ob-sh.el
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
@@ -8,17 +8,10 @@
;; Template test file for Org-mode tests
-\f
;;; Code:
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
+(unless (featurep 'ob-sh)
+ (signal 'missing-test-dependency "Support for Sh code blocks"))
+
(ert-deftest test-ob-sh/dont-insert-spaces-on-expanded-bodies ()
"Expanded shell bodies should not start with a blank line
unless the body of the tangled block does."
diff --git a/testing/lisp/test-ob-table.el b/testing/lisp/test-ob-table.el
index 65fd7af..d25c7a1 100644
--- a/testing/lisp/test-ob-table.el
+++ b/testing/lisp/test-ob-table.el
@@ -1,6 +1,6 @@
;;; test-ob-table.el
-;; Copyright (c) ߚ Eric Schulte
+;; Copyright (c) 2011-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
@@ -10,17 +10,7 @@
;; Template test file for Org-mode tests
-\f
;;; Code:
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
;; TODO Test Broken (wrong-type-argument number-or-marker-p "2.0")
;; (ert-deftest test-ob-table/sbe ()
diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el
index 5f0385e..17bb433 100644
--- a/testing/lisp/test-ob-tangle.el
+++ b/testing/lisp/test-ob-tangle.el
@@ -1,6 +1,6 @@
;;; test-ob-tangle.el
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
@@ -12,15 +12,6 @@
\f
;;; Code:
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
;; TODO
;; (ert-deftest ob-tangle/noweb-on-tangle ()
diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el
index 3f4186e..5f9e29c 100644
--- a/testing/lisp/test-ob.el
+++ b/testing/lisp/test-ob.el
@@ -1,18 +1,10 @@
;;; test-ob.el --- tests for ob.el
-;; Copyright (c) 2010, 2011 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte, Martyn Jago
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
-
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
(ert-deftest test-org-babel/multi-line-header-regexp ()
(should(equal "^[ \t]*#\\+headers?:[ \t]*\\([^\n]*\\)$"
org-babel-multi-line-header-regexp))
@@ -26,7 +18,7 @@
(match-string
1
" \t #+headers: blah1 blah2 blah3 \t\n\t\n blah4 blah5 blah6 \n")))
-
+
;;TODO Check - should this fail?
(should
(not (org-test-string-exact-match
@@ -114,11 +106,21 @@
(ert-deftest test-org-babel/elisp-in-header-arguments ()
"Test execution of elisp forms in header arguments."
- ;; at the babel.org:elisp-forms-in-header-arguments header
- (org-test-at-id "22d67284-bf14-4cdc-8319-f4bd876829d7"
- (org-babel-next-src-block)
- (let ((info (org-babel-get-src-block-info)))
- (should (= 4 (org-babel-execute-src-block))))))
+ (org-test-with-temp-text-in-file "
+
+* elisp forms in header arguments
+ :PROPERTIES:
+ :var: prop = (* 7 6)
+ :END:
+#+begin_src emacs-lisp
+ prop
+#+end_src"
+
+ (progn
+ (goto-char (point-min))
+ (org-babel-next-src-block)
+ (let ((info (org-babel-get-src-block-info)))
+ (should (= 42 (org-babel-execute-src-block)))))))
(ert-deftest test-org-babel/simple-named-code-block ()
"Test that simple named code blocks can be evaluated."
@@ -135,37 +137,84 @@
(ert-deftest test-org-babel/simple-variable-resolution ()
"Test that simple variable resolution is working."
- (org-test-at-id "f68821bc-7f49-4389-85b5-914791ee3718"
- (org-babel-next-src-block 2)
- (should (= 4 (org-babel-execute-src-block)))))
+ (org-test-with-temp-text-in-file "
+
+#+name: four
+#+begin_src emacs-lisp
+ (list 1 2 3 4)
+#+end_src
+
+#+begin_src emacs-lisp :var four=four
+ (length four)
+#+end_src"
+
+ (progn
+ (org-babel-next-src-block 2)
+ (should (= 4 (org-babel-execute-src-block)))
+ (forward-line 5)
+ (should (string= ": 4" (buffer-substring
+ (point-at-bol)
+ (point-at-eol)))))))
(ert-deftest test-org-babel/multi-line-header-arguments ()
"Test that multi-line header arguments and can be read."
- (org-test-at-id "b77c8857-6c76-4ea9-8a61-ddc2648d96c4"
- (org-babel-next-src-block)
- (let ((results (org-babel-execute-src-block)))
- (should(equal 'a (cadr (assoc 1 results))))
- (should(equal 'd (cadr (assoc 4 results)))))))
+ (org-test-with-temp-text-in-file "
+
+#+headers: :var letters='(a b c d e f g)
+#+begin_src emacs-lisp :var numbers='(1 2 3 4 5 6 7)
+ (map 'list #'list numbers letters)
+#+end_src"
+
+ (progn
+ (org-babel-next-src-block)
+ (let ((results (org-babel-execute-src-block)))
+ (should(equal 'a (cadr (assoc 1 results))))
+ (should(equal 'd (cadr (assoc 4 results))))))))
(ert-deftest test-org-babel/parse-header-args ()
- (org-test-at-id "7eb0dc6e-1c53-4275-88b3-b22f3113b9c3"
- (org-babel-next-src-block)
- (let* ((info (org-babel-get-src-block-info))
- (params (nth 2 info)))
- (message "%S" params)
- (should(equal "example-lang" (nth 0 info)))
- (should(string= "the body" (org-babel-trim (nth 1 info))))
- (should-not (member '(:session\ \ \ \ ) params))
- (should(equal '(:session) (assoc :session params)))
- (should(equal '(:result-type . output) (assoc :result-type params)))
- (should(equal '(num . 9) (cdr (assoc :var params)))))))
+ (org-test-with-temp-text-in-file "
+
+#+begin_src example-lang :session :results output :var num=9
+ the body
+#+end_src"
+
+ (progn
+ (org-babel-next-src-block)
+ (let* ((info (org-babel-get-src-block-info))
+ (params (nth 2 info)))
+ (message "%S" params)
+ (should(equal "example-lang" (nth 0 info)))
+ (should(string= "the body" (org-babel-trim (nth 1 info))))
+ (should-not (member '(:session\ \ \ \ ) params))
+ (should(equal '(:session) (assoc :session params)))
+ (should(equal '(:result-type . output) (assoc :result-type params)))
+ (should(equal '(num . 9) (cdr (assoc :var params))))))))
(ert-deftest test-org-babel/parse-header-args2 ()
- (org-test-at-id "2409e8ba-7b5f-4678-8888-e48aa02d8cb4"
- (should (string-match (regexp-quote "this is simple")
- (org-babel-ref-resolve "simple-subtree")))
- (org-babel-next-src-block)
- (should (= 14 (org-babel-execute-src-block)))))
+ (org-test-with-temp-text-in-file "
+
+* resolving sub-trees as references
+
+#+begin_src emacs-lisp :var text=d4faa7b3-072b-4dcf-813c-dd7141c633f3
+ (length text)
+#+end_src
+
+#+begin_src org :noweb yes
+ <<simple-subtree>>
+ <<d4faa7b3-072b-4dcf-813c-dd7141c633f3>>
+#+end_src
+
+** simple subtree with custom ID
+ :PROPERTIES:
+ :CUSTOM_ID: simple-subtree
+ :END:
+this is simple"
+
+ (progn
+ (should (string-match (regexp-quote "this is simple")
+ (org-babel-ref-resolve "simple-subtree")))
+ (org-babel-next-src-block)
+ (should (= 14 (org-babel-execute-src-block))))))
(ert-deftest test-org-babel/inline-src-blocks ()
(org-test-at-id "54cb8dc3-298c-4883-a933-029b3c9d4b18"
@@ -199,8 +248,7 @@
(should (re-search-forward ":results" nil t)) ;; 4
(should (org-babel-get-inline-src-block-matches))
(end-of-line)
- (should-not (org-babel-get-inline-src-block-matches))
- )))
+ (should-not (org-babel-get-inline-src-block-matches)))))
(ert-deftest test-org-babel/inline-src_blk-default-results-replace-line-1 ()
(let ((test-line "src_sh{echo 1}"))
@@ -227,7 +275,7 @@
(org-test-with-temp-text
test-line
(should-error (org-ctrl-c-ctrl-c))
- (forward-char) (org-ctrl-c-ctrl-c)
+ (forward-char) (org-ctrl-c-ctrl-c)
(should (string=
(concat test-line " =1=")
(buffer-substring-no-properties (point-at-bol) (point-at-eol))))
@@ -284,7 +332,7 @@
(concat test-line " =x=")
(buffer-substring-no-properties
(point-at-bol) (point-at-eol))))))
-
+
(let ((test-line (concat " Some text prior to block "
"src_emacs-lisp[:results replace]{ \"y\" }")))
(org-test-with-temp-text test-line
@@ -375,12 +423,25 @@
(point-min) (point-max)))))))
(ert-deftest test-org-babel/combining-scalar-and-raw-result-types ()
- (flet ((next-result ()
- (org-babel-next-src-block)
- (org-babel-execute-src-block)
- (goto-char (org-babel-where-is-src-block-result))
- (forward-line 1)))
- (org-test-at-id "a73a2ab6-b8b2-4c0e-ae7f-23ad14eab7bc"
+ (org-test-with-temp-text-in-file "
+
+#+begin_src sh :results scalar
+echo \"[[file:./cv.cls]]\"
+#+end_src
+
+#+name:
+: [[file:./cv.cls]]
+
+#+begin_src sh :results raw scalar
+ echo \"[[file:./cv.cls]]\"
+#+end_src
+"
+ (flet ((next-result ()
+ (org-babel-next-src-block)
+ (org-babel-execute-src-block)
+ (goto-char (org-babel-where-is-src-block-result))
+ (forward-line 1)))
+ (goto-char (point-min))
(next-result)
(should (org-babel-in-example-or-verbatim))
(next-result)
@@ -558,7 +619,7 @@
(check-eval "never-export" nil)
(check-eval "no-export" nil))))
-(ert-deftest test-ob/noweb-expansion ()
+(ert-deftest test-ob/noweb-expansion-1 ()
(org-test-with-temp-text "#+begin_src sh :results output :tangle yes
<<foo>>
#+end_src
@@ -567,7 +628,9 @@
#+begin_src sh
bar
#+end_src"
- (should (string= (org-babel-expand-noweb-references) "bar")))
+ (should (string= (org-babel-expand-noweb-references) "bar"))))
+
+(ert-deftest test-ob/noweb-expansion-2 ()
(org-test-with-temp-text "#+begin_src sh :results output :tangle yes
<<foo>>
#+end_src
@@ -594,6 +657,7 @@
'(":a 1" "b [2 3]" "c (4 :d (5 6))")
(org-babel-balanced-split ":a 1 :b [2 3] :c (4 :d (5 6))"
'((32 9) . 58)))))
+
(ert-deftest test-ob/commented-last-block-line-no-var ()
(org-test-with-temp-text-in-file "
#+begin_src emacs-lisp
@@ -791,6 +855,213 @@ (defun test-ob-verify-result-and-removed-result (result buffer-text)
* next heading"))
+(ert-deftest test-org-babel/inline-src_blk-preceded-punct-preceded-by-point ()
+ (let ((test-line ".src_emacs-lisp[ :results verbatim ]{ \"x\" }"))
+ (org-test-with-temp-text
+ test-line
+ (forward-char 1)
+ (org-ctrl-c-ctrl-c)
+ (should (re-search-forward "=\"x\"=" nil t))
+ (forward-line))))
+
+(ert-deftest test-ob/commented-last-block-line-with-var ()
+ (org-test-with-temp-text-in-file "
+#+begin_src emacs-lisp :var a=1
+;;
+#+end_src"
+ (progn
+ (org-babel-next-src-block)
+ (org-ctrl-c-ctrl-c)
+ (re-search-forward "\\#\\+results:" nil t)
+ (forward-line)
+ (should (string=
+ ""
+ (buffer-substring-no-properties (point-at-bol) (point-at-eol))))))
+ (org-test-with-temp-text-in-file "
+#+begin_src emacs-lisp :var a=2
+2;;
+#+end_src"
+ (progn
+ (org-babel-next-src-block)
+ (org-ctrl-c-ctrl-c)
+ (re-search-forward "\\#\\+results:" nil t)
+ (forward-line)
+ (should (string=
+ ": 2"
+ (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))))
+
+(defun test-ob-verify-result-and-removed-result (result buffer-text)
+ "Test helper function to test `org-babel-remove-result'.
+A temp buffer is populated with BUFFER-TEXT, the first block is executed,
+and the result of execution is verified against RESULT.
+
+The block is actually executed /twice/ to ensure result
+replacement happens correctly."
+ (org-test-with-temp-text
+ buffer-text
+ (progn
+ (org-babel-next-src-block) (org-ctrl-c-ctrl-c) (org-ctrl-c-ctrl-c)
+ (should (re-search-forward "\\#\\+results:" nil t))
+ (forward-line)
+ (should (string= result
+ (buffer-substring-no-properties
+ (point-at-bol)
+ (- (point-max) 16))))
+ (org-babel-previous-src-block) (org-babel-remove-result)
+ (should (string= buffer-text
+ (buffer-substring-no-properties
+ (point-min) (point-max)))))))
+
+(ert-deftest test-ob/org-babel-remove-result--results-default ()
+ "Test `org-babel-remove-result' with default :results."
+ (mapcar (lambda (language)
+ (test-ob-verify-result-and-removed-result
+ "\n"
+ (concat
+"* org-babel-remove-result
+#+begin_src " language "
+#+end_src
+
+* next heading")))
+ '("sh" "emacs-lisp")))
+
+(ert-deftest test-ob/org-babel-remove-result--results-list ()
+ "Test `org-babel-remove-result' with :results list."
+ (test-ob-verify-result-and-removed-result
+ "- 1
+- 2
+- 3
+- (quote (4 5))"
+
+"* org-babel-remove-result
+#+begin_src emacs-lisp :results list
+'(1 2 3 '(4 5))
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/org-babel-remove-result--results-wrap ()
+ "Test `org-babel-remove-result' with :results wrap."
+ (test-ob-verify-result-and-removed-result
+ ":RESULTS:
+hello there
+:END:"
+
+ "* org-babel-remove-result
+
+#+begin_src emacs-lisp :results wrap
+\"hello there\"
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/org-babel-remove-result--results-org ()
+ "Test `org-babel-remove-result' with :results org."
+ (test-ob-verify-result-and-removed-result
+ "#+BEGIN_ORG
+* heading
+** subheading
+content
+#+END_ORG"
+
+"* org-babel-remove-result
+#+begin_src emacs-lisp :results org
+\"* heading
+** subheading
+content\"
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/org-babel-remove-result--results-html ()
+ "Test `org-babel-remove-result' with :results html."
+ (test-ob-verify-result-and-removed-result
+ "#+BEGIN_HTML
+<head><body></body></head>
+#+END_HTML"
+
+"* org-babel-remove-result
+#+begin_src emacs-lisp :results html
+\"<head><body></body></head>\"
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/org-babel-remove-result--results-latex ()
+ "Test `org-babel-remove-result' with :results latex."
+ (test-ob-verify-result-and-removed-result
+ "#+BEGIN_LaTeX
+Line 1
+Line 2
+Line 3
+#+END_LaTeX"
+
+"* org-babel-remove-result
+#+begin_src emacs-lisp :results latex
+\"Line 1
+Line 2
+Line 3\"
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/org-babel-remove-result--results-code ()
+ "Test `org-babel-remove-result' with :results code."
+
+ (test-ob-verify-result-and-removed-result
+ "#+BEGIN_SRC emacs-lisp
+\"I am working!\"
+#+END_SRC"
+
+"* org-babel-remove-result
+#+begin_src emacs-lisp :results code
+(message \"I am working!\")
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/org-babel-remove-result--results-pp ()
+ "Test `org-babel-remove-result' with :results pp."
+ (test-ob-verify-result-and-removed-result
+ ": \"I /am/ working!\""
+
+"* org-babel-remove-result
+#+begin_src emacs-lisp :results pp
+\"I /am/ working!\")
+#+end_src
+
+* next heading"))
+
+(ert-deftest test-ob/results-do-not-replace-code-blocks ()
+ (org-test-with-temp-text "Block two has a space after the name.
+
+ #+name: foo
+ #+begin_src emacs-lisp
+ 1
+ #+end_src emacs-lisp
+
+#+name: foo
+#+begin_src emacs-lisp
+ 2
+#+end_src
+
+#+name: foo
+#+begin_src emacs-lisp
+ 3
+#+end_src
+
+#+RESULTS: foo
+: foo
+"
+ (dolist (num '(1 2 3))
+ ;; execute the block
+ (goto-char (point-min))
+ (org-babel-next-src-block num) (org-babel-execute-src-block)
+ ;; check the results
+ (goto-char (point-max))
+ (move-beginning-of-line 0)
+ (should (looking-at (format ": %d" num))))))
+
(provide 'test-ob)
;;; test-ob ends here
diff --git a/testing/lisp/test-org-exp.el b/testing/lisp/test-org-exp.el
index 0ed8d68..1f01499 100644
--- a/testing/lisp/test-org-exp.el
+++ b/testing/lisp/test-org-exp.el
@@ -1,19 +1,12 @@
;;; test-org-exp.el --- tests for org-exp.el
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts)
- (require 'org-ascii))
-
+;;; Code:
(ert-deftest test-org-exp/stripping-commas ()
"Test the stripping of commas from within blocks during export."
(org-test-at-id "76d3a083-67fa-4506-a41d-837cc48158b5"
diff --git a/testing/lisp/test-org-html.el b/testing/lisp/test-org-html.el
index c2cc067..74780bd 100644
--- a/testing/lisp/test-org-html.el
+++ b/testing/lisp/test-org-html.el
@@ -10,18 +10,9 @@
;; Template test file for Org-mode tests
-\f
;;; Code:
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
-(require 'org-html)
+(unless (featurep 'org-html)
+ (signal 'missing-test-dependency "Support for Org-html"))
(defmacro org-test-html/export-link (name link expected &optional desc opt-plist)
`(ert-deftest ,(intern (concat "test-org-html/export-link/" name)) ()
diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el
index 3ecc384..92c136d 100644
--- a/testing/lisp/test-org-table.el
+++ b/testing/lisp/test-org-table.el
@@ -10,17 +10,7 @@
;; Template test file for Org-mode tests
-\f
;;; Code:
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
-\f
-;;; Tests
(ert-deftest test-org-table/org-table-convert-refs-to-an/1 ()
"Simple reference @1$1."
(should
@@ -54,12 +44,28 @@
;; (string= "$3 = remote(FOO, @@#$2)" (org-table-convert-refs-to-rc "C& = remote(FOO, @@#B&)"))))
(ert-deftest test-org-table/simple-formula ()
- (org-test-at-id "563523f7-3f3e-49c9-9622-9216cc9a5d95"
- (re-search-forward (regexp-quote "#+tblname: simple-formula") nil t)
- (forward-line 1)
- (should (org-at-table-p))
- (should (org-table-recalculate 'all))
- (should (string= "10" (first (nth 5 (org-table-to-lisp)))))))
+ (org-test-with-temp-text-in-file "
+
+* simple formula
+ :PROPERTIES:
+ :ID: 563523f7-3f3e-49c9-9622-9216cc9a5d95
+ :END:
+
+#+tblname: simple-formula
+| 1 |
+| 2 |
+| 3 |
+| 4 |
+|----|
+| |
+ #+TBLFM: $1=vsum(@1..@-1)
+"
+ (progn
+ (re-search-forward (regexp-quote "#+tblname: simple-formula") nil t)
+ (forward-line 1)
+ (should (org-at-table-p))
+ (should (org-table-recalculate 'all))
+ (should (string= "10" (first (nth 5 (org-table-to-lisp))))))))
(provide 'test-org-table)
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 00ccd81..5edc401 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -10,17 +10,7 @@
;; Template test file for Org-mode tests
-\f
;;; Code:
-(let* ((testing-lisp-dir (file-name-directory
- (or load-file-name buffer-file-name)))
- (load-path (cons testing-lisp-dir load-path)))
- (dolist (file (directory-files testing-lisp-dir 'full
- "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*\\.org$"))
- (require (intern (substring file 0 (- (length file) 3))))))
-
-\f
-;;; Tests
(ert-deftest test-org/org-link-escape-ascii-character ()
"Escape an ascii character."
(should
@@ -92,6 +82,53 @@
"http://some.host.com/form?&id=blah%2Bblah25"
(org-link-unescape (org-link-escape "http://some.host.com/form?&id=blah%2Bblah25")))))
+(ert-deftest test-org/accumulated-properties-in-drawers ()
+ "Ensure properties accumulate in subtree drawers."
+ (org-test-at-id "75282ba2-f77a-4309-a970-e87c149fe125"
+ (org-babel-next-src-block)
+ (should (equal '(2 1) (org-babel-execute-src-block)))))
+
+
+\f
+;;; Links
+
+;;;; Fuzzy links
+
+;; Fuzzy links [[text]] encompass links to a target (<<text>>), to
+;; a target keyword (aka an invisible target: #+TARGET: text), to
+;; a named element (#+name: text) and to headlines (* Text).
+
+(ert-deftest test-org-export/fuzzy-links ()
+ "Test fuzzy links specifications."
+ ;; 1. Fuzzy link goes in priority to a matching target.
+ (org-test-with-temp-text
+ "#+TARGET: Test\n#+NAME: Test\n|a|b|\n<<Test>>\n* Test\n[[Test]]"
+ (goto-line 6)
+ (org-open-at-point)
+ (should (looking-at "<<Test>>")))
+ ;; 2. Fuzzy link should then go to a matching target keyword.
+ (org-test-with-temp-text
+ "#+NAME: Test\n|a|b|\n#+TARGET: Test\n* Test\n[[Test]]"
+ (goto-line 5)
+ (org-open-at-point)
+ (should (looking-at "#\\+TARGET: Test")))
+ ;; 3. Then fuzzy link points to an element with a given name.
+ (org-test-with-temp-text "Test\n#+NAME: Test\n|a|b|\n* Test\n[[Test]]"
+ (goto-line 5)
+ (org-open-at-point)
+ (should (looking-at "#\\+NAME: Test")))
+ ;; 4. A target still lead to a matching headline otherwise.
+ (org-test-with-temp-text "* Head1\n* Head2\n*Head3\n[[Head2]]"
+ (goto-line 4)
+ (org-open-at-point)
+ (should (looking-at "\\* Head2")))
+ ;; 5. With a leading star in link, enforce heading match.
+ (org-test-with-temp-text "#+TARGET: Test\n* Test\n<<Test>>\n[[*Test]]"
+ (goto-line 4)
+ (org-open-at-point)
+ (should (looking-at "\\* Test"))))
+
+
(provide 'test-org)
;;; test-org.el ends here
diff --git a/testing/lisp/test-property-inheritance.el b/testing/lisp/test-property-inheritance.el
index 60e955d..a68d7c6 100644
--- a/testing/lisp/test-property-inheritance.el
+++ b/testing/lisp/test-property-inheritance.el
@@ -1,24 +1,19 @@
;;; test-ob-R.el --- tests for ob-R.el
-;; Copyright (c) 2011 Eric Schulte
+;; Copyright (c) 2011-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
;; see: http://www.gnu.org/licenses/gpl-3.0.html
-(let ((load-path (cons (expand-file-name
- ".." (file-name-directory
- (or load-file-name buffer-file-name)))
- load-path)))
- (require 'org-test)
- (require 'org-test-ob-consts))
-
+;;; Code:
(defmacro test-org-in-property-buffer (&rest body)
`(with-temp-buffer
(insert-file-contents (expand-file-name "property-inheritance.org"
org-test-example-dir))
(org-mode)
,@body))
+(def-edebug-spec test-org-in-property-buffer (body))
(ert-deftest test-org-property-accumulation-top-use ()
(test-org-in-property-buffer
diff --git a/testing/org-test-ob-consts.el b/testing/org-test-ob-consts.el
index 75b4e3b..c0cb181 100644
--- a/testing/org-test-ob-consts.el
+++ b/testing/org-test-ob-consts.el
@@ -1,6 +1,6 @@
;;; org-test-ob-consts.el --- constants for use in code block tests
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010-2012 Eric Schulte
;; Authors: Eric Schulte
;; Released under the GNU General Public License version 3
@@ -20,4 +20,4 @@ (defconst org-test-link-in-heading-file-ob-anchor
(provide 'org-test-ob-consts)
-;;; org-test-ob-consts.el ends here
\ No newline at end of file
+;;; org-test-ob-consts.el ends here
diff --git a/testing/org-test.el b/testing/org-test.el
index 255cb96..f255584 100644
--- a/testing/org-test.el
+++ b/testing/org-test.el
@@ -1,6 +1,6 @@
;;;; org-test.el --- Tests for Org-mode
-;; Copyright (c) 2010 Sebastian Rose, Eric Schulte
+;; Copyright (c) 2010-2012 Sebastian Rose, Eric Schulte
;; Authors:
;; Sebastian Rose, Hannover, Germany, sebastian_rose gmx de
;; Eric Schulte, Santa Fe, New Mexico, USA, schulte.eric gmail com
@@ -30,6 +30,8 @@
\f
;;;; Code:
+(require 'org-test-ob-consts)
+
(let* ((org-test-dir (expand-file-name
(file-name-directory
(or load-file-name buffer-file-name))))
@@ -170,6 +172,7 @@ (defmacro org-test-in-example-file (file &rest body)
(save-restriction ,@body)))
(unless visited-p
(kill-buffer to-be-removed))))
+(def-edebug-spec org-test-in-example-file (form body))
(defmacro org-test-at-marker (file marker &rest body)
"Run body after placing the point at MARKER in FILE.
@@ -198,7 +201,7 @@ (defmacro org-test-with-temp-text (text &rest body)
(goto-char ,(match-beginning 0)))
`(progn (insert ,inside-text)
(goto-char (point-min)))))
- ,@body)))
+ (prog1 ,@body (kill-buffer)))))
(def-edebug-spec org-test-with-temp-text (form body))
(defmacro org-test-with-temp-text-in-file (text &rest body)
@@ -223,12 +226,8 @@ (defmacro org-test-with-temp-text-in-file (text &rest body)
(defjump org-test-jump
(("lisp/\\1.el" . "testing/lisp/test-\\1.el")
("lisp/\\1.el" . "testing/lisp/\\1.el/test.*.el")
- ("contrib/lisp/\\1.el" . "testing/contrib/lisp/test-\\1.el")
- ("contrib/lisp/\\1.el" . "testing/contrib/lisp/\\1.el/test.*.el")
("testing/lisp/test-\\1.el" . "lisp/\\1.el")
- ("testing/lisp/\\1.el" . "lisp/\\1.el/test.*.el")
- ("testing/contrib/lisp/test-\\1.el" . "contrib/lisp/\\1.el")
- ("testing/contrib/lisp/test-\\1.el" . "contrib/lisp/\\1.el/test.*.el"))
+ ("testing/lisp/\\1.el" . "lisp/\\1.el/test.*.el"))
(concat org-base-dir "/")
"Jump between org-mode files and their tests."
(lambda (path)
@@ -312,8 +311,7 @@ (defun org-test-load ()
:expected-result :failed (should nil))))))))
(directory-files base 'full
"^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*\\.el$"))))
- (rld (expand-file-name "lisp" org-test-dir))
- (rld (expand-file-name "lisp" (expand-file-name "contrib" org-test-dir)))))
+ (rld (expand-file-name "lisp" org-test-dir))))
(defun org-test-current-defun ()
"Test the current function."
@@ -328,11 +326,20 @@ (defun org-test-current-file ()
(file-name-nondirectory (buffer-file-name)))
"/")))
+(defvar org-test-buffers nil
+ "Hold buffers open for running Org-mode tests.")
+
(defun org-test-touch-all-examples ()
(dolist (file (directory-files
org-test-example-dir 'full
"^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*\\.org$"))
- (find-file file)))
+ (unless (get-file-buffer file)
+ (add-to-list 'org-test-buffers (find-file file)))))
+
+(defun org-test-kill-all-examples ()
+ (while org-test-buffers
+ (let ((b (pop org-test-buffers)))
+ (when (buffer-live-p b) (kill-buffer b)))))
(defun org-test-update-id-locations ()
(org-id-update-id-locations
@@ -361,7 +368,8 @@ (defun org-test-run-all-tests ()
(interactive)
(org-test-touch-all-examples)
(org-test-load)
- (ert "\\(org\\|ob\\)"))
+ (ert "\\(org\\|ob\\)")
+ (org-test-kill-all-examples))
(provide 'org-test)
--
1.7.9.2
[-- Attachment #3: Fixup for maint branch --]
[-- Type: text/x-patch, Size: 507765 bytes --]
From d735714fb82ebd1f1a5ba7ccdc741177b0bc2bd1 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Sun, 18 Mar 2012 21:30:49 +0100
Subject: [PATCH] Maint fixup
---
EXPERIMENTAL/org-e-ascii.el | 1927 --------
EXPERIMENTAL/org-e-html.el | 3162 --------------
EXPERIMENTAL/org-e-odt.el | 4589 --------------------
EXPERIMENTAL/org-e-publish.el | 1211 ------
| 155 -
.../BasicODConverter/BasicODConverter-0.8.0.oxt | Bin 0 -> 8009 bytes
contrib/odt/BasicODConverter/Filters.bas | 213 +
contrib/odt/BasicODConverter/Main.bas | 201 +
lisp/ob-io.el | 122 -
lisp/ob-scala.el | 120 -
testing/README | 45 -
testing/README.org | 115 +
testing/contrib/lisp/.gitignore | 1 +
testing/examples/include.org | 10 -
testing/examples/include2.org | 1 -
testing/examples/table.org | 19 +
testing/lisp/test-org-element.el | 436 --
testing/lisp/test-org-export.el | 625 ---
18 files changed, 549 insertions(+), 12403 deletions(-)
delete mode 100644 EXPERIMENTAL/org-e-ascii.el
delete mode 100644 EXPERIMENTAL/org-e-html.el
delete mode 100644 EXPERIMENTAL/org-e-odt.el
delete mode 100644 EXPERIMENTAL/org-e-publish.el
delete mode 100644 contrib/lisp/org-bibtex-extras.el
create mode 100644 contrib/odt/BasicODConverter/BasicODConverter-0.8.0.oxt
create mode 100644 contrib/odt/BasicODConverter/Filters.bas
create mode 100644 contrib/odt/BasicODConverter/Main.bas
delete mode 100644 lisp/ob-io.el
delete mode 100644 lisp/ob-scala.el
delete mode 100644 testing/README
create mode 100644 testing/README.org
create mode 100644 testing/contrib/lisp/.gitignore
delete mode 100644 testing/examples/include.org
delete mode 100644 testing/examples/include2.org
create mode 100644 testing/examples/table.org
delete mode 100644 testing/lisp/test-org-element.el
delete mode 100644 testing/lisp/test-org-export.el
diff --git a/EXPERIMENTAL/org-e-ascii.el b/EXPERIMENTAL/org-e-ascii.el
deleted file mode 100644
index a4b5cbf..0000000
--- a/EXPERIMENTAL/org-e-ascii.el
+++ /dev/null
@@ -1,1927 +0,0 @@
-;;; org-e-ascii.el --- ASCII Back-End For Org Export Engine
-
-;; Copyright (C) 2012 Free Software Foundation, Inc.
-
-;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
-;; Keywords: outlines, hypermedia, calendar, wp
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library implements an ASCII back-end for Org generic exporter.
-
-;; To test it, run
-;;
-;; M-: (org-export-to-buffer 'e-ascii "*Test e-ASCII*") RET
-;;
-;; in an Org mode buffer then switch to that buffer to see the ASCII
-;; export. See contrib/lisp/org-export.el for more details on how
-;; this exporter works.
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-
-(declare-function org-element-contents "org-element" (element))
-(declare-function org-element-property "org-element" (property element))
-(declare-function org-element-normalize-string "org-element" (s))
-(declare-function org-element-map "org-element"
- (data types fun &optional info first-match))
-(declare-function org-element-time-stamp-interpreter
- "org-element" (time-stamp contents))
-
-(declare-function org-export-clean-table "org-export" (table specialp))
-(declare-function org-export-collect-footnote-definitions
- "org-export" (data info))
-(declare-function org-export-collect-headlines "org-export" (info &optional n))
-(declare-function org-export-collect-listings "org-export" (info))
-(declare-function org-export-collect-tables "org-export" (info))
-(declare-function org-export-data "org-export" (data backend info))
-(declare-function org-export-expand-macro "org-export" (macro info))
-(declare-function org-export-format-code-default "org-export" (element info))
-(declare-function org-export-get-coderef-format "org-export" (path desc))
-(declare-function org-export-get-footnote-number "org-export" (footnote info))
-(declare-function org-export-get-headline-number "org-export" (headline info))
-(declare-function org-export-get-ordinal "org-export"
- (element info &optional types predicate))
-(declare-function org-export-get-parent-headline "org-export" (blob info))
-(declare-function org-export-get-relative-level "org-export" (headline info))
-(declare-function org-export-included-file "org-export" (keyword backend info))
-(declare-function org-export-low-level-p "org-export" (headline info))
-(declare-function org-export-output-file-name "org-export"
- (extension &optional subtreep pub-dir))
-(declare-function org-export-resolve-coderef "org-export" (ref info))
-(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
-(declare-function org-export-resolve-id-link "org-export" (link info))
-(declare-function org-export-resolve-ref-link "org-export" (link info))
-(declare-function org-export-secondary-string
- "org-export" (secondary backend info))
-(declare-function org-export-table-format-info "org-export" (table))
-(declare-function
- org-export-to-file "org-export"
- (backend file &optional subtreep visible-only body-only ext-plist))
-
-
-\f
-;;; Internal Variables
-
-;; The following setting won't allow to modify preferred charset
-;; through a buffer keyword or an option item, but, since the property
-;; will appear in communication channel nonetheless, it allows to
-;; override `org-e-ascii-charset' variable on the fly by the ext-plist
-;; mechanism.
-
-;; We also install a filter for headlines and sections, in order to
-;; control blank lines separating them in output string.
-
-(defconst org-e-ascii-option-alist
- '((:ascii-charset nil nil org-e-ascii-charset)
- )
- "Alist between ASCII export properties and ways to set them.
-See `org-export-option-alist' for more information on the
-structure or the values.")
-
-(defconst org-e-ascii-filters-alist
- '((:filter-headline . org-e-ascii-filter-headline-blank-lines)
- (:filter-section . org-e-ascii-filter-headline-blank-lines))
- "Alist between filters keywords and back-end specific filters.
-See `org-export-filters-alist' for more information.")
-
-(defconst org-e-ascii-dictionary
- '(("Footnotes\n"
- ("en"
- :ascii "Footnotes\n"
- :latin1 "Footnotes\n"
- :utf-8 "Footnotes\n")
- ("fr"
- :ascii "Notes de bas de page\n"
- :latin1 "Notes de bas de page\n"
- :utf-8 "Notes de bas de page\n"))
- ("Listing %d: %s"
- ("en"
- :ascii "Listing %d: %s"
- :latin1 "Listing %d: %s"
- :utf-8 "Listing %d: %s")
- ("fr"
- :ascii "Programme %d : %s"
- :latin1 "Programme %d : %s"
- :utf-8 "Programme nº %d : %s"))
- ("List Of Listings\n"
- ("en"
- :ascii "List Of Listings\n"
- :latin1 "List Of Listings\n"
- :utf-8 "List Of Listings\n")
- ("fr"
- :ascii "Liste des programmes\n"
- :latin1 "Liste des programmes\n"
- :utf-8 "Liste des programmes\n"))
- ("List Of Tables\n"
- ("en"
- :ascii "List Of Tables\n"
- :latin1 "List Of Tables\n"
- :utf-8 "List Of Tables\n")
- ("fr"
- :ascii "Liste des tableaux\n"
- :latin1 "Liste des tableaux\n"
- :utf-8 "Liste des tableaux\n"))
- ("Listing %d: "
- ("en"
- :ascii "Listing %d: "
- :latin1 "Listing %d: "
- :utf-8 "Listing %d: ")
- ("fr"
- :ascii "Programme %d : "
- :latin1 "Programme %d : "
- :utf-8 "Programme nº %d : "))
- ("Table Of Contents\n"
- ("en"
- :ascii "Table Of Contents\n"
- :latin1 "Table Of Contents\n"
- :utf-8 "Table Of Contents\n")
- ("fr"
- :ascii "Sommaire\n"
- :latin1 "Table des matières\n"
- :utf-8 "Table des matières\n"))
- ("Table %d: %s"
- ("en"
- :ascii "Table %d: %s"
- :latin1 "Table %d: %s"
- :utf-8 "Table %d: %s")
- ("fr"
- :ascii "Tableau %d : %s"
- :latin1 "Tableau %d : %s"
- :utf-8 "Tableau nº %d : %s"))
- ("See section %s"
- ("en"
- :ascii "See section %s"
- :latin1 "See section %s"
- :utf-8 "See section %s")
- ("fr"
- :ascii "cf. section %s"
- :latin1 "cf. section %s"
- :utf-8 "cf. section %s"))
- ("Table %d: "
- ("en"
- :ascii "Table %d: "
- :latin1 "Table %d: "
- :utf-8 "Table %d: ")
- ("fr"
- :ascii "Tableau %d : "
- :latin1 "Tableau %d : "
- :utf-8 "Tableau nº %d : "))
- ("Unknown reference"
- ("en"
- :ascii "Unknown reference"
- :latin1 "Unknown reference"
- :utf-8 "Unknown reference")
- ("fr"
- :ascii "Destination inconnue"
- :latin1 "Référence inconnue"
- :utf-8 "Référence inconnue")))
- "Dictionary for ASCII back-end.
-
-Alist whose car is the string to translate and cdr is an alist
-whose car is the language string and cdr is a plist whose
-properties are possible charsets and value the translated term.
-
-It is used as a database for `org-e-ascii--translate'.")
-
-
-\f
-;;; User Configurable Variables
-
-(defgroup org-export-e-ascii nil
- "Options for exporting Org mode files to ASCII."
- :tag "Org Export ASCII"
- :group 'org-export)
-
-(defcustom org-e-ascii-text-width 72
- "Maximum width of exported text.
-This number includes margin size, as set in
-`org-e-ascii-global-margin'."
- :group 'org-export-e-ascii
- :type 'integer)
-
-(defcustom org-e-ascii-global-margin 0
- "Width of the left margin, in number of characters."
- :group 'org-export-e-ascii
- :type 'integer)
-
-(defcustom org-e-ascii-inner-margin 2
- "Width of the inner margin, in number of characters.
-Inner margin is applied between each headline."
- :group 'org-export-e-ascii
- :type 'integer)
-
-(defcustom org-e-ascii-quote-margin 6
- "Width of margin used for quoting text, in characters.
-This margin is applied on both sides of the text."
- :group 'org-export-e-ascii
- :type 'integer)
-
-(defcustom org-e-ascii-inlinetask-width 30
- "Width of inline tasks, in number of characters.
-This number ignores any margin."
- :group 'org-export-e-ascii
- :type 'integer)
-
-(defcustom org-e-ascii-headline-spacing '(1 . 2)
- "Number of blank lines inserted around headlines.
-
-This variable can be set to a cons cell. In that case, its car
-represents the number of blank lines present before headline
-contents whereas its cdr reflects the number of blank lines after
-contents.
-
-A nil value replicates the number of blank lines found in the
-original Org buffer at the same place."
- :group 'org-export-e-ascii
- :type '(choice
- (const :tag "Replicate original spacing" nil)
- (cons :tag "Set an uniform spacing"
- (integer :tag "Number of blank lines before contents")
- (integer :tag "Number of blank lines after contents"))))
-
-(defcustom org-e-ascii-charset 'ascii
- "The charset allowed to represent various elements and objects.
-Possible values are:
-`ascii' Only use plain ASCII characters
-`latin1' Include Latin-1 characters
-`utf-8' Use all UTF-8 characters"
- :group 'org-export-e-ascii
- :type '(choice
- (const :tag "ASCII" ascii)
- (const :tag "Latin-1" latin1)
- (const :tag "UTF-8" utf-8)))
-
-(defcustom org-e-ascii-underline '((ascii ?= ?~ ?-)
- (latin1 ?= ?~ ?-)
- (utf-8 ?═ ?─ ?╌ ?┄ ?┈))
- "Characters for underlining headings in ASCII export.
-
-Alist whose key is a symbol among `ascii', `latin1' and `utf-8'
-and whose value is a list of characters.
-
-For each supported charset, this variable associates a sequence
-of underline characters. In a sequence, the characters will be
-used in order for headlines level 1, 2, ... If no character is
-available for a given level, the headline won't be underlined."
- :group 'org-export-e-ascii
- :type '(list
- (cons :tag "Underline characters sequence"
- (const :tag "ASCII charset" ascii)
- (repeat character))
- (cons :tag "Underline characters sequence"
- (const :tag "Latin-1 charset" latin1)
- (repeat character))
- (cons :tag "Underline characters sequence"
- (const :tag "UTF-8 charset" utf-8)
- (repeat character))))
-
-(defcustom org-e-ascii-bullets '((ascii ?* ?+ ?-)
- (latin1 ?§ ?¶)
- (utf-8 ?◊))
- "Bullet characters for headlines converted to lists in ASCII export.
-
-Alist whose key is a symbol among `ascii', `latin1' and `utf-8'
-and whose value is a list of characters.
-
-The first character is used for the first level considered as low
-level, and so on. If there are more levels than characters given
-here, the list will be repeated.
-
-Note that this variable doesn't affect plain lists
-representation."
- :group 'org-export-e-ascii
- :type '(list
- (cons :tag "Bullet characters for low level headlines"
- (const :tag "ASCII charset" ascii)
- (repeat character))
- (cons :tag "Bullet characters for low level headlines"
- (const :tag "Latin-1 charset" latin1)
- (repeat character))
- (cons :tag "Bullet characters for low level headlines"
- (const :tag "UTF-8 charset" utf-8)
- (repeat character))))
-
-(defcustom org-e-ascii-links-to-notes t
- "Non-nil means convert links to notes before the next headline.
-When nil, the link will be exported in place. If the line
-becomes long in this way, it will be wrapped."
- :group 'org-export-e-ascii
- :type 'boolean)
-
-(defcustom org-e-ascii-table-keep-all-vertical-lines nil
- "Non-nil means keep all vertical lines in ASCII tables.
-When nil, vertical lines will be removed except for those needed
-for column grouping."
- :group 'org-export-e-ascii
- :type 'boolean)
-
-(defcustom org-e-ascii-table-widen-columns t
- "Non-nil means widen narrowed columns for export.
-When nil, narrowed columns will look in ASCII export just like in
-Org mode, i.e. with \"=>\" as ellipsis."
- :group 'org-export-e-ascii
- :type 'boolean)
-
-(defcustom org-e-ascii-caption-above nil
- "When non-nil, place caption string before the element.
-Otherwise, place it right after it."
- :group 'org-export-e-ascii
- :type 'boolean)
-
-(defcustom org-e-ascii-verbatim-format "`%s'"
- "Format string used for verbatim text and inline code."
- :group 'org-export-e-ascii
- :type 'string)
-
-(defcustom org-e-ascii-format-drawer-function nil
- "Function called to format a drawer in ASCII.
-
-The function must accept two parameters:
- NAME the drawer name, like \"LOGBOOK\"
- CONTENTS the contents of the drawer.
- WIDTH the text width within the drawer.
-
-The function should return either the string to be exported or
-nil to ignore the drawer.
-
-For example, the variable could be set to the following function
-in order to mimic default behaviour:
-
-\(defun org-e-ascii-format-drawer-default \(name contents width\)
- \"Format a drawer element for ASCII export.\"
- contents\)"
- :group 'org-export-e-ascii
- :type 'function)
-
-(defcustom org-e-ascii-format-inlinetask-function nil
- "Function called to format an inlinetask in ASCII.
-
-The function must accept six parameters:
- TODO the todo keyword, as a string
- TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
- PRIORITY the inlinetask priority, as a string
- NAME the inlinetask name, as a string.
- TAGS the inlinetask tags, as a string.
- CONTENTS the contents of the inlinetask, as a string.
-
-The function should return either the string to be exported or
-nil to ignore the inline task.
-
-For example, the variable could be set to the following function
-in order to mimic default behaviour:
-
-\(defun org-e-ascii-format-inlinetask-default
- \(todo type priority name tags contents\)
- \"Format an inline task element for ASCII export.\"
- \(let* \(\(utf8p \(eq \(plist-get info :ascii-charset\) 'utf-8\)\)
- \(width org-e-ascii-inlinetask-width\)
- \(org-e-ascii--indent-string
- \(concat
- ;; Top line, with an additional blank line if not in UTF-8.
- \(make-string width \(if utf8p ?━ ?_\)\) \"\\n\"
- \(unless utf8p \(concat \(make-string width ? \) \"\\n\"\)\)
- ;; Add title. Fill it if wider than inlinetask.
- \(let \(\(title \(org-e-ascii--build-title inlinetask info width\)\)\)
- \(if \(<= \(length title\) width\) title
- \(org-e-ascii--fill-string title width info\)\)\)
- \"\\n\"
- ;; If CONTENTS is not empty, insert it along with
- ;; a separator.
- \(when \(org-string-nw-p contents\)
- \(concat \(make-string width \(if utf8p ?─ ?-\)\) \"\\n\" contents\)\)
- ;; Bottom line.
- \(make-string width \(if utf8p ?━ ?_\)\)\)
- ;; Flush the inlinetask to the right.
- \(- \(plist-get info :ascii-width\)
- \(plist-get info :ascii-margin\)
- \(plist-get info :ascii-inner-margin\)
- \(org-e-ascii--current-text-width inlinetask info\)\)"
- :group 'org-export-e-ascii
- :type 'function)
-
-
-\f
-;;; Internal Functions
-
-;; Internal functions fall into three categories.
-
-;; The first one is about text formatting. The core function is
-;; `org-e-ascii--current-text-width', which determines the current
-;; text width allowed to a given element. In other words, it helps
-;; keeping each line width within maximum text width defined in
-;; `org-e-ascii-text-width'. Once this information is known,
-;; `org-e-ascii--fill-string', `org-e-ascii--justify-string',
-;; `org-e-ascii--box-string' and `org-e-ascii--indent-string' can
-;; operate on a given output string.
-
-;; The second category contains functions handling elements listings,
-;; triggered by "#+TOC:" keyword. As such, `org-e-ascii--build-toc'
-;; returns a complete table of contents, `org-e-ascii--list-listings'
-;; returns a list of referenceable src-block elements, and
-;; `org-e-ascii--list-tables' does the same for table elements.
-
-;; The third category includes general helper functions.
-;; `org-e-ascii--build-title' creates the title for a given headline
-;; or inlinetask element. `org-e-ascii--build-caption' returns the
-;; caption string associated to a table or a src-block.
-;; `org-e-ascii--describe-links' creates notes about links for
-;; insertion at the end of a section. It uses
-;; `org-e-ascii--unique-links' to get the list of links to describe.
-;; Eventually, `org-e-ascii--translate' reads `org-e-ascii-dictionary'
-;; to internationalize output.
-
-
-(defun org-e-ascii--fill-string (s text-width info &optional justify)
- "Fill a string with specified text-width and return it.
-
-S is the string being filled. TEXT-WIDTH is an integer
-specifying maximum length of a line. INFO is the plist used as
-a communication channel.
-
-Optional argument JUSTIFY can specify any type of justification
-among `left', `center', `right' or `full'. A nil value is
-equivalent to `left'. For a justification that doesn't also fill
-string, see `org-e-ascii--justify-string'.
-
-Return nil if S isn't a string."
- ;; Don't fill paragraph when break should be preserved.
- (cond ((not (stringp s)) nil)
- ((plist-get info :preserve-breaks) s)
- (t (with-temp-buffer
- (let ((fill-column text-width)
- (use-hard-newlines t))
- (insert s)
- (fill-region (point-min) (point-max) justify))
- (buffer-string)))))
-
-(defun org-e-ascii--justify-string (s text-width how)
- "Justify string S.
-TEXT-WIDTH is an integer specifying maximum length of a line.
-HOW determines the type of justification: it can be `left',
-`right', `full' or `center'."
- (with-temp-buffer
- (insert s)
- (goto-char (point-min))
- (let ((fill-column text-width))
- (while (< (point) (point-max))
- (justify-current-line how)
- (forward-line)))
- (buffer-string)))
-
-(defun org-e-ascii--indent-string (s width)
- "Indent string S by WIDTH white spaces.
-Empty lines are not indented."
- (when (stringp s)
- (replace-regexp-in-string
- "\\(^\\)\\(?:.*\\S-\\)" (make-string width ? ) s nil nil 1)))
-
-(defun org-e-ascii--box-string (s info)
- "Return string S with a partial box to its left.
-INFO is a plist used as a communicaton channel."
- (let ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)))
- (format (if utf8p "╭────\n%s\n╰────" ",----\n%s\n`----")
- (replace-regexp-in-string
- "^" (if utf8p "│ " "| ")
- ;; Remove last newline character.
- (replace-regexp-in-string "\n[ \t]*\\'" "" s)))))
-
-(defun org-e-ascii--current-text-width (element info)
- "Return maximum text width for ELEMENT's contents.
-INFO is a plist used as a communication channel."
- (case (org-element-type element)
- ;; Elements with an absolute width: `headline' and `inlinetask'.
- (inlinetask org-e-ascii-inlinetask-width)
- ('headline
- (- org-e-ascii-text-width
- (let ((low-level-rank (org-export-low-level-p element info)))
- (if low-level-rank (* low-level-rank 2) org-e-ascii-global-margin))))
- ;; Elements with a relative width: store maximum text width in
- ;; TOTAL-WIDTH.
- (otherwise
- (let* ((genealogy (cons element (org-export-get-genealogy element info)))
- ;; Total width is determined by the presence, or not, of an
- ;; inline task among ELEMENT parents.
- (total-width
- (if (loop for parent in genealogy
- thereis (eq (org-element-type parent) 'inlinetask))
- org-e-ascii-inlinetask-width
- ;; No inlinetask: Remove global margin from text width.
- (- org-e-ascii-text-width
- org-e-ascii-global-margin
- (let ((parent (org-export-get-parent-headline element info)))
- ;; Inner margin doesn't apply to text before first
- ;; headline.
- (if (not parent) 0
- (let ((low-level-rank
- (org-export-low-level-p parent info)))
- ;; Inner margin doesn't apply to contents of
- ;; low level headlines, since they've got their
- ;; own indentation mechanism.
- (if low-level-rank (* low-level-rank 2)
- org-e-ascii-inner-margin))))))))
- (- total-width
- ;; Each `quote-block', `quote-section' and `verse-block' above
- ;; narrows text width by twice the standard margin size.
- (+ (* (loop for parent in genealogy
- when (memq (org-element-type parent)
- '(quote-block quote-section verse-block))
- count parent)
- 2 org-e-ascii-quote-margin)
- ;; Text width within a plain-list is restricted by
- ;; indentation of current item. If that's the case,
- ;; compute it with the help of `:structure' property from
- ;; parent item, if any.
- (let ((parent-item
- (if (eq (org-element-type element) 'item) element
- (loop for parent in genealogy
- when (eq (org-element-type parent) 'item)
- return parent))))
- (if (not parent-item) 0
- ;; Compute indentation offset of the current item,
- ;; that is the sum of the difference between its
- ;; indentation and the indentation of the top item in
- ;; the list and current item bullet's length. Also
- ;; remove tag length (for description lists) or bullet
- ;; length.
- (let ((struct (org-element-property :structure parent-item))
- (beg-item (org-element-property :begin parent-item)))
- (+ (- (org-list-get-ind beg-item struct)
- (org-list-get-ind
- (org-list-get-top-point struct) struct))
- (length
- (or (org-list-get-tag beg-item struct)
- (org-list-get-bullet beg-item struct)))))))))))))
-
-(defun org-e-ascii--build-title
- (element info text-width &optional underline notags)
- "Format ELEMENT title and return it.
-
-ELEMENT is either an `headline' or `inlinetask' element. INFO is
-a plist used as a communication channel. TEXT-WIDTH is an
-integer representing the maximum length of a line.
-
-When optional argument UNDERLINE is non-nil, underline title,
-without the tags, according to `org-e-ascii-underline'
-specifications.
-
-if optional argument NOTAGS is nil, no tags will be added to the
-title."
- (let* ((headlinep (eq (org-element-type element) 'headline))
- (numbers
- ;; Numbering is specific to headlines.
- (and headlinep (org-export-numbered-headline-p element info)
- ;; All tests passed: build numbering string.
- (concat
- (mapconcat
- #'number-to-string
- (org-export-get-headline-number element info) ".")
- " ")))
- (text (org-export-secondary-string
- (org-element-property :title element) 'e-ascii info))
- (todo
- (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property :todo-keyword element)))
- (and todo
- (concat (org-export-secondary-string todo 'e-ascii info)
- " ")))))
- (tags (and (not notags)
- (plist-get info :with-tags)
- (org-element-property :tags element)))
- (priority
- (and (plist-get info :with-priority)
- (concat (org-element-property :priority element) " ")))
- (first-part (concat numbers todo priority text)))
- (concat
- first-part
- ;; Align tags, if any.
- (when tags
- (format
- (format " %%%ds"
- (max (- text-width (1+ (length first-part))) (length tags)))
- tags))
- ;; Maybe underline text, if ELEMENT type is `headline' and an
- ;; underline character has been defined.
- (when (and underline headlinep)
- (let ((under-char
- (nth (1- (org-export-get-relative-level element info))
- (cdr (assq (plist-get info :ascii-charset)
- org-e-ascii-underline)))))
- (and under-char
- (concat "\n"
- (make-string (length first-part) under-char))))))))
-
-(defun org-e-ascii--build-caption (element info)
- "Return caption string for ELEMENT, if applicable.
-
-INFO is a plist used as a communication channel.
-
-The caption string contains the sequence number of ELEMENT if it
-has a name affiliated keyword, along with the real caption, if
-any. Return nil when ELEMENT has no affiliated caption or name
-keyword."
- (let ((caption (org-element-property :caption element))
- (name (org-element-property :name element)))
- (when (or caption name)
- ;; Get sequence number of current src-block among every
- ;; src-block with either a caption or a name.
- (let ((reference
- (org-export-get-ordinal
- element info nil
- (lambda (el) (or (org-element-property :caption el)
- (org-element-property :name el)))))
- (title-fmt (org-e-ascii--translate
- (case (org-element-type element)
- (table "Table %d: %s")
- (src-block "Listing %d: %s")) info)))
- (org-e-ascii--fill-string
- (format
- title-fmt reference
- (if (not caption) name
- (org-export-secondary-string (car caption) 'e-ascii info)))
- (org-e-ascii--current-text-width element info) info)))))
-
-(defun org-e-ascii--build-toc (info &optional n keyword)
- "Return a table of contents.
-
-INFO is a plist used as a communication channel.
-
-Optional argument N, when non-nil, is an integer specifying the
-depth of the table.
-
-Optional argument KEYWORD specifies the TOC keyword, if any, from
-which the table of contents generation has been initiated."
- (let ((title (org-e-ascii--translate "Table Of Contents\n" info)))
- (concat
- title
- (make-string (1- (length title))
- (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
- "\n\n"
- (let ((text-width
- (if keyword (org-e-ascii--current-text-width keyword info)
- (- org-e-ascii-text-width org-e-ascii-global-margin))))
- (mapconcat
- (lambda (headline)
- (let* ((level (org-export-get-relative-level headline info))
- (indent (* (1- level) 3)))
- (concat
- (unless (zerop indent) (concat (make-string (1- indent) ?.) " "))
- (org-e-ascii--build-title
- headline info (- text-width indent) nil
- (eq (plist-get info :with-tags) 'not-in-toc)))))
- (org-export-collect-headlines info n) "\n")))))
-
-(defun org-e-ascii--list-listings (keyword info)
- "Return a list of listings.
-
-KEYWORD is the keyword that initiated the list of listings
-generation. INFO is a plist used as a communication channel."
- (let ((title (org-e-ascii--translate "List Of Listings\n" info)))
- (concat
- title
- (make-string (1- (length title))
- (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
- "\n\n"
- (let ((text-width
- (if keyword (org-e-ascii--current-text-width keyword info)
- (- org-e-ascii-text-width org-e-ascii-global-margin)))
- ;; Use a counter instead of retreiving ordinal of each
- ;; src-block.
- (count 0))
- (mapconcat
- (lambda (src-block)
- ;; Store initial text so its length can be computed. This is
- ;; used to properly align caption right to it in case of
- ;; filling (like contents of a description list item).
- (let ((initial-text
- (format (org-e-ascii--translate "Listing %d: " info)
- (incf count))))
- (concat
- initial-text
- (org-trim
- (org-e-ascii--indent-string
- (org-e-ascii--fill-string
- (let ((caption (org-element-property :caption src-block)))
- (if (not caption) (org-element-property :name src-block)
- (org-export-secondary-string
- ;; Use short name in priority, if available.
- (or (cdr caption) (car caption)) 'e-ascii info)))
- (- text-width (length initial-text)) info)
- (length initial-text))))))
- (org-export-collect-listings info) "\n")))))
-
-(defun org-e-ascii--list-tables (keyword info)
- "Return a list of listings.
-
-KEYWORD is the keyword that initiated the list of listings
-generation. INFO is a plist used as a communication channel."
- (let ((title (org-e-ascii--translate "List Of Tables\n" info)))
- (concat
- title
- (make-string (1- (length title))
- (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
- "\n\n"
- (let ((text-width
- (if keyword (org-e-ascii--current-text-width keyword info)
- (- org-e-ascii-text-width org-e-ascii-global-margin)))
- ;; Use a counter instead of retreiving ordinal of each
- ;; src-block.
- (count 0))
- (mapconcat
- (lambda (table)
- ;; Store initial text so its length can be computed. This is
- ;; used to properly align caption right to it in case of
- ;; filling (like contents of a description list item).
- (let ((initial-text
- (format (org-e-ascii--translate "Table %d: " info)
- (incf count))))
- (concat
- initial-text
- (org-trim
- (org-e-ascii--indent-string
- (org-e-ascii--fill-string
- (let ((caption (org-element-property :caption table)))
- (if (not caption) (org-element-property :name table)
- ;; Use short name in priority, if available.
- (org-export-secondary-string
- (or (cdr caption) (car caption)) 'e-ascii info)))
- (- text-width (length initial-text)) info)
- (length initial-text))))))
- (org-export-collect-tables info) "\n")))))
-
-(defun org-e-ascii--unique-links (element info)
- "Return a list of unique link references in ELEMENT.
-
-ELEMENT is either an headline element or a section element. INFO
-is a plist used as a communication channel.
-
-It covers links that may be found current headline's title, in
-the following section and in any inlinetask's title there."
- (let* (seen
- (unique-link-p
- (function
- ;; Return LINK if it wasn't referenced so far, or nil.
- ;; Update SEEN links along the way.
- (lambda (link)
- (let ((footprint
- (cons (org-element-property :raw-link link)
- (org-element-contents link))))
- (unless (member footprint seen)
- (push footprint seen) link)))))
- (harvest-links-in-title
- (function
- ;; Return a list of all unique links in ELEMENT. ELEMENT
- ;; may be an headline or an inlinetask element.
- (lambda (element)
- (let (acc)
- (dolist (obj (org-element-property :title element) acc)
- (when (eq (org-element-type obj) 'link)
- (let ((link (funcall unique-link-p obj)))
- (and link (push link acc)))))))))
- ;; Retrieve HEADLINE's section, if it exists.
- (section (if (eq (org-element-type element) 'section) element
- (let ((sec (car (org-element-contents element))))
- (and (eq (org-element-type sec) 'section) sec))))
- (headline (if (eq (org-element-type element) 'headline) element
- (org-export-get-parent-headline element info))))
- (append
- ;; Links that may be in HEADLINE's title.
- (funcall harvest-links-in-title headline)
- ;; Get all links in SECTION.
- (org-element-map
- section 'link (lambda (link) (funcall unique-link-p link)) info))))
-
-(defun org-e-ascii--describe-links (links width info)
- "Return a string describing a list of links.
-
-LINKS is a list of link type objects, as returned by
-`org-e-ascii--unique-links'. WIDTH is the text width allowed for
-the output string. INFO is a plist used as a communication
-channel."
- (mapconcat
- (lambda (link)
- (let ((type (org-element-property :type link))
- (anchor (let ((desc (org-element-contents link)))
- (if (not desc) (org-element-property :raw-link link)
- (org-export-secondary-string desc 'e-ascii info)))))
- (cond
- ;; Coderefs, radio links and fuzzy links are ignored.
- ((member type '("coderef" "radio" "fuzzy")) nil)
- ;; Id and custom-id links: Headlines refer to their numbering.
- ((member type '("custom-id" "id"))
- (let ((dest (org-export-resolve-id-link link info)))
- (concat
- (org-e-ascii--fill-string
- (format
- "[%s] %s"
- anchor
- (if (not dest) (org-e-ascii--translate "Unknown reference" info)
- (format
- (org-e-ascii--translate "See section %s" info)
- (mapconcat 'number-to-string
- (org-export-get-headline-number dest info) "."))))
- width info) "\n\n")))
- ;; Do not add a link that cannot be resolved and doesn't have
- ;; any description: destination is already visible in the
- ;; paragraph.
- ((not (org-element-contents link)) nil)
- (t
- (concat
- (org-e-ascii--fill-string
- (format "[%s] %s" anchor (org-element-property :raw-link link))
- width info)
- "\n\n")))))
- links ""))
-
-
-\f
-;;; Template
-
-(defun org-e-ascii-template--document-title (info)
- "Return document title, as a string.
-INFO is a plist used as a communication channel."
- (let ((text-width org-e-ascii-text-width)
- (title (org-export-secondary-string
- (plist-get info :title) 'e-ascii info))
- (author
- (and (plist-get info :with-author)
- (let ((auth (plist-get info :author)))
- (and auth (org-export-secondary-string auth 'e-ascii info)))))
- (email
- (and (plist-get info :with-email)
- (org-export-secondary-string
- (plist-get info :email) 'e-ascii info)))
- (date (plist-get info :date)))
- ;; There are two types of title blocks depending on the presence
- ;; of a title to display.
- (if (string= title "")
- ;; Title block without a title. DATE is positioned at the top
- ;; right of the document, AUTHOR to the top left and EMAIL
- ;; just below.
- (cond
- ((and (org-string-nw-p date) (org-string-nw-p author))
- (concat
- author
- (make-string (- text-width (length date) (length author)) ? )
- date
- (when (org-string-nw-p email) (concat "\n" email))
- "\n\n\n"))
- ((and (org-string-nw-p date) (org-string-nw-p email))
- (concat
- email
- (make-string (- text-width (length date) (length email)) ? )
- date "\n\n\n"))
- ((org-string-nw-p date)
- (concat
- (org-e-ascii--justify-string date text-width 'right)
- "\n\n\n"))
- ((and (org-string-nw-p author) (org-string-nw-p email))
- (concat author "\n" email "\n\n\n"))
- ((org-string-nw-p author) (concat author "\n\n\n"))
- ((org-string-nw-p email) (concat email "\n\n\n")))
- ;; Title block with a title. Document's TITLE, along with the
- ;; AUTHOR and its EMAIL are both overlined and an underlined,
- ;; centered. Date is just below, also centered.
- (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8))
- ;; Format TITLE. It may be filled if it is too wide,
- ;; that is wider than the two thirds of the total width.
- (title-len (min (length title) (/ (* 2 text-width) 3)))
- (formatted-title (org-e-ascii--fill-string title title-len info))
- (line
- (make-string
- (min (+ (max title-len (length author) (length email)) 2)
- text-width) (if utf8p ?━ ?_))))
- (org-e-ascii--justify-string
- (concat line "\n"
- (unless utf8p "\n")
- (upcase formatted-title)
- (cond
- ((and (org-string-nw-p author) (org-string-nw-p email))
- (concat (if utf8p "\n\n\n" "\n\n") author "\n" email))
- ((org-string-nw-p author)
- (concat (if utf8p "\n\n\n" "\n\n") author))
- ((org-string-nw-p email)
- (concat (if utf8p "\n\n\n" "\n\n") email)))
- "\n" line
- (when (org-string-nw-p date) (concat "\n\n\n" date))
- "\n\n\n") text-width 'center)))))
-
-(defun org-e-ascii-template (contents info)
- "Return complete document string after ASCII conversion.
-CONTENTS is the transcoded contents string. INFO is a plist
-holding export options."
- (org-element-normalize-string
- (org-e-ascii--indent-string
- (let ((text-width (- org-e-ascii-text-width org-e-ascii-global-margin)))
- ;; 1. Build title block.
- (concat
- (org-e-ascii-template--document-title info)
- ;; 2. Table of contents.
- (let ((depth (plist-get info :with-toc)))
- (when depth
- (concat
- (org-e-ascii--build-toc info (and (wholenump depth) depth))
- "\n\n\n")))
- ;; 3. Document's body.
- contents
- ;; 4. Footnote definitions.
- (let ((definitions (org-export-collect-footnote-definitions
- (plist-get info :parse-tree) info))
- ;; Insert full links right inside the footnote definition
- ;; as they have no chance to be inserted later.
- (org-e-ascii-links-to-notes nil))
- (when definitions
- (concat
- "\n\n\n"
- (let ((title (org-e-ascii--translate "Footnotes\n" info)))
- (concat
- title
- (make-string
- (1- (length title))
- (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))))
- "\n\n"
- (mapconcat
- (lambda (ref)
- (let ((id (format "[%s] " (car ref))))
- ;; Distinguish between inline definitions and
- ;; full-fledged definitions.
- (org-trim
- (let ((def (nth 2 ref)))
- (if (eq (org-element-type def) 'org-data)
- ;; Full-fledged definition: footnote ID is
- ;; inserted inside the first parsed paragraph
- ;; (FIRST), if any, to be sure filling will
- ;; take it into consideration.
- (let ((first (car (org-element-contents def))))
- (if (not (eq (org-element-type first) 'paragraph))
- (concat id "\n" (org-export-data def 'e-ascii info))
- (push id (nthcdr 2 first))
- (org-export-data def 'e-ascii info)))
- ;; Fill paragraph once footnote ID is inserted in
- ;; order to have a correct length for first line.
- (org-e-ascii--fill-string
- (concat id (org-export-secondary-string def 'e-ascii info))
- text-width info))))))
- definitions "\n\n"))))
- ;; 5. Creator. Ignore `comment' value as there are no comments in
- ;; ASCII. Justify it to the bottom right.
- (let ((creator-info (plist-get info :with-creator)))
- (unless (or (not creator-info) (eq creator-info 'comment))
- (concat
- "\n\n\n"
- (org-e-ascii--fill-string
- (plist-get info :creator) text-width info 'right))))))
- org-e-ascii-global-margin)))
-
-(defun org-e-ascii--translate (s info)
- "Translate string S.
-
-INFO is a plist used as a communication channel.
-
-Translation depends on `:language' property and allowed charset.
-If no translation in found for a given language and a given
-charset, fall-back to S."
- (let* ((charset (intern (format ":%s" (plist-get info :ascii-charset))))
- (lang (plist-get info :language))
- (translations (cdr (assoc s org-e-ascii-dictionary))))
- (or (plist-get (cdr (assoc lang translations)) charset) s)))
-
-
-\f
-;;; Transcode Functions
-
-;;;; Babel Call
-
-;; Babel Calls are ignored.
-
-
-;;;; Center Block
-
-(defun org-e-ascii-center-block (center-block contents info)
- "Transcode a CENTER-BLOCK element from Org to ASCII.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (org-e-ascii--justify-string
- contents (org-e-ascii--current-text-width center-block info) 'center))
-
-
-;;;; Comment
-
-;; Comments are ignored.
-
-
-;;;; Comment Block
-
-;; Comment Blocks are ignored.
-
-
-;;;; Drawer
-
-(defun org-e-ascii-drawer (drawer contents info)
- "Transcode a DRAWER element from Org to ASCII.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let ((name (org-element-property :drawer-name drawer))
- (width (org-e-ascii--current-text-width drawer info)))
- (if (functionp org-e-ascii-format-drawer-function)
- (funcall org-e-ascii-format-drawer-function name contents width)
- ;; If there's no user defined function: simply
- ;; display contents of the drawer.
- contents)))
-
-
-;;;; Dynamic Block
-
-(defun org-e-ascii-dynamic-block (dynamic-block contents info)
- "Transcode a DYNAMIC-BLOCK element from Org to ASCII.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information. See
-`org-export-data'."
- contents)
-
-
-;;;; Emphasis
-
-(defun org-e-ascii-emphasis (emphasis contents info)
- "Transcode EMPHASIS from Org to ASCII.
-CONTENTS is the contents of the emphasized text. INFO is a plist
-holding contextual information.."
- (let ((marker (org-element-property :marker emphasis)))
- ;; Leave emphasis markers as-is.
- (concat marker contents marker)))
-
-
-;;;; Entity
-
-(defun org-e-ascii-entity (entity contents info)
- "Transcode an ENTITY object from Org to ASCII.
-CONTENTS are the definition itself. INFO is a plist holding
-contextual information."
- (org-element-property
- (intern (concat ":" (symbol-name (plist-get info :ascii-charset))))
- entity))
-
-
-;;;; Example Block
-
-(defun org-e-ascii-example-block (example-block contents info)
- "Transcode a EXAMPLE-BLOCK element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-ascii--box-string
- (org-export-format-code-default example-block info) info))
-
-
-;;;; Export Snippet
-
-(defun org-e-ascii-export-snippet (export-snippet contents info)
- "Transcode a EXPORT-SNIPPET object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (when (eq (org-export-snippet-backend export-snippet) 'e-ascii)
- (org-element-property :value export-snippet)))
-
-
-;;;; Export Block
-
-(defun org-e-ascii-export-block (export-block contents info)
- "Transcode a EXPORT-BLOCK element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (when (string= (org-element-property :type export-block) "ascii")
- (org-remove-indentation (org-element-property :value export-block))))
-
-
-;;;; Fixed Width
-
-(defun org-e-ascii-fixed-width (fixed-width contents info)
- "Transcode a FIXED-WIDTH element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-ascii--box-string
- (replace-regexp-in-string
- "^[ \t]*: ?" "" (org-element-property :value fixed-width)) info))
-
-
-;;;; Footnote Definition
-
-;; Footnote Definitions are ignored. They are compiled at the end of
-;; the document, by `org-e-ascii-template'.
-
-
-;;;; Footnote Reference
-
-(defun org-e-ascii-footnote-reference (footnote-reference contents info)
- "Transcode a FOOTNOTE-REFERENCE element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (format "[%s]" (org-export-get-footnote-number footnote-reference info)))
-
-
-;;;; Headline
-
-(defun org-e-ascii-headline (headline contents info)
- "Transcode an HEADLINE element from Org to ASCII.
-CONTENTS holds the contents of the headline. INFO is a plist
-holding contextual information."
- ;; Don't export footnote section, which will be handled at the end
- ;; of the template.
- (unless (org-element-property :footnote-section-p headline)
- (let* ((low-level-rank (org-export-low-level-p headline info))
- (width (org-e-ascii--current-text-width headline info))
- ;; Blank lines between headline and its contents.
- ;; `org-e-ascii-headline-spacing', when set, overwrites
- ;; original buffer's spacing.
- (pre-blanks
- (make-string
- (if org-e-ascii-headline-spacing (car org-e-ascii-headline-spacing)
- (org-element-property :pre-blank headline)) ?\n))
- ;; Even if HEADLINE has no section, there might be some
- ;; links in its title that we shouldn't forget to describe.
- (links
- (unless (eq (caar (org-element-contents headline)) 'section)
- (org-e-ascii--describe-links
- (org-e-ascii--unique-links headline info) width info))))
- ;; Deep subtree: export it as a list item.
- (if low-level-rank
- (concat
- ;; Bullet.
- (let ((bullets (cdr (assq (plist-get info :ascii-charset)
- org-e-ascii-bullets))))
- (char-to-string
- (nth (mod (1- low-level-rank) (length bullets)) bullets)))
- " "
- ;; Title.
- (org-e-ascii--build-title headline info width) "\n"
- ;; Contents, indented by length of bullet.
- pre-blanks
- (org-e-ascii--indent-string
- (concat contents
- (when (org-string-nw-p links) (concat "\n\n" links)))
- 2))
- ;; Else: Standard headline.
- (concat
- (org-e-ascii--build-title headline info width 'underline)
- "\n" pre-blanks
- (concat (when (org-string-nw-p links) links) contents))))))
-
-
-;;;; Horizontal Rule
-
-(defun org-e-ascii-horizontal-rule (horizontal-rule contents info)
- "Transcode an HORIZONTAL-RULE object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (let ((attr
- (read
- (format
- "(%s)"
- (mapconcat
- #'identity
- (org-element-property :attr_ascii horizontal-rule)
- " ")))))
- (make-string (or (and (wholenump (plist-get attr :width))
- (plist-get attr :width))
- (org-e-ascii--current-text-width horizontal-rule info))
- (if (eq (plist-get info :ascii-charset) 'utf-8) ?― ?-))))
-
-
-;;;; Inline Babel Call
-
-;; Inline Babel Calls are ignored.
-
-
-;;;; Inline Src Block
-
-(defun org-e-ascii-inline-src-block (inline-src-block contents info)
- "Transcode an INLINE-SRC-BLOCK element from Org to ASCII.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (format org-e-ascii-verbatim-format
- (org-element-property :value inline-src-block)))
-
-
-;;;; Inlinetask
-
-(defun org-e-ascii-inlinetask (inlinetask contents info)
- "Transcode an INLINETASK element from Org to ASCII.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let ((width (org-e-ascii--current-text-width inlinetask info))
- (title (org-export-secondary-string
- (org-element-property :title inlinetask) 'e-ascii info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property
- :todo-keyword inlinetask)))
- (and todo
- (org-export-secondary-string todo 'e-ascii info)))))
- (todo-type (org-element-property :todo-type inlinetask))
- (tags (and (plist-get info :with-tags)
- (org-element-property :tags inlinetask)))
- (priority (and (plist-get info :with-priority)
- (org-element-property :priority inlinetask))))
- ;; If `org-e-ascii-format-inlinetask-function' is provided, call it
- ;; with appropriate arguments.
- (if (functionp org-e-ascii-format-inlinetask-function)
- (funcall org-e-ascii-format-inlinetask-function
- todo todo-type priority title tags contents width)
- ;; Otherwise, use a default template.
- (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)))
- (org-e-ascii--indent-string
- (concat
- ;; Top line, with an additional blank line if not in UTF-8.
- (make-string width (if utf8p ?━ ?_)) "\n"
- (unless utf8p (concat (make-string width ? ) "\n"))
- ;; Add title. Fill it if wider than inlinetask.
- (let ((title (org-e-ascii--build-title inlinetask info width)))
- (if (<= (length title) width) title
- (org-e-ascii--fill-string title width info)))
- "\n"
- ;; If CONTENTS is not empty, insert it along with
- ;; a separator.
- (when (org-string-nw-p contents)
- (concat (make-string width (if utf8p ?─ ?-)) "\n" contents))
- ;; Bottom line.
- (make-string width (if utf8p ?━ ?_)))
- ;; Flush the inlinetask to the right.
- (- org-e-ascii-text-width org-e-ascii-global-margin
- (if (not (org-export-get-parent-headline inlinetask info)) 0
- org-e-ascii-inner-margin)
- (org-e-ascii--current-text-width inlinetask info)))))))
-
-
-;;;; Item
-
-(defun org-e-ascii-item (item contents info)
- "Transcode an ITEM element from Org to ASCII.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (let ((bullet
- ;; First parent of ITEM is always the plain-list. Get
- ;; `:type' property from it.
- (org-list-bullet-string
- (case (org-element-property :type (org-export-get-parent item info))
- (descriptive
- (concat
- (org-export-secondary-string
- (org-element-property :tag item) 'e-ascii info) ": "))
- (ordered
- ;; Return correct number for ITEM, paying attention to
- ;; counters.
- (let* ((struct (org-element-property :structure item))
- (bul (org-element-property :bullet item))
- (num
- (number-to-string
- (car (last (org-list-get-item-number
- (org-element-property :begin item)
- struct
- (org-list-prevs-alist struct)
- (org-list-parents-alist struct)))))))
- (replace-regexp-in-string "[0-9]+" num bul)))
- (t (let ((bul (org-element-property :bullet item)))
- ;; Change bullets into more visible form if UTF-8 is active.
- (if (not (eq (plist-get info :ascii-charset) 'utf-8)) bul
- (replace-regexp-in-string
- "-" "•"
- (replace-regexp-in-string
- "+" "⁃"
- (replace-regexp-in-string "*" "‣" bul))))))))))
- (concat
- bullet
- ;; Contents: Pay attention to indentation. Note: check-boxes are
- ;; already taken care of at the paragraph level so they don't
- ;; interfere with indentation.
- (let ((contents (org-e-ascii--indent-string contents (length bullet))))
- (if (eq (caar (org-element-contents item)) 'paragraph)
- (org-trim contents)
- (concat "\n" contents))))))
-
-
-;;;; Keyword
-
-(defun org-e-ascii-keyword (keyword contents info)
- "Transcode a KEYWORD element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (let ((key (downcase (org-element-property :key keyword)))
- (value (org-element-property :value keyword)))
- (cond
- ((string= key "ascii") value)
- ((string= key "toc")
- (let ((value (downcase value)))
- (cond
- ((string-match "\\<headlines\\>" value)
- (let ((depth (or (and (string-match "[0-9]+" value)
- (string-to-number (match-string 0 value)))
- (plist-get info :with-toc))))
- (org-e-ascii--build-toc
- info (and (wholenump depth) depth) keyword)))
- ((string= "tables" value)
- (org-e-ascii--list-tables keyword info))
- ((string= "listings" value)
- (org-e-ascii--list-listings keyword info))))))))
-
-
-;;;; Latex Environment
-
-(defun org-e-ascii-latex-environment (latex-environment contents info)
- "Transcode a LATEX-ENVIRONMENT element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (org-remove-indentation (org-element-property :value latex-environment)))
-
-
-;;;; Latex Fragment
-
-(defun org-e-ascii-latex-fragment (latex-fragment contents info)
- "Transcode a LATEX-FRAGMENT object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (org-element-property :value latex-fragment))
-
-
-;;;; Line Break
-
-(defun org-e-ascii-line-break (line-break contents info)
- "Transcode a LINE-BREAK object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual
- information." hard-newline)
-
-
-;;;; Link
-
-(defun org-e-ascii-link (link desc info)
- "Transcode a LINK object from Org to ASCII.
-
-DESC is the description part of the link, or the empty string.
-INFO is a plist holding contextual information."
- (let ((raw-link (org-element-property :raw-link link))
- (type (org-element-property :type link)))
- (cond
- ((string= type "coderef")
- (let ((ref (org-element-property :path link)))
- (format (org-export-get-coderef-format ref desc)
- (org-export-resolve-coderef ref info))))
- ;; Do not apply a special syntax on radio links. Though, parse
- ;; and transcode path to have a proper display of contents.
- ((string= type "radio")
- (org-export-secondary-string
- (org-element-parse-secondary-string
- (org-element-property :path link)
- (cdr (assq 'radio-target org-element-object-restrictions)))
- 'e-ascii info))
- ;; Do not apply a special syntax on fuzzy links pointing to
- ;; targets.
- ((string= type "fuzzy")
- (let ((destination (org-export-resolve-fuzzy-link link info)))
- ;; Ignore invisible "#+target: path".
- (unless (eq (org-element-type destination) 'keyword)
- (if (org-string-nw-p desc) desc
- (when destination
- (let ((number (org-export-get-ordinal destination info)))
- (when number
- (if (atom number) (number-to-string number)
- (mapconcat 'number-to-string number ".")))))))))
- (t
- (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
- (concat
- (format "[%s]" desc)
- (unless org-e-ascii-links-to-notes (format " (%s)" raw-link))))))))
-
-
-;;;; Macro
-
-(defun org-e-ascii-macro (macro contents info)
- "Transcode a MACRO element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (org-export-expand-macro macro info))
-
-
-;;;; Paragraph
-
-(defun org-e-ascii-paragraph (paragraph contents info)
- "Transcode a PARAGRAPH element from Org to ASCII.
-CONTENTS is the contents of the paragraph, as a string. INFO is
-the plist used as a communication channel."
- (org-e-ascii--fill-string
- (let ((parent (org-export-get-parent paragraph info)))
- ;; If PARAGRAPH is the first one in a list element, be sure to
- ;; add the check-box in front of it, before any filling. Later,
- ;; it would interfere with line width.
- (if (and (eq (org-element-type parent) 'item)
- (equal (car (org-element-contents parent)) paragraph))
- (let ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)))
- (concat (case (org-element-property :checkbox parent)
- (on (if utf8p "☑ " "[X] "))
- (off (if utf8p "☐ " "[ ] "))
- (trans (if utf8p "☒ " "[-] ")))
- contents))
- contents))
- (org-e-ascii--current-text-width paragraph info) info))
-
-
-;;;; Plain List
-
-(defun org-e-ascii-plain-list (plain-list contents info)
- "Transcode a PLAIN-LIST element from Org to ASCII.
-CONTENTS is the contents of the list. INFO is a plist holding
-contextual information."
- contents)
-
-
-;;;; Plain Text
-
-(defun org-e-ascii-plain-text (text info)
- "Transcode a TEXT string from Org to ASCII.
-INFO is a plist used as a communication channel."
- (if (not (and (eq (plist-get info :ascii-charset) 'utf-8)
- (plist-get info :with-special-strings)))
- text
- ;; Usual replacements in utf-8 with proper option set.
- (replace-regexp-in-string
- "\\.\\.\\." "…"
- (replace-regexp-in-string
- "--" "–"
- (replace-regexp-in-string "---" "—" text)))))
-
-
-;;;; Property Drawer
-
-(defun org-e-ascii-property-drawer (property-drawer contents info)
- "Transcode a PROPERTY-DRAWER element from Org to ASCII.
-CONTENTS is nil. INFO is a plist used as a communication
-channel."
- ;; The property drawer isn't exported but we want separating blank
- ;; lines nonetheless.
- "")
-
-
-;;;; Quote Block
-
-(defun org-e-ascii-quote-block (quote-block contents info)
- "Transcode a QUOTE-BLOCK element from Org to ASCII.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let ((width (org-e-ascii--current-text-width quote-block info)))
- (org-e-ascii--indent-string
- (org-remove-indentation
- (org-e-ascii--fill-string contents width info))
- org-e-ascii-quote-margin)))
-
-
-;;;; Quote Section
-
-(defun org-e-ascii-quote-section (quote-section contents info)
- "Transcode a QUOTE-SECTION element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((width (org-e-ascii--current-text-width quote-section info))
- (value
- (org-export-secondary-string
- (org-remove-indentation
- (org-element-property :value quote-section)) 'e-ascii info)))
- (org-e-ascii--indent-string
- value
- (+ org-e-ascii-quote-margin
- ;; Don't apply inner margin if parent headline is low level.
- (let ((headline (org-export-get-parent-headline quote-section info)))
- (if (org-export-low-level-p headline info) 0
- org-e-ascii-inner-margin))))))
-
-
-;;;; Radio Target
-
-(defun org-e-ascii-radio-target (radio-target contents info)
- "Transcode a RADIO-TARGET object from Org to ASCII.
-CONTENTS is the contents of the target. INFO is a plist holding
-contextual information."
- contents)
-
-;;;; Section
-
-(defun org-e-ascii-section (section contents info)
- "Transcode a SECTION element from Org to ASCII.
-CONTENTS is the contents of the section. INFO is a plist holding
-contextual information."
- (org-e-ascii--indent-string
- (concat
- contents
- (when org-e-ascii-links-to-notes
- ;; Add list of links at the end of SECTION.
- (let ((links (org-e-ascii--describe-links
- (org-e-ascii--unique-links section info)
- (org-e-ascii--current-text-width section info) info)))
- ;; Separate list of links and section contents.
- (when (org-string-nw-p links) (concat "\n\n" links)))))
- ;; Do not apply inner margin if parent headline is low level.
- (let ((headline (org-export-get-parent-headline section info)))
- (if (or (not headline) (org-export-low-level-p headline info)) 0
- org-e-ascii-inner-margin))))
-
-
-;;;; Special Block
-
-(defun org-e-ascii-special-block (special-block contents info)
- "Transcode a SPECIAL-BLOCK element from Org to ASCII.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- contents)
-
-
-;;;; Src Block
-
-(defun org-e-ascii-src-block (src-block contents info)
- "Transcode a SRC-BLOCK element from Org to ASCII.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (let ((caption (org-e-ascii--build-caption src-block info)))
- (concat
- (when (and caption org-e-ascii-caption-above) (concat caption "\n"))
- (org-e-ascii--box-string
- (org-export-format-code-default src-block info) info)
- (when (and caption (not org-e-ascii-caption-above))
- (concat "\n" caption)))))
-
-;;;; Statistics Cookie
-
-(defun org-e-ascii-statistics-cookie (statistics-cookie contents info)
- "Transcode a STATISTICS-COOKIE object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-property :value statistics-cookie))
-
-
-;;;; Subscript
-
-(defun org-e-ascii-subscript (subscript contents info)
- "Transcode a SUBSCRIPT object from Org to ASCII.
-CONTENTS is the contents of the object. INFO is a plist holding
-contextual information."
- (if (org-element-property :use-brackets-p subscript)
- (format "_{%s}" contents)
- (format "_%s" contents)))
-
-
-;;;; Superscript
-
-(defun org-e-ascii-superscript (superscript contents info)
- "Transcode a SUPERSCRIPT object from Org to ASCII.
-CONTENTS is the contents of the object. INFO is a plist holding
-contextual information."
- (if (org-element-property :use-brackets-p superscript)
- (format "_{%s}" contents)
- (format "_%s" contents)))
-
-
-;;;; Table
-
-;; While `org-e-ascii-table' is the callback function expected by
-;; org-export mechanism, it requires four subroutines to display
-;; tables accordingly to chosen charset, alignment and width
-;; specifications.
-
-;; Thus, `org-e-ascii-table--column-width' computes the display width
-;; for each column in the table,
-;; `org-e-ascii-table--vertical-separators' returns a vector
-;; containing separators (or lack thereof),
-;; `org-e-ascii-table--build-hline' creates various hline strings,
-;; depending on charset, separators and position within the tabl and
-;; `org-e-ascii-table--format-cell' properly aligns contents within
-;; a given cell and width.
-
-(defun org-e-ascii-table (table contents info)
- "Transcode a TABLE element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((raw-table (org-element-property :raw-table table))
- (caption (org-e-ascii--build-caption table info)))
- (concat
- ;; Possibly add a caption string above.
- (when (and caption org-e-ascii-caption-above) (concat caption "\n"))
- ;; Insert table. Note: "table.el" tables are left unmodified.
- (if (eq (org-element-property :type table) 'table.el) raw-table
- (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8))
- ;; Extract information out of the raw table (TABLE-INFO)
- ;; and clean it (CLEAN-TABLE).
- (table-info (org-export-table-format-info raw-table))
- (special-col-p (plist-get table-info :special-column-p))
- (alignment (plist-get table-info :alignment))
- (clean-table (org-export-clean-table raw-table special-col-p))
- ;; Change table into lisp, much like
- ;; `org-table-to-lisp', though cells are parsed and
- ;; transcoded along the way.
- (lisp-table
- (mapcar
- (lambda (line)
- (if (string-match org-table-hline-regexp line) 'hline
- (mapcar
- (lambda (cell)
- (org-trim
- (org-export-secondary-string
- (org-element-parse-secondary-string
- cell
- (cdr (assq 'item org-element-string-restrictions)))
- 'e-ascii info)))
- (org-split-string (org-trim line) "\\s-?|\\s-?"))))
- (org-split-string clean-table "[ \t]*\n[ \t]*")))
- ;; Compute real column widths.
- (column-widths
- (org-e-ascii-table--column-width lisp-table table-info))
- ;; Construct separators according to column groups.
- (separators (org-e-ascii-table--vertical-separators table-info))
- ;; Build different `hline' strings, depending on
- ;; separators, column widths and position.
- (hline-standard
- (org-e-ascii-table--build-hline
- nil separators column-widths info))
- (hline-top
- (and utf8p (org-e-ascii-table--build-hline
- 'top separators column-widths info)))
- (hline-bottom
- (and utf8p (org-e-ascii-table--build-hline
- 'bottom separators column-widths info))))
- ;; Now build table back, with correct alignment, considering
- ;; columns widths and separators.
- (mapconcat
- (lambda (line)
- (cond
- ((eq line 'hline) hline-standard)
- ((eq line 'hline-bottom) hline-bottom)
- ((eq line 'hline-top) hline-top)
- (t (loop for cell in line
- for col from 0 to (length line)
- concat
- (concat
- (let ((sep (aref separators col)))
- (if (and utf8p (not (string= sep ""))) "│" sep))
- (org-e-ascii-table--format-cell
- cell col column-widths alignment info)) into l
- finally return
- (concat l
- (let ((sep (aref separators col)))
- (if (and utf8p (not (string= sep ""))) "│"
- sep)))))))
- ;; If charset is `utf-8', make sure lisp-table always starts
- ;; with `hline-top' and ends with `hline-bottom'.
- (if (not utf8p) lisp-table
- (setq lisp-table
- (cons 'hline-top
- (if (eq (car lisp-table) 'hline) (cdr lisp-table)
- lisp-table)))
- (setq lisp-table
- (nconc
- (if (eq (car (last lisp-table)) 'hline) (butlast lisp-table)
- lisp-table)
- '(hline-bottom)))) "\n")))
- ;; Possible add a caption string below.
- (when (and caption (not org-e-ascii-caption-above))
- (concat "\n" caption)))))
-
-(defun org-e-ascii-table--column-width (table table-info)
- "Return vector of TABLE columns width.
-
-TABLE is the Lisp representation of the Org table considered.
-TABLE-INFO holds information about the table. See
-`org-export-table-format-info'.
-
-Unlike to `:width' property from `org-export-table-format-info',
-the return value is a vector containing width of every column,
-not only those with an explicit width cookie. Special column, if
-any, is ignored."
- ;; All rows have the same length, but be sure to ignore hlines.
- (let ((width (make-vector
- (loop for row in table
- unless (eq row 'hline)
- return (length row))
- 0)))
- ;; Set column width to the maximum width of the cells in that
- ;; column.
- (mapc
- (lambda (line)
- (let ((idx 0))
- (unless (eq line 'hline)
- (mapc (lambda (cell)
- (let ((len (length cell)))
- (when (> len (aref width idx)) (aset width idx len)))
- (incf idx))
- line))))
- table)
- (unless org-e-ascii-table-widen-columns
- ;; When colums are not widened, width cookies have precedence
- ;; over string lengths. Thus, overwrite the latter with the
- ;; former.
- (let ((cookies (plist-get table-info :width))
- (specialp (plist-get table-info :special-column-p)))
- ;; Remove special column from COOKIES vector, if any.
- (loop for w across (if specialp (substring cookies 1) cookies)
- for idx from 0 to width
- when w do (aset width idx w))))
- ;; Return value.
- width))
-
-(defun org-e-ascii-table--vertical-separators (table-info)
- "Return a vector of strings for vertical separators.
-
-TABLE-INFO holds information about considered table. See
-`org-export-table-format-info'.
-
-Return value is a vector whose length is one more than the number
-of columns in the table. Special column, if any, is ignored."
- (let* ((colgroups (plist-get table-info :column-groups))
- (separators (make-vector (1+ (length colgroups)) "")))
- (if org-e-ascii-table-keep-all-vertical-lines
- (make-vector (length separators) "|")
- (let ((column 0))
- (mapc (lambda (group)
- (when (memq group '(start start-end))
- (aset separators column "|"))
- (when (memq group '(end start-end))
- (aset separators (1+ column) "|"))
- (incf column))
- colgroups)
- ;; Remove unneeded special column.
- (if (not (plist-get table-info :special-column-p)) separators
- (substring separators 1))))))
-
-(defun org-e-ascii-table--format-cell (cell col width alignment info)
- "Format CELL with column width and alignment constraints.
-
-CELL is the contents of the cell, as a string.
-
-COL is the column containing the cell considered.
-
-WIDTH is a vector holding every column width, as returned by
-`org-e-ascii-table--column-width'.
-
-ALIGNMENT is a vector containing alignment strings for every
-column.
-
-INFO is a plist used as a communication channel."
- (let ((col-width (if org-e-ascii-table-widen-columns (aref width col)
- (or (aref width col) (length cell)))))
- ;; When CELL is too large, it has to be truncated.
- (unless (or org-e-ascii-table-widen-columns (<= (length cell) col-width))
- (setq cell (concat (substring cell 0 (- col-width 2)) "=>")))
- (let* ((indent-tabs-mode nil)
- (align (aref alignment col))
- (aligned-cell
- (org-e-ascii--justify-string
- (org-trim cell) col-width
- (cond ((string= align "c") 'center)
- ((string= align "r") 'right)))))
- ;; Return aligned cell, with missing white spaces added and
- ;; space separators between columns.
- (format
- " %s "
- (concat aligned-cell
- (make-string (- col-width (length aligned-cell)) ? ))))))
-
-(defun org-e-ascii-table--build-hline (position separators column-widths info)
- "Return string used as an horizontal line in tables.
-
-POSITION is a symbol among `top', `bottom' and nil, which
-specifies position of the horizontal line within the table.
-
-SEPARATORS is a vector strings specifying separators used in the
-table, as returned by `org-e-ascii-table--vertical-separators'.
-
-COLUMN-WIDTHS is a vector of numbers specifying widths of all
-columns in the table, as returned by
-`org-e-ascii-table--column-width'.
-
-INFO is a plist used as a communication channel."
- (let ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)))
- (loop for idx from 0 to (length separators)
- for width across column-widths
- concat
- (concat
- (cond ((string= (aref separators idx) "") nil)
- ((and utf8p (zerop idx))
- (cond ((eq position 'top) "┍")
- ((eq position 'bottom) "┕")
- (t "├")))
- (utf8p
- (cond ((eq position 'top) "┯")
- ((eq position 'bottom) "┷")
- (t "┼")))
- (t "+"))
- ;; Hline has to cover all the cell and both white spaces
- ;; between columns.
- (make-string (+ width 2)
- (cond ((not utf8p) ?-)
- ((not position) ?─)
- (t ?━))))
- into hline
- finally return
- ;; There is one separator more than columns, so handle it
- ;; here.
- (concat
- hline
- (cond
- ((string= (aref separators idx) "") nil)
- (utf8p (cond ((eq position 'top) "┑")
- ((eq position 'bottom) "┙")
- (t "┤")))
- (t "+"))))))
-
-
-;;;; Target
-
-;; Targets are invisible.
-
-
-;;;; Time-stamp
-
-(defun org-e-ascii-time-stamp (time-stamp contents info)
- "Transcode a TIME-STAMP object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- ;; Return time-stamps as-is.
- (org-element-time-stamp-interpreter time-stamp contents))
-
-
-;;;; Verbatim
-
-(defun org-e-ascii-verbatim (verbatim contents info)
- "Return a VERBATIM object from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (format org-e-ascii-verbatim-format
- (org-element-property :value verbatim)))
-
-
-;;;; Verse Block
-
-(defun org-e-ascii-verse-block (verse-block contents info)
- "Transcode a VERSE-BLOCK element from Org to ASCII.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((verse-width (org-e-ascii--current-text-width verse-block info)))
- (org-e-ascii--indent-string
- (org-e-ascii--justify-string
- (org-export-secondary-string
- (org-element-property :value verse-block) 'e-ascii info)
- verse-width 'left)
- org-e-ascii-quote-margin)))
-
-\f
-;;; Filter
-
-(defun org-e-ascii-filter-headline-blank-lines (headline back-end info)
- "Filter controlling number of blank lines after an headline.
-
-HEADLINE is a string representing a transcoded headline.
-BACK-END is symbol specifying back-end used for export. INFO is
-plist containing the communication channel.
-
-This function only applies to `e-ascii' back-end. See
-`org-e-ascii-headline-spacing' for information.
-
-For any other back-end, HEADLINE is returned as-is."
- (if (not (and (eq back-end 'e-ascii) org-e-ascii-headline-spacing)) headline
- (let ((blanks (make-string (1+ (cdr org-e-ascii-headline-spacing)) ?\n)))
- (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline))))
-
-
-\f
-;;; Interactive function
-
-(defun org-e-ascii-export-to-ascii
- (&optional subtreep visible-only body-only ext-plist pub-dir)
- "Export current buffer to a text file.
-
-If narrowing is active in the current buffer, only export its
-narrowed part.
-
-If a region is active, export that region.
-
-When optional argument SUBTREEP is non-nil, export the sub-tree
-at point, extracting information from the headline properties
-first.
-
-When optional argument VISIBLE-ONLY is non-nil, don't export
-contents of hidden elements.
-
-When optional argument BODY-ONLY is non-nil, strip title, table
-of contents and footnote definitions from output.
-
-EXT-PLIST, when provided, is a property list with external
-parameters overriding Org default settings, but still inferior to
-file-local settings.
-
-When optional argument PUB-DIR is set, use it as the publishing
-directory.
-
-Return output file's name."
- (interactive)
- (let ((outfile (org-export-output-file-name ".txt" subtreep pub-dir)))
- (org-export-to-file
- 'e-ascii outfile subtreep visible-only body-only ext-plist)))
-
-
-(provide 'org-e-ascii)
-;;; org-e-ascii.el ends here
diff --git a/EXPERIMENTAL/org-e-html.el b/EXPERIMENTAL/org-e-html.el
deleted file mode 100644
index 1e1e94a..0000000
--- a/EXPERIMENTAL/org-e-html.el
+++ /dev/null
@@ -1,3162 +0,0 @@
-;;; org-e-html.el --- HTML Back-End For Org Export Engine
-
-;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
-
-;; Author: Jambunathan K <kjambunathan at gmail dot com>
-;; Keywords: outlines, hypermedia, calendar, wp
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This library implements a HTML back-end for Org generic exporter.
-
-;; To test it, run
-;;
-;; M-: (org-export-to-buffer 'e-html "*Test e-HTML*") RET
-;;
-;; in an org-mode buffer then switch to the buffer to see the HTML
-;; export. See contrib/lisp/org-export.el for more details on how
-;; this exporter works.
-
-;;; Code:
-
-;;; org-e-html.el
-;;; Dependencies
-
-(require 'format-spec)
-(eval-when-compile (require 'cl) (require 'table))
-
-
-\f
-;;; Function Declarations
-
-(declare-function org-element-get-property "org-element" (property element))
-(declare-function org-element-normalize-string "org-element" (s))
-(declare-function org-element-parse-secondary-string
- "org-element" (string restriction &optional buffer))
-(defvar org-element-string-restrictions)
-(defvar org-element-object-restrictions)
-
-(declare-function org-export-clean-table "org-export" (table specialp))
-(declare-function org-export-data "org-export" (data backend info))
-(declare-function org-export-directory "org-export" (type plist))
-(declare-function org-export-expand-macro "org-export" (macro info))
-(declare-function org-export-first-sibling-p "org-export" (headline info))
-(declare-function org-export-footnote-first-reference-p "org-export"
- (footnote-reference info))
-(declare-function org-export-get-coderef-format "org-export" (path desc))
-(declare-function org-export-get-footnote-definition "org-export"
- (footnote-reference info))
-(declare-function org-export-get-footnote-number "org-export" (footnote info))
-(declare-function org-export-get-previous-element "org-export" (blob info))
-(declare-function org-export-get-relative-level "org-export" (headline info))
-(declare-function org-export-handle-code
- "org-export" (element info &optional num-fmt ref-fmt delayed))
-(declare-function org-export-included-file "org-export" (keyword backend info))
-(declare-function org-export-inline-image-p "org-export"
- (link &optional extensions))
-(declare-function org-export-last-sibling-p "org-export" (headline info))
-(declare-function org-export-low-level-p "org-export" (headline info))
-(declare-function org-export-output-file-name
- "org-export" (extension &optional subtreep pub-dir))
-(declare-function org-export-resolve-coderef "org-export" (ref info))
-(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
-(declare-function org-export-secondary-string "org-export"
- (secondary backend info))
-(declare-function org-export-solidify-link-text "org-export" (s))
-(declare-function org-export-table-format-info "org-export" (table))
-(declare-function
- org-export-to-buffer "org-export"
- (backend buffer &optional subtreep visible-only body-only ext-plist))
-(declare-function
- org-export-to-file "org-export"
- (backend file &optional subtreep visible-only body-only ext-plist))
-
-(declare-function org-id-find-id-file "org-id" (id))
-(declare-function htmlize-region "ext:htmlize" (beg end))
-(declare-function org-pop-to-buffer-same-window
- "org-compat" (&optional buffer-or-name norecord label))
-
-
-
-\f
-;;; Internal Variables
-
-(defconst org-e-html-option-alist
- '((:agenda-style nil nil org-agenda-export-html-style)
- (:convert-org-links nil nil org-e-html-link-org-files-as-html)
- ;; FIXME Use (org-xml-encode-org-text-skip-links s) ??
- ;; (:expand-quoted-html nil "@" org-e-html-expand)
- (:inline-images nil nil org-e-html-inline-images)
- ;; (:link-home nil nil org-e-html-link-home) FIXME
- ;; (:link-up nil nil org-e-html-link-up) FIXME
- (:style nil nil org-e-html-style)
- (:style-extra nil nil org-e-html-style-extra)
- (:style-include-default nil nil org-e-html-style-include-default)
- (:style-include-scripts nil nil org-e-html-style-include-scripts)
- ;; (:timestamp nil nil org-e-html-with-timestamp)
- (:html-extension nil nil org-e-html-extension)
- (:html-postamble nil nil org-e-html-postamble)
- (:html-preamble nil nil org-e-html-preamble)
- (:html-table-tag nil nil org-e-html-table-tag)
- (:xml-declaration nil nil org-e-html-xml-declaration)
- (:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments)
- (:mathjax "MATHJAX" nil "" space))
- "Alist between export properties and ways to set them.
-
-The car of the alist is the property name, and the cdr is a list
-like \(KEYWORD OPTION DEFAULT BEHAVIOUR\) where:
-
-KEYWORD is a string representing a buffer keyword, or nil.
-OPTION is a string that could be found in an #+OPTIONS: line.
-DEFAULT is the default value for the property.
-BEHAVIOUR determine how Org should handle multiple keywords for
-the same property. It is a symbol among:
- nil Keep old value and discard the new one.
- t Replace old value with the new one.
- `space' Concatenate the values, separating them with a space.
- `newline' Concatenate the values, separating them with
- a newline.
- `split' Split values at white spaces, and cons them to the
- previous list.
-
-KEYWORD and OPTION have precedence over DEFAULT.
-
-All these properties should be back-end agnostic. For back-end
-specific properties, define a similar variable named
-`org-BACKEND-option-alist', replacing BACKEND with the name of
-the appropriate back-end. You can also redefine properties
-there, as they have precedence over these.")
-
-(defvar html-table-tag nil) ; dynamically scoped into this.
-
-;; FIXME: it already exists in org-e-html.el
-(defconst org-e-html-cvt-link-fn
- nil
- "Function to convert link URLs to exportable URLs.
-Takes two arguments, TYPE and PATH.
-Returns exportable url as (TYPE PATH), or nil to signal that it
-didn't handle this case.
-Intended to be locally bound around a call to `org-export-as-html'." )
-
-
-\f
-
-(defvar org-e-html-format-table-no-css)
-(defvar htmlize-buffer-places) ; from htmlize.el
-(defvar body-only) ; dynamically scoped into this.
-
-(defvar org-e-html-table-rowgrp-open)
-(defvar org-e-html-table-rownum)
-(defvar org-e-html-table-cur-rowgrp-is-hdr)
-(defvar org-lparse-table-is-styled)
-
-
-\f
-;;; User Configuration Variables
-
-(defgroup org-export-e-html nil
- "Options for exporting Org mode files to HTML."
- :tag "Org Export HTML"
- :group 'org-export)
-
-;;;; Debugging
-
-(defcustom org-e-html-pretty-output t
- "Enable this to generate pretty HTML."
- :group 'org-export-e-html
- :type 'boolean)
-
-
-;;;; Document
-
-(defcustom org-e-html-extension "html"
- "The extension for exported HTML files."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-xml-declaration
- '(("html" . "<?xml version=\"1.0\" encoding=\"%s\"?>")
- ("php" . "<?php echo \"<?xml version=\\\"1.0\\\" encoding=\\\"%s\\\" ?>\"; ?>"))
- "The extension for exported HTML files.
-%s will be replaced with the charset of the exported file.
-This may be a string, or an alist with export extensions
-and corresponding declarations."
- :group 'org-export-e-html
- :type '(choice
- (string :tag "Single declaration")
- (repeat :tag "Dependent on extension"
- (cons (string :tag "Extension")
- (string :tag "Declaration")))))
-
-(defcustom org-e-html-coding-system nil
- "Coding system for HTML export, defaults to `buffer-file-coding-system'."
- :group 'org-export-e-html
- :type 'coding-system)
-
-(defvar org-e-html-content-div "content"
- "The name of the container DIV that holds all the page contents.
-
-This variable is obsolete since Org version 7.7.
-Please set `org-e-html-divs' instead.")
-
-(defcustom org-e-html-divs '("preamble" "content" "postamble")
- "The name of the main divs for HTML export.
-This is a list of three strings, the first one for the preamble
-DIV, the second one for the content DIV and the third one for the
-postamble DIV."
- :group 'org-export-e-html
- :type '(list
- (string :tag " Div for the preamble:")
- (string :tag " Div for the content:")
- (string :tag "Div for the postamble:")))
-
-
-;;;; Document Header (Styles)
-
-(defconst org-e-html-style-default
-"<style type=\"text/css\">
- <!--/*--><![CDATA[/*><!--*/
- html { font-family: Times, serif; font-size: 12pt; }
- .title { text-align: center; }
- .todo { color: red; }
- .done { color: green; }
- .tag { background-color: #add8e6; font-weight:normal }
- .target { }
- .timestamp { color: #bebebe; }
- .timestamp-kwd { color: #5f9ea0; }
- .right {margin-left:auto; margin-right:0px; text-align:right;}
- .left {margin-left:0px; margin-right:auto; text-align:left;}
- .center {margin-left:auto; margin-right:auto; text-align:center;}
- p.verse { margin-left: 3% }
- pre {
- border: 1pt solid #AEBDCC;
- background-color: #F3F5F7;
- padding: 5pt;
- font-family: courier, monospace;
- font-size: 90%;
- overflow:auto;
- }
- table { border-collapse: collapse; }
- td, th { vertical-align: top; }
- th.right { text-align:center; }
- th.left { text-align:center; }
- th.center { text-align:center; }
- td.right { text-align:right; }
- td.left { text-align:left; }
- td.center { text-align:center; }
- dt { font-weight: bold; }
- div.figure { padding: 0.5em; }
- div.figure p { text-align: center; }
- div.inlinetask {
- padding:10px;
- border:2px solid gray;
- margin:10px;
- background: #ffffcc;
- }
- textarea { overflow-x: auto; }
- .linenr { font-size:smaller }
- .code-highlighted {background-color:#ffff00;}
- .org-info-js_info-navigation { border-style:none; }
- #org-info-js_console-label { font-size:10px; font-weight:bold;
- white-space:nowrap; }
- .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
- font-weight:bold; }
- /*]]>*/-->
-</style>"
- "The default style specification for exported HTML files.
-Please use the variables `org-e-html-style' and
-`org-e-html-style-extra' to add to this style. If you wish to not
-have the default style included, customize the variable
-`org-e-html-style-include-default'.")
-
-(defcustom org-e-html-style-include-default t
- "Non-nil means include the default style in exported HTML files.
-The actual style is defined in `org-e-html-style-default' and should
-not be modified. Use the variables `org-e-html-style' to add
-your own style information."
- :group 'org-export-e-html
- :type 'boolean)
-;;;###autoload
-(put 'org-e-html-style-include-default 'safe-local-variable 'booleanp)
-
-(defcustom org-e-html-style ""
- "Org-wide style definitions for exported HTML files.
-
-This variable needs to contain the full HTML structure to provide a style,
-including the surrounding HTML tags. If you set the value of this variable,
-you should consider to include definitions for the following classes:
- title, todo, done, timestamp, timestamp-kwd, tag, target.
-
-For example, a valid value would be:
-
- <style type=\"text/css\">
- <![CDATA[
- p { font-weight: normal; color: gray; }
- h1 { color: black; }
- .title { text-align: center; }
- .todo, .timestamp-kwd { color: red; }
- .done { color: green; }
- ]]>
- </style>
-
-If you'd like to refer to an external style file, use something like
-
- <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
-
-As the value of this option simply gets inserted into the HTML <head> header,
-you can \"misuse\" it to add arbitrary text to the header.
-See also the variable `org-e-html-style-extra'."
- :group 'org-export-e-html
- :type 'string)
-;;;###autoload
-(put 'org-e-html-style 'safe-local-variable 'stringp)
-
-(defcustom org-e-html-style-extra ""
- "Additional style information for HTML export.
-The value of this variable is inserted into the HTML buffer right after
-the value of `org-e-html-style'. Use this variable for per-file
-settings of style information, and do not forget to surround the style
-settings with <style>...</style> tags."
- :group 'org-export-e-html
- :type 'string)
-;;;###autoload
-(put 'org-e-html-style-extra 'safe-local-variable 'stringp)
-
-(defcustom org-e-html-mathjax-options
- '((path "http://orgmode.org/mathjax/MathJax.js")
- (scale "100")
- (align "center")
- (indent "2em")
- (mathml nil))
- "Options for MathJax setup.
-
-path The path where to find MathJax
-scale Scaling for the HTML-CSS backend, usually between 100 and 133
-align How to align display math: left, center, or right
-indent If align is not center, how far from the left/right side?
-mathml Should a MathML player be used if available?
- This is faster and reduces bandwidth use, but currently
- sometimes has lower spacing quality. Therefore, the default is
- nil. When browsers get better, this switch can be flipped.
-
-You can also customize this for each buffer, using something like
-
-#+MATHJAX: scale:\"133\" align:\"right\" mathml:t path:\"/MathJax/\""
- :group 'org-export-e-html
- :type '(list :greedy t
- (list :tag "path (the path from where to load MathJax.js)"
- (const :format " " path) (string))
- (list :tag "scale (scaling for the displayed math)"
- (const :format " " scale) (string))
- (list :tag "align (alignment of displayed equations)"
- (const :format " " align) (string))
- (list :tag "indent (indentation with left or right alignment)"
- (const :format " " indent) (string))
- (list :tag "mathml (should MathML display be used is possible)"
- (const :format " " mathml) (boolean))))
-
-
-;;;; Document Header (Scripts)
-
-(defcustom org-e-html-style-include-scripts t
- "Non-nil means include the JavaScript snippets in exported HTML files.
-The actual script is defined in `org-e-html-scripts' and should
-not be modified."
- :group 'org-export-e-html
- :type 'boolean)
-
-(defconst org-e-html-scripts
-"<script type=\"text/javascript\">
-<!--/*--><![CDATA[/*><!--*/
- function CodeHighlightOn(elem, id)
- {
- var target = document.getElementById(id);
- if(null != target) {
- elem.cacheClassElem = elem.className;
- elem.cacheClassTarget = target.className;
- target.className = \"code-highlighted\";
- elem.className = \"code-highlighted\";
- }
- }
- function CodeHighlightOff(elem, id)
- {
- var target = document.getElementById(id);
- if(elem.cacheClassElem)
- elem.className = elem.cacheClassElem;
- if(elem.cacheClassTarget)
- target.className = elem.cacheClassTarget;
- }
-/*]]>*///-->
-</script>"
-"Basic JavaScript that is needed by HTML files produced by Org-mode.")
-
-
-;;;; Document Header (Mathjax)
-
-(defcustom org-e-html-mathjax-template
- "<script type=\"text/javascript\" src=\"%PATH\">
-<!--/*--><![CDATA[/*><!--*/
- MathJax.Hub.Config({
- // Only one of the two following lines, depending on user settings
- // First allows browser-native MathML display, second forces HTML/CSS
- :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"],
- :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"],
- extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\",
- \"TeX/noUndefined.js\"],
- tex2jax: {
- inlineMath: [ [\"\\\\(\",\"\\\\)\"] ],
- displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ],
- skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"],
- ignoreClass: \"tex2jax_ignore\",
- processEscapes: false,
- processEnvironments: true,
- preview: \"TeX\"
- },
- showProcessingMessages: true,
- displayAlign: \"%ALIGN\",
- displayIndent: \"%INDENT\",
-
- \"HTML-CSS\": {
- scale: %SCALE,
- availableFonts: [\"STIX\",\"TeX\"],
- preferredFont: \"TeX\",
- webFont: \"TeX\",
- imageFont: \"TeX\",
- showMathMenu: true,
- },
- MMLorHTML: {
- prefer: {
- MSIE: \"MML\",
- Firefox: \"MML\",
- Opera: \"HTML\",
- other: \"HTML\"
- }
- }
- });
-/*]]>*///-->
-</script>"
- "The MathJax setup for XHTML files."
- :group 'org-export-e-html
- :type 'string)
-
-
-;;;; Preamble
-
-(defcustom org-e-html-preamble t
- "Non-nil means insert a preamble in HTML export.
-
-When `t', insert a string as defined by one of the formatting
-strings in `org-e-html-preamble-format'. When set to a
-string, this string overrides `org-e-html-preamble-format'.
-When set to a function, apply this function and insert the
-returned string. The function takes the property list of export
-options as its only argument.
-
-Setting :html-preamble in publishing projects will take
-precedence over this variable."
- :group 'org-export-e-html
- :type '(choice (const :tag "No preamble" nil)
- (const :tag "Default preamble" t)
- (string :tag "Custom formatting string")
- (function :tag "Function (must return a string)")))
-
-(defcustom org-e-html-preamble-format '(("en" ""))
- "The format for the HTML preamble.
-
-%t stands for the title.
-%a stands for the author's name.
-%e stands for the author's email.
-%d stands for the date.
-
-If you need to use a \"%\" character, you need to escape it
-like that: \"%%\"."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-home/up-format
- "<div id=\"org-div-home-and-up\" style=\"text-align:right;font-size:70%%;white-space:nowrap;\">
- <a accesskey=\"h\" href=\"%s\"> UP </a>
- |
- <a accesskey=\"H\" href=\"%s\"> HOME </a>
-</div>"
- "Snippet used to insert the HOME and UP links.
-This is a format string, the first %s will receive the UP link,
-the second the HOME link. If both `org-e-html-link-up' and
-`org-e-html-link-home' are empty, the entire snippet will be
-ignored."
- :group 'org-export-e-html
- :type 'string)
-
-;;;; Postamble
-
-(defcustom org-e-html-postamble 'auto
- "Non-nil means insert a postamble in HTML export.
-
-When `t', insert a string as defined by the formatting string in
-`org-e-html-postamble-format'. When set to a string, this
-string overrides `org-e-html-postamble-format'. When set to
-'auto, discard `org-e-html-postamble-format' and honor
-`org-export-author/email/creator-info' variables. When set to a
-function, apply this function and insert the returned string.
-The function takes the property list of export options as its
-only argument.
-
-Setting :html-postamble in publishing projects will take
-precedence over this variable."
- :group 'org-export-e-html
- :type '(choice (const :tag "No postamble" nil)
- (const :tag "Auto preamble" 'auto)
- (const :tag "Default formatting string" t)
- (string :tag "Custom formatting string")
- (function :tag "Function (must return a string)")))
-
-(defcustom org-e-html-postamble-format
- '(("en" "<p class=\"author\">Author: %a (%e)</p>
-<p class=\"date\">Date: %d</p>
-<p class=\"creator\">Generated by %c</p>
-<p class=\"xhtml-validation\">%v</p>
-"))
- "The format for the HTML postamble.
-
-%a stands for the author's name.
-%e stands for the author's email.
-%d stands for the date.
-%c will be replaced by information about Org/Emacs versions.
-%v will be replaced by `org-e-html-validation-link'.
-
-If you need to use a \"%\" character, you need to escape it
-like that: \"%%\"."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-validation-link
- "<a href=\"http://validator.w3.org/check?uri=referer\">Validate XHTML 1.0</a>"
- "Link to HTML validation service."
- :group 'org-export-e-html
- :type 'string)
-
-;; FIXME Obsolete since Org 7.7
-;; Use the :timestamp option or `org-export-time-stamp-file' instead
-;;;; Emphasis
-
-(defcustom org-e-html-protect-char-alist
- '(("&" . "&")
- ("<" . "<")
- (">" . ">"))
- "Alist of characters to be converted by `org-e-html-protect'."
- :group 'org-export-e-html
- :type '(repeat (cons (string :tag "Character")
- (string :tag "HTML equivalent"))))
-
-(defconst org-e-html-special-string-regexps
- '(("\\\\-" . "­")
- ("---\\([^-]\\)" . "—\\1")
- ("--\\([^-]\\)" . "–\\1")
- ("\\.\\.\\." . "…"))
- "Regular expressions for special string conversion.")
-
-
-;;;; Todos
-
-(defcustom org-e-html-todo-kwd-class-prefix ""
- "Prefix to class names for TODO keywords.
-Each TODO keyword gets a class given by the keyword itself, with this prefix.
-The default prefix is empty because it is nice to just use the keyword
-as a class name. But if you get into conflicts with other, existing
-CSS classes, then this prefix can be very useful."
- :group 'org-export-e-html
- :type 'string)
-
-
-;;;; Tags
-
-(defcustom org-e-html-tag-class-prefix ""
- "Prefix to class names for TODO keywords.
-Each tag gets a class given by the tag itself, with this prefix.
-The default prefix is empty because it is nice to just use the keyword
-as a class name. But if you get into conflicts with other, existing
-CSS classes, then this prefix can be very useful."
- :group 'org-export-e-html
- :type 'string)
-
-;;;; Time-stamps
-;;;; Statistics Cookie
-;;;; Subscript
-;;;; Superscript
-
-;;;; Inline images
-
-(defcustom org-e-html-inline-images 'maybe
- "Non-nil means inline images into exported HTML pages.
-This is done using an <img> tag. When nil, an anchor with href is used to
-link to the image. If this option is `maybe', then images in links with
-an empty description will be inlined, while images with a description will
-be linked only."
- :group 'org-export-e-html
- :type '(choice (const :tag "Never" nil)
- (const :tag "Always" t)
- (const :tag "When there is no description" maybe)))
-
-(defcustom org-e-html-inline-image-extensions
- '("png" "jpeg" "jpg" "gif" "svg")
- "Extensions of image files that can be inlined into HTML."
- :group 'org-export-e-html
- :type '(repeat (string :tag "Extension")))
-
-
-;;;; Block
-;;;; Comment
-;;;; Comment Block
-;;;; Drawer
-;;;; Dynamic Block
-;;;; Emphasis
-;;;; Entity
-;;;; Example Block
-;;;; Export Snippet
-;;;; Export Block
-;;;; Fixed Width
-;;;; Footnotes
-
-(defcustom org-e-html-footnotes-section "<div id=\"footnotes\">
-<h2 class=\"footnotes\">%s: </h2>
-<div id=\"text-footnotes\">
-%s
-</div>
-</div>"
- "Format for the footnotes section.
-Should contain a two instances of %s. The first will be replaced with the
-language-specific word for \"Footnotes\", the second one will be replaced
-by the footnotes themselves."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-footnote-format "<sup>%s</sup>"
- "The format for the footnote reference.
-%s will be replaced by the footnote reference itself."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-footnote-separator "<sup>, </sup>"
- "Text used to separate footnotes."
- :group 'org-export-e-html
- :type 'string)
-
-
-;;;; Headline
-;;;; Horizontal Rule
-;;;; Inline Babel Call
-;;;; Inline Src Block
-;;;; Inlinetask
-;;;; Item
-;;;; Keyword
-;;;; Latex Environment
-;;;; Latex Fragment
-;;;; Line Break
-;;;; Link
-;;;; Babel Call
-;;;; Macro
-;;;; Paragraph
-;;;; Plain List
-;;;; Plain Text
-;;;; Property Drawer
-;;;; Quote Block
-;;;; Quote Section
-;;;; Section
-;;;; Radio Target
-;;;; Special Block
-;;;; Src Block
-
-(defgroup org-export-e-htmlize nil
- "Options for processing examples with htmlize.el."
- :tag "Org Export Htmlize"
- :group 'org-export-e-html)
-
-(defcustom org-export-e-htmlize-output-type 'inline-css
- "Output type to be used by htmlize when formatting code snippets.
-Choices are `css', to export the CSS selectors only, or `inline-css', to
-export the CSS attribute values inline in the HTML. We use as default
-`inline-css', in order to make the resulting HTML self-containing.
-
-However, this will fail when using Emacs in batch mode for export, because
-then no rich font definitions are in place. It will also not be good if
-people with different Emacs setup contribute HTML files to a website,
-because the fonts will represent the individual setups. In these cases,
-it is much better to let Org/Htmlize assign classes only, and to use
-a style file to define the look of these classes.
-To get a start for your css file, start Emacs session and make sure that
-all the faces you are interested in are defined, for example by loading files
-in all modes you want. Then, use the command
-\\[org-export-e-htmlize-generate-css] to extract class definitions."
- :group 'org-export-e-htmlize
- :type '(choice (const css) (const inline-css)))
-
-(defcustom org-export-e-htmlize-css-font-prefix "org-"
- "The prefix for CSS class names for htmlize font specifications."
- :group 'org-export-e-htmlize
- :type 'string)
-
-(defcustom org-export-e-htmlized-org-css-url nil
- "URL pointing to a CSS file defining text colors for htmlized Emacs buffers.
-Normally when creating an htmlized version of an Org buffer, htmlize will
-create CSS to define the font colors. However, this does not work when
-converting in batch mode, and it also can look bad if different people
-with different fontification setup work on the same website.
-When this variable is non-nil, creating an htmlized version of an Org buffer
-using `org-export-as-org' will remove the internal CSS section and replace it
-with a link to this URL."
- :group 'org-export-e-htmlize
- :type '(choice
- (const :tag "Keep internal css" nil)
- (string :tag "URL or local href")))
-
-
-;;;; Table
-
-(defcustom org-e-html-table-tag
- "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">"
- "The HTML tag that is used to start a table.
-This must be a <table> tag, but you may change the options like
-borders and spacing."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>")
- "The opening tag for table header fields.
-This is customizable so that alignment options can be specified.
-The first %s will be filled with the scope of the field, either row or col.
-The second %s will be replaced by a style entry to align the field.
-See also the variable `org-e-html-table-use-header-tags-for-first-column'.
-See also the variable `org-e-html-table-align-individual-fields'."
- :group 'org-export-tables ; FIXME: change group?
- :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
-
-(defcustom org-e-html-table-data-tags '("<td%s>" . "</td>")
- "The opening tag for table data fields.
-This is customizable so that alignment options can be specified.
-The first %s will be filled with the scope of the field, either row or col.
-The second %s will be replaced by a style entry to align the field.
-See also the variable `org-e-html-table-align-individual-fields'."
- :group 'org-export-tables
- :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
-
-(defcustom org-e-html-table-row-tags '("<tr>" . "</tr>")
- "The opening tag for table data fields.
-This is customizable so that alignment options can be specified.
-Instead of strings, these can be Lisp forms that will be evaluated
-for each row in order to construct the table row tags. During evaluation,
-the variable `head' will be true when this is a header line, nil when this
-is a body line. And the variable `nline' will contain the line number,
-starting from 1 in the first header line. For example
-
- (setq org-e-html-table-row-tags
- (cons '(if head
- \"<tr>\"
- (if (= (mod nline 2) 1)
- \"<tr class=\\\"tr-odd\\\">\"
- \"<tr class=\\\"tr-even\\\">\"))
- \"</tr>\"))
-
-will give even lines the class \"tr-even\" and odd lines the class \"tr-odd\"."
- :group 'org-export-tables
- :type '(cons
- (choice :tag "Opening tag"
- (string :tag "Specify")
- (sexp))
- (choice :tag "Closing tag"
- (string :tag "Specify")
- (sexp))))
-
-(defcustom org-e-html-table-align-individual-fields t
- "Non-nil means attach style attributes for alignment to each table field.
-When nil, alignment will only be specified in the column tags, but this
-is ignored by some browsers (like Firefox, Safari). Opera does it right
-though."
- :group 'org-export-tables
- :type 'boolean)
-
-(defcustom org-e-html-table-use-header-tags-for-first-column nil
- "Non-nil means format column one in tables with header tags.
-When nil, also column one will use data tags."
- :group 'org-export-tables
- :type 'boolean)
-
-
-;;;; Target
-;;;; Time-stamp
-
-;;;; Verbatim
-;;;; Verse Block
-;;;; Headline
-
-(defcustom org-e-html-toplevel-hlevel 2
- "The <H> level for level 1 headings in HTML export.
-This is also important for the classes that will be wrapped around headlines
-and outline structure. If this variable is 1, the top-level headlines will
-be <h1>, and the corresponding classes will be outline-1, section-number-1,
-and outline-text-1. If this is 2, all of these will get a 2 instead.
-The default for this variable is 2, because we use <h1> for formatting the
-document title."
- :group 'org-export-e-html
- :type 'string)
-
-
-;;;; Links
-;;;; Drawers
-;;;; Inlinetasks
-;;;; Publishing
-
-(defcustom org-e-html-link-org-files-as-html t
- "Non-nil means make file links to `file.org' point to `file.html'.
-When org-mode is exporting an org-mode file to HTML, links to
-non-html files are directly put into a href tag in HTML.
-However, links to other Org-mode files (recognized by the
-extension `.org.) should become links to the corresponding html
-file, assuming that the linked org-mode file will also be
-converted to HTML.
-When nil, the links still point to the plain `.org' file."
- :group 'org-export-e-html
- :type 'boolean)
-
-
-;;;; Compilation
-
-
-\f
-;;; User Configurable Variables (MAYBE)
-
-;;;; Preamble
-
-(defcustom org-e-html-date-format
- "\\today"
- "Format string for \\date{...}."
- :group 'org-export-e-html
- :type 'boolean)
-
-;;;; Headline
-
-(defcustom org-e-html-format-headline-function nil
- "Function to format headline text.
-
-This function will be called with 5 arguments:
-TODO the todo keyword \(string or nil\).
-TODO-TYPE the type of todo \(symbol: `todo', `done', nil\)
-PRIORITY the priority of the headline \(integer or nil\)
-TEXT the main headline text \(string\).
-TAGS the tags string, separated with colons \(string or nil\).
-
-The function result will be used in the section format string.
-
-As an example, one could set the variable to the following, in
-order to reproduce the default set-up:
-
-\(defun org-e-html-format-headline \(todo todo-type priority text tags\)
- \"Default format function for an headline.\"
- \(concat \(when todo
- \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
- \(when priority
- \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
- text
- \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
- :group 'org-export-e-html
- :type 'function)
-
-;;;; Emphasis
-
-(defcustom org-e-html-emphasis-alist
- '(("*" . "<b>%s</b>")
- ("/" . "<i>%s</i>")
- ("_" . "<span style=\"text-decoration:underline;\">%s</span>")
- ("+" . "<del>%s</del>")
- ("=" . "<code>%s</code>")
- ("~" . "<code>%s</code>"))
- "Alist of HTML expressions to convert emphasis fontifiers.
-
-The key is the character used as a marker for fontification. The
-value is a formatting string to wrap fontified text with.
-
-Value can also be set to the following symbols: `verb' and
-`protectedtexttt'. For the former, Org will use \"\\verb\" to
-create a format string and select a delimiter character that
-isn't in the string. For the latter, Org will use \"\\texttt\"
-to typeset and try to protect special characters."
- :group 'org-export-e-html
- :type 'alist)
-
-
-;;;; Footnotes
-
-(defcustom org-e-html-footnote-separator "<sup>, </sup>"
- "Text used to separate footnotes."
- :group 'org-export-e-html
- :type 'string)
-
-
-;;;; Time-stamps
-
-(defcustom org-e-html-active-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to active time-stamps."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-inactive-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to inactive time-stamps."
- :group 'org-export-e-html
- :type 'string)
-
-(defcustom org-e-html-diary-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to diary time-stamps."
- :group 'org-export-e-html
- :type 'string)
-
-
-;;;; Links
-
-(defcustom org-e-html-inline-image-rules
- '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
- ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
- ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
- "Rules characterizing image files that can be inlined into HTML.
-
-A rule consists in an association whose key is the type of link
-to consider, and value is a regexp that will be matched against
-link's path.
-
-Note that, by default, the image extension *actually* allowed
-depend on the way the HTML file is processed. When used with
-pdflatex, pdf, jpg and png images are OK. When processing
-through dvi to Postscript, only ps and eps are allowed. The
-default we use here encompasses both."
- :group 'org-export-e-html
- :type '(alist :key-type (string :tag "Type")
- :value-type (regexp :tag "Path")))
-
-;;;; Tables
-
-(defcustom org-e-html-table-caption-above t
- "When non-nil, place caption string at the beginning of the table.
-Otherwise, place it near the end."
- :group 'org-export-e-html
- :type 'boolean)
-
-;;;; Drawers
-
-(defcustom org-e-html-format-drawer-function nil
- "Function called to format a drawer in HTML code.
-
-The function must accept two parameters:
- NAME the drawer name, like \"LOGBOOK\"
- CONTENTS the contents of the drawer.
-
-The function should return the string to be exported.
-
-For example, the variable could be set to the following function
-in order to mimic default behaviour:
-
-\(defun org-e-html-format-drawer-default \(name contents\)
- \"Format a drawer element for HTML export.\"
- contents\)"
- :group 'org-export-e-html
- :type 'function)
-
-
-;;;; Inlinetasks
-
-(defcustom org-e-html-format-inlinetask-function nil
- "Function called to format an inlinetask in HTML code.
-
-The function must accept six parameters:
- TODO the todo keyword, as a string
- TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
- PRIORITY the inlinetask priority, as a string
- NAME the inlinetask name, as a string.
- TAGS the inlinetask tags, as a string.
- CONTENTS the contents of the inlinetask, as a string.
-
-The function should return the string to be exported.
-
-For example, the variable could be set to the following function
-in order to mimic default behaviour:
-
-\(defun org-e-html-format-inlinetask \(todo type priority name tags contents\)
-\"Format an inline task element for HTML export.\"
- \(let \(\(full-title
- \(concat
- \(when todo
- \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
- \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
- title
- \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
- \(format \(concat \"\\\\begin{center}\\n\"
- \"\\\\fbox{\\n\"
- \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
- \"%s\\n\\n\"
- \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
- \"%s\"
- \"\\\\end{minipage}}\"
- \"\\\\end{center}\"\)
- full-title contents\)\)"
- :group 'org-export-e-html
- :type 'function)
-
-
-;; Src blocks
-
-;;;; Plain text
-
-(defcustom org-e-html-quotes
- '(("fr"
- ("\\(\\s-\\|[[(]\\)\"" . "«~")
- ("\\(\\S-\\)\"" . "~»")
- ("\\(\\s-\\|(\\)'" . "'"))
- ("en"
- ("\\(\\s-\\|[[(]\\)\"" . "``")
- ("\\(\\S-\\)\"" . "''")
- ("\\(\\s-\\|(\\)'" . "`")))
- "Alist for quotes to use when converting english double-quotes.
-
-The CAR of each item in this alist is the language code.
-The CDR of each item in this alist is a list of three CONS.
-- the first CONS defines the opening quote
-- the second CONS defines the closing quote
-- the last CONS defines single quotes
-
-For each item in a CONS, the first string is a regexp for allowed
-characters before/after the quote, the second string defines the
-replacement string for this quote."
- :group 'org-export-e-html
- :type '(list
- (cons :tag "Opening quote"
- (string :tag "Regexp for char before")
- (string :tag "Replacement quote "))
- (cons :tag "Closing quote"
- (string :tag "Regexp for char after ")
- (string :tag "Replacement quote "))
- (cons :tag "Single quote"
- (string :tag "Regexp for char before")
- (string :tag "Replacement quote "))))
-
-
-;;;; Compilation
-
-
-\f
-;;; Internal Functions (HTML)
-
-(defun org-e-html-cvt-org-as-html (opt-plist type path)
- "Convert an org filename to an equivalent html filename.
-If TYPE is not file, just return `nil'.
-See variable `org-e-html-link-org-files-as-html'."
- (save-match-data
- (and
- org-e-html-link-org-files-as-html
- (string= type "file")
- (string-match "\\.org$" path)
- (progn
- (list
- "file"
- (concat
- (substring path 0 (match-beginning 0))
- "." (plist-get opt-plist :html-extension)))))))
-
-(defun org-e-html-format-org-link (opt-plist type-1 path fragment desc attr
- descp)
- "Make an HTML link.
-OPT-PLIST is an options list.
-TYPE is the device-type of the link (THIS://foo.html).
-PATH is the path of the link (http://THIS#location).
-FRAGMENT is the fragment part of the link, if any (foo.html#THIS).
-DESC is the link description, if any.
-ATTR is a string of other attributes of the \"a\" element."
- (declare (special org-lparse-par-open))
- (save-match-data
- (when (string= type-1 "coderef")
- (let ((ref fragment))
- (setq desc (format (org-export-get-coderef-format ref (and descp desc))
- (cdr (assoc ref org-export-code-refs)))
- fragment (concat "coderef-" ref)
- attr (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\""
- fragment fragment))))
- (let* ((may-inline-p
- (and (member type-1 '("http" "https" "file"))
- (org-lparse-should-inline-p path descp)
- (not fragment)))
- (type (if (equal type-1 "id") "file" type-1))
- (filename path)
- ;;First pass. Just sanity stuff.
- (components-1
- (cond
- ((string= type "file")
- (list
- type
- ;;Substitute just if original path was absolute.
- ;;(Otherwise path must remain relative)
- (if (file-name-absolute-p path)
- (concat "file://" (expand-file-name path))
- path)))
- ((string= type "")
- (list nil path))
- (t (list type path))))
-
- ;;Second pass. Components converted so they can refer
- ;;to a remote site.
- (components-2
- (or
- (and org-e-html-cvt-link-fn
- (apply org-e-html-cvt-link-fn
- opt-plist components-1))
- (apply #'org-e-html-cvt-org-as-html
- opt-plist components-1)
- components-1))
- (type (first components-2))
- (thefile (second components-2)))
-
-
- ;;Third pass. Build final link except for leading type
- ;;spec.
- (cond
- ((or
- (not type)
- (string= type "http")
- (string= type "https")
- (string= type "file")
- (string= type "coderef"))
- (if fragment
- (setq thefile (concat thefile "#" fragment))))
-
- (t))
-
- ;;Final URL-build, for all types.
- (setq thefile
- (let
- ((str (org-xml-format-href thefile)))
- (if (and type (not (or (string= "file" type)
- (string= "coderef" type))))
- (concat type ":" str)
- str)))
-
- (if may-inline-p
- (ignore) ;; (org-e-html-format-image thefile)
- (org-lparse-format
- 'LINK (org-xml-format-desc desc) thefile attr)))))
-
-;; (caption (and caption (org-xml-encode-org-text caption)))
-;; alt = (file-name-nondirectory path)
-
-(defun org-e-html-format-inline-image (src &optional
- caption label attr standalone-p)
- (let* ((id (if (not label) ""
- (format " id=\"%s\"" (org-export-solidify-link-text label))))
- (attr (concat attr
- (cond
- ((string-match "\\<alt=" (or attr "")) "")
- ((string-match "^ltxpng/" src)
- (format " alt=\"%s\""
- (org-e-html-encode-plain-text
- (org-find-text-property-in-string
- 'org-latex-src src))))
- (t (format " alt=\"%s\""
- (file-name-nondirectory src)))))))
- (cond
- (standalone-p
- (let ((img (format "<img src=\"%s\" %s/>" src attr)))
- (format "\n<div%s class=\"figure\">%s%s\n</div>"
- id (format "\n<p>%s</p>" img)
- (when caption (format "\n<p>%s</p>" caption)))))
- (t (format "<img src=\"%s\" %s/>" src (concat attr id))))))
-
-;;;; Bibliography
-
-(defun org-e-html-bibliography ()
- "Find bibliography, cut it out and return it."
- (catch 'exit
- (let (beg end (cnt 1) bib)
- (save-excursion
- (goto-char (point-min))
- (when (re-search-forward
- "^[ \t]*<div \\(id\\|class\\)=\"bibliography\"" nil t)
- (setq beg (match-beginning 0))
- (while (re-search-forward "</?div\\>" nil t)
- (setq cnt (+ cnt (if (string= (match-string 0) "<div") +1 -1)))
- (when (= cnt 0)
- (and (looking-at ">") (forward-char 1))
- (setq bib (buffer-substring beg (point)))
- (delete-region beg (point))
- (throw 'exit bib))))
- nil))))
-
-;;;; Table
-
-(defun org-e-html-format-table (lines olines)
- (let ((org-e-html-format-table-no-css nil))
- (org-lparse-format-table lines olines)))
-
-(defun org-e-html-splice-attributes (tag attributes)
- "Read attributes in string ATTRIBUTES, add and replace in HTML tag TAG."
- (if (not attributes)
- tag
- (let (oldatt newatt)
- (setq oldatt (org-extract-attributes-from-string tag)
- tag (pop oldatt)
- newatt (cdr (org-extract-attributes-from-string attributes)))
- (while newatt
- (setq oldatt (plist-put oldatt (pop newatt) (pop newatt))))
- (if (string-match ">" tag)
- (setq tag
- (replace-match (concat (org-attributes-to-string oldatt) ">")
- t t tag)))
- tag)))
-
-(defun org-export-splice-style (style extra)
- "Splice EXTRA into STYLE, just before \"</style>\"."
- (if (and (stringp extra)
- (string-match "\\S-" extra)
- (string-match "</style>" style))
- (concat (substring style 0 (match-beginning 0))
- "\n" extra "\n"
- (substring style (match-beginning 0)))
- style))
-
-(defun org-export-e-htmlize-region-for-paste (beg end)
- "Convert the region to HTML, using htmlize.el.
-This is much like `htmlize-region-for-paste', only that it uses
-the settings define in the org-... variables."
- (let* ((htmlize-output-type org-export-e-htmlize-output-type)
- (htmlize-css-name-prefix org-export-e-htmlize-css-font-prefix)
- (htmlbuf (htmlize-region beg end)))
- (unwind-protect
- (with-current-buffer htmlbuf
- (buffer-substring (plist-get htmlize-buffer-places 'content-start)
- (plist-get htmlize-buffer-places 'content-end)))
- (kill-buffer htmlbuf))))
-
-;;;###autoload
-(defun org-export-e-htmlize-generate-css ()
- "Create the CSS for all font definitions in the current Emacs session.
-Use this to create face definitions in your CSS style file that can then
-be used by code snippets transformed by htmlize.
-This command just produces a buffer that contains class definitions for all
-faces used in the current Emacs session. You can copy and paste the ones you
-need into your CSS file.
-
-If you then set `org-export-e-htmlize-output-type' to `css', calls to
-the function `org-export-e-htmlize-region-for-paste' will produce code
-that uses these same face definitions."
- (interactive)
- (require 'htmlize)
- (and (get-buffer "*html*") (kill-buffer "*html*"))
- (with-temp-buffer
- (let ((fl (face-list))
- (htmlize-css-name-prefix "org-")
- (htmlize-output-type 'css)
- f i)
- (while (setq f (pop fl)
- i (and f (face-attribute f :inherit)))
- (when (and (symbolp f) (or (not i) (not (listp i))))
- (insert (org-add-props (copy-sequence "1") nil 'face f))))
- (htmlize-region (point-min) (point-max))))
- (org-pop-to-buffer-same-window "*html*")
- (goto-char (point-min))
- (if (re-search-forward "<style" nil t)
- (delete-region (point-min) (match-beginning 0)))
- (if (re-search-forward "</style>" nil t)
- (delete-region (1+ (match-end 0)) (point-max)))
- (beginning-of-line 1)
- (if (looking-at " +") (replace-match ""))
- (goto-char (point-min)))
-
-(defun org-e-html-make-string (n string)
- (let (out) (dotimes (i n out) (setq out (concat string out)))))
-
-(defun org-e-html-toc-text (toc-entries)
- (let* ((prev-level (1- (nth 1 (car toc-entries))))
- (start-level prev-level))
- (concat
- (mapconcat
- (lambda (entry)
- (let ((headline (nth 0 entry))
- (level (nth 1 entry)))
- (concat
- (let* ((cnt (- level prev-level))
- (times (if (> cnt 0) (1- cnt) (- cnt)))
- rtn)
- (setq prev-level level)
- (concat
- (org-e-html-make-string
- times (cond ((> cnt 0) "\n<ul>\n<li>")
- ((< cnt 0) "</li>\n</ul>\n")))
- (if (> cnt 0) "\n<ul>\n<li>" "</li>\n<li>")))
- headline)))
- toc-entries "")
- (org-e-html-make-string
- (- prev-level start-level) "</li>\n</ul>\n"))))
-
-(defun* org-e-html-format-toc-headline
- (todo todo-type priority text tags
- &key level section-number headline-label &allow-other-keys)
- (let ((headline (concat
- section-number (and section-number ". ")
- text
- (and tags " ") (org-e-html--tags tags))))
- (format "<a href=\"#%s\">%s</a>"
- headline-label
- (if (not nil) headline
- (format "<span class=\"%s\">%s</span>" todo-type headline)))))
-
-(defun org-e-html-toc (depth info)
- (assert (wholenump depth))
- (let* ((headlines (org-export-collect-headlines info depth))
- (toc-entries
- (loop for headline in headlines collect
- (list (org-e-html-format-headline--wrap
- headline info 'org-e-html-format-toc-headline)
- (org-export-get-relative-level headline info)))))
- (when toc-entries
- (let* ((lang-specific-heading
- (nth 3 (or (assoc (plist-get info :language)
- org-export-language-setup)
- (assoc "en" org-export-language-setup)))))
- (concat
- "<div id=\"table-of-contents\">\n"
- (format "<h%d>%s</h%d>\n"
- org-e-html-toplevel-hlevel
- lang-specific-heading
- org-e-html-toplevel-hlevel)
- "<div id=\"text-table-of-contents\">"
- (org-e-html-toc-text toc-entries)
- "</div>\n"
- "</div>\n")))))
-
-;; (defun org-e-html-format-line (line)
-;; (case org-lparse-dyn-current-environment
-;; ((quote fixedwidth) (concat (org-e-html-encode-plain-text line) "\n"))
-;; (t (concat line "\n"))))
-
-(defun org-e-html-fix-class-name (kwd) ; audit callers of this function
- "Turn todo keyword into a valid class name.
-Replaces invalid characters with \"_\"."
- (save-match-data
- (while (string-match "[^a-zA-Z0-9_]" kwd)
- (setq kwd (replace-match "_" t t kwd))))
- kwd)
-
-(defun org-e-html-format-footnote-reference (n def refcnt)
- (let ((extra (if (= refcnt 1) "" (format ".%d" refcnt))))
- (format org-e-html-footnote-format
- (format
- "<a class=\"footref\" name=\"fnr.%s%s\" href=\"#fn.%s\">%s</a>"
- n extra n n))))
-
-(defun org-e-html-format-footnotes-section (section-name definitions)
- (if (not definitions) ""
- (format org-e-html-footnotes-section section-name definitions)))
-
-(defun org-e-html-format-footnote-definition (fn)
- (let ((n (car fn)) (def (cdr fn)))
- (format
- "<tr>\n<td>%s</td>\n<td>%s</td>\n</tr>\n"
- (format
- (format org-e-html-footnote-format
- "<a class=\"footnum\" name=\"fn.%s\" href=\"#fnr.%s\">%s</a>")
- n n n) def)))
-
-(defun org-e-html-footnote-section (info)
- (let* ((fn-alist (org-export-collect-footnote-definitions
- (plist-get info :parse-tree) info))
-
- (fn-alist
- (loop for (n type raw) in fn-alist collect
- (cons n (if (equal (org-element-type raw) 'org-data)
- (org-trim (org-export-data raw 'e-html info))
- (format "<p>%s</p>"
- (org-trim (org-export-secondary-string
- raw 'e-html info))))))))
- (when fn-alist
- (org-e-html-format-footnotes-section
- (nth 4 (or (assoc (plist-get info :language)
- org-export-language-setup)
- (assoc "en" org-export-language-setup)))
- (format
- "<table>\n%s\n</table>\n"
- (mapconcat 'org-e-html-format-footnote-definition fn-alist "\n"))))))
-
-(defun org-e-html-get-coding-system-for-write ()
- (or org-e-html-coding-system
- (and (boundp 'buffer-file-coding-system) buffer-file-coding-system)))
-
-(defun org-e-html-get-coding-system-for-save ()
- (or org-e-html-coding-system
- (and (boundp 'buffer-file-coding-system) buffer-file-coding-system)))
-
-(defun org-e-html-format-date (info)
- (let ((date (plist-get info :date)))
- (cond
- ((and date (string-match "%" date))
- (format-time-string date))
- (date date)
- (t (format-time-string "%Y-%m-%d %T %Z")))))
-
-
-\f
-;;; Internal Functions (Ngz)
-
-(defun org-e-html--caption/label-string (caption label info)
- "Return caption and label HTML string for floats.
-
-CAPTION is a cons cell of secondary strings, the car being the
-standard caption and the cdr its short form. LABEL is a string
-representing the label. INFO is a plist holding contextual
-information.
-
-If there's no caption nor label, return the empty string.
-
-For non-floats, see `org-e-html--wrap-label'."
- (setq label nil) ;; FIXME
-
- (let ((label-str (if label (format "\\label{%s}" label) "")))
- (cond
- ((and (not caption) (not label)) "")
- ((not caption) (format "\\label{%s}\n" label))
- ;; Option caption format with short name.
- ((cdr caption)
- (format "\\caption[%s]{%s%s}\n"
- (org-export-secondary-string (cdr caption) 'e-html info)
- label-str
- (org-export-secondary-string (car caption) 'e-html info)))
- ;; Standard caption format.
- ;; (t (format "\\caption{%s%s}\n"
- ;; label-str
- ;; (org-export-secondary-string (car caption) 'e-html info)))
-
- (t (org-export-secondary-string (car caption) 'e-html info)))))
-
-(defun org-e-html--find-verb-separator (s)
- "Return a character not used in string S.
-This is used to choose a separator for constructs like \\verb."
- (let ((ll "~,./?;':\"|!@#%^&-_=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>()[]{}"))
- (loop for c across ll
- when (not (string-match (regexp-quote (char-to-string c)) s))
- return (char-to-string c))))
-
-(defun org-e-html--quotation-marks (text info)
- "Export quotation marks depending on language conventions.
-TEXT is a string containing quotation marks to be replaced. INFO
-is a plist used as a communication channel."
- (mapc (lambda(l)
- (let ((start 0))
- (while (setq start (string-match (car l) text start))
- (let ((new-quote (concat (match-string 1 text) (cdr l))))
- (setq text (replace-match new-quote t t text))))))
- (cdr (or (assoc (plist-get info :language) org-e-html-quotes)
- ;; Falls back on English.
- (assoc "en" org-e-html-quotes))))
- text)
-
-(defun org-e-html--wrap-label (element output)
- "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-This function shouldn't be used for floats. See
-`org-e-html--caption/label-string'."
- ;; (let ((label (org-element-property :name element)))
- ;; (if (or (not output) (not label) (string= output "") (string= label ""))
- ;; output
- ;; (concat (format "\\label{%s}\n" label) output)))
- output)
-
-
-\f
-;;; Template
-
-(defun org-e-html-meta-info (info)
- (let* ((title (org-export-secondary-string
- (plist-get info :title) 'e-html info))
- (author (and (plist-get info :with-author)
- (let ((auth (plist-get info :author)))
- (and auth (org-export-secondary-string
- auth 'e-html info)))))
- (description (plist-get info :description))
- (keywords (plist-get info :keywords)))
- (concat
- (format "\n<title>%s</title>\n" title)
- (format
- "\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>"
- (and coding-system-for-write
- (fboundp 'coding-system-get)
- (coding-system-get coding-system-for-write
- 'mime-charset)))
- (format "\n<meta name=\"title\" content=\"%s\"/>" title)
- (format "\n<meta name=\"generator\" content=\"Org-mode\"/>")
- (format "\n<meta name=\"generated\" content=\"%s\"/>"
- (org-e-html-format-date info))
- (format "\n<meta name=\"author\" content=\"%s\"/>" author)
- (format "\n<meta name=\"description\" content=\"%s\"/>" description)
- (format "\n<meta name=\"keywords\" content=\"%s\"/>" keywords))))
-
-(defun org-e-html-style (info)
- (concat
- "\n" (when (plist-get info :style-include-default) org-e-html-style-default)
- (plist-get info :style)
- (plist-get info :style-extra)
- "\n"
- (when (plist-get info :style-include-scripts)
- org-e-html-scripts)))
-
-(defun org-e-html-mathjax-config (info)
- "Insert the user setup into the matchjax template."
- (when (member (plist-get info :LaTeX-fragments) '(mathjax t))
- (let ((template org-e-html-mathjax-template)
- (options org-e-html-mathjax-options)
- (in-buffer (or (plist-get info :mathjax) ""))
- name val (yes " ") (no "// ") x)
- (mapc
- (lambda (e)
- (setq name (car e) val (nth 1 e))
- (if (string-match (concat "\\<" (symbol-name name) ":") in-buffer)
- (setq val (car (read-from-string
- (substring in-buffer (match-end 0))))))
- (if (not (stringp val)) (setq val (format "%s" val)))
- (if (string-match (concat "%" (upcase (symbol-name name))) template)
- (setq template (replace-match val t t template))))
- options)
- (setq val (nth 1 (assq 'mathml options)))
- (if (string-match (concat "\\<mathml:") in-buffer)
- (setq val (car (read-from-string
- (substring in-buffer (match-end 0))))))
- ;; Exchange prefixes depending on mathml setting
- (if (not val) (setq x yes yes no no x))
- ;; Replace cookies to turn on or off the config/jax lines
- (if (string-match ":MMLYES:" template)
- (setq template (replace-match yes t t template)))
- (if (string-match ":MMLNO:" template)
- (setq template (replace-match no t t template)))
- ;; Return the modified template
- template)))
-
-(defun org-e-html-preamble (info)
- (when (plist-get info :html-preamble)
- (let* ((title (plist-get info :title))
- (date (org-e-html-format-date info))
- (author (plist-get info :author))
- (lang-words (or (assoc (plist-get info :language)
- org-export-language-setup)
- (assoc "en" org-export-language-setup)))
- (email (plist-get info :email))
- (html-pre-real-contents
- (cond
- ((functionp (plist-get info :html-preamble))
- (with-temp-buffer
- (funcall (plist-get info :html-preamble))
- (buffer-string)))
- ((stringp (plist-get info :html-preamble))
- (format-spec (plist-get info :html-preamble)
- `((?t . ,title) (?a . ,author)
- (?d . ,date) (?e . ,email))))
- (t
- (format-spec
- (or (cadr (assoc (nth 0 lang-words)
- org-e-html-preamble-format))
- (cadr (assoc "en" org-e-html-preamble-format)))
- `((?t . ,title) (?a . ,author)
- (?d . ,date) (?e . ,email)))))))
- (when (not (equal html-pre-real-contents ""))
- (concat
- (format "
-<div id=\"%s\"> " (nth 0 org-e-html-divs))
- "
-"
- html-pre-real-contents
- "
-</div>")))))
-
-(defun org-e-html-postamble (info)
- (concat
- (when (and (not body-only)
- (plist-get info :html-postamble))
- (let* ((html-post (plist-get info :html-postamble))
- (date (org-e-html-format-date info))
- (author (plist-get info :author))
- (email (plist-get info :email))
- (lang-words (or (assoc (plist-get info :language)
- org-export-language-setup)
- (assoc "en" org-export-language-setup)))
- (email
- (mapconcat (lambda(e)
- (format "<a href=\"mailto:%s\">%s</a>" e e))
- (split-string email ",+ *")
- ", "))
- (html-validation-link (or org-e-html-validation-link ""))
- (creator-info
- (concat "Org version " org-version " with Emacs version "
- (number-to-string emacs-major-version))))
- (concat
- ;; begin postamble
- "
-<div id=\"" (nth 2 org-e-html-divs) "\">"
- (cond
- ;; auto postamble
- ((eq (plist-get info :html-postamble) 'auto)
- (concat
- (when (plist-get info :time-stamp-file)
- (format "
-<p class=\"date\"> %s: %s </p> " (nth 2 lang-words) date))
- (when (and (plist-get info :with-author) author)
- (format "
-<p class=\"author\"> %s : %s</p>" (nth 1 lang-words) author))
- (when (and (plist-get info :with-email) email)
- (format "
-<p class=\"email\"> %s </p>" email))
- (when (plist-get info :with-creator)
- (format "
-<p class=\"creator\"> %s </p>" creator-info))
- html-validation-link "\n"))
- ;; postamble from a string
- ((stringp (plist-get info :html-postamble))
- (format-spec (plist-get info :html-postamble)
- `((?a . ,author) (?e . ,email)
- (?d . ,date) (?c . ,creator-info)
- (?v . ,html-validation-link))))
-
- ;; postamble from a function
- ((functionp (plist-get info :html-postamble))
- (with-temp-buffer
- (funcall (plist-get info :html-postamble))
- (buffer-string)))
- ;; default postamble
- (t
- (format-spec
- (or (cadr (assoc (nth 0 lang-words)
- org-e-html-postamble-format))
- (cadr (assoc "en" org-e-html-postamble-format)))
- `((?a . ,author) (?e . ,email)
- (?d . ,date) (?c . ,creator-info)
- (?v . ,html-validation-link)))))
- "
-</div>")))
- ;; org-e-html-html-helper-timestamp
- ))
-
-(defun org-e-html-template (contents info)
- "Return complete document string after HTML conversion.
-CONTENTS is the transcoded contents string. RAW-DATA is the
-original parsed data. INFO is a plist holding export options."
- (concat
- (format
- (or (and (stringp org-e-html-xml-declaration)
- org-e-html-xml-declaration)
- (cdr (assoc (plist-get info :html-extension)
- org-e-html-xml-declaration))
- (cdr (assoc "html" org-e-html-xml-declaration))
-
- "")
- (or (and coding-system-for-write
- (fboundp 'coding-system-get)
- (coding-system-get coding-system-for-write
- 'mime-charset))
- "iso-8859-1"))
- "
-<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
- \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
- (format "
-<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\"> "
- (plist-get info :language) (plist-get info :language))
- "
-<head>"
- (org-e-html-meta-info info) ; meta
- (org-e-html-style info) ; style
- (org-e-html-mathjax-config info) ; mathjax
- "
-</head>"
-
- "
-<body>"
- (let ((link-up (and (plist-get info :link-up)
- (string-match "\\S-" (plist-get info :link-up))
- (plist-get info :link-up)))
- (link-home (and (plist-get info :link-home)
- (string-match "\\S-" (plist-get info :link-home))
- (plist-get info :link-home))))
- (when (or link-up link-home)
- (format org-e-html-home/up-format
- (or link-up link-home)
- (or link-home link-up))))
- ;; preamble
- (org-e-html-preamble info)
- ;; begin content
- (format "
-<div id=\"%s\">" (or org-e-html-content-div
- (nth 1 org-e-html-divs)))
- ;; document title
- (format "
-<h1 class=\"title\"> %s </h1>\n" (plist-get info :title))
- ;; table of contents
- (let ((depth (plist-get info :with-toc)))
- (when (wholenump depth) (org-e-html-toc depth info)))
- ;; document contents
- contents
- ;; footnotes section
- (org-e-html-footnote-section info)
- ;; bibliography
- (org-e-html-bibliography)
- ;; end content
- (unless body-only
- "
-</div>")
-
- ;; postamble
- (org-e-html-postamble info)
-
- (unless body-only
- "
-</body>")
- "
-</html>"))
-
-
-\f
-;;; Transcode Helpers
-
-;;;; Todo
-
-(defun org-e-html--todo (todo)
- (when todo
- (format "<span class=\"%s %s%s\">%s</span>"
- (if (member todo org-done-keywords) "done" "todo")
- org-e-html-todo-kwd-class-prefix (org-e-html-fix-class-name todo)
- todo)))
-
-;;;; Tags
-
-(defun org-e-html--tags (tags)
- (when tags
- (format "<span class=\"tag\">%s</span>"
- (mapconcat
- (lambda (tag)
- (format "<span class=\"%s\">%s</span>"
- (concat org-e-html-tag-class-prefix
- (org-e-html-fix-class-name tag))
- tag))
- (org-split-string tags ":") " "))))
-
-;;;; Headline
-
-(defun* org-e-html-format-headline
- (todo todo-type priority text tags
- &key level section-number headline-label &allow-other-keys)
- (let ((section-number
- (when section-number
- (format "<span class=\"section-number-%d\">%s</span> "
- level section-number)))
- (todo (org-e-html--todo todo))
- (tags (org-e-html--tags tags)))
- (concat section-number todo (and todo " ") text
- (and tags " ") tags)))
-
-;;;; Src Code
-
-(defun org-e-html-fontify-code (code lang)
- (when code
- (cond
- ;; Case 1: No lang. Possibly an example block.
- ((not lang)
- ;; Simple transcoding.
- (org-e-html-encode-plain-text code))
- ;; Case 2: No htmlize or an inferior version of htmlize
- ((not (and (require 'htmlize nil t) (fboundp 'htmlize-region-for-paste)))
- ;; Emit a warning.
- (message "Cannot fontify src block (htmlize.el >= 1.34 required)")
- ;; Simple transcoding.
- (org-e-html-encode-plain-text code))
- (t
- ;; Map language
- (setq lang (or (assoc-default lang org-src-lang-modes) lang))
- (let* ((lang-mode (and lang (intern (format "%s-mode" lang)))))
- (cond
- ;; Case 1: Language is not associated with any Emacs mode
- ((not (functionp lang-mode))
- ;; Simple transcoding.
- (org-e-html-encode-plain-text code))
- ;; Case 2: Default. Fotify code.
- (t
- ;; htmlize
- (setq code (with-temp-buffer
- (insert code)
- (funcall lang-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-e-htmlize-region-for-paste
- (point-min) (point-max))))
- ;; Strip any encolosing <pre></pre> tags
- (if (string-match "<pre[^>]*>\n*\\([^\000]*\\)</pre>" code)
- (match-string 1 code)
- code))))))))
-
-(defun org-e-html-do-format-code
- (code &optional lang refs retain-labels num-start textarea-p)
- (when textarea-p
- (setq num-start nil refs nil lang nil))
- (let* ((code-lines (org-split-string code "\n"))
- (code-length (length code-lines))
- (num-fmt
- (and num-start
- (format "%%%ds: "
- (length (number-to-string (+ code-length num-start))))))
- (code (org-e-html-fontify-code code lang)))
- (assert (= code-length (length (org-split-string code "\n"))))
- (org-export-format-code
- code
- (lambda (loc line-num ref)
- (setq loc
- (concat
- ;; Add line number, if needed.
- (when num-start
- (format "<span class=\"linenr\">%s</span>"
- (format num-fmt line-num)))
- ;; Transcoded src line.
- loc
- ;; Add label, if needed.
- (when (and ref retain-labels) (format " (%s)" ref))))
- ;; Mark transcoded line as an anchor, if needed.
- (if (not ref) loc
- (format "<span id=\"coderef-%s\" class=\"coderef-off\">%s</span>"
- ref loc)))
- num-start refs)))
-
-(defun org-e-html-format-code (element info)
- (let* ((lang (org-element-property :language element))
- ;; (switches (org-element-property :switches element))
- (switches nil) ; FIXME
- (textarea-p (and switches (string-match "-t\\>" switches)))
- ;; Extract code and references.
- (code-info (org-export-unravel-code element))
- (code (car code-info))
- (refs (cdr code-info))
- ;; Does the src block contain labels?
- (retain-labels (org-element-property :retain-labels element))
- ;; Does it have line numbers?
- (num-start (case (org-element-property :number-lines element)
- (continued (org-export-get-loc element info))
- (new 0))))
- (org-e-html-do-format-code
- code lang refs retain-labels num-start textarea-p)))
-
-
-\f
-;;; Transcode Functions
-
-;;;; Block
-
-(defun org-e-html-center-block (center-block contents info)
- "Transcode a CENTER-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (org-e-html--wrap-label
- center-block
- (format "<div style=\"text-align: center\">\n%s</div>" contents)))
-
-
-;;;; Comment
-
-;; Comments are ignored.
-
-
-;;;; Comment Block
-
-;; Comment Blocks are ignored.
-
-
-;;;; Drawer
-
-(defun org-e-html-drawer (drawer contents info)
- "Transcode a DRAWER element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let* ((name (org-element-property :drawer-name drawer))
- (output (if (functionp org-e-html-format-drawer-function)
- (funcall org-e-html-format-drawer-function
- name contents)
- ;; If there's no user defined function: simply
- ;; display contents of the drawer.
- contents)))
- (org-e-html--wrap-label drawer output)))
-
-
-;;;; Dynamic Block
-
-(defun org-e-html-dynamic-block (dynamic-block contents info)
- "Transcode a DYNAMIC-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information. See
-`org-export-data'."
- (org-e-html--wrap-label dynamic-block contents))
-
-
-;;;; Emphasis
-
-(defun org-e-html-emphasis (emphasis contents info)
- "Transcode EMPHASIS from Org to HTML.
-CONTENTS is the contents of the emphasized text. INFO is a plist
-holding contextual information.."
- (let* ((marker (org-element-property :marker emphasis)))
- (format (cdr (assoc marker org-e-html-emphasis-alist)) contents)))
-
-
-;;;; Entity
-
-(defun org-e-html-entity (entity contents info)
- "Transcode an ENTITY object from Org to HTML.
-CONTENTS are the definition itself. INFO is a plist holding
-contextual information."
- (org-element-property :html entity))
-
-
-;;;; Example Block
-
-(defun org-e-html-example-block (example-block contents info)
- "Transcode a EXAMPLE-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((options (or (org-element-property :options example-block) ""))
- (lang (org-element-property :language example-block))
- (caption (org-element-property :caption example-block))
- (label (org-element-property :name example-block))
- (caption-str (org-e-html--caption/label-string caption label info))
- (attr (mapconcat #'identity
- (org-element-property :attr_html example-block)
- " "))
- ;; (switches (org-element-property :switches example-block))
- (switches nil) ; FIXME
- (textarea-p (and switches (string-match "-t\\>" switches)))
- (code (org-e-html-format-code example-block info)))
- (cond
- (textarea-p
- (let ((cols (if (not (string-match "-w[ \t]+\\([0-9]+\\)" switches))
- 80 (string-to-number (match-string 1 switches))))
- (rows (if (string-match "-h[ \t]+\\([0-9]+\\)" switches)
- (string-to-number (match-string 1 switches))
- (org-count-lines code))))
- (format
- "\n<p>\n<textarea cols=\"%d\" rows=\"%d\">\n%s\n</textarea>\n</p>"
- cols rows code)))
- (t (format "\n<pre class=\"example\">\n%s\n</pre>" code)))))
-
-
-;;;; Export Snippet
-
-(defun org-e-html-export-snippet (export-snippet contents info)
- "Transcode a EXPORT-SNIPPET object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (when (eq (org-export-snippet-backend export-snippet) 'e-html)
- (org-element-property :value export-snippet)))
-
-
-;;;; Export Block
-
-(defun org-e-html-export-block (export-block contents info)
- "Transcode a EXPORT-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (when (string= (org-element-property :type export-block) "latex")
- (org-remove-indentation (org-element-property :value export-block))))
-
-
-;;;; Fixed Width
-
-(defun org-e-html-fixed-width (fixed-width contents info)
- "Transcode a FIXED-WIDTH element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((value (org-element-normalize-string
- (replace-regexp-in-string
- "^[ \t]*: ?" ""
- (org-element-property :value fixed-width)))))
- (org-e-html--wrap-label
- fixed-width (format "\n<pre class=\"example\">\n%s\n</pre>"
- (org-e-html-do-format-code value)))))
-
-
-;;;; Footnote Definition
-
-;; Footnote Definitions are ignored.
-
-
-;;;; Footnote Reference
-
-(defun org-e-html-footnote-reference (footnote-reference contents info)
- "Transcode a FOOTNOTE-REFERENCE element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (concat
- ;; Insert separator between two footnotes in a row.
- (let ((prev (org-export-get-previous-element footnote-reference info)))
- (when (eq (org-element-type prev) 'footnote-reference)
- org-e-html-footnote-separator))
- (cond
- ((not (org-export-footnote-first-reference-p footnote-reference info))
- (org-e-html-format-footnote-reference
- (org-export-get-footnote-number footnote-reference info)
- "IGNORED" 100))
- ;; Inline definitions are secondary strings.
- ((eq (org-element-property :type footnote-reference) 'inline)
- (org-e-html-format-footnote-reference
- (org-export-get-footnote-number footnote-reference info)
- "IGNORED" 1))
- ;; Non-inline footnotes definitions are full Org data.
- (t (org-e-html-format-footnote-reference
- (org-export-get-footnote-number footnote-reference info)
- "IGNORED" 1)))))
-
-
-;;;; Headline
-
-(defun org-e-html-format-headline--wrap (headline info
- &optional format-function
- &rest extra-keys)
- "Transcode an HEADLINE element from Org to HTML.
-CONTENTS holds the contents of the headline. INFO is a plist
-holding contextual information."
- (let* ((level (+ (org-export-get-relative-level headline info)
- (1- org-e-html-toplevel-hlevel)))
- (headline-number (org-export-get-headline-number headline info))
- (section-number (and (org-export-numbered-headline-p headline info)
- (mapconcat 'number-to-string
- headline-number ".")))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property
- :todo-keyword headline)))
- (and todo
- (org-export-secondary-string todo 'e-html info)))))
- (todo-type (and todo (org-element-property :todo-type headline)))
- (priority (and (plist-get info :with-priority)
- (org-element-property :priority headline)))
- (text (org-export-secondary-string
- (org-element-property :title headline) 'e-html info))
- (tags (and (plist-get info :with-tags)
- (org-element-property :tags headline)))
- (headline-label (concat "sec-" (mapconcat 'number-to-string
- headline-number "-")))
- (format-function (cond
- ((functionp format-function) format-function)
- ((functionp org-e-html-format-headline-function)
- (function*
- (lambda (todo todo-type priority text tags
- &allow-other-keys)
- (funcall org-e-html-format-headline-function
- todo todo-type priority text tags))))
- (t 'org-e-html-format-headline))))
- (apply format-function
- todo todo-type priority text tags
- :headline-label headline-label :level level
- :section-number section-number extra-keys)))
-
-(defun org-e-html-headline (headline contents info)
- "Transcode an HEADLINE element from Org to HTML.
-CONTENTS holds the contents of the headline. INFO is a plist
-holding contextual information."
- (let* ((numberedp (org-export-numbered-headline-p headline info))
- (level (org-export-get-relative-level headline info))
- (text (org-export-secondary-string
- (org-element-property :title headline) 'e-html info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property
- :todo-keyword headline)))
- (and todo
- (org-export-secondary-string todo 'e-html info)))))
- (todo-type (and todo (org-element-property :todo-type headline)))
- (tags (and (plist-get info :with-tags)
- (org-element-property :tags headline)))
- (priority (and (plist-get info :with-priority)
- (org-element-property :priority headline)))
- (section-number (and (org-export-numbered-headline-p headline info)
- (mapconcat 'number-to-string
- (org-export-get-headline-number
- headline info) ".")))
- ;; Create the headline text.
- (full-text (org-e-html-format-headline--wrap headline info)))
- (cond
- ;; Case 1: This is a footnote section: ignore it.
- ((org-element-property :footnote-section-p headline) nil)
- ;; Case 2. This is a deep sub-tree: export it as a list item.
- ;; Also export as items headlines for which no section
- ;; format has been found.
- ((org-export-low-level-p headline info) ; FIXME (or (not section-fmt))
- ;; Build the real contents of the sub-tree.
- (let* ((type (if numberedp 'unordered 'unordered)) ; FIXME
- (itemized-body (org-e-html-format-list-item
- contents type nil nil full-text)))
- (concat
- (and (org-export-first-sibling-p headline info)
- (org-e-html-begin-plain-list type))
- itemized-body
- (and (org-export-last-sibling-p headline info)
- (org-e-html-end-plain-list type)))))
- ;; Case 3. Standard headline. Export it as a section.
- (t
- (let* ((extra-class (org-element-property :html-container-class headline))
- (extra-ids (list (org-element-property :custom-id headline)
- (org-element-property :id headline)))
- (extra-ids
- (mapconcat
- (lambda (x)
- (when x
- (let ((id (org-solidify-link-text
- (if (org-uuidgen-p x) (concat "ID-" x) x))))
- (format "<a id=\"%s\" name=\"%s\"/>" id id))))
- extra-ids ""))
- (level1 (+ level (1- org-e-html-toplevel-hlevel)))
- (id (mapconcat 'number-to-string
- (org-export-get-headline-number headline info) "-")))
- (format "<div id=\"%s\" class=\"%s\">%s%s</div>\n"
- (format "outline-container-%s" id)
- (concat (format "outline-%d" level1) (and extra-class " ")
- extra-class)
- (format "\n<h%d id=\"sec-%s\">%s%s</h%d>\n"
- level1 id extra-ids full-text level1)
- contents))))))
-
-
-;;;; Horizontal Rule
-
-(defun org-e-html-horizontal-rule (horizontal-rule contents info)
- "Transcode an HORIZONTAL-RULE object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((attr (mapconcat #'identity
- (org-element-property :attr_html horizontal-rule)
- " ")))
- (org-e-html--wrap-label horizontal-rule "<hr/>\n")))
-
-
-;;;; Inline Babel Call
-
-;; Inline Babel Calls are ignored.
-
-
-;;;; Inline Src Block
-
-(defun org-e-html-inline-src-block (inline-src-block contents info)
- "Transcode an INLINE-SRC-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (let* ((org-lang (org-element-property :language inline-src-block))
- (code (org-element-property :value inline-src-block))
- (separator (org-e-html--find-verb-separator code)))
- (error "FIXME")))
-
-
-;;;; Inlinetask
-
-(defun org-e-html-format-section (text class &optional id)
- (let ((extra (concat (when id (format " id=\"%s\"" id)))))
- (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
-
-(defun org-e-html-inlinetask (inlinetask contents info)
- "Transcode an INLINETASK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (cond
- ;; If `org-e-html-format-inlinetask-function' is provided, call it
- ;; with appropriate arguments.
- ((functionp org-e-html-format-inlinetask-function)
- (let ((format-function
- (function*
- (lambda (todo todo-type priority text tags
- &key contents &allow-other-keys)
- (funcall org-e-html-format-inlinetask-function
- todo todo-type priority text tags contents)))))
- (org-e-html-format-headline--wrap
- inlinetask info format-function :contents contents)))
- ;; Otherwise, use a default template.
- (t (org-e-html--wrap-label
- inlinetask
- (format
- "\n<div class=\"inlinetask\">\n<b>%s</b><br/>\n%s\n</div>"
- (org-e-html-format-headline--wrap inlinetask info)
- contents)))))
-
-
-;;;; Item
-
-(defun org-e-html-checkbox (checkbox)
- (case checkbox (on "<code>[X]</code>")
- (off "<code>[ ]</code>")
- (trans "<code>[-]</code>")
- (t "")))
-
-(defun org-e-html-format-list-item (contents type checkbox
- &optional term-counter-id
- headline)
- (concat
- (case type
- (ordered
- (let* ((counter term-counter-id)
- (extra (if counter (format " value=\"%s\"" counter) "")))
- (format "<li%s>" extra)))
- (unordered
- (let* ((id term-counter-id)
- (extra (if id (format " id=\"%s\"" id) "")))
- (concat
- (format "<li%s>" extra)
- (when headline (concat headline "<br/>")))))
- (descriptive
- (let* ((term term-counter-id))
- (setq term (or term "(no term)"))
- (concat (format "<dt> %s </dt>" term) "<dd>"))))
- (org-e-html-checkbox checkbox) (and checkbox " ")
- contents
- (case type
- (ordered "</li>")
- (unordered "</li>")
- (descriptive "</dd>"))))
-
-(defun org-e-html-item (item contents info)
- "Transcode an ITEM element from Org to HTML.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- ;; Grab `:level' from plain-list properties, which is always the
- ;; first element above current item.
- (let* ((plain-list (org-export-get-parent item info))
- (type (org-element-property :type plain-list))
- (level (org-element-property :level plain-list))
- (counter (org-element-property :counter item))
- (checkbox (org-element-property :checkbox item))
- (tag (let ((tag (org-element-property :tag item)))
- (and tag (org-export-secondary-string tag 'e-html info)))))
- (org-e-html-format-list-item
- contents type checkbox (or tag counter))))
-
-
-;;;; Keyword
-
-(defun org-e-html-keyword (keyword contents info)
- "Transcode a KEYWORD element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((key (downcase (org-element-property :key keyword)))
- (value (org-element-property :value keyword)))
- (cond
- ((string= key "latex") value)
- ((string= key "index") (format "\\index{%s}" value))
- ;; Invisible targets.
- ((string= key "target") nil) ; FIXME
- ((string= key "toc")
- (let ((value (downcase value)))
- (cond
- ((string-match "\\<headlines\\>" value)
- (let ((depth (or (and (string-match "[0-9]+" value)
- (string-to-number (match-string 0 value)))
- (plist-get info :with-toc))))
- (when (wholenump depth) (org-e-html-toc depth info))))
- ((string= "tables" value) "\\listoftables")
- ((string= "figures" value) "\\listoffigures")
- ((string= "listings" value)
- (cond
- ;; At the moment, src blocks with a caption are wrapped
- ;; into a figure environment.
- (t "\\listoffigures")))))))))
-
-
-;;;; Latex Environment
-
-(defun org-e-html-format-latex (latex-frag processing-type)
- (let* ((cache-relpath
- (concat "ltxpng/" (file-name-sans-extension
- (file-name-nondirectory (buffer-file-name)))))
- (cache-dir (file-name-directory (buffer-file-name )))
- (display-msg "Creating LaTeX Image..."))
-
- (with-temp-buffer
- (insert latex-frag)
- (org-format-latex cache-relpath cache-dir nil display-msg
- nil nil processing-type)
- (buffer-string))))
-
-(defun org-e-html-latex-environment (latex-environment contents info)
- "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-html--wrap-label
- latex-environment
- (let ((processing-type (plist-get info :LaTeX-fragments))
- (latex-frag (org-remove-indentation
- (org-element-property :value latex-environment)))
- (caption (org-e-html--caption/label-string
- (org-element-property :caption latex-environment)
- (org-element-property :name latex-environment)
- info))
- (attr nil) ; FIXME
- (label (org-element-property :name latex-environment)))
- (cond
- ((member processing-type '(t mathjax))
- (org-e-html-format-latex latex-frag 'mathjax))
- ((equal processing-type 'dvipng)
- (let* ((formula-link (org-e-html-format-latex
- latex-frag processing-type)))
- (when (and formula-link
- (string-match "file:\\([^]]*\\)" formula-link))
- (org-e-html-format-inline-image
- (match-string 1 formula-link) caption label attr t))))
- (t latex-frag)))))
-
-
-;;;; Latex Fragment
-
-(defun org-e-html-latex-fragment (latex-fragment contents info)
- "Transcode a LATEX-FRAGMENT object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((latex-frag (org-element-property :value latex-fragment))
- (processing-type (plist-get info :LaTeX-fragments)))
- (case processing-type
- ((t mathjax)
- (org-e-html-format-latex latex-frag 'mathjax))
- (dvipng
- (let* ((formula-link (org-e-html-format-latex
- latex-frag processing-type)))
- (when (and formula-link
- (string-match "file:\\([^]]*\\)" formula-link))
- (org-e-html-format-inline-image
- (match-string 1 formula-link)))))
- (t latex-frag))))
-
-;;;; Line Break
-
-(defun org-e-html-line-break (line-break contents info)
- "Transcode a LINE-BREAK object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- "<br/>")
-
-
-;;;; Link
-
-(defun org-e-html-link--inline-image (link desc info)
- "Return HTML code for an inline image.
-LINK is the link pointing to the inline image. INFO is a plist
-used as a communication channel."
- (let* ((type (org-element-property :type link))
- (raw-path (org-element-property :path link))
- (path (cond ((member type '("http" "https"))
- (concat type ":" raw-path))
- ((file-name-absolute-p raw-path)
- (expand-file-name raw-path))
- (t raw-path)))
- (parent (org-export-get-parent-paragraph link info))
- (caption (org-e-html--caption/label-string
- (org-element-property :caption parent)
- (org-element-property :name parent)
- info))
- (label (org-element-property :name parent))
- ;; Retrieve latex attributes from the element around.
- (attr (let ((raw-attr
- (mapconcat #'identity
- (org-element-property :attr_html parent)
- " ")))
- (unless (string= raw-attr "") raw-attr))))
- ;; Now clear ATTR from any special keyword and set a default
- ;; value if nothing is left.
- (setq attr (if (not attr) "" (org-trim attr)))
- ;; Return proper string, depending on DISPOSITION.
- (org-e-html-format-inline-image
- path caption label attr (org-e-html-standalone-image-p link info))))
-
-(defvar org-e-html-standalone-image-predicate)
-(defun org-e-html-standalone-image-p (element info &optional predicate)
- "Test if ELEMENT is a standalone image for the purpose HTML export.
-INFO is a plist holding contextual information.
-
-Return non-nil, if ELEMENT is of type paragraph and it's sole
-content, save for whitespaces, is a link that qualifies as an
-inline image.
-
-Return non-nil, if ELEMENT is of type link and it's containing
-paragraph has no other content save for leading and trailing
-whitespaces.
-
-Return nil, otherwise.
-
-Bind `org-e-html-standalone-image-predicate' to constrain
-paragraph further. For example, to check for only captioned
-standalone images, do the following.
-
- \(setq org-e-html-standalone-image-predicate
- \(lambda \(paragraph\)
- \(org-element-property :caption paragraph\)\)\)
-"
- (let ((paragraph (case (org-element-type element)
- (paragraph element)
- (link (and (org-export-inline-image-p
- element org-e-html-inline-image-rules)
- (org-export-get-parent element info)))
- (t nil))))
- (when paragraph
- (assert (eq (org-element-type paragraph) 'paragraph))
- (when (or (not (and (boundp 'org-e-html-standalone-image-predicate)
- (functionp org-e-html-standalone-image-predicate)))
- (funcall org-e-html-standalone-image-predicate paragraph))
- (let ((contents (org-element-contents paragraph)))
- (loop for x in contents
- with inline-image-count = 0
- always (cond
- ((eq (org-element-type x) 'plain-text)
- (not (org-string-nw-p x)))
- ((eq (org-element-type x) 'link)
- (when (org-export-inline-image-p
- x org-e-html-inline-image-rules)
- (= (incf inline-image-count) 1)))
- (t nil))))))))
-
-(defun org-e-html-link (link desc info)
- "Transcode a LINK object from Org to HTML.
-
-DESC is the description part of the link, or the empty string.
-INFO is a plist holding contextual information. See
-`org-export-data'."
- (let* ((type (org-element-property :type link))
- (raw-path (org-element-property :path link))
- ;; Ensure DESC really exists, or set it to nil.
- (desc (and (not (string= desc "")) desc))
- (path (cond
- ((member type '("http" "https" "ftp" "mailto"))
- (concat type ":" raw-path))
- ((string= type "file")
- (when (string-match "\\(.+\\)::.+" raw-path)
- (setq raw-path (match-string 1 raw-path)))
- (if (file-name-absolute-p raw-path)
- (concat "file://" (expand-file-name raw-path))
- ;; TODO: Not implemented yet. Concat also:
- ;; (org-export-directory :HTML info)
- (concat "file://" raw-path)))
- (t raw-path)))
- protocol)
- (cond
- ;; Image file.
- ((and (or (eq t org-e-html-inline-images)
- (and org-e-html-inline-images (not desc)))
- (org-export-inline-image-p link org-e-html-inline-image-rules))
- (org-e-html-link--inline-image link desc info))
- ;; Radioed target: Target's name is obtained from original raw
- ;; link. Path is parsed and transcoded in order to have a proper
- ;; display of the contents.
- ((string= type "radio")
- (format "<a href=\"#%s\">%s</a>"
- (org-export-solidify-link-text path)
- (org-export-secondary-string
- (org-element-parse-secondary-string
- path (cdr (assq 'radio-target org-element-object-restrictions)))
- 'e-html info)))
- ;; Links pointing to an headline: Find destination and build
- ;; appropriate referencing command.
- ((member type '("custom-id" "fuzzy" "id"))
- (let ((destination (if (string= type "fuzzy")
- (org-export-resolve-fuzzy-link link info)
- (org-export-resolve-id-link link info))))
- (case (org-element-type destination)
- ;; Fuzzy link points nowhere.
- ('nil
- (format "<i>%s</i>"
- (or desc (org-export-secondary-string
- (org-element-property :raw-link link)
- 'e-html info))))
- ;; Fuzzy link points to an invisible target.
- (keyword nil)
- ;; LINK points to an headline. If headlines are numbered
- ;; and the link has no description, display headline's
- ;; number. Otherwise, display description or headline's
- ;; title.
- (headline
- (let* ((headline-no (org-export-get-headline-number destination info))
- (label (format "sec-%s" (mapconcat 'number-to-string
- headline-no "-")))
- (section-no (mapconcat 'number-to-string headline-no ".")))
- (setq desc
- (cond
- (desc desc)
- ((plist-get info :section-numbers) section-no)
- (t (org-export-secondary-string
- (org-element-property :title destination)
- 'e-html info))))
- (format "<a href=\"#%s\">%s</a>" label desc)))
- ;; Fuzzy link points to a target. Do as above.
- (otherwise
- (let ((path (org-export-solidify-link-text path)) number)
- (unless desc
- (setq number (cond
- ((org-e-html-standalone-image-p destination info)
- (org-export-get-ordinal
- (assoc 'link (org-element-contents destination))
- info 'link 'org-e-html-standalone-image-p))
- (t (org-export-get-ordinal destination info))))
- (setq desc (when number
- (if (atom number) (number-to-string number)
- (mapconcat 'number-to-string number ".")))))
- (format "<a href=\"#%s\">%s</a>" path (or desc "FIXME")))))))
- ;; Coderef: replace link with the reference name or the
- ;; equivalent line number.
- ((string= type "coderef")
- (let ((fragment (concat "coderef-" path)))
- (format "<a href=\"#%s\" %s>%s</a>" fragment
- (format (concat "class=\"coderef\""
- " onmouseover=\"CodeHighlightOn(this, '%s');\""
- " onmouseout=\"CodeHighlightOff(this, '%s');\"")
- fragment fragment)
- (format (org-export-get-coderef-format path (or desc "%s"))
- (org-export-resolve-coderef path info)))))
- ;; Link type is handled by a special function.
- ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
- (funcall protocol (org-link-unescape path) desc 'html))
- ;; External link with a description part.
- ((and path desc) (format "<a href=\"%s\">%s</a>" path desc))
- ;; External link without a description part.
- (path (format "<a href=\"%s\">%s</a>" path path))
- ;; No path, only description. Try to do something useful.
- (t (format "<i>%s</i>" desc)))))
-
-
-;;;; Babel Call
-
-;; Babel Calls are ignored.
-
-
-;;;; Macro
-
-(defun org-e-html-macro (macro contents info)
- "Transcode a MACRO element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- ;; Use available tools.
- (org-export-expand-macro macro info))
-
-
-;;;; Paragraph
-
-(defun org-e-html-paragraph (paragraph contents info)
- "Transcode a PARAGRAPH element from Org to HTML.
-CONTENTS is the contents of the paragraph, as a string. INFO is
-the plist used as a communication channel."
- (let* ((style nil) ; FIXME
- (class (cdr (assoc style '((footnote . "footnote")
- (verse . nil)))))
- (extra (if class (format " class=\"%s\"" class) ""))
- (parent (org-export-get-parent paragraph info)))
- (cond
- ((and (equal (car parent) 'item)
- (= (org-element-property :begin paragraph)
- (org-element-property :contents-begin parent)))
- ;; leading paragraph in a list item have no tags
- contents)
- ((org-e-html-standalone-image-p paragraph info)
- ;; standalone image
- contents)
- (t (format "\n<p%s>\n%s\n</p>" extra contents)))))
-
-
-;;;; Plain List
-
-(defun org-e-html-begin-plain-list (type &optional arg1)
- (case type
- (ordered
- (format "<ol%s>" (if arg1 ; FIXME
- (format " start=\"%d\"" arg1)
- "")))
- (unordered "<ul>")
- (descriptive "<dl>")))
-
-(defun org-e-html-end-plain-list (type)
- (case type
- (ordered "</ol>")
- (unordered "</ul>")
- (descriptive "</dl>")))
-
-(defun org-e-html-plain-list (plain-list contents info)
- "Transcode a PLAIN-LIST element from Org to HTML.
-CONTENTS is the contents of the list. INFO is a plist holding
-contextual information."
- (let* (arg1 ;; FIXME
- (type (org-element-property :type plain-list))
- (attr (mapconcat #'identity
- (org-element-property :attr_html plain-list)
- " ")))
- (org-e-html--wrap-label
- plain-list (format "%s\n%s%s"
- (org-e-html-begin-plain-list type)
- contents (org-e-html-end-plain-list type)))))
-
-;;;; Plain Text
-
-(defun org-e-html-convert-special-strings (string)
- "Convert special characters in STRING to HTML."
- (let ((all org-e-html-special-string-regexps)
- e a re rpl start)
- (while (setq a (pop all))
- (setq re (car a) rpl (cdr a) start 0)
- (while (string-match re string start)
- (setq string (replace-match rpl t nil string))))
- string))
-
-(defun org-e-html-encode-plain-text (s)
- "Convert plain text characters to HTML equivalent.
-Possible conversions are set in `org-export-html-protect-char-alist'."
- (let ((cl org-e-html-protect-char-alist) c)
- (while (setq c (pop cl))
- (let ((start 0))
- (while (string-match (car c) s start)
- (setq s (replace-match (cdr c) t t s)
- start (1+ (match-beginning 0))))))
- s))
-
-(defun org-e-html-plain-text (text info)
- "Transcode a TEXT string from Org to HTML.
-TEXT is the string to transcode. INFO is a plist holding
-contextual information."
- (setq text (org-e-html-encode-plain-text text))
- ;; Protect %, #, &, $, ~, ^, _, { and }.
- ;; (while (string-match "\\([^\\]\\|^\\)\\([%$#&{}~^_]\\)" text)
- ;; (setq text
- ;; (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
- ;; Protect \
- ;; (setq text (replace-regexp-in-string
- ;; "\\(?:[^\\]\\|^\\)\\(\\\\\\)\\(?:[^%$#&{}~^_\\]\\|$\\)"
- ;; "$\\backslash$" text nil t 1))
- ;; HTML into \HTML{} and TeX into \TeX{}.
- ;; (let ((case-fold-search nil)
- ;; (start 0))
- ;; (while (string-match "\\<\\(\\(?:La\\)?TeX\\)\\>" text start)
- ;; (setq text (replace-match
- ;; (format "\\%s{}" (match-string 1 text)) nil t text)
- ;; start (match-end 0))))
- ;; Handle quotation marks
- ;; (setq text (org-e-html--quotation-marks text info))
- ;; Convert special strings.
- ;; (when (plist-get info :with-special-strings)
- ;; (while (string-match (regexp-quote "...") text)
- ;; (setq text (replace-match "\\ldots{}" nil t text))))
- (when (plist-get info :with-special-strings)
- (setq text (org-e-html-convert-special-strings text)))
- ;; Handle break preservation if required.
- (when (plist-get info :preserve-breaks)
- (setq text (replace-regexp-in-string "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
- text)))
- ;; Return value.
- text)
-
-
-;;;; Property Drawer
-
-(defun org-e-html-property-drawer (property-drawer contents info)
- "Transcode a PROPERTY-DRAWER element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- ;; The property drawer isn't exported but we want separating blank
- ;; lines nonetheless.
- "")
-
-
-;;;; Quote Block
-
-(defun org-e-html-quote-block (quote-block contents info)
- "Transcode a QUOTE-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (org-e-html--wrap-label
- quote-block (format "<blockquote>\n%s</blockquote>" contents)))
-
-
-;;;; Quote Section
-
-(defun org-e-html-quote-section (quote-section contents info)
- "Transcode a QUOTE-SECTION element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((value (org-remove-indentation
- (org-element-property :value quote-section))))
- (when value (format "<pre>\n%s</pre>" value))))
-
-
-;;;; Section
-
-(defun org-e-html-section (section contents info) ; FIXME
- "Transcode a SECTION element from Org to HTML.
-CONTENTS holds the contents of the section. INFO is a plist
-holding contextual information."
- (let ((parent (org-export-get-parent-headline section info)))
- ;; Before first headline: no container, just return CONTENTS.
- (if (not parent) contents
- ;; Get div's class and id references.
- (let ((class-num (+ (org-export-get-relative-level parent info)
- (1- org-e-html-toplevel-hlevel)))
- (id-num
- (mapconcat
- 'number-to-string
- (org-export-get-headline-number parent info) "-")))
- ;; Build return value.
- (format "<div class=\"outline-text-%d\" id=\"text-%s\">\n%s</div>"
- class-num id-num contents)))))
-
-;;;; Radio Target
-
-(defun org-e-html-radio-target (radio-target text info)
- "Transcode a RADIO-TARGET object from Org to HTML.
-TEXT is the text of the target. INFO is a plist holding
-contextual information."
- (let ((id (org-export-solidify-link-text
- (org-element-property :raw-value radio-target))))
- (format "<a id=\"%s\" name=\"%s\">%s</a>" id id text)))
-
-
-;;;; Special Block
-
-(defun org-e-html-special-block (special-block contents info)
- "Transcode a SPECIAL-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let ((type (downcase (org-element-property :type special-block))))
- (org-e-html--wrap-label
- special-block
- (format "\\begin{%s}\n%s\\end{%s}" type contents type))))
-
-
-;;;; Src Block
-
-(defun org-e-html-src-block (src-block contents info)
- "Transcode a SRC-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (let* ((lang (org-element-property :language src-block))
- (caption (org-element-property :caption src-block))
- (label (org-element-property :name src-block))
- (caption-str (org-e-html--caption/label-string caption label info))
- (attr (mapconcat #'identity
- (org-element-property :attr_html src-block)
- " "))
- ;; (switches (org-element-property :switches src-block))
- (switches nil) ; FIXME
- (textarea-p (and switches (string-match "-t\\>" switches)))
- (code (org-e-html-format-code src-block info)))
- (cond
- (lang (format
- "\n<div class=\"org-src-container\">\n%s%s\n</div>"
- (if (not caption) ""
- (format "<label class=\"org-src-name\">%s</label>" caption-str))
- (format "\n<pre class=\"src src-%s\">%s\n</pre>" lang code)))
- (textarea-p
- (let ((cols (if (not (string-match "-w[ \t]+\\([0-9]+\\)" switches))
- 80 (string-to-number (match-string 1 switches))))
- (rows (if (string-match "-h[ \t]+\\([0-9]+\\)" switches)
- (string-to-number (match-string 1 switches))
- (org-count-lines code))))
- (format
- "\n<p>\n<textarea cols=\"%d\" rows=\"%d\">\n%s\n</textarea>\n</p>"
- cols rows code)))
- (t (format "\n<pre class=\"example\">\n%s\n</pre>" code)))))
-
-;;;; Statistics Cookie
-
-(defun org-e-html-statistics-cookie (statistics-cookie contents info)
- "Transcode a STATISTICS-COOKIE object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((cookie-value (org-element-property :value statistics-cookie)))
- (format "<code>%s</code>" cookie-value)))
-
-
-;;;; Subscript
-
-(defun org-e-html-subscript (subscript contents info)
- "Transcode a SUBSCRIPT object from Org to HTML.
-CONTENTS is the contents of the object. INFO is a plist holding
-contextual information."
- (format "<sub>%s</sub>" contents))
-
-
-;;;; Superscript
-
-(defun org-e-html-superscript (superscript contents info)
- "Transcode a SUPERSCRIPT object from Org to HTML.
-CONTENTS is the contents of the object. INFO is a plist holding
-contextual information."
- (format "<sup>%s</sup>" contents))
-
-
-;;;; Table
-
-(defun org-e-html-begin-table (caption label attributes)
- (let* ((html-table-tag (or (plist-get info :html-table-tag) ; FIXME
- org-e-html-table-tag))
- (html-table-tag
- (org-e-html-splice-attributes html-table-tag attributes)))
- (when label
- (setq html-table-tag
- (org-e-html-splice-attributes
- html-table-tag
- (format "id=\"%s\"" (org-solidify-link-text label)))))
- (concat "\n" html-table-tag
- (format "\n<caption>%s</caption>" (or caption "")))))
-
-(defun org-e-html-end-table ()
- "</table>\n")
-
-(defun org-e-html-format-table-cell (text r c horiz-span)
- (let ((cell-style-cookie
- (if org-e-html-table-align-individual-fields
- (format (if (and (boundp 'org-e-html-format-table-no-css)
- org-e-html-format-table-no-css)
- " align=\"%s\"" " class=\"%s\"")
- (or (aref (plist-get table-info :alignment) c) "left")) ""))) ;; FIXME
- (cond
- (org-e-html-table-cur-rowgrp-is-hdr
- (concat
- (format (car org-e-html-table-header-tags) "col" cell-style-cookie)
- text (cdr org-e-html-table-header-tags)))
- ((and (= c 0) org-e-html-table-use-header-tags-for-first-column)
- (concat
- (format (car org-e-html-table-header-tags) "row" cell-style-cookie)
- text (cdr org-e-html-table-header-tags)))
- (t
- (concat
- (format (car org-e-html-table-data-tags) cell-style-cookie)
- text (cdr org-e-html-table-data-tags))))))
-
-(defun org-e-html-format-table-row (row)
- (concat (eval (car org-e-html-table-row-tags)) row
- (eval (cdr org-e-html-table-row-tags))))
-
-(defun org-e-html-table-row (fields &optional text-for-empty-fields)
- (incf org-e-html-table-rownum)
- (let ((i -1))
- (org-e-html-format-table-row
- (mapconcat
- (lambda (x)
- (when (and (string= x "") text-for-empty-fields)
- (setq x text-for-empty-fields))
- (incf i)
- (let (horiz-span)
- (org-e-html-format-table-cell
- x org-e-html-table-rownum i (or horiz-span 0))))
- fields "\n"))))
-
-(defun org-e-html-end-table-rowgroup ()
- (when org-e-html-table-rowgrp-open
- (setq org-e-html-table-rowgrp-open nil)
- (if org-e-html-table-cur-rowgrp-is-hdr "</thead>" "</tbody>")))
-
-(defun org-e-html-begin-table-rowgroup (&optional is-header-row)
- (concat
- (when org-e-html-table-rowgrp-open
- (org-e-html-end-table-rowgroup))
- (progn
- (setq org-e-html-table-rowgrp-open t)
- (setq org-e-html-table-cur-rowgrp-is-hdr is-header-row)
- (if is-header-row "<thead>" "<tbody>"))))
-
-(defun org-e-html-table-preamble ()
- (let ((colgroup-vector (plist-get table-info :column-groups)) ;; FIXME
- c gr colgropen preamble)
- (unless (aref colgroup-vector 0)
- (setf (aref colgroup-vector 0) 'start))
- (dotimes (c columns-number preamble)
- (setq gr (aref colgroup-vector c))
- (setq preamble
- (concat
- preamble
- (when (memq gr '(start start-end))
- (prog1 (if colgropen "</colgroup>\n<colgroup>" "\n<colgroup>")
- (setq colgropen t)))
- (let* ((colalign-vector (plist-get table-info :alignment)) ;; FIXME
- (align (cdr (assoc (aref colalign-vector c)
- '(("l" . "left")
- ("r" . "right")
- ("c" . "center")))))
- (alignspec (if (and (boundp 'org-e-html-format-table-no-css)
- org-e-html-format-table-no-css)
- " align=\"%s\"" " class=\"%s\""))
- (extra (format alignspec align)))
- (format "<col%s />" extra))
- (when (memq gr '(end start-end))
- (setq colgropen nil)
- "</colgroup>"))))
- (concat preamble (if colgropen "</colgroup>"))))
-
-(defun org-e-html-list-table (lines caption label attributes)
- (setq lines (org-e-html-org-table-to-list-table lines))
- (let* ((splice nil) head
- (org-e-html-table-rownum -1)
- i (cnt 0)
- fields line
- org-e-html-table-cur-rowgrp-is-hdr
- org-e-html-table-rowgrp-open
- n
- (org-lparse-table-style 'org-table)
- org-lparse-table-is-styled)
- (cond
- (splice
- (setq org-lparse-table-is-styled nil)
- (mapconcat 'org-e-html-table-row lines "\n"))
- (t
- (setq org-lparse-table-is-styled t)
-
- (concat
- (org-e-html-begin-table caption label attributes)
- (org-e-html-table-preamble)
- (org-e-html-begin-table-rowgroup head)
-
- (mapconcat
- (lambda (line)
- (cond
- ((equal line 'hline) (org-e-html-begin-table-rowgroup))
- (t (org-e-html-table-row line))))
- lines "\n")
-
- (org-e-html-end-table-rowgroup)
- (org-e-html-end-table))))))
-
-(defun org-e-html-transcode-table-row (row)
- (if (string-match org-table-hline-regexp row) 'hline
- (mapcar
- (lambda (cell)
- (org-export-secondary-string
- (let ((cell (org-element-parse-secondary-string
- cell
- (cdr (assq 'table org-element-string-restrictions)))))
- cell)
- 'e-html info))
- (org-split-string row "[ \t]*|[ \t]*"))))
-
-(defun org-e-html-org-table-to-list-table (lines &optional splice)
- "Convert org-table to list-table.
-LINES is a list of the form (ROW1 ROW2 ROW3 ...) where each
-element is a `string' representing a single row of org-table.
-Thus each ROW has vertical separators \"|\" separating the table
-fields. A ROW could also be a row-group separator of the form
-\"|---...|\". Return a list of the form (ROW1 ROW2 ROW3
-...). ROW could either be symbol `'hline' or a list of the
-form (FIELD1 FIELD2 FIELD3 ...) as appropriate."
- (let (line lines-1)
- (cond
- (splice
- (while (setq line (pop lines))
- (unless (string-match "^[ \t]*|-" line)
- (push (org-e-html-transcode-table-row line) lines-1))))
- (t (while (setq line (pop lines))
- (cond
- ((string-match "^[ \t]*|-" line)
- (when lines (push 'hline lines-1)))
- (t (push (org-e-html-transcode-table-row line) lines-1))))))
- (nreverse lines-1)))
-
-(defun org-e-html-table-table (raw-table)
- (require 'table)
- (with-current-buffer (get-buffer-create "*org-export-table*")
- (erase-buffer))
- (let ((output (with-temp-buffer
- (insert raw-table)
- (goto-char 1)
- (re-search-forward "^[ \t]*|[^|]" nil t)
- (table-generate-source 'html "*org-export-table*")
- (with-current-buffer "*org-export-table*"
- (org-trim (buffer-string))))))
- (kill-buffer (get-buffer "*org-export-table*"))
- output))
-
-(defun org-e-html-table (table contents info)
- "Transcode a TABLE element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((label (org-element-property :name table))
- (caption (org-e-html--caption/label-string
- (org-element-property :caption table) label info))
- (attr (mapconcat #'identity
- (org-element-property :attr_html table)
- " "))
- (raw-table (org-element-property :raw-table table))
- (table-type (org-element-property :type table)))
- (case table-type
- (table.el
- (org-e-html-table-table raw-table))
- (t
- (let* ((table-info (org-export-table-format-info raw-table))
- (columns-number (length (plist-get table-info :alignment)))
- (lines (org-split-string
- (org-export-clean-table
- raw-table (plist-get table-info :special-column-p)) "\n")))
- (org-e-html-list-table lines caption label attr))))))
-
-
-;;;; Target
-
-(defun org-e-html-target (target contents info)
- "Transcode a TARGET object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (let ((id (org-export-solidify-link-text
- (org-element-property :value target))))
- (format "<a id=\"%s\" name=\"%s\"/>" id id)))
-
-
-;;;; Time-stamp
-
-(defun org-e-html-time-stamp (time-stamp contents info)
- "Transcode a TIME-STAMP object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (let ((value (org-element-property :value time-stamp))
- (type (org-element-property :type time-stamp))
- (appt-type (org-element-property :appt-type time-stamp)))
- (setq value (org-translate-time
- (org-export-secondary-string value 'e-html info)))
- (setq appt-type (case appt-type
- (scheduled org-scheduled-string)
- (deadline org-deadline-string)
- (closed org-closed-string)))
- (format "<span class=\"timestamp-wrapper\">%s%s</span>"
- (if (not appt-type) ""
- (format "<span class=\"timestamp-kwd\">%s</span> " appt-type))
- (format "<span class=\"timestamp\">%s</span>" value))))
-
-
-;;;; Verbatim
-
-(defun org-e-html-verbatim (verbatim contents info)
- "Transcode a VERBATIM object from Org to HTML.
-CONTENTS is nil. INFO is a plist used as a communication
-channel."
- (org-e-html-emphasis
- verbatim (org-element-property :value verbatim) info))
-
-
-;;;; Verse Block
-
-(defun org-e-html-verse-block (verse-block contents info)
- "Transcode a VERSE-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- ;; Replace each newline character with line break. Also replace
- ;; each blank line with a line break.
- (setq contents (replace-regexp-in-string
- "^ *\\\\\\\\$" "<br/>\n"
- (replace-regexp-in-string
- "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n"
- (org-remove-indentation
- (org-export-secondary-string
- (org-element-property :value verse-block)
- 'e-html info)))))
- ;; Replace each white space at beginning of a line with a
- ;; non-breaking space.
- (while (string-match "^[ \t]+" contents)
- (let* ((num-ws (length (match-string 0 contents)))
- (ws (let (out) (dotimes (i num-ws out)
- (setq out (concat out " "))))))
- (setq contents (replace-match ws nil t contents))))
- (org-e-html--wrap-label
- verse-block (format "<p class=\"verse\">\n%s</p>" contents)))
-
-
-\f
-
-;;; Filter Functions
-
-;;;; Filter Settings
-
-(defconst org-e-html-filters-alist
- '((:filter-final-output . org-e-html-final-function))
- "Alist between filters keywords and back-end specific filters.
-See `org-export-filters-alist' for more information.")
-
-
-;;;; Filters
-
-(defun org-e-html-final-function (contents backend info)
- (if (not org-e-html-pretty-output) contents
- (with-temp-buffer
- (nxml-mode)
- (insert contents)
- (indent-region (point-min) (point-max))
- (buffer-substring-no-properties (point-min) (point-max)))))
-
-
-;;; Interactive functions
-
-(defun org-e-html-export-to-html
- (&optional subtreep visible-only body-only ext-plist pub-dir)
- "Export current buffer to a HTML file.
-
-If narrowing is active in the current buffer, only export its
-narrowed part.
-
-If a region is active, export that region.
-
-When optional argument SUBTREEP is non-nil, export the sub-tree
-at point, extracting information from the headline properties
-first.
-
-When optional argument VISIBLE-ONLY is non-nil, don't export
-contents of hidden elements.
-
-When optional argument BODY-ONLY is non-nil, only write code
-between \"\\begin{document}\" and \"\\end{document}\".
-
-EXT-PLIST, when provided, is a property list with external
-parameters overriding Org default settings, but still inferior to
-file-local settings.
-
-When optional argument PUB-DIR is set, use it as the publishing
-directory.
-
-Return output file's name."
- (interactive)
-
- ;; FIXME
- (with-current-buffer (get-buffer-create "*debug*")
- (erase-buffer))
- (let* ((extension (concat "." org-e-html-extension))
- (file (org-export-output-file-name extension subtreep pub-dir)))
- (org-export-to-file
- 'e-html file subtreep visible-only body-only ext-plist)))
-
-
-\f
-;;; FIXMES, TODOS, FOR REVIEW etc
-
-;;;; org-format-table-html
-;;;; org-format-org-table-html
-;;;; org-format-table-table-html
-;;;; org-table-number-fraction
-;;;; org-table-number-regexp
-;;;; org-e-html-table-caption-above
-
-;;;; org-whitespace
-;;;; "<span style=\"visibility:hidden;\">%s</span>"
-;;;; Remove display properties
-
-;;;; org-e-html-with-timestamp
-;;;; org-e-html-html-helper-timestamp
-
-;;;; org-export-as-html-and-open
-;;;; org-export-as-html-batch
-;;;; org-export-as-html-to-buffer
-;;;; org-replace-region-by-html
-;;;; org-export-region-as-html
-;;;; org-export-as-html
-
-;;;; (org-export-directory :html opt-plist)
-;;;; (plist-get opt-plist :html-extension)
-;;;; org-e-html-toplevel-hlevel
-;;;; org-e-html-special-string-regexps
-;;;; org-e-html-coding-system
-;;;; org-e-html-coding-system
-;;;; org-e-html-inline-images
-;;;; org-e-html-inline-image-extensions
-;;;; org-e-html-protect-char-alist
-;;;; org-e-html-table-use-header-tags-for-first-column
-;;;; org-e-html-todo-kwd-class-prefix
-;;;; org-e-html-tag-class-prefix
-;;;; org-e-html-footnote-separator
-
-;;;; org-export-preferred-target-alist
-;;;; org-solidify-link-text
-;;;; class for anchors
-;;;; org-export-with-section-numbers, body-only
-;;;; org-export-mark-todo-in-toc
-
-(provide 'org-e-html)
-;;; org-e-html.el ends here
diff --git a/EXPERIMENTAL/org-e-odt.el b/EXPERIMENTAL/org-e-odt.el
deleted file mode 100644
index 9b59954..0000000
--- a/EXPERIMENTAL/org-e-odt.el
+++ /dev/null
@@ -1,4589 +0,0 @@
-;;; org-e-odt.el --- OpenDocument Text exporter for Org-mode
-
-;; Copyright (C) 2010-2012 Free Software Foundation, Inc.
-
-;; Author: Jambunathan K <kjambunathan at gmail dot com>
-;; Keywords: outlines, hypermedia, calendar, wp
-;; Homepage: http://orgmode.org
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-(eval-when-compile
- (require 'cl))
-
-(defgroup org-export-e-odt nil
- "Options specific for ODT export of Org-mode files."
- :tag "Org Export ODT"
- :group 'org-export
- :version "24.1")
-
-;; FIXMES
-;; org-export-preprocess-after-blockquote-hook
-;; org-export-e-odt-preprocess-latex-fragments
-;; org-export-as-e-odt-and-open
-;; org-export-as-e-odt-batch
-;; org-export-as-e-odt
-
-(defun org-e-odt-get-style-name-for-entity (category &optional entity)
- (let ((entity (or entity 'default)))
- (or
- (cdr (assoc entity (cdr (assoc category
- org-export-e-odt-org-styles-alist))))
- (cdr (assoc entity (cdr (assoc category
- org-export-e-odt-default-org-styles-alist))))
- (error "Cannot determine style name for entity %s of type %s"
- entity category))))
-
-
-;; Following variable is let bound when `org-do-lparse' is in
-;; progress. See org-html.el.
-
-(defun org-e-odt-format-preamble (info)
- (let* ((title (plist-get info :title))
- (author (plist-get info :author))
- (date (plist-get info :date))
- (iso-date (org-e-odt-format-date date))
- (date (org-e-odt-format-date date "%d %b %Y"))
- (email (plist-get info :email))
- ;; switch on or off above vars based on user settings
- (author (and (plist-get info :with-author) (or author email)))
- (email (and (plist-get info :with-email) email))
- ;; (date (and (plist-get info :time-stamp-file) date))
- )
- (concat
- ;; title
- (when title
- (concat
- (org-e-odt-format-stylized-paragraph
- 'title (format "\n<text:title>%s</text:title>" title))
- ;; separator
- "\n<text:p text:style-name=\"OrgTitle\"/>"))
- (cond
- ((and author (not email))
- ;; author only
- (concat
- (org-e-odt-format-stylized-paragraph
- 'subtitle
- (format "<text:initial-creator>%s</text:initial-creator>" author))
- ;; separator
- "\n<text:p text:style-name=\"OrgSubtitle\"/>"))
- ((and author email)
- ;; author and email
- (concat
- (org-e-odt-format-stylized-paragraph
- 'subtitle
- (org-e-odt-format-link
- (format "<text:initial-creator>%s</text:initial-creator>" author)
- (concat "mailto:" email)))
- ;; separator
- "\n<text:p text:style-name=\"OrgSubtitle\"/>")))
- ;; date
- (when date
- (concat
- (org-e-odt-format-stylized-paragraph
- 'subtitle
- (org-odt-format-tags
- '("<text:date style:data-style-name=\"%s\" text:date-value=\"%s\">"
- . "</text:date>")
- date "N75" iso-date))
- ;; separator
- "<text:p text:style-name=\"OrgSubtitle\"/>")))))
-
-(defun org-e-odt-begin-section (style &optional name)
- (let ((default-name (car (org-e-odt-add-automatic-style "Section"))))
- (format "<text:section text:style-name=\"%s\" text:name=\"%s\">"
- style (or name default-name))))
-
-(defun org-e-odt-end-section ()
- "</text:section>")
-
-(defun org-e-odt-begin-paragraph (&optional style)
- (format "<text:p%s>" (org-e-odt-get-extra-attrs-for-paragraph-style style)))
-
-(defun org-e-odt-end-paragraph ()
- "</text:p>")
-
-(defun org-e-odt-get-extra-attrs-for-paragraph-style (style)
- (let (style-name)
- (setq style-name
- (cond
- ((stringp style) style)
- ((symbolp style) (org-e-odt-get-style-name-for-entity
- 'paragraph style))))
- (unless style-name
- (error "Don't know how to handle paragraph style %s" style))
- (format " text:style-name=\"%s\"" style-name)))
-
-(defun org-e-odt-format-stylized-paragraph (style text)
- (format "\n<text:p%s>%s</text:p>"
- (org-e-odt-get-extra-attrs-for-paragraph-style style)
- text))
-
-(defun org-e-odt-format-author (&optional author )
- (when (setq author (or author (plist-get org-lparse-opt-plist :author)))
- (format "<dc:creator>%s</dc:creator>" author)))
-
-(defun org-e-odt-format-date (&optional org-ts fmt)
- (save-match-data
- (let* ((time
- (and (stringp org-ts)
- (string-match org-ts-regexp0 org-ts)
- (apply 'encode-time
- (org-fix-decoded-time
- (org-parse-time-string (match-string 0 org-ts) t)))))
- date)
- (cond
- (fmt (format-time-string fmt time))
- (t (setq date (format-time-string "%Y-%m-%dT%H:%M:%S%z" time))
- (format "%s:%s" (substring date 0 -2) (substring date -2)))))))
-
-(defun org-e-odt-begin-annotation (&optional author date)
- (concat
- "<office:annotation>\n"
- (and author (org-e-odt-format-author author))
- (org-e-odt-format-tags
- '("<dc:date>" . "</dc:date>")
- (org-e-odt-format-date
- (or date (plist-get org-lparse-opt-plist :date))))
- (org-e-odt-begin-paragraph)))
-
-(defun org-e-odt-end-annotation ()
- "</office:annotation>")
-
-(defun org-e-odt-begin-plain-list (ltype)
- (let* ((style-name (org-e-odt-get-style-name-for-entity 'list ltype))
- (extra (concat
- ;; (if (or org-lparse-list-table-p
- ;; (and (= 1 (length org-lparse-list-stack))
- ;; (null org-e-odt-list-stack-stashed)))
- ;; " text:continue-numbering=\"false\""
- ;; " text:continue-numbering=\"true\"")
-
- " text:continue-numbering=\"true\""
-
- (when style-name
- (format " text:style-name=\"%s\"" style-name)))))
- (case ltype
- ((ordered unordered descriptive)
- (concat
- ;; (org-e-odt-end-paragraph)
- (format "<text:list%s>" extra)))
- (t (error "Unknown list type: %s" ltype)))))
-
-(defun org-e-odt-end-plain-list (ltype)
- (if ltype "</text:list>"
- (error "Unknown list type: %s" ltype)))
-
-(defun org-e-odt-begin-list-item (ltype &optional arg headline)
- (case ltype
- (ordered
- (assert (not headline) t)
- (let* ((counter arg) (extra ""))
- (concat "<text:list-item>" ;; (org-e-odt-begin-paragraph)
- )
- ;; (if (= (length org-lparse-list-stack)
- ;; (length org-e-odt-list-stack-stashed))
- ;; "<text:list-header>" "<text:list-item>")
- ))
- (unordered
- (let* ((id arg) (extra ""))
- (concat
- "<text:list-item>"
- ;; (org-e-odt-begin-paragraph)
- (if headline (org-e-odt-format-target headline id)
- (org-e-odt-format-bookmark "" id)))
- ;; (if (= (length org-lparse-list-stack)
- ;; (length org-e-odt-list-stack-stashed))
- ;; "<text:list-header>" "<text:list-item>")
- ))
- (descriptive
- (assert (not headline) t)
- (let ((term (or arg "(no term)")))
- (concat
- (org-e-odt-format-tags
- '("<text:list-item>" . "</text:list-item>")
- (org-e-odt-format-stylized-paragraph 'definition-term term))
- (org-e-odt-begin-list-item 'unordered)
- (org-e-odt-begin-plain-list 'descriptive)
- (org-e-odt-begin-list-item 'unordered))))
- (t (error "Unknown list type"))))
-
-(defun org-e-odt-end-list-item (ltype)
- (case ltype
- ((ordered unordered)
- ;; (org-lparse-insert-tag
- ;; (if (= (length org-lparse-list-stack)
- ;; (length org-e-odt-list-stack-stashed))
- ;; (prog1 "</text:list-header>"
- ;; (setq org-e-odt-list-stack-stashed nil))
- ;; "</text:list-item>")
- "</text:list-item>"
- ;; )
- )
- (descriptive
- (concat
- (org-e-odt-end-list-item 'unordered)
- (org-e-odt-end-plain-list 'descriptive)
- (org-e-odt-end-list-item 'unordered)
- ))
- (t (error "Unknown list type"))))
-
-(defun org-e-odt-discontinue-list ()
- (let ((stashed-stack org-lparse-list-stack))
- (loop for list-type in stashed-stack
- do (org-lparse-end-list-item-1 list-type)
- (org-lparse-end-list list-type))
- (setq org-e-odt-list-stack-stashed stashed-stack)))
-
-(defun org-e-odt-continue-list ()
- (setq org-e-odt-list-stack-stashed (nreverse org-e-odt-list-stack-stashed))
- (loop for list-type in org-e-odt-list-stack-stashed
- do (org-lparse-begin-list list-type)
- (org-lparse-begin-list-item list-type)))
-
-(defun org-e-odt-write-automatic-styles ()
- "Write automatic styles to \"content.xml\"."
- (with-current-buffer
- (find-file-noselect (expand-file-name "content.xml") t)
- ;; position the cursor
- (goto-char (point-min))
- (re-search-forward " </office:automatic-styles>" nil t)
- (goto-char (match-beginning 0))
- ;; write automatic table styles
- (loop for (style-name props) in
- (plist-get org-e-odt-automatic-styles 'Table) do
- (when (setq props (or (plist-get props :rel-width) 96))
- (insert (format org-e-odt-table-style-format style-name props))))))
-
-(defun org-e-odt-add-automatic-style (object-type &optional object-props)
- "Create an automatic style of type OBJECT-TYPE with param OBJECT-PROPS.
-OBJECT-PROPS is (typically) a plist created by passing
-\"#+ATTR_ODT: \" option of the object in question to
-`org-lparse-get-block-params'.
-
-Use `org-e-odt-object-counters' to generate an automatic
-OBJECT-NAME and STYLE-NAME. If OBJECT-PROPS is non-nil, add a
-new entry in `org-e-odt-automatic-styles'. Return (OBJECT-NAME
-. STYLE-NAME)."
- (assert (stringp object-type))
- (let* ((object (intern object-type))
- (seqvar object)
- (seqno (1+ (or (plist-get org-e-odt-object-counters seqvar) 0)))
- (object-name (format "%s%d" object-type seqno)) style-name)
- (setq org-e-odt-object-counters
- (plist-put org-e-odt-object-counters seqvar seqno))
- (when object-props
- (setq style-name (format "Org%s" object-name))
- (setq org-e-odt-automatic-styles
- (plist-put org-e-odt-automatic-styles object
- (append (list (list style-name object-props))
- (plist-get org-e-odt-automatic-styles object)))))
- (cons object-name style-name)))
-
-(defun org-e-odt-format-table-columns ()
- (let* ((num-cols (length (plist-get table-info :alignment)))
- (col-nos (loop for i from 0 below num-cols collect i))
- (levels )
- (col-widths (plist-get table-info :width))
- (style (or (nth 1 org-e-odt-table-style-spec) "OrgTable")))
- (mapconcat
- (lambda (c)
- (let* ((width (or (and org-lparse-table-is-styled (aref col-widths c))
- 0)))
- (org-e-odt-make-string
- (1+ width)
- (org-e-odt-format-tags
- "<table:table-column table:style-name=\"%sColumn\"/>" "" style))))
- col-nos "\n")))
-
-
-(defun org-e-odt-begin-table (caption label attributes)
- ;; (setq org-e-odt-table-indentedp (not (null org-lparse-list-stack)))
- (setq org-e-odt-table-indentedp nil) ; FIXME
- (when org-e-odt-table-indentedp
- ;; Within the Org file, the table is appearing within a list item.
- ;; OpenDocument doesn't allow table to appear within list items.
- ;; Temporarily terminate the list, emit the table and then
- ;; re-continue the list.
- (org-e-odt-discontinue-list)
- ;; Put the Table in an indented section.
- (let ((level (length org-e-odt-list-stack-stashed)))
- (org-e-odt-begin-section (format "OrgIndentedSection-Level-%d" level))))
- (setq attributes (org-lparse-get-block-params attributes))
- (setq org-e-odt-table-style (plist-get attributes :style))
- (setq org-e-odt-table-style-spec
- (assoc org-e-odt-table-style org-export-e-odt-table-styles))
- (concat
- (org-e-odt-format-stylized-paragraph
- 'table (org-e-odt-format-entity-caption label caption "__Table__"))
- (let ((name-and-style (org-e-odt-add-automatic-style "Table" attributes)))
- (format
- "\n<table:table table:name=\"%s\" table:style-name=\"%s\">\n"
- (car name-and-style) (or (nth 1 org-e-odt-table-style-spec)
- (cdr name-and-style) "OrgTable")))
- (org-e-odt-format-table-columns) "\n")
-
- ;; (org-e-html-pp table-info)
-
- )
-
-(defun org-e-odt-end-table ()
- (concat
- "</table:table>"
- ;; (when org-e-odt-table-indentedp
- ;; (org-e-odt-end-section)
- ;; (org-e-odt-continue-list))
- ))
-
-(defun org-e-odt-begin-table-rowgroup (&optional is-header-row)
- (prog1
- (concat (when org-e-odt-table-rowgrp-open
- (org-e-odt-end-table-rowgroup))
- (if is-header-row "<table:table-header-rows>"
- "<table:table-rows>"))
- (setq org-e-odt-table-rowgrp-open t)
- (setq org-e-odt-table-cur-rowgrp-is-hdr is-header-row)))
-
-(defun org-e-odt-end-table-rowgroup ()
- (when org-e-odt-table-rowgrp-open
- (setq org-e-odt-table-rowgrp-open nil)
- (if org-e-odt-table-cur-rowgrp-is-hdr
- "</table:table-header-rows>" "</table:table-rows>")))
-
-(defun org-e-odt-format-table-row (row)
- (org-e-odt-format-tags
- '("<table:table-row>" . "</table:table-row>") row))
-
-(defun org-e-odt-get-column-alignment (c)
- (let ((colalign-vector (plist-get table-info :alignment)))
- ;; FIXME
- (assoc-default (aref colalign-vector c)
- '(("l" . "left")
- ("r" . "right")
- ("c" . "center")))))
-
-(defun org-e-odt-get-table-cell-styles (r c &optional style-spec)
- "Retrieve styles applicable to a table cell.
-R and C are (zero-based) row and column numbers of the table
-cell. STYLE-SPEC is an entry in `org-export-e-odt-table-styles'
-applicable to the current table. It is `nil' if the table is not
-associated with any style attributes.
-
-Return a cons of (TABLE-CELL-STYLE-NAME . PARAGRAPH-STYLE-NAME).
-
-When STYLE-SPEC is nil, style the table cell the conventional way
-- choose cell borders based on row and column groupings and
-choose paragraph alignment based on `org-col-cookies' text
-property. See also
-`org-e-odt-get-paragraph-style-cookie-for-table-cell'.
-
-When STYLE-SPEC is non-nil, ignore the above cookie and return
-styles congruent with the ODF-1.2 specification."
- (cond
- (style-spec
-
- ;; LibreOffice - particularly the Writer - honors neither table
- ;; templates nor custom table-cell styles. Inorder to retain
- ;; inter-operability with LibreOffice, only automatic styles are
- ;; used for styling of table-cells. The current implementation is
- ;; congruent with ODF-1.2 specification and hence is
- ;; future-compatible.
-
- ;; Additional Note: LibreOffice's AutoFormat facility for tables -
- ;; which recognizes as many as 16 different cell types - is much
- ;; richer. Unfortunately it is NOT amenable to easy configuration
- ;; by hand.
-
- (let* ((template-name (nth 1 style-spec))
- (cell-style-selectors (nth 2 style-spec))
- (cell-type
- (cond
- ((and (cdr (assoc 'use-first-column-styles cell-style-selectors))
- (= c 0)) "FirstColumn")
- ((and (cdr (assoc 'use-last-column-styles cell-style-selectors))
- (= c (1- org-lparse-table-ncols))) "LastColumn")
- ((and (cdr (assoc 'use-first-row-styles cell-style-selectors))
- (= r 0)) "FirstRow")
- ((and (cdr (assoc 'use-last-row-styles cell-style-selectors))
- (= r org-e-odt-table-rownum))
- "LastRow")
- ((and (cdr (assoc 'use-banding-rows-styles cell-style-selectors))
- (= (% r 2) 1)) "EvenRow")
- ((and (cdr (assoc 'use-banding-rows-styles cell-style-selectors))
- (= (% r 2) 0)) "OddRow")
- ((and (cdr (assoc 'use-banding-columns-styles cell-style-selectors))
- (= (% c 2) 1)) "EvenColumn")
- ((and (cdr (assoc 'use-banding-columns-styles cell-style-selectors))
- (= (% c 2) 0)) "OddColumn")
- (t ""))))
- (cons
- (concat template-name cell-type "TableCell")
- (concat template-name cell-type "TableParagraph"))))
- (t
- (cons
- (concat
- "OrgTblCell"
- (cond
- ((= r 0) "T")
- ((eq (cdr (assoc r nil ;; org-lparse-table-rowgrp-info FIXME
- )) :start) "T")
- (t ""))
- (when (= r org-e-odt-table-rownum) "B")
- (cond
- ((= c 0) "")
- ((or (memq (nth c org-table-colgroup-info) '(:start :startend))
- (memq (nth (1- c) org-table-colgroup-info) '(:end :startend))) "L")
- (t "")))
- (capitalize (org-e-odt-get-column-alignment c))))))
-
-(defun org-e-odt-get-paragraph-style-cookie-for-table-cell (r c)
- (concat
- (and (not org-e-odt-table-style-spec)
- (cond
- (org-e-odt-table-cur-rowgrp-is-hdr "OrgTableHeading")
- ((and (= c 0) nil
- ;; (org-lparse-get 'TABLE-FIRST-COLUMN-AS-LABELS)
- )
- "OrgTableHeading")
- (t "OrgTableContents")))
- (and org-lparse-table-is-styled
- (cdr (org-e-odt-get-table-cell-styles
- r c org-e-odt-table-style-spec)))))
-
-(defun org-e-odt-get-style-name-cookie-for-table-cell (r c)
- (when org-lparse-table-is-styled
- (let* ((cell-styles (org-e-odt-get-table-cell-styles
- r c org-e-odt-table-style-spec))
- (table-cell-style (car cell-styles)))
- table-cell-style)))
-
-(defun org-e-odt-format-table-cell (data r c horiz-span)
- (concat
- (let* ((paragraph-style-cookie
- (org-e-odt-get-paragraph-style-cookie-for-table-cell r c))
- (style-name-cookie
- (org-e-odt-get-style-name-cookie-for-table-cell r c))
- (extra (and style-name-cookie
- (format " table:style-name=\"%s\"" style-name-cookie)))
- (extra (concat extra
- (and (> horiz-span 0)
- (format " table:number-columns-spanned=\"%d\""
- (1+ horiz-span))))))
- (org-e-odt-format-tags
- '("<table:table-cell%s>" . "</table:table-cell>")
- (if org-lparse-list-table-p data
- (org-e-odt-format-stylized-paragraph paragraph-style-cookie data)) extra))
- (let (s)
- (dotimes (i horiz-span)
- (setq s (concat s "\n<table:covered-table-cell/>"))) s)
- "\n"))
-
-(defun org-e-odt-begin-toc (lang-specific-heading max-level)
- (concat
- (format "
- <text:table-of-content text:style-name=\"Sect2\" text:protected=\"true\" text:name=\"Table of Contents1\">
- <text:table-of-content-source text:outline-level=\"%d\">
- <text:index-title-template text:style-name=\"Contents_20_Heading\">%s</text:index-title-template>
-" max-level lang-specific-heading)
-
- (let ((entry-templates ""))
- (loop for level from 1 upto 10
- do (setq entry-templates
- (concat entry-templates
- (format
- "
- <text:table-of-content-entry-template text:outline-level=\"%d\" text:style-name=\"Contents_20_%d\">
- <text:index-entry-link-start text:style-name=\"Internet_20_link\"/>
- <text:index-entry-chapter/>
- <text:index-entry-text/>
- <text:index-entry-link-end/>
- </text:table-of-content-entry-template>
-" level level))))
- entry-templates)
-
- (format "
- </text:table-of-content-source>
-
- <text:index-body>
- <text:index-title text:style-name=\"Sect1\" text:name=\"Table of Contents1_Head\">
- <text:p text:style-name=\"Contents_20_Heading\">%s</text:p>
- </text:index-title>
- " lang-specific-heading)))
-
-(defun org-e-odt-end-toc ()
- (format "
- </text:index-body>
- </text:table-of-content>
-"))
-
-(defun org-e-odt-format-toc-entry (snumber todo headline tags href)
-
- ;; FIXME
- (setq headline (concat
- (and org-export-with-section-numbers
- (concat snumber ". "))
- headline
- (and tags
- (concat
- (org-e-odt-format-spaces 3)
- (org-e-odt-format-fontify tags "tag")))))
- (when todo
- (setq headline (org-e-odt-format-fontify headline "todo")))
-
- (let ((org-e-odt-suppress-xref t))
- (org-e-odt-format-link headline (concat "#" href))))
-
-(defun org-e-odt-format-toc-item (toc-entry level org-last-level)
- (let ((style (format "Contents_20_%d"
- (+ level (or ;; (org-lparse-get 'TOPLEVEL-HLEVEL)
- 1
- 1) -1))))
- (concat "\n" (org-e-odt-format-stylized-paragraph style toc-entry) "\n")))
-
-;; Following variable is let bound during 'ORG-LINK callback. See
-;; org-html.el
-
-(defun org-e-odt-format-link (desc href &optional attr)
- (cond
- ((and (= (string-to-char href) ?#) (not org-e-odt-suppress-xref))
- (setq href (concat org-export-e-odt-bookmark-prefix (substring href 1)))
- (let ((xref-format "text"))
- (when (numberp desc)
- (setq desc (format "%d" desc) xref-format "number"))
- (org-e-odt-format-tags-simple
- '("<text:bookmark-ref text:reference-format=\"%s\" text:ref-name=\"%s\">" .
- "</text:bookmark-ref>")
- desc xref-format href)))
- (org-lparse-link-description-is-image
- (org-e-odt-format-tags
- '("<draw:a xlink:type=\"simple\" xlink:href=\"%s\" %s>" . "</draw:a>")
- desc href (or attr "")))
- (t
- (org-e-odt-format-tags-simple
- '("<text:a xlink:type=\"simple\" xlink:href=\"%s\" %s>" . "</text:a>")
- desc href (or attr "")))))
-
-(defun org-e-odt-format-spaces (n)
- (cond
- ((= n 1) " ")
- ((> n 1) (concat
- " " (org-e-odt-format-tags "<text:s text:c=\"%d\"/>" "" (1- n))))
- (t "")))
-
-(defun org-e-odt-format-tabs (&optional n)
- (let ((tab "<text:tab/>")
- (n (or n 1)))
- (insert tab)))
-
-(defun org-e-odt-format-line-break ()
- (org-e-odt-format-tags "<text:line-break/>" ""))
-
-(defun org-e-odt-format-horizontal-line ()
- (org-e-odt-format-stylized-paragraph 'horizontal-line ""))
-
-(defun org-e-odt-encode-plain-text (line &optional no-whitespace-filling)
- (setq line (org-e-html-encode-plain-text line))
- (if no-whitespace-filling line
- (org-e-odt-fill-tabs-and-spaces line)))
-
-(defun org-e-odt-format-line (line)
- (case org-lparse-dyn-current-environment
- (fixedwidth (concat
- (org-e-odt-format-stylized-paragraph
- 'fixedwidth (org-e-odt-encode-plain-text line)) "\n"))
- (t (concat line "\n"))))
-
-(defun org-e-odt-format-comment (fmt &rest args)
- (let ((comment (apply 'format fmt args)))
- (format "\n<!-- %s -->\n" comment)))
-
-(defun org-e-odt-format-org-entity (wd)
- (org-entity-get-representation wd 'utf8))
-
-(defun org-e-odt-fill-tabs-and-spaces (line)
- (replace-regexp-in-string
- "\\([\t]\\|\\([ ]+\\)\\)" (lambda (s)
- (cond
- ((string= s "\t") (org-e-odt-format-tabs))
- (t (org-e-odt-format-spaces (length s))))) line))
-
-(defun org-e-odt-hfy-face-to-css (fn)
- "Create custom style for face FN.
-When FN is the default face, use it's foreground and background
-properties to create \"OrgSrcBlock\" paragraph style. Otherwise
-use it's color attribute to create a character style whose name
-is obtained from FN. Currently all attributes of FN other than
-color are ignored.
-
-The style name for a face FN is derived using the following
-operations on the face name in that order - de-dash, CamelCase
-and prefix with \"OrgSrc\". For example,
-`font-lock-function-name-face' is associated with
-\"OrgSrcFontLockFunctionNameFace\"."
- (let* ((css-list (hfy-face-to-style fn))
- (style-name ((lambda (fn)
- (concat "OrgSrc"
- (mapconcat
- 'capitalize (split-string
- (hfy-face-or-def-to-name fn) "-")
- ""))) fn))
- (color-val (cdr (assoc "color" css-list)))
- (background-color-val (cdr (assoc "background" css-list)))
- (style (and org-export-e-odt-create-custom-styles-for-srcblocks
- (cond
- ((eq fn 'default)
- (format org-src-block-paragraph-format
- background-color-val color-val))
- (t
- (format
- "
-<style:style style:name=\"%s\" style:family=\"text\">
- <style:text-properties fo:color=\"%s\"/>
- </style:style>" style-name color-val))))))
- (cons style-name style)))
-
-(defun org-e-odt-insert-custom-styles-for-srcblocks (styles)
- "Save STYLES used for colorizing of source blocks.
-Update styles.xml with styles that were collected as part of
-`org-e-odt-hfy-face-to-css' callbacks."
- (when styles
- (with-current-buffer
- (find-file-noselect (expand-file-name "styles.xml") t)
- (goto-char (point-min))
- (when (re-search-forward "</office:styles>" nil t)
- (goto-char (match-beginning 0))
- (insert "\n<!-- Org Htmlfontify Styles -->\n" styles "\n")))))
-
-(defun org-e-odt-remap-stylenames (style-name)
- (or
- (cdr (assoc style-name '(("timestamp-wrapper" . "OrgTimestampWrapper")
- ("timestamp" . "OrgTimestamp")
- ("timestamp-kwd" . "OrgTimestampKeyword")
- ("tag" . "OrgTag")
- ("todo" . "OrgTodo")
- ("done" . "OrgDone")
- ("target" . "OrgTarget"))))
- style-name))
-
-(defun org-e-odt-format-fontify (text style &optional id)
- (let* ((style-name
- (cond
- ((stringp style)
- (org-e-odt-remap-stylenames style))
- ((symbolp style)
- (org-e-odt-get-style-name-for-entity 'character style))
- ((listp style)
- (assert (< 1 (length style)))
- (let ((parent-style (pop style)))
- (mapconcat (lambda (s)
- ;; (assert (stringp s) t)
- (org-e-odt-remap-stylenames s)) style "")
- (org-e-odt-remap-stylenames parent-style)))
- (t (error "Don't how to handle style %s" style)))))
- (org-e-odt-format-tags
- '("<text:span text:style-name=\"%s\">" . "</text:span>")
- text style-name)))
-
-(defun org-e-odt-relocate-relative-path (path dir)
- (if (file-name-absolute-p path) path
- (file-relative-name (expand-file-name path dir)
- (expand-file-name "eyecandy" dir))))
-
-(defun org-e-odt-format-inline-image (thefile
- &optional caption label attrs ; FIXME - CLA
- )
- (let* ((thelink (if (file-name-absolute-p thefile) thefile
- (org-xml-format-href
- (org-e-odt-relocate-relative-path
- thefile org-current-export-file))))
- (href
- (org-e-odt-format-tags
- "<draw:image xlink:href=\"%s\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"/>" ""
- (if org-export-e-odt-embed-images
- (org-e-odt-copy-image-file thefile) thelink))))
- (org-export-e-odt-format-image thefile href)))
-
-(defun org-export-e-odt-format-formula (src href)
- (save-match-data
- (let* ((caption (org-find-text-property-in-string 'org-caption src))
- (caption (and caption (org-xml-format-desc caption)))
- (label (org-find-text-property-in-string 'org-label src))
- (latex-frag (org-find-text-property-in-string 'org-latex-src src))
- (embed-as (or (and latex-frag
- (org-find-text-property-in-string
- 'org-latex-src-embed-type src))
- (if (or caption label) 'paragraph 'character)))
- width height)
- (when latex-frag
- (setq href (org-propertize href :title "LaTeX Fragment"
- :description latex-frag)))
- (cond
- ((eq embed-as 'character)
- (org-e-odt-format-entity "InlineFormula" href width height))
- (t
- (org-lparse-end-paragraph)
- (org-lparse-insert-list-table
- `((,(org-e-odt-format-entity
- (if caption "CaptionedDisplayFormula" "DisplayFormula")
- href width height :caption caption :label nil)
- ,(if (not label) ""
- (org-e-odt-format-entity-caption label nil "__MathFormula__"))))
- nil nil nil ":style \"OrgEquation\"" nil '((1 "c" 8) (2 "c" 1)))
- (throw 'nextline nil))))))
-
-(defun org-e-odt-copy-formula-file (path)
- "Returns the internal name of the file"
- (let* ((src-file (expand-file-name
- path (file-name-directory org-current-export-file)))
- (target-dir (format "Formula-%04d/"
- (incf org-e-odt-embedded-formulas-count)))
- (target-file (concat target-dir "content.xml")))
- (message "Embedding %s as %s ..."
- (substring-no-properties path) target-file)
-
- (make-directory target-dir)
- (org-e-odt-create-manifest-file-entry
- "application/vnd.oasis.opendocument.formula" target-dir "1.2")
-
- (case (org-e-odt-is-formula-link-p src-file)
- (mathml
- (copy-file src-file target-file 'overwrite))
- (odf
- (org-e-odt-zip-extract-one src-file "content.xml" target-dir))
- (t
- (error "%s is not a formula file" src-file)))
-
- (org-e-odt-create-manifest-file-entry "text/xml" target-file)
- target-file))
-
-(defun org-e-odt-format-inline-formula (thefile)
- (let* ((thelink (if (file-name-absolute-p thefile) thefile
- (org-xml-format-href
- (org-e-odt-relocate-relative-path
- thefile org-current-export-file))))
- (href
- (org-e-odt-format-tags
- "<draw:object xlink:href=\"%s\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"/>" ""
- (file-name-directory (org-e-odt-copy-formula-file thefile)))))
- (org-export-e-odt-format-formula thefile href)))
-
-(defun org-e-odt-is-formula-link-p (file)
- (let ((case-fold-search nil))
- (cond
- ((string-match "\\.\\(mathml\\|mml\\)\\'" file)
- 'mathml)
- ((string-match "\\.odf\\'" file)
- 'odf))))
-
-(defun org-e-odt-format-org-link (opt-plist type-1 path fragment desc attr
- descp)
- "Make a OpenDocument link.
-OPT-PLIST is an options list.
-TYPE-1 is the device-type of the link (THIS://foo.html).
-PATH is the path of the link (http://THIS#location).
-FRAGMENT is the fragment part of the link, if any (foo.html#THIS).
-DESC is the link description, if any.
-ATTR is a string of other attributes of the a element."
- (declare (special org-lparse-par-open))
- (save-match-data
- (let* ((may-inline-p
- (and (member type-1 '("http" "https" "file"))
- (org-lparse-should-inline-p path descp)
- (not fragment)))
- (type (if (equal type-1 "id") "file" type-1))
- (filename path)
- (thefile path))
- (cond
- ;; check for inlined images
- ((and (member type '("file"))
- (not fragment)
- (org-file-image-p
- filename org-export-e-odt-inline-image-extensions)
- (or (eq t org-export-e-odt-inline-images)
- (and org-export-e-odt-inline-images (not descp))))
- (org-e-odt-format-inline-image thefile))
- ;; check for embedded formulas
- ((and (member type '("file"))
- (not fragment)
- (org-e-odt-is-formula-link-p filename)
- (or (not descp)))
- (org-e-odt-format-inline-formula thefile))
- ((string= type "coderef")
- (let* ((ref fragment)
- (lineno-or-ref (cdr (assoc ref org-export-code-refs)))
- (desc (and descp desc))
- (org-e-odt-suppress-xref nil)
- (href (org-xml-format-href (concat "#coderef-" ref))))
- (cond
- ((and (numberp lineno-or-ref) (not desc))
- (org-e-odt-format-link lineno-or-ref href))
- ((and (numberp lineno-or-ref) desc
- (string-match (regexp-quote (concat "(" ref ")")) desc))
- (format (replace-match "%s" t t desc)
- (org-e-odt-format-link lineno-or-ref href)))
- (t
- (setq desc (format
- (if (and desc (string-match
- (regexp-quote (concat "(" ref ")"))
- desc))
- (replace-match "%s" t t desc)
- (or desc "%s"))
- lineno-or-ref))
- (org-e-odt-format-link (org-xml-format-desc desc) href)))))
- (t
- (when (string= type "file")
- (setq thefile
- (cond
- ((file-name-absolute-p path)
- (concat "file://" (expand-file-name path)))
- (t (org-e-odt-relocate-relative-path
- thefile org-current-export-file)))))
-
- (when (and (member type '("" "http" "https" "file")) fragment)
- (setq thefile (concat thefile "#" fragment)))
-
- (setq thefile (org-xml-format-href thefile))
-
- (when (not (member type '("" "file")))
- (setq thefile (concat type ":" thefile)))
-
- (let ((org-e-odt-suppress-xref nil))
- (org-e-odt-format-link
- (org-xml-format-desc desc) thefile attr)))))))
-
-(defun org-e-odt-format-heading (text level &optional id)
- (let* ((text (if id (org-e-odt-format-target text id) text)))
- (org-e-odt-format-tags
- '("<text:h text:style-name=\"Heading_20_%s\" text:outline-level=\"%s\">" .
- "</text:h>") text level level)))
-
-(defun org-e-odt-format-headline (title extra-targets tags
- &optional snumber level)
- (concat
- (org-e-odt-format-extra-targets extra-targets)
-
- ;; No need to generate section numbers. They are auto-generated by
- ;; the application
-
- ;; (concat (org-lparse-format 'SECTION-NUMBER snumber level) " ")
- title
- (and tags (concat (org-e-odt-format-spaces 3)
- (org-e-odt-format-org-tags tags)))))
-
-(defun org-e-odt-format-anchor (text name &optional class)
- (org-e-odt-format-target text name))
-
-(defun org-e-odt-format-bookmark (text id)
- (if id
- (org-e-odt-format-tags "<text:bookmark text:name=\"%s\"/>" text id)
- text))
-
-(defun org-e-odt-format-target (text id)
- (let ((name (concat org-export-e-odt-bookmark-prefix id)))
- (concat
- (and id (org-e-odt-format-tags
- "<text:bookmark-start text:name=\"%s\"/>" "" name))
- (org-e-odt-format-bookmark text id)
- (and id (org-e-odt-format-tags
- "<text:bookmark-end text:name=\"%s\"/>" "" name)))))
-
-(defun org-e-odt-format-footnote (n def)
- (setq n (format "%d" n))
- (let ((id (concat "fn" n))
- (note-class "footnote")
- (par-style "Footnote"))
- (org-e-odt-format-tags
- '("<text:note text:id=\"%s\" text:note-class=\"%s\">" .
- "</text:note>")
- (concat
- (org-e-odt-format-tags
- '("<text:note-citation>" . "</text:note-citation>")
- n)
- (org-e-odt-format-tags
- '("<text:note-body>" . "</text:note-body>")
- def))
- id note-class)))
-
-(defun org-e-odt-format-footnote-reference (n def refcnt)
- (if (= refcnt 1)
- (org-e-odt-format-footnote n def)
- (org-e-odt-format-footnote-ref n)))
-
-(defun org-e-odt-format-footnote-ref (n)
- (setq n (format "%d" n))
- (let ((note-class "footnote")
- (ref-format "text")
- (ref-name (concat "fn" n)))
- (org-e-odt-format-tags
- '("<text:span text:style-name=\"%s\">" . "</text:span>")
- (org-e-odt-format-tags
- '("<text:note-ref text:note-class=\"%s\" text:reference-format=\"%s\" text:ref-name=\"%s\">" . "</text:note-ref>")
- n note-class ref-format ref-name)
- "OrgSuperscript")))
-
-(defun org-e-odt-get-image-name (file-name)
- (require 'sha1)
- (file-relative-name
- (expand-file-name
- (concat (sha1 file-name) "." (file-name-extension file-name)) "Pictures")))
-
-(defun org-export-e-odt-format-image (src href)
- "Create image tag with source and attributes."
- (save-match-data
- (let* ((caption (org-find-text-property-in-string 'org-caption src))
- (caption (and caption (org-xml-format-desc caption)))
- (attr (org-find-text-property-in-string 'org-attributes src))
- (label (org-find-text-property-in-string 'org-label src))
- (latex-frag (org-find-text-property-in-string
- 'org-latex-src src))
- (category (and latex-frag "__DvipngImage__"))
- (attr-plist (org-lparse-get-block-params attr))
- (user-frame-anchor
- (car (assoc-string (plist-get attr-plist :anchor)
- '(("as-char") ("paragraph") ("page")) t)))
- (user-frame-style
- (and user-frame-anchor (plist-get attr-plist :style)))
- (user-frame-attrs
- (and user-frame-anchor (plist-get attr-plist :attributes)))
- (user-frame-params
- (list user-frame-style user-frame-attrs user-frame-anchor))
- (embed-as (cond
- (latex-frag
- (symbol-name
- (case (org-find-text-property-in-string
- 'org-latex-src-embed-type src)
- (paragraph 'paragraph)
- (t 'as-char))))
- (user-frame-anchor)
- (t "paragraph")))
- (size (org-e-odt-image-size-from-file
- src (plist-get attr-plist :width)
- (plist-get attr-plist :height)
- (plist-get attr-plist :scale) nil embed-as))
- (width (car size)) (height (cdr size)))
- (when latex-frag
- (setq href (org-propertize href :title "LaTeX Fragment"
- :description latex-frag)))
- (let ((frame-style-handle (concat (and (or caption label) "Captioned")
- embed-as "Image")))
- (org-e-odt-format-entity
- frame-style-handle href width height
- :caption caption :label label :category category
- :user-frame-params user-frame-params)))))
-
-(defun org-e-odt-format-object-description (title description)
- (concat (and title (org-e-odt-format-tags
- '("<svg:title>" . "</svg:title>")
- (org-e-odt-encode-plain-text title t)))
- (and description (org-e-odt-format-tags
- '("<svg:desc>" . "</svg:desc>")
- (org-e-odt-encode-plain-text description t)))))
-
-(defun org-e-odt-format-frame (text width height style &optional
- extra anchor-type)
- (let ((frame-attrs
- (concat
- (if width (format " svg:width=\"%0.2fcm\"" width) "")
- (if height (format " svg:height=\"%0.2fcm\"" height) "")
- extra
- (format " text:anchor-type=\"%s\"" (or anchor-type "paragraph")))))
- (org-e-odt-format-tags
- '("<draw:frame draw:style-name=\"%s\"%s>" . "</draw:frame>")
- (concat text (org-e-odt-format-object-description
- (get-text-property 0 :title text)
- (get-text-property 0 :description text)))
- style frame-attrs)))
-
-(defun org-e-odt-format-textbox (text width height style &optional
- extra anchor-type)
- (org-e-odt-format-frame
- (org-e-odt-format-tags
- '("<draw:text-box %s>" . "</draw:text-box>")
- text (concat (format " fo:min-height=\"%0.2fcm\"" (or height .2))
- (unless width
- (format " fo:min-width=\"%0.2fcm\"" (or width .2)))))
- width nil style extra anchor-type))
-
-(defun org-e-odt-format-inlinetask (heading content
- &optional todo priority tags)
- (org-e-odt-format-stylized-paragraph
- nil (org-e-odt-format-textbox
- (concat (org-e-odt-format-stylized-paragraph
- "OrgInlineTaskHeading"
- (org-lparse-format
- 'HEADLINE (concat (org-lparse-format-todo todo) " " heading)
- nil tags))
- content) nil nil "OrgInlineTaskFrame" " style:rel-width=\"100%\"")))
-
-
-(defun org-e-odt-merge-frame-params(default-frame-params user-frame-params)
- (if (not user-frame-params) default-frame-params
- (assert (= (length default-frame-params) 3))
- (assert (= (length user-frame-params) 3))
- (loop for user-frame-param in user-frame-params
- for default-frame-param in default-frame-params
- collect (or user-frame-param default-frame-param))))
-
-(defun* org-e-odt-format-entity (entity href width height
- &key caption label category
- user-frame-params)
- (let* ((entity-style (assoc-string entity org-e-odt-entity-frame-styles t))
- default-frame-params frame-params)
- (cond
- ((not (or caption label))
- (setq default-frame-params (nth 2 entity-style))
- (setq frame-params (org-e-odt-merge-frame-params
- default-frame-params user-frame-params))
- (apply 'org-e-odt-format-frame href width height frame-params))
- (t
- (setq default-frame-params (nth 3 entity-style))
- (setq frame-params (org-e-odt-merge-frame-params
- default-frame-params user-frame-params))
- (apply 'org-e-odt-format-textbox
- (org-e-odt-format-stylized-paragraph
- 'illustration
- (concat
- (apply 'org-e-odt-format-frame href width height
- (nth 2 entity-style))
- (org-e-odt-format-entity-caption
- label caption (or category (nth 1 entity-style)))))
- width height frame-params)))))
-
-(defun org-e-odt-copy-image-file (path)
- "Returns the internal name of the file"
- (let* ((image-type (file-name-extension path))
- (media-type (format "image/%s" image-type))
- (src-file (expand-file-name
- path (file-name-directory org-current-export-file)))
- (target-dir "Images/")
- (target-file
- (format "%s%04d.%s" target-dir
- (incf org-e-odt-embedded-images-count) image-type)))
- (message "Embedding %s as %s ..."
- (substring-no-properties path) target-file)
-
- (when (= 1 org-e-odt-embedded-images-count)
- (make-directory target-dir)
- (org-e-odt-create-manifest-file-entry "" target-dir))
-
- (copy-file src-file target-file 'overwrite)
- (org-e-odt-create-manifest-file-entry media-type target-file)
- target-file))
-
-(defun org-e-odt-do-image-size (probe-method file &optional dpi anchor-type)
- (setq dpi (or dpi org-export-e-odt-pixels-per-inch))
- (setq anchor-type (or anchor-type "paragraph"))
- (flet ((size-in-cms (size-in-pixels)
- (flet ((pixels-to-cms (pixels)
- (let* ((cms-per-inch 2.54)
- (inches (/ pixels dpi)))
- (* cms-per-inch inches))))
- (and size-in-pixels
- (cons (pixels-to-cms (car size-in-pixels))
- (pixels-to-cms (cdr size-in-pixels)))))))
- (case probe-method
- (emacs
- (size-in-cms (ignore-errors ; Emacs could be in batch mode
- (clear-image-cache)
- (image-size (create-image file) 'pixels))))
- (imagemagick
- (size-in-cms
- (let ((dim (shell-command-to-string
- (format "identify -format \"%%w:%%h\" \"%s\"" file))))
- (when (string-match "\\([0-9]+\\):\\([0-9]+\\)" dim)
- (cons (string-to-number (match-string 1 dim))
- (string-to-number (match-string 2 dim)))))))
- (t
- (cdr (assoc-string anchor-type
- org-export-e-odt-default-image-sizes-alist))))))
-
-(defun org-e-odt-image-size-from-file (file &optional user-width
- user-height scale dpi embed-as)
- (unless (file-name-absolute-p file)
- (setq file (expand-file-name
- file (file-name-directory org-current-export-file))))
- (let* (size width height)
- (unless (and user-height user-width)
- (loop for probe-method in org-export-e-odt-image-size-probe-method
- until size
- do (setq size (org-e-odt-do-image-size
- probe-method file dpi embed-as)))
- (or size (error "Cannot determine Image size. Aborting ..."))
- (setq width (car size) height (cdr size)))
- (cond
- (scale
- (setq width (* width scale) height (* height scale)))
- ((and user-height user-width)
- (setq width user-width height user-height))
- (user-height
- (setq width (* user-height (/ width height)) height user-height))
- (user-width
- (setq height (* user-width (/ height width)) width user-width))
- (t (ignore)))
- ;; ensure that an embedded image fits comfortably within a page
- (let ((max-width (car org-export-e-odt-max-image-size))
- (max-height (cdr org-export-e-odt-max-image-size)))
- (when (or (> width max-width) (> height max-height))
- (let* ((scale1 (/ max-width width))
- (scale2 (/ max-height height))
- (scale (min scale1 scale2)))
- (setq width (* scale width) height (* scale height)))))
- (cons width height)))
-
-(defun org-e-odt-get-label-category-and-style (label default-category)
- "See `org-export-e-odt-get-category-from-label'."
- (let ((default-category-map
- (assoc default-category org-e-odt-category-map-alist))
- user-category user-category-map category)
- (cond
- ((not org-export-e-odt-get-category-from-label)
- default-category-map)
- ((not (setq user-category
- (save-match-data
- (and (string-match "\\`\\(.*\\):.+" label)
- (match-string 1 label)))))
- default-category-map)
- (t
- (setq user-category-map
- (or (assoc user-category org-e-odt-category-map-alist)
- (list nil user-category "category-and-value"))
- category (nth 1 user-category-map))
- (if (member category org-export-e-odt-user-categories)
- user-category-map
- default-category-map)))))
-
-(defun org-e-odt-add-label-definition (label default-category)
- "Create an entry in `org-e-odt-entity-labels-alist' and return it."
- (setq label (substring-no-properties label))
- (let* ((label-props (org-e-odt-get-label-category-and-style
- label default-category))
- (category (nth 1 label-props))
- (counter category)
- (label-style (nth 2 label-props))
- (sequence-var (intern (mapconcat
- 'downcase
- (org-split-string counter) "-")))
- (seqno (1+ (or (plist-get org-e-odt-entity-counts-plist sequence-var)
- 0)))
- (label-props (list label category seqno label-style)))
- (setq org-e-odt-entity-counts-plist
- (plist-put org-e-odt-entity-counts-plist sequence-var seqno))
- (push label-props org-e-odt-entity-labels-alist)
- label-props))
-
-(defun org-e-odt-format-label-definition (caption label category seqno label-style)
- (assert label)
- (format-spec
- (cadr (assoc-string label-style org-e-odt-label-styles t))
- `((?e . ,category)
- (?n . ,(org-e-odt-format-tags
- '("<text:sequence text:ref-name=\"%s\" text:name=\"%s\" text:formula=\"ooow:%s+1\" style:num-format=\"1\">" . "</text:sequence>")
- (format "%d" seqno) label category category))
- (?c . ,(or (and caption (concat ": " caption)) "")))))
-
-(defun org-e-odt-format-label-reference (label category seqno label-style)
- (assert label)
- (save-match-data
- (let* ((fmt (cddr (assoc-string label-style org-e-odt-label-styles t)))
- (fmt1 (car fmt))
- (fmt2 (cadr fmt)))
- (org-e-odt-format-tags
- '("<text:sequence-ref text:reference-format=\"%s\" text:ref-name=\"%s\">"
- . "</text:sequence-ref>")
- (format-spec fmt2 `((?e . ,category)
- (?n . ,(format "%d" seqno)))) fmt1 label))))
-
-(defun org-e-odt-fixup-label-references ()
- (goto-char (point-min))
- (while (re-search-forward
- "<text:sequence-ref text:ref-name=\"\\([^\"]+\\)\">[ \t\n]*</text:sequence-ref>"
- nil t)
- (let* ((label (match-string 1))
- (label-def (assoc label org-e-odt-entity-labels-alist))
- (rpl (and label-def
- (apply 'org-e-odt-format-label-reference label-def))))
- (if rpl (replace-match rpl t t)
- (org-lparse-warn
- (format "Unable to resolve reference to label \"%s\"" label))))))
-
-(defun org-e-odt-format-entity-caption (label caption category)
- (or (and label
- (apply 'org-e-odt-format-label-definition
- caption (org-e-odt-add-label-definition label category)))
- caption ""))
-
-(defun org-e-odt-format-tags-1 (tag text prefix suffix &rest args)
- (cond
- ((consp tag)
- (concat prefix (apply 'format (car tag) args) text suffix
- (format (cdr tag))))
- ((stringp tag) ; singleton tag
- (concat prefix (apply 'format tag args) text))))
-
-(defun org-e-odt-format-tags (tag text &rest args)
- (apply 'org-e-odt-format-tags-1 tag text "\n" "\n" args))
-
-(defun org-e-odt-format-tags-simple (tag text &rest args)
- (apply 'org-e-odt-format-tags-1 tag text nil nil args))
-
-(defun org-e-odt-init-outfile ()
- (unless (executable-find "zip")
- ;; Not at all OSes ship with zip by default
- (error "Executable \"zip\" needed for creating OpenDocument files"))
-
- (let* ((outdir (make-temp-file
- (format org-export-e-odt-tmpdir-prefix org-lparse-backend) t))
- (content-file (expand-file-name "content.xml" outdir)))
-
- ;; reset variables
- (setq org-e-odt-manifest-file-entries nil
- org-e-odt-embedded-images-count 0
- org-e-odt-embedded-formulas-count 0
- org-e-odt-section-count 0
- org-e-odt-entity-labels-alist nil
- org-e-odt-list-stack-stashed nil
- org-e-odt-automatic-styles nil
- org-e-odt-object-counters nil
- org-e-odt-entity-counts-plist nil)
-
- ;; let `htmlfontify' know that we are interested in collecting
- ;; styles - FIXME
-
- (setq hfy-user-sheet-assoc nil)
-
- ;; init conten.xml
- (with-current-buffer
- (find-file-noselect content-file t)
- (current-buffer))))
-
-
-
-(defun org-e-odt-save-as-outfile (target opt-plist)
- ;; write automatic styles
- (org-e-odt-write-automatic-styles)
-
- ;; write styles file
- ;; (when (equal org-lparse-backend 'odt) FIXME
- ;; )
-
- (org-e-odt-update-styles-file opt-plist)
-
- ;; create mimetype file
- (let ((mimetype (org-e-odt-write-mimetype-file ;; org-lparse-backend FIXME
- 'odt)))
- (org-e-odt-create-manifest-file-entry mimetype "/" "1.2"))
-
- ;; create a manifest entry for content.xml
- (org-e-odt-create-manifest-file-entry "text/xml" "content.xml")
-
- ;; write out the manifest entries before zipping
- (org-e-odt-write-manifest-file)
-
- (let ((xml-files '("mimetype" "META-INF/manifest.xml" "content.xml"
- "meta.xml"))
- (zipdir default-directory))
- (when (or t (equal org-lparse-backend 'odt)) ; FIXME
- (push "styles.xml" xml-files))
- (message "Switching to directory %s" (expand-file-name zipdir))
-
- ;; save all xml files
- (mapc (lambda (file)
- (with-current-buffer
- (find-file-noselect (expand-file-name file) t)
- ;; prettify output if needed
- (when org-export-e-odt-prettify-xml
- (indent-region (point-min) (point-max)))
- (save-buffer 0)))
- xml-files)
-
- (let* ((target-name (file-name-nondirectory target))
- (target-dir (file-name-directory target))
- (cmds `(("zip" "-mX0" ,target-name "mimetype")
- ("zip" "-rmTq" ,target-name "."))))
- (when (file-exists-p target)
- ;; FIXME: If the file is locked this throws a cryptic error
- (delete-file target))
-
- (let ((coding-system-for-write 'no-conversion) exitcode err-string)
- (message "Creating odt file...")
- (mapc
- (lambda (cmd)
- (message "Running %s" (mapconcat 'identity cmd " "))
- (setq err-string
- (with-output-to-string
- (setq exitcode
- (apply 'call-process (car cmd)
- nil standard-output nil (cdr cmd)))))
- (or (zerop exitcode)
- (ignore (message "%s" err-string))
- (error "Unable to create odt file (%S)" exitcode)))
- cmds))
-
- ;; move the file from outdir to target-dir
- (rename-file target-name target-dir)
-
- ;; kill all xml buffers
- (mapc (lambda (file)
- (kill-buffer
- (find-file-noselect (expand-file-name file zipdir) t)))
- xml-files)
-
- (delete-directory zipdir)))
- (message "Created %s" target)
- (set-buffer (find-file-noselect target t)))
-
-
-(defun org-e-odt-create-manifest-file-entry (&rest args)
- (push args org-e-odt-manifest-file-entries))
-
-(defun org-e-odt-write-manifest-file ()
- (make-directory "META-INF")
- (let ((manifest-file (expand-file-name "META-INF/manifest.xml")))
- (with-current-buffer
- (find-file-noselect manifest-file t)
- (insert
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
- <manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">\n")
- (mapc
- (lambda (file-entry)
- (let* ((version (nth 2 file-entry))
- (extra (if version
- (format " manifest:version=\"%s\"" version)
- "")))
- (insert
- (format org-e-odt-manifest-file-entry-tag
- (nth 0 file-entry) (nth 1 file-entry) extra))))
- org-e-odt-manifest-file-entries)
- (insert "\n</manifest:manifest>"))))
-
-(defun org-e-odt-update-meta-file (info) ; FIXME opt-plist
- (let ((date (org-e-odt-format-date (plist-get info :date)))
- (author (or (plist-get info :author) ""))
- (email (plist-get info :email))
- (keywords (plist-get info :keywords))
- (description (plist-get info :description))
- (title (plist-get info :title)))
- (write-region
- (concat
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
- <office:document-meta
- xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"
- xmlns:xlink=\"http://www.w3.org/1999/xlink\"
- xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
- xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"
- xmlns:ooo=\"http://openoffice.org/2004/office\"
- office:version=\"1.2\">
- <office:meta>\n"
- (org-e-odt-format-author author) "\n"
- (format "<meta:initial-creator>%s</meta:initial-creator>\n" author)
- (format "<dc:date>%s</dc:date>\n" date)
- (format "<meta:creation-date>%s</meta:creation-date>\n" date)
- (format "<meta:generator>%s</meta:generator>\n"
- (when org-export-creator-info
- (format "Org-%s/Emacs-%s"
- org-version emacs-version)))
- (format "<meta:keyword>%s</meta:keyword>\n" keywords)
- (format "<dc:subject>%s</dc:subject>\n" description)
- (format "<dc:title>%s</dc:title>\n" title)
- "\n"
- " </office:meta>\n" "</office:document-meta>")
- nil (expand-file-name "meta.xml")))
-
- ;; create a manifest entry for meta.xml
- (org-e-odt-create-manifest-file-entry "text/xml" "meta.xml"))
-
-(defun org-e-odt-update-styles-file (opt-plist)
- ;; write styles file
- (let ((styles-file (plist-get opt-plist :odt-styles-file)))
- (org-e-odt-copy-styles-file (and styles-file
- (read (org-trim styles-file)))))
-
- ;; Update styles.xml - take care of outline numbering
- (with-current-buffer
- (find-file-noselect (expand-file-name "styles.xml") t)
- ;; Don't make automatic backup of styles.xml file. This setting
- ;; prevents the backed-up styles.xml file from being zipped in to
- ;; odt file. This is more of a hackish fix. Better alternative
- ;; would be to fix the zip command so that the output odt file
- ;; includes only the needed files and excludes any auto-generated
- ;; extra files like backups and auto-saves etc etc. Note that
- ;; currently the zip command zips up the entire temp directory so
- ;; that any auto-generated files created under the hood ends up in
- ;; the resulting odt file.
- (set (make-local-variable 'backup-inhibited) t)
-
- ;; Import local setting of `org-export-with-section-numbers'
- (org-e-odt-configure-outline-numbering
- (if org-export-with-section-numbers org-export-headline-levels 0)))
-
- ;; Write custom styles for source blocks
- (org-e-odt-insert-custom-styles-for-srcblocks
- (mapconcat
- (lambda (style)
- (format " %s\n" (cddr style)))
- hfy-user-sheet-assoc "")))
-
-(defun org-e-odt-write-mimetype-file (format)
- ;; create mimetype file
- (let ((mimetype
- (case format
- (odt "application/vnd.oasis.opendocument.text")
- (odf "application/vnd.oasis.opendocument.formula")
- (t (error "Unknown OpenDocument backend %S" org-lparse-backend)))))
- (write-region mimetype nil (expand-file-name "mimetype"))
- mimetype))
-
-(defun org-e-odt-finalize-outfile ()
- (org-e-odt-delete-empty-paragraphs))
-
-(defun org-e-odt-delete-empty-paragraphs ()
- (goto-char (point-min))
- (let ((open "<text:p[^>]*>")
- (close "</text:p>"))
- (while (re-search-forward (format "%s[ \r\n\t]*%s" open close) nil t)
- (replace-match ""))))
-
-(declare-function org-create-math-formula "org"
- (latex-frag &optional mathml-file))
-
-;;;###autoload
-(defun org-export-e-odt-convert (&optional in-file out-fmt prefix-arg)
- "Convert IN-FILE to format OUT-FMT using a command line converter.
-IN-FILE is the file to be converted. If unspecified, it defaults
-to variable `buffer-file-name'. OUT-FMT is the desired output
-format. Use `org-export-e-odt-convert-process' as the converter.
-If PREFIX-ARG is non-nil then the newly converted file is opened
-using `org-open-file'."
- (interactive
- (append (org-lparse-convert-read-params) current-prefix-arg))
- (org-lparse-do-convert in-file out-fmt prefix-arg))
-
-(defun org-e-odt-get (what &optional opt-plist)
- (case what
- (BACKEND 'odt)
- (EXPORT-DIR (org-export-directory :html opt-plist))
- (FILE-NAME-EXTENSION "odt")
- (EXPORT-BUFFER-NAME "*Org ODT Export*")
- (ENTITY-CONTROL org-e-odt-entity-control-callbacks-alist)
- (ENTITY-FORMAT org-e-odt-entity-format-callbacks-alist)
- (INIT-METHOD 'org-e-odt-init-outfile)
- (FINAL-METHOD 'org-e-odt-finalize-outfile)
- (SAVE-METHOD 'org-e-odt-save-as-outfile)
- (CONVERT-METHOD
- (and org-export-e-odt-convert-process
- (cadr (assoc-string org-export-e-odt-convert-process
- org-export-e-odt-convert-processes t))))
- (CONVERT-CAPABILITIES
- (and org-export-e-odt-convert-process
- (cadr (assoc-string org-export-e-odt-convert-process
- org-export-e-odt-convert-processes t))
- org-export-e-odt-convert-capabilities))
- (TOPLEVEL-HLEVEL 1)
- (SPECIAL-STRING-REGEXPS org-export-e-odt-special-string-regexps)
- (INLINE-IMAGES 'maybe)
- (INLINE-IMAGE-EXTENSIONS '("png" "jpeg" "jpg" "gif" "svg"))
- (PLAIN-TEXT-MAP '(("&" . "&") ("<" . "<") (">" . ">")))
- (TABLE-FIRST-COLUMN-AS-LABELS nil)
- (FOOTNOTE-SEPARATOR )
- (CODING-SYSTEM-FOR-WRITE 'utf-8)
- (CODING-SYSTEM-FOR-SAVE 'utf-8)
- (t (error "Unknown property: %s" what))))
-
-(defun org-export-e-odt-do-preprocess-latex-fragments ()
- "Convert LaTeX fragments to images."
- (let* ((latex-frag-opt (plist-get org-lparse-opt-plist :LaTeX-fragments))
- (latex-frag-opt ; massage the options
- (or (and (member latex-frag-opt '(mathjax t))
- (not (and (fboundp 'org-format-latex-mathml-available-p)
- (org-format-latex-mathml-available-p)))
- (prog1 org-lparse-latex-fragment-fallback
- (org-lparse-warn
- (concat
- "LaTeX to MathML converter not available. "
- (format "Using %S instead."
- org-lparse-latex-fragment-fallback)))))
- latex-frag-opt))
- cache-dir display-msg)
- (cond
- ((eq latex-frag-opt 'dvipng)
- (setq cache-dir "ltxpng/")
- (setq display-msg "Creating LaTeX image %s"))
- ((member latex-frag-opt '(mathjax t))
- (setq latex-frag-opt 'mathml)
- (setq cache-dir "ltxmathml/")
- (setq display-msg "Creating MathML formula %s")))
- (when (and org-current-export-file)
- (org-format-latex
- (concat cache-dir (file-name-sans-extension
- (file-name-nondirectory org-current-export-file)))
- org-current-export-dir nil display-msg
- nil nil latex-frag-opt))))
-
-(defadvice org-format-latex-as-mathml
- (after org-e-odt-protect-latex-fragment activate)
- "Encode LaTeX fragment as XML.
-Do this when translation to MathML fails."
- (when (or (not (> (length ad-return-value) 0))
- (get-text-property 0 'org-protected ad-return-value))
- (setq ad-return-value
- (org-propertize (org-e-odt-encode-plain-text (ad-get-arg 0))
- 'org-protected t))))
-
-(defun org-export-e-odt-preprocess-latex-fragments ()
- (when (equal org-export-current-backend 'odt)
- (org-export-e-odt-do-preprocess-latex-fragments)))
-
-(defun org-export-e-odt-preprocess-label-references ()
- (goto-char (point-min))
- (let (label label-components category value pretty-label)
- (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t)
- (org-if-unprotected-at (match-beginning 1)
- (replace-match
- (let ((org-lparse-encode-pending t)
- (label (match-string 1)))
- ;; markup generated below is mostly an eye-candy. At
- ;; pre-processing stage, there is no information on which
- ;; entity a label reference points to. The actual markup
- ;; is generated as part of `org-e-odt-fixup-label-references'
- ;; which gets called at the fag end of export. By this
- ;; time we would have seen and collected all the label
- ;; definitions in `org-e-odt-entity-labels-alist'.
- (org-e-odt-format-tags
- '("<text:sequence-ref text:ref-name=\"%s\">" .
- "</text:sequence-ref>")
- "" (org-add-props label '(org-protected t)))) t t)))))
-
-;; process latex fragments as part of
-;; `org-export-preprocess-after-blockquote-hook'. Note that this hook
-;; is the one that is closest and well before the call to
-;; `org-export-attach-captions-and-attributes' in
-;; `org-export-preprocess-string'. The above arrangement permits
-;; captions, labels and attributes to be attached to png images
-;; generated out of latex equations.
-(add-hook 'org-export-preprocess-after-blockquote-hook
- 'org-export-e-odt-preprocess-latex-fragments)
-
-(defun org-export-e-odt-preprocess (parameters)
- (org-export-e-odt-preprocess-label-references))
-
-
-(defun org-e-odt-zip-extract-one (archive member &optional target)
- (require 'arc-mode)
- (let* ((target (or target default-directory))
- (archive (expand-file-name archive))
- (archive-zip-extract
- (list "unzip" "-qq" "-o" "-d" target))
- exit-code command-output)
- (setq command-output
- (with-temp-buffer
- (setq exit-code (archive-zip-extract archive member))
- (buffer-string)))
- (unless (zerop exit-code)
- (message command-output)
- (error "Extraction failed"))))
-
-(defun org-e-odt-zip-extract (archive members &optional target)
- (when (atom members) (setq members (list members)))
- (mapc (lambda (member)
- (org-e-odt-zip-extract-one archive member target))
- members))
-
-(defun org-e-odt-copy-styles-file (&optional styles-file)
- ;; Non-availability of styles.xml is not a critical error. For now
- ;; throw an error purely for aesthetic reasons.
- (setq styles-file (or styles-file
- org-export-e-odt-styles-file
- (expand-file-name "OrgOdtStyles.xml"
- org-e-odt-styles-dir)
- (error "org-e-odt: Missing styles file?")))
- (cond
- ((listp styles-file)
- (let ((archive (nth 0 styles-file))
- (members (nth 1 styles-file)))
- (org-e-odt-zip-extract archive members)
- (mapc
- (lambda (member)
- (when (org-file-image-p member)
- (let* ((image-type (file-name-extension member))
- (media-type (format "image/%s" image-type)))
- (org-e-odt-create-manifest-file-entry media-type member))))
- members)))
- ((and (stringp styles-file) (file-exists-p styles-file))
- (let ((styles-file-type (file-name-extension styles-file)))
- (cond
- ((string= styles-file-type "xml")
- (copy-file styles-file "styles.xml" t))
- ((member styles-file-type '("odt" "ott"))
- (org-e-odt-zip-extract styles-file "styles.xml")))))
- (t
- (error (format "Invalid specification of styles.xml file: %S"
- org-export-e-odt-styles-file))))
-
- ;; create a manifest entry for styles.xml
- (org-e-odt-create-manifest-file-entry "text/xml" "styles.xml"))
-
-(defun org-e-odt-configure-outline-numbering (level)
- "Outline numbering is retained only upto LEVEL.
-To disable outline numbering pass a LEVEL of 0."
- (goto-char (point-min))
- (let ((regex
- "<text:outline-level-style\\([^>]*\\)text:level=\"\\([^\"]*\\)\"\\([^>]*\\)>")
- (replacement
- "<text:outline-level-style\\1text:level=\"\\2\" style:num-format=\"\">"))
- (while (re-search-forward regex nil t)
- (when (> (string-to-number (match-string 2)) level)
- (replace-match replacement t nil))))
- (save-buffer 0))
-
-;;;###autoload
-(defun org-export-as-odf (latex-frag &optional odf-file)
- "Export LATEX-FRAG as OpenDocument formula file ODF-FILE.
-Use `org-create-math-formula' to convert LATEX-FRAG first to
-MathML. When invoked as an interactive command, use
-`org-latex-regexps' to infer LATEX-FRAG from currently active
-region. If no LaTeX fragments are found, prompt for it. Push
-MathML source to kill ring, if `org-export-copy-to-kill-ring' is
-non-nil."
- (interactive
- `(,(let (frag)
- (setq frag (and (setq frag (and (region-active-p)
- (buffer-substring (region-beginning)
- (region-end))))
- (loop for e in org-latex-regexps
- thereis (when (string-match (nth 1 e) frag)
- (match-string (nth 2 e) frag)))))
- (read-string "LaTeX Fragment: " frag nil frag))
- ,(let ((odf-filename (expand-file-name
- (concat
- (file-name-sans-extension
- (or (file-name-nondirectory buffer-file-name)))
- "." "odf")
- (file-name-directory buffer-file-name))))
- (read-file-name "ODF filename: " nil odf-filename nil
- (file-name-nondirectory odf-filename)))))
- (let* ((org-lparse-backend 'odf)
- org-lparse-opt-plist
- (filename (or odf-file
- (expand-file-name
- (concat
- (file-name-sans-extension
- (or (file-name-nondirectory buffer-file-name)))
- "." "odf")
- (file-name-directory buffer-file-name))))
- (buffer (find-file-noselect (org-e-odt-init-outfile filename)))
- (coding-system-for-write 'utf-8)
- (save-buffer-coding-system 'utf-8))
- (set-buffer buffer)
- (set-buffer-file-coding-system coding-system-for-write)
- (let ((mathml (org-create-math-formula latex-frag)))
- (unless mathml (error "No Math formula created"))
- (insert mathml)
- (or (org-export-push-to-kill-ring
- (upcase (symbol-name org-lparse-backend)))
- (message "Exporting... done")))
- (org-e-odt-save-as-outfile filename nil ; FIXME
- )))
-
-;;;###autoload
-(defun org-export-as-odf-and-open ()
- "Export LaTeX fragment as OpenDocument formula and immediately open it.
-Use `org-export-as-odf' to read LaTeX fragment and OpenDocument
-formula file."
- (interactive)
- (org-lparse-and-open
- nil nil nil (call-interactively 'org-export-as-odf)))
-
-
-\f
-
-;;; Driver Starts here
-;;; Dependencies
-
-(require 'format-spec)
-(eval-when-compile (require 'cl) (require 'table))
-
-
-\f
-;;; Hooks
-
-(defvar org-e-odt-after-blockquotes-hook nil
- "Hook run during HTML export, after blockquote, verse, center are done.")
-
-(defvar org-e-odt-final-hook nil
- "Hook run at the end of HTML export, in the new buffer.")
-
-;; FIXME: it already exists in org-e-odt.el
-;;; Function Declarations
-
-(declare-function org-element-property "org-element" (property element))
-(declare-function org-element-normalize-string "org-element" (s))
-(declare-function org-element-parse-secondary-string
- "org-element" (string restriction &optional buffer))
-(defvar org-element-string-restrictions)
-(defvar org-element-object-restrictions)
-
-(declare-function org-export-clean-table "org-export" (table specialp))
-(declare-function org-export-data "org-export" (data backend info))
-(declare-function org-export-directory "org-export" (type plist))
-(declare-function org-export-expand-macro "org-export" (macro info))
-(declare-function org-export-first-sibling-p "org-export" (headline info))
-(declare-function org-export-footnote-first-reference-p "org-export"
- (footnote-reference info))
-(declare-function org-export-get-coderef-format "org-export" (path desc))
-(declare-function org-export-get-footnote-definition "org-export"
- (footnote-reference info))
-(declare-function org-export-get-footnote-number "org-export" (footnote info))
-(declare-function org-export-get-previous-element "org-export" (blob info))
-(declare-function org-export-get-relative-level "org-export" (headline info))
-(declare-function org-export-handle-code
- "org-export" (element info &optional num-fmt ref-fmt delayed))
-(declare-function org-export-included-file "org-export" (keyword backend info))
-(declare-function org-export-inline-image-p "org-export"
- (link &optional extensions))
-(declare-function org-export-last-sibling-p "org-export" (headline info))
-(declare-function org-export-low-level-p "org-export" (headline info))
-(declare-function org-export-output-file-name
- "org-export" (extension &optional subtreep pub-dir))
-(declare-function org-export-resolve-coderef "org-export" (ref info))
-(declare-function org-export-resolve-fuzzy-link "org-export" (link info))
-(declare-function org-export-secondary-string "org-export"
- (secondary backend info))
-(declare-function org-export-solidify-link-text "org-export" (s))
-(declare-function org-export-table-format-info "org-export" (table))
-(declare-function
- org-export-to-buffer "org-export"
- (backend buffer &optional subtreep visible-only body-only ext-plist))
-(declare-function
- org-export-to-file "org-export"
- (backend file &optional subtreep visible-only body-only ext-plist))
-
-(declare-function org-id-find-id-file "org-id" (id))
-(declare-function htmlize-region "ext:htmlize" (beg end))
-(declare-function org-pop-to-buffer-same-window
- "org-compat" (&optional buffer-or-name norecord label))
-
-
-
-\f
-
-(declare-function hfy-face-to-style "htmlfontify" (fn))
-(declare-function hfy-face-or-def-to-name "htmlfontify" (fn))
-(declare-function archive-zip-extract "arc-mode.el" (archive name))
-
-;;; Internal Variables
-
-;;;; ODT Internal Variables
-
-(defconst org-e-odt-lib-dir
- (file-name-directory load-file-name)
- "Location of ODT exporter.
-Use this to infer values of `org-e-odt-styles-dir' and
-`org-export-e-odt-schema-dir'.")
-
-(defvar org-e-odt-data-dir
- (expand-file-name "../etc/" org-e-odt-lib-dir)
- "Data directory for ODT exporter.
-Use this to infer values of `org-e-odt-styles-dir' and
-`org-export-e-odt-schema-dir'.")
-
-
-
-
-(defconst org-export-e-odt-special-string-regexps
- '(("\\\\-" . "­\\1") ; shy
- ("---\\([^-]\\)" . "—\\1") ; mdash
- ("--\\([^-]\\)" . "–\\1") ; ndash
- ("\\.\\.\\." . "…")) ; hellip
- "Regular expressions for special string conversion.")
-
-(defconst org-e-odt-schema-dir-list
- (list
- (and org-e-odt-data-dir
- (expand-file-name "./schema/" org-e-odt-data-dir)) ; bail out
- (eval-when-compile
- (and (boundp 'org-e-odt-data-dir) org-e-odt-data-dir ; see make install
- (expand-file-name "./schema/" org-e-odt-data-dir)))
- (expand-file-name "../contrib/odt/etc/schema/" org-e-odt-lib-dir) ; git
- )
- "List of directories to search for OpenDocument schema files.
-Use this list to set the default value of
-`org-export-e-odt-schema-dir'. The entries in this list are
-populated heuristically based on the values of `org-e-odt-lib-dir'
-and `org-e-odt-data-dir'.")
-
-
-(defconst org-e-odt-styles-dir-list
- (list
- (and org-e-odt-data-dir
- (expand-file-name "./styles/" org-e-odt-data-dir)) ; bail out
- (eval-when-compile
- (and (boundp 'org-e-odt-data-dir) org-e-odt-data-dir ; see make install
- (expand-file-name "./styles/" org-e-odt-data-dir)))
- (expand-file-name "../etc/styles/" org-e-odt-lib-dir) ; git
- (expand-file-name "./etc/styles/" org-e-odt-lib-dir) ; elpa
- (expand-file-name "./org/" data-directory) ; system
- )
- "List of directories to search for OpenDocument styles files.
-See `org-e-odt-styles-dir'. The entries in this list are populated
-heuristically based on the values of `org-e-odt-lib-dir' and
-`org-e-odt-data-dir'.")
-
-(defconst org-e-odt-styles-dir
- (let* ((styles-dir
- (catch 'styles-dir
- (message "Debug (org-e-odt): Searching for OpenDocument styles files...")
- (mapc (lambda (styles-dir)
- (when styles-dir
- (message "Debug (org-e-odt): Trying %s..." styles-dir)
- (when (and (file-readable-p
- (expand-file-name
- "OrgOdtContentTemplate.xml" styles-dir))
- (file-readable-p
- (expand-file-name
- "OrgOdtStyles.xml" styles-dir)))
- (message "Debug (org-e-odt): Using styles under %s"
- styles-dir)
- (throw 'styles-dir styles-dir))))
- org-e-odt-styles-dir-list)
- nil)))
- (unless styles-dir
- (error "Error (org-e-odt): Cannot find factory styles files. Aborting."))
- styles-dir)
- "Directory that holds auxiliary XML files used by the ODT exporter.
-
-This directory contains the following XML files -
- \"OrgOdtStyles.xml\" and \"OrgOdtContentTemplate.xml\". These
- XML files are used as the default values of
- `org-export-e-odt-styles-file' and
- `org-export-e-odt-content-template-file'.
-
-The default value of this variable varies depending on the
-version of org in use and is initialized from
-`org-e-odt-styles-dir-list'. Note that the user could be using org
-from one of: org's own private git repository, GNU ELPA tar or
-standard Emacs.")
-
-(defconst org-export-e-odt-tmpdir-prefix "%s-")
-(defconst org-export-e-odt-bookmark-prefix "OrgXref.")
-
-(defconst org-e-odt-manifest-file-entry-tag
- "
-<manifest:file-entry manifest:media-type=\"%s\" manifest:full-path=\"%s\"%s/>")
-
-
-
-(defvar org-lparse-dyn-first-heading-pos) ; let bound during org-do-lparse
-
-(defvar org-e-odt-suppress-xref nil)
-(defvar org-e-odt-file-extensions
- '(("odt" . "OpenDocument Text")
- ("ott" . "OpenDocument Text Template")
- ("odm" . "OpenDocument Master Document")
- ("ods" . "OpenDocument Spreadsheet")
- ("ots" . "OpenDocument Spreadsheet Template")
- ("odg" . "OpenDocument Drawing (Graphics)")
- ("otg" . "OpenDocument Drawing Template")
- ("odp" . "OpenDocument Presentation")
- ("otp" . "OpenDocument Presentation Template")
- ("odi" . "OpenDocument Image")
- ("odf" . "OpenDocument Formula")
- ("odc" . "OpenDocument Chart")))
-
-(defvar org-export-e-odt-embed-images t
- "Should the images be copied in to the odt file or just linked?")
-
-(defvar org-export-e-odt-inline-images 'maybe)
-(defvar org-export-e-odt-default-org-styles-alist
- '((paragraph . ((default . "Text_20_body")
- (fixedwidth . "OrgFixedWidthBlock")
- (verse . "OrgVerse")
- (quote . "Quotations")
- (blockquote . "Quotations")
- (center . "OrgCenter")
- (left . "OrgLeft")
- (right . "OrgRight")
- (title . "OrgTitle")
- (subtitle . "OrgSubtitle")
- (footnote . "Footnote")
- (src . "OrgSrcBlock")
- (illustration . "Illustration")
- (table . "Table")
- (definition-term . "Text_20_body_20_bold")
- (horizontal-line . "Horizontal_20_Line")))
- (character . ((bold . "Bold")
- (emphasis . "Emphasis")
- (code . "OrgCode")
- (verbatim . "OrgCode")
- (strike . "Strikethrough")
- (underline . "Underline")
- (subscript . "OrgSubscript")
- (superscript . "OrgSuperscript")))
- (list . ((ordered . "OrgNumberedList")
- (unordered . "OrgBulletedList")
- (descriptive . "OrgDescriptionList"))))
- "Default styles for various entities.")
-
-(defvar org-export-e-odt-org-styles-alist org-export-e-odt-default-org-styles-alist)
-
-;;;_. callbacks
-;;;_. control callbacks
-;;;_ , document body
-
-(defvar org-lparse-body-only) ; let bound during org-do-lparse
-(defvar org-lparse-opt-plist) ; bound during org-do-lparse
-(defvar org-lparse-list-stack) ; dynamically bound in org-do-lparse
-(defvar org-e-odt-list-stack-stashed)
-(defvar org-lparse-table-ncols)
-(defvar org-e-odt-table-rowgrp-open)
-(defvar org-e-odt-table-rownum)
-(defvar org-e-odt-table-cur-rowgrp-is-hdr)
-(defvar org-lparse-table-is-styled)
-(defvar org-lparse-table-rowgrp-info)
-(defvar org-lparse-table-colalign-vector)
-
-(defvar org-e-odt-table-style nil
- "Table style specified by \"#+ATTR_ODT: <style-name>\" line.
-This is set during `org-e-odt-begin-table'.")
-
-(defvar org-e-odt-table-style-spec nil
- "Entry for `org-e-odt-table-style' in `org-export-e-odt-table-styles'.")
-
-
-(defvar org-e-odt-table-style-format
- "
-<style:style style:name=\"%s\" style:family=\"table\">
- <style:table-properties style:rel-width=\"%d%%\" fo:margin-top=\"0cm\" fo:margin-bottom=\"0.20cm\" table:align=\"center\"/>
-</style:style>
-"
- "Template for auto-generated Table styles.")
-
-(defvar org-e-odt-automatic-styles '()
- "Registry of automatic styles for various OBJECT-TYPEs.
-The variable has the following form:
-\(\(OBJECT-TYPE-A
- \(\(OBJECT-NAME-A.1 OBJECT-PROPS-A.1\)
- \(OBJECT-NAME-A.2 OBJECT-PROPS-A.2\) ...\)\)
- \(OBJECT-TYPE-B
- \(\(OBJECT-NAME-B.1 OBJECT-PROPS-B.1\)
- \(OBJECT-NAME-B.2 OBJECT-PROPS-B.2\) ...\)\)
- ...\).
-
-OBJECT-TYPEs could be \"Section\", \"Table\", \"Figure\" etc.
-OBJECT-PROPS is (typically) a plist created by passing
-\"#+ATTR_ODT: \" option to `org-lparse-get-block-params'.
-
-Use `org-e-odt-add-automatic-style' to add update this variable.'")
-
-(defvar org-e-odt-object-counters nil
- "Running counters for various OBJECT-TYPEs.
-Use this to generate automatic names and style-names. See
-`org-e-odt-add-automatic-style'.")
-
-(defvar org-e-odt-table-indentedp nil)
-(defvar org-lparse-table-colalign-info)
-(defvar org-lparse-link-description-is-image nil)
-
-
-(defvar org-src-block-paragraph-format
- "<style:style style:name=\"OrgSrcBlock\" style:family=\"paragraph\" style:parent-style-name=\"Preformatted_20_Text\">
- <style:paragraph-properties fo:background-color=\"%s\" fo:padding=\"0.049cm\" fo:border=\"0.51pt solid #000000\" style:shadow=\"none\">
- <style:background-image/>
- </style:paragraph-properties>
- <style:text-properties fo:color=\"%s\"/>
- </style:style>"
- "Custom paragraph style for colorized source and example blocks.
-This style is much the same as that of \"OrgFixedWidthBlock\"
-except that the foreground and background colors are set
-according to the default face identified by the `htmlfontify'.")
-
-(defvar hfy-optimisations)
-(defvar org-e-odt-embedded-formulas-count 0)
-(defvar org-e-odt-entity-frame-styles
- '(("As-CharImage" "__Figure__" ("OrgInlineImage" nil "as-char"))
- ("ParagraphImage" "__Figure__" ("OrgDisplayImage" nil "paragraph"))
- ("PageImage" "__Figure__" ("OrgPageImage" nil "page"))
- ("CaptionedAs-CharImage" "__Figure__"
- ("OrgCaptionedImage"
- " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
- ("OrgInlineImage" nil "as-char"))
- ("CaptionedParagraphImage" "__Figure__"
- ("OrgCaptionedImage"
- " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
- ("OrgImageCaptionFrame" nil "paragraph"))
- ("CaptionedPageImage" "__Figure__"
- ("OrgCaptionedImage"
- " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
- ("OrgPageImageCaptionFrame" nil "page"))
- ("InlineFormula" "__MathFormula__" ("OrgInlineFormula" nil "as-char"))
- ("DisplayFormula" "__MathFormula__" ("OrgDisplayFormula" nil "as-char"))
- ("CaptionedDisplayFormula" "__MathFormula__"
- ("OrgCaptionedFormula" nil "paragraph")
- ("OrgFormulaCaptionFrame" nil "as-char"))))
-
-(defvar org-e-odt-embedded-images-count 0)
-
-(defvar org-export-e-odt-image-size-probe-method
- (append (and (executable-find "identify") '(imagemagick)) ; See Bug#10675
- '(emacs fixed))
- "Ordered list of methods for determining image sizes.")
-
-(defvar org-export-e-odt-default-image-sizes-alist
- '(("as-char" . (5 . 0.4))
- ("paragraph" . (5 . 5)))
- "Hardcoded image dimensions one for each of the anchor
- methods.")
-
-;; A4 page size is 21.0 by 29.7 cms
-;; The default page settings has 2cm margin on each of the sides. So
-;; the effective text area is 17.0 by 25.7 cm
-(defvar org-export-e-odt-max-image-size '(17.0 . 20.0)
- "Limiting dimensions for an embedded image.")
-
-(defvar org-e-odt-entity-labels-alist nil
- "Associate Labels with the Labeled entities.
-Each element of the alist is of the form (LABEL-NAME
-CATEGORY-NAME SEQNO LABEL-STYLE-NAME). LABEL-NAME is same as
-that specified by \"#+LABEL: ...\" line. CATEGORY-NAME is the
-type of the entity that LABEL-NAME is attached to. CATEGORY-NAME
-can be one of \"Table\", \"Figure\" or \"Equation\". SEQNO is
-the unique number assigned to the referenced entity on a
-per-CATEGORY basis. It is generated sequentially and is 1-based.
-LABEL-STYLE-NAME is a key `org-e-odt-label-styles'.
-
-See `org-e-odt-add-label-definition' and
-`org-e-odt-fixup-label-references'.")
-
-(defvar org-e-odt-entity-counts-plist nil
- "Plist of running counters of SEQNOs for each of the CATEGORY-NAMEs.
-See `org-e-odt-entity-labels-alist' for known CATEGORY-NAMEs.")
-
-(defvar org-e-odt-label-styles
- '(("text" "(%n)" "text" "(%n)")
- ("category-and-value" "%e %n%c" "category-and-value" "%e %n")
- ("value" "%e %n%c" "value" "%n"))
- "Specify how labels are applied and referenced.
-This is an alist where each element is of the
-form (LABEL-STYLE-NAME LABEL-ATTACH-FMT LABEL-REF-MODE
-LABEL-REF-FMT).
-
-LABEL-ATTACH-FMT controls how labels and captions are attached to
-an entity. It may contain following specifiers - %e, %n and %c.
-%e is replaced with the CATEGORY-NAME. %n is replaced with
-\"<text:sequence ...> SEQNO </text:sequence>\". %c is replaced
-with CAPTION. See `org-e-odt-format-label-definition'.
-
-LABEL-REF-MODE and LABEL-REF-FMT controls how label references
-are generated. The following XML is generated for a label
-reference - \"<text:sequence-ref
-text:reference-format=\"LABEL-REF-MODE\" ...> LABEL-REF-FMT
-</text:sequence-ref>\". LABEL-REF-FMT may contain following
-specifiers - %e and %n. %e is replaced with the CATEGORY-NAME.
-%n is replaced with SEQNO. See
-`org-e-odt-format-label-reference'.")
-
-(defvar org-e-odt-category-map-alist
- '(("__Table__" "Table" "value")
- ("__Figure__" "Figure" "value")
- ("__MathFormula__" "Equation" "text")
- ("__DvipngImage__" "Equation" "value")
- ;; ("__Table__" "Table" "category-and-value")
- ;; ("__Figure__" "Figure" "category-and-value")
- ;; ("__DvipngImage__" "Equation" "category-and-value")
- )
- "Map a CATEGORY-HANDLE to CATEGORY-NAME and LABEL-STYLE.
-This is an alist where each element is of the form
-\\(CATEGORY-HANDLE CATEGORY-NAME LABEL-STYLE\\). CATEGORY_HANDLE
-could either be one of the internal handles (as seen above) or be
-derived from the \"#+LABEL:<label-name>\" specification. See
-`org-export-e-odt-get-category-from-label'. CATEGORY-NAME and
-LABEL-STYLE are used for generating ODT labels. See
-`org-e-odt-label-styles'.")
-
-(defvar org-export-e-odt-user-categories
- '("Illustration" "Table" "Text" "Drawing" "Equation" "Figure"))
-
-(defvar org-export-e-odt-get-category-from-label nil
- "Should category of label be inferred from label itself.
-When this option is non-nil, a label is parsed in to two
-component parts delimited by a \":\" (colon) as shown here -
-#+LABEL:[CATEGORY-HANDLE:]EXTRA. The CATEGORY-HANDLE is mapped
-to a CATEGORY-NAME and LABEL-STYLE using
-`org-e-odt-category-map-alist'. (If no such map is provided and
-CATEGORY-NAME is set to CATEGORY-HANDLE and LABEL-STYLE is set to
-\"category-and-value\"). If CATEGORY-NAME so obtained is listed
-under `org-export-e-odt-user-categories' then the user specified
-styles are used. Otherwise styles as determined by the internal
-CATEGORY-HANDLE is used. See
-`org-e-odt-get-label-category-and-style' for details.")
-
-(defvar org-e-odt-manifest-file-entries nil)
-(defvar hfy-user-sheet-assoc) ; bound during org-do-lparse
-(defvar org-lparse-latex-fragment-fallback) ; set by org-do-lparse
-
-
-;;;; HTML Internal Variables
-
-(defvar org-e-odt-option-alist
- '(
- ;; (:agenda-style nil nil org-agenda-export-html-style)
- ;; (:convert-org-links nil nil org-e-odt-link-org-files-as-html)
- ;; ;; FIXME Use (org-xml-encode-org-text-skip-links s) ??
- ;; ;; (:expand-quoted-html nil "@" org-e-odt-expand)
- ;; (:inline-images nil nil org-e-odt-inline-images)
- ;; ;; (:link-home nil nil org-e-odt-link-home) FIXME
- ;; ;; (:link-up nil nil org-e-odt-link-up) FIXME
- ;; (:style nil nil org-e-odt-style)
- ;; (:style-extra nil nil org-e-odt-style-extra)
- ;; (:style-include-default nil nil org-e-odt-style-include-default)
- ;; (:style-include-scripts nil nil org-e-odt-style-include-scripts)
- ;; ;; (:timestamp nil nil org-e-odt-with-timestamp)
- ;; (:html-extension nil nil org-e-odt-extension)
- ;; (:html-postamble nil nil org-e-odt-postamble)
- ;; (:html-preamble nil nil org-e-odt-preamble)
- ;; (:html-table-tag nil nil org-e-odt-table-tag)
- ;; (:xml-declaration nil nil org-e-odt-xml-declaration)
- (:LaTeX-fragments nil "LaTeX" org-export-with-LaTeX-fragments))
- "Alist between export properties and ways to set them.
-
-The car of the alist is the property name, and the cdr is a list
-like \(KEYWORD OPTION DEFAULT BEHAVIOUR\) where:
-
-KEYWORD is a string representing a buffer keyword, or nil.
-OPTION is a string that could be found in an #+OPTIONS: line.
-DEFAULT is the default value for the property.
-BEHAVIOUR determine how Org should handle multiple keywords for
-the same property. It is a symbol among:
- nil Keep old value and discard the new one.
- t Replace old value with the new one.
- `space' Concatenate the values, separating them with a space.
- `newline' Concatenate the values, separating them with
- a newline.
- `split' Split values at white spaces, and cons them to the
- previous list.
-
-KEYWORD and OPTION have precedence over DEFAULT.
-
-All these properties should be back-end agnostic. For back-end
-specific properties, define a similar variable named
-`org-BACKEND-option-alist', replacing BACKEND with the name of
-the appropriate back-end. You can also redefine properties
-there, as they have precedence over these.")
-
-(defvar html-table-tag nil) ; dynamically scoped into this.
-
-;; FIXME: it already exists in org-e-odt.el
-(defconst org-e-odt-cvt-link-fn
- nil
- "Function to convert link URLs to exportable URLs.
-Takes two arguments, TYPE and PATH.
-Returns exportable url as (TYPE PATH), or nil to signal that it
-didn't handle this case.
-Intended to be locally bound around a call to `org-export-as-html'." )
-
-
-\f
-
-(defvar org-e-odt-format-table-no-css)
-(defvar htmlize-buffer-places) ; from htmlize.el
-(defvar body-only) ; dynamically scoped into this.
-
-(defvar org-e-odt-table-rowgrp-open)
-(defvar org-e-odt-table-rownum)
-(defvar org-e-odt-table-cur-rowgrp-is-hdr)
-(defvar org-lparse-table-is-styled)
-
-\f
-(defvar org-e-odt-headline-formatter
- (lambda (level snumber todo todo-type priority
- title tags target extra-targets extra-class)
- (concat snumber " " title)))
-
-
-\f
-;;; User Configuration Variables
-
-(defgroup org-export-e-odt nil
- "Options for exporting Org mode files to HTML."
- :tag "Org Export HTML"
- :group 'org-export)
-
-(defcustom org-e-odt-protect-char-alist
- '(("&" . "&")
- ("<" . "<")
- (">" . ">"))
- "Alist of characters to be converted by `org-e-html-protect'."
- :group 'org-export-e-html
- :type '(repeat (cons (string :tag "Character")
- (string :tag "ODT equivalent"))))
-(defcustom org-export-e-odt-schema-dir
- (let* ((schema-dir
- (catch 'schema-dir
- (message "Debug (org-e-odt): Searching for OpenDocument schema files...")
- (mapc
- (lambda (schema-dir)
- (when schema-dir
- (message "Debug (org-e-odt): Trying %s..." schema-dir)
- (when (and (file-readable-p
- (expand-file-name "od-manifest-schema-v1.2-cs01.rnc"
- schema-dir))
- (file-readable-p
- (expand-file-name "od-schema-v1.2-cs01.rnc"
- schema-dir))
- (file-readable-p
- (expand-file-name "schemas.xml" schema-dir)))
- (message "Debug (org-e-odt): Using schema files under %s"
- schema-dir)
- (throw 'schema-dir schema-dir))))
- org-e-odt-schema-dir-list)
- (message "Debug (org-e-odt): No OpenDocument schema files installed")
- nil)))
- schema-dir)
- "Directory that contains OpenDocument schema files.
-
-This directory contains:
-1. rnc files for OpenDocument schema
-2. a \"schemas.xml\" file that specifies locating rules needed
- for auto validation of OpenDocument XML files.
-
-Use the customize interface to set this variable. This ensures
-that `rng-schema-locating-files' is updated and auto-validation
-of OpenDocument XML takes place based on the value
-`rng-nxml-auto-validate-flag'.
-
-The default value of this variable varies depending on the
-version of org in use and is initialized from
-`org-e-odt-schema-dir-list'. The OASIS schema files are available
-only in the org's private git repository. It is *not* bundled
-with GNU ELPA tar or standard Emacs distribution."
- :type '(choice
- (const :tag "Not set" nil)
- (directory :tag "Schema directory"))
- :group 'org-export-e-odt
- :version "24.1"
- :set
- (lambda (var value)
- "Set `org-export-e-odt-schema-dir'.
-Also add it to `rng-schema-locating-files'."
- (let ((schema-dir value))
- (set var
- (if (and
- (file-readable-p
- (expand-file-name "od-manifest-schema-v1.2-cs01.rnc" schema-dir))
- (file-readable-p
- (expand-file-name "od-schema-v1.2-cs01.rnc" schema-dir))
- (file-readable-p
- (expand-file-name "schemas.xml" schema-dir)))
- schema-dir
- (when value
- (message "Error (org-e-odt): %s has no OpenDocument schema files"
- value))
- nil)))
- (when org-export-e-odt-schema-dir
- (eval-after-load 'rng-loc
- '(add-to-list 'rng-schema-locating-files
- (expand-file-name "schemas.xml"
- org-export-e-odt-schema-dir))))))
-
-(defcustom org-export-e-odt-content-template-file nil
- "Template file for \"content.xml\".
-The exporter embeds the exported content just before
-\"</office:text>\" element.
-
-If unspecified, the file named \"OrgOdtContentTemplate.xml\"
-under `org-e-odt-styles-dir' is used."
- :type 'file
- :group 'org-export-e-odt
- :version "24.1")
-
-(defcustom org-export-e-odt-styles-file nil
- "Default styles file for use with ODT export.
-Valid values are one of:
-1. nil
-2. path to a styles.xml file
-3. path to a *.odt or a *.ott file
-4. list of the form (ODT-OR-OTT-FILE (FILE-MEMBER-1 FILE-MEMBER-2
-...))
-
-In case of option 1, an in-built styles.xml is used. See
-`org-e-odt-styles-dir' for more information.
-
-In case of option 3, the specified file is unzipped and the
-styles.xml embedded therein is used.
-
-In case of option 4, the specified ODT-OR-OTT-FILE is unzipped
-and FILE-MEMBER-1, FILE-MEMBER-2 etc are copied in to the
-generated odt file. Use relative path for specifying the
-FILE-MEMBERS. styles.xml must be specified as one of the
-FILE-MEMBERS.
-
-Use options 1, 2 or 3 only if styles.xml alone suffices for
-achieving the desired formatting. Use option 4, if the styles.xml
-references additional files like header and footer images for
-achieving the desired formatting.
-
-Use \"#+ODT_STYLES_FILE: ...\" directive to set this variable on
-a per-file basis. For example,
-
-#+ODT_STYLES_FILE: \"/path/to/styles.xml\" or
-#+ODT_STYLES_FILE: (\"/path/to/file.ott\" (\"styles.xml\" \"image/hdr.png\"))."
- :group 'org-export-e-odt
- :version "24.1"
- :type
- '(choice
- (const :tag "Factory settings" nil)
- (file :must-match t :tag "styles.xml")
- (file :must-match t :tag "ODT or OTT file")
- (list :tag "ODT or OTT file + Members"
- (file :must-match t :tag "ODF Text or Text Template file")
- (cons :tag "Members"
- (file :tag " Member" "styles.xml")
- (repeat (file :tag "Member"))))))
-
-
-(defcustom org-export-e-odt-inline-image-extensions
- '("png" "jpeg" "jpg" "gif")
- "Extensions of image files that can be inlined into HTML."
- :type '(repeat (string :tag "Extension"))
- :group 'org-export-e-odt
- :version "24.1")
-
-(defcustom org-export-e-odt-pixels-per-inch display-pixels-per-inch
- "Scaling factor for converting images pixels to inches.
-Use this for sizing of embedded images. See Info node `(org)
-Images in ODT export' for more information."
- :type 'float
- :group 'org-export-e-odt
- :version "24.1")
-
-(defcustom org-export-e-odt-create-custom-styles-for-srcblocks t
- "Whether custom styles for colorized source blocks be automatically created.
-When this option is turned on, the exporter creates custom styles
-for source blocks based on the advice of `htmlfontify'. Creation
-of custom styles happen as part of `org-e-odt-hfy-face-to-css'.
-
-When this option is turned off exporter does not create such
-styles.
-
-Use the latter option if you do not want the custom styles to be
-based on your current display settings. It is necessary that the
-styles.xml already contains needed styles for colorizing to work.
-
-This variable is effective only if
-`org-export-e-odt-fontify-srcblocks' is turned on."
- :group 'org-export-e-odt
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-export-e-odt-preferred-output-format nil
- "Automatically post-process to this format after exporting to \"odt\".
-Interactive commands `org-export-as-e-odt' and
-`org-export-as-e-odt-and-open' export first to \"odt\" format and
-then use `org-export-e-odt-convert-process' to convert the
-resulting document to this format. During customization of this
-variable, the list of valid values are populated based on
-`org-export-e-odt-convert-capabilities'."
- :group 'org-export-e-odt
- :version "24.1"
- :type '(choice :convert-widget
- (lambda (w)
- (apply 'widget-convert (widget-type w)
- (eval (car (widget-get w :args)))))
- `((const :tag "None" nil)
- ,@(mapcar (lambda (c)
- `(const :tag ,c ,c))
- (org-lparse-reachable-formats "odt")))))
-
-(defcustom org-export-e-odt-table-styles
- '(("OrgEquation" "OrgEquation"
- ((use-first-column-styles . t)
- (use-last-column-styles . t))))
- "Specify how Table Styles should be derived from a Table Template.
-This is a list where each element is of the
-form (TABLE-STYLE-NAME TABLE-TEMPLATE-NAME TABLE-CELL-OPTIONS).
-
-TABLE-STYLE-NAME is the style associated with the table through
-`org-e-odt-table-style'.
-
-TABLE-TEMPLATE-NAME is a set of - upto 9 - automatic
-TABLE-CELL-STYLE-NAMEs and PARAGRAPH-STYLE-NAMEs (as defined
-below) that is included in
-`org-export-e-odt-content-template-file'.
-
-TABLE-CELL-STYLE-NAME := TABLE-TEMPLATE-NAME + TABLE-CELL-TYPE +
- \"TableCell\"
-PARAGRAPH-STYLE-NAME := TABLE-TEMPLATE-NAME + TABLE-CELL-TYPE +
- \"TableParagraph\"
-TABLE-CELL-TYPE := \"FirstRow\" | \"LastColumn\" |
- \"FirstRow\" | \"LastRow\" |
- \"EvenRow\" | \"OddRow\" |
- \"EvenColumn\" | \"OddColumn\" | \"\"
-where \"+\" above denotes string concatenation.
-
-TABLE-CELL-OPTIONS is an alist where each element is of the
-form (TABLE-CELL-STYLE-SELECTOR . ON-OR-OFF).
-TABLE-CELL-STYLE-SELECTOR := `use-first-row-styles' |
- `use-last-row-styles' |
- `use-first-column-styles' |
- `use-last-column-styles' |
- `use-banding-rows-styles' |
- `use-banding-columns-styles' |
- `use-first-row-styles'
-ON-OR-OFF := `t' | `nil'
-
-For example, with the following configuration
-
-\(setq org-export-e-odt-table-styles
- '\(\(\"TableWithHeaderRowsAndColumns\" \"Custom\"
- \(\(use-first-row-styles . t\)
- \(use-first-column-styles . t\)\)\)
- \(\"TableWithHeaderColumns\" \"Custom\"
- \(\(use-first-column-styles . t\)\)\)\)\)
-
-1. A table associated with \"TableWithHeaderRowsAndColumns\"
- style will use the following table-cell styles -
- \"CustomFirstRowTableCell\", \"CustomFirstColumnTableCell\",
- \"CustomTableCell\" and the following paragraph styles
- \"CustomFirstRowTableParagraph\",
- \"CustomFirstColumnTableParagraph\", \"CustomTableParagraph\"
- as appropriate.
-
-2. A table associated with \"TableWithHeaderColumns\" style will
- use the following table-cell styles -
- \"CustomFirstColumnTableCell\", \"CustomTableCell\" and the
- following paragraph styles
- \"CustomFirstColumnTableParagraph\", \"CustomTableParagraph\"
- as appropriate..
-
-Note that TABLE-TEMPLATE-NAME corresponds to the
-\"<table:table-template>\" elements contained within
-\"<office:styles>\". The entries (TABLE-STYLE-NAME
-TABLE-TEMPLATE-NAME TABLE-CELL-OPTIONS) correspond to
-\"table:template-name\" and \"table:use-first-row-styles\" etc
-attributes of \"<table:table>\" element. Refer ODF-1.2
-specification for more information. Also consult the
-implementation filed under `org-e-odt-get-table-cell-styles'.
-
-The TABLE-STYLE-NAME \"OrgEquation\" is used internally for
-formatting of numbered display equations. Do not delete this
-style from the list."
- :group 'org-export-e-odt
- :version "24.1"
- :type '(choice
- (const :tag "None" nil)
- (repeat :tag "Table Styles"
- (list :tag "Table Style Specification"
- (string :tag "Table Style Name")
- (string :tag "Table Template Name")
- (alist :options (use-first-row-styles
- use-last-row-styles
- use-first-column-styles
- use-last-column-styles
- use-banding-rows-styles
- use-banding-columns-styles)
- :key-type symbol
- :value-type (const :tag "True" t))))))
-(defcustom org-export-e-odt-fontify-srcblocks t
- "Specify whether or not source blocks need to be fontified.
-Turn this option on if you want to colorize the source code
-blocks in the exported file. For colorization to work, you need
-to make available an enhanced version of `htmlfontify' library."
- :type 'boolean
- :group 'org-export-e-odt
- :version "24.1")
-
-(defcustom org-export-e-odt-prettify-xml t ; FIXME
- "Specify whether or not the xml output should be prettified.
-When this option is turned on, `indent-region' is run on all
-component xml buffers before they are saved. Turn this off for
-regular use. Turn this on if you need to examine the xml
-visually."
- :group 'org-export-e-odt
- :version "24.1"
- :type 'boolean)
-
-(defcustom org-export-e-odt-convert-processes
- '(("LibreOffice"
- "soffice --headless --convert-to %f%x --outdir %d %i")
- ("unoconv"
- "unoconv -f %f -o %d %i"))
- "Specify a list of document converters and their usage.
-The converters in this list are offered as choices while
-customizing `org-export-e-odt-convert-process'.
-
-This variable is a list where each element is of the
-form (CONVERTER-NAME CONVERTER-CMD). CONVERTER-NAME is the name
-of the converter. CONVERTER-CMD is the shell command for the
-converter and can contain format specifiers. These format
-specifiers are interpreted as below:
-
-%i input file name in full
-%I input file name as a URL
-%f format of the output file
-%o output file name in full
-%O output file name as a URL
-%d output dir in full
-%D output dir as a URL.
-%x extra options as set in `org-export-e-odt-convert-capabilities'."
- :group 'org-export-e-odt
- :version "24.1"
- :type
- '(choice
- (const :tag "None" nil)
- (alist :tag "Converters"
- :key-type (string :tag "Converter Name")
- :value-type (group (string :tag "Command line")))))
-
-(defcustom org-export-e-odt-convert-process "LibreOffice"
- "Use this converter to convert from \"odt\" format to other formats.
-During customization, the list of converter names are populated
-from `org-export-e-odt-convert-processes'."
- :group 'org-export-e-odt
- :version "24.1"
- :type '(choice :convert-widget
- (lambda (w)
- (apply 'widget-convert (widget-type w)
- (eval (car (widget-get w :args)))))
- `((const :tag "None" nil)
- ,@(mapcar (lambda (c)
- `(const :tag ,(car c) ,(car c)))
- org-export-e-odt-convert-processes))))
-
-(defcustom org-export-e-odt-convert-capabilities
- '(("Text"
- ("odt" "ott" "doc" "rtf" "docx")
- (("pdf" "pdf") ("odt" "odt") ("rtf" "rtf") ("ott" "ott")
- ("doc" "doc" ":\"MS Word 97\"") ("docx" "docx") ("html" "html")))
- ("Web"
- ("html")
- (("pdf" "pdf") ("odt" "odt") ("html" "html")))
- ("Spreadsheet"
- ("ods" "ots" "xls" "csv" "xlsx")
- (("pdf" "pdf") ("ots" "ots") ("html" "html") ("csv" "csv") ("ods" "ods")
- ("xls" "xls") ("xlsx" "xlsx")))
- ("Presentation"
- ("odp" "otp" "ppt" "pptx")
- (("pdf" "pdf") ("swf" "swf") ("odp" "odp") ("otp" "otp") ("ppt" "ppt")
- ("pptx" "pptx") ("odg" "odg"))))
- "Specify input and output formats of `org-export-e-odt-convert-process'.
-More correctly, specify the set of input and output formats that
-the user is actually interested in.
-
-This variable is an alist where each element is of the
-form (DOCUMENT-CLASS INPUT-FMT-LIST OUTPUT-FMT-ALIST).
-INPUT-FMT-LIST is a list of INPUT-FMTs. OUTPUT-FMT-ALIST is an
-alist where each element is of the form (OUTPUT-FMT
-OUTPUT-FILE-EXTENSION EXTRA-OPTIONS).
-
-The variable is interpreted as follows:
-`org-export-e-odt-convert-process' can take any document that is in
-INPUT-FMT-LIST and produce any document that is in the
-OUTPUT-FMT-LIST. A document converted to OUTPUT-FMT will have
-OUTPUT-FILE-EXTENSION as the file name extension. OUTPUT-FMT
-serves dual purposes:
-- It is used for populating completion candidates during
- `org-export-e-odt-convert' commands.
-- It is used as the value of \"%f\" specifier in
- `org-export-e-odt-convert-process'.
-
-EXTRA-OPTIONS is used as the value of \"%x\" specifier in
-`org-export-e-odt-convert-process'.
-
-DOCUMENT-CLASS is used to group a set of file formats in
-INPUT-FMT-LIST in to a single class.
-
-Note that this variable inherently captures how LibreOffice based
-converters work. LibreOffice maps documents of various formats
-to classes like Text, Web, Spreadsheet, Presentation etc and
-allow document of a given class (irrespective of it's source
-format) to be converted to any of the export formats associated
-with that class.
-
-See default setting of this variable for an typical
-configuration."
- :group 'org-export-e-odt
- :version "24.1"
- :type
- '(choice
- (const :tag "None" nil)
- (alist :tag "Capabilities"
- :key-type (string :tag "Document Class")
- :value-type
- (group (repeat :tag "Input formats" (string :tag "Input format"))
- (alist :tag "Output formats"
- :key-type (string :tag "Output format")
- :value-type
- (group (string :tag "Output file extension")
- (choice
- (const :tag "None" nil)
- (string :tag "Extra options"))))))))
-
-;;;; Debugging
-
-
-;;;; Document
-
-;;;; Document Header (Styles)
-
-;;;; Document Header (Scripts)
-
-;;;; Document Header (Mathjax)
-
-;;;; Preamble
-
-;;;; Postamble
-
-;;;; Emphasis
-
-;;;; Todos
-
-;;;; Tags
-
-;;;; Time-stamps
-;;;; Statistics Cookie
-;;;; Subscript
-;;;; Superscript
-
-;;;; Inline images
-
-;;;; Block
-;;;; Comment
-;;;; Comment Block
-;;;; Drawer
-;;;; Dynamic Block
-;;;; Emphasis
-;;;; Entity
-;;;; Example Block
-;;;; Export Snippet
-;;;; Export Block
-;;;; Fixed Width
-;;;; Footnotes
-
-;;;; Headline
-;;;; Horizontal Rule
-;;;; Inline Babel Call
-;;;; Inline Src Block
-;;;; Inlinetask
-;;;; Item
-;;;; Keyword
-;;;; Latex Environment
-;;;; Latex Fragment
-;;;; Line Break
-;;;; Link
-;;;; Babel Call
-;;;; Macro
-;;;; Paragraph
-;;;; Plain List
-;;;; Plain Text
-;;;; Property Drawer
-;;;; Quote Block
-;;;; Quote Section
-;;;; Section
-;;;; Radio Target
-;;;; Special Block
-;;;; Src Block
-
-;;;; Table
-
-;;;; Target
-;;;; Time-stamp
-
-;;;; Verbatim
-;;;; Verse Block
-;;;; Headline
-
-;;;; Links
-;;;; Drawers
-;;;; Inlinetasks
-;;;; Publishing
-
-;;;; Compilation
-
-
-\f
-;;; User Configurable Variables (MAYBE)
-
-;;;; Preamble
-
-;;;; Headline
-
-;;;; Emphasis
-
-(defcustom org-e-odt-format-headline-function nil
- "Function to format headline text.
-
-This function will be called with 5 arguments:
-TODO the todo keyword \(string or nil\).
-TODO-TYPE the type of todo \(symbol: `todo', `done', nil\)
-PRIORITY the priority of the headline \(integer or nil\)
-TEXT the main headline text \(string\).
-TAGS the tags string, separated with colons \(string or nil\).
-
-The function result will be used in the section format string.
-
-As an example, one could set the variable to the following, in
-order to reproduce the default set-up:
-
-\(defun org-e-odt-format-headline \(todo todo-type priority text tags\)
- \"Default format function for an headline.\"
- \(concat \(when todo
- \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
- \(when priority
- \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
- text
- \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
- :group 'org-export-e-odt
- :type 'function)
-
-;;;; Footnotes
-
-;;;; Time-stamps
-
-(defcustom org-e-odt-active-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to active time-stamps."
- :group 'org-export-e-odt
- :type 'string)
-
-(defcustom org-e-odt-inactive-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to inactive time-stamps."
- :group 'org-export-e-odt
- :type 'string)
-
-(defcustom org-e-odt-diary-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to diary time-stamps."
- :group 'org-export-e-odt
- :type 'string)
-
-
-;;;; Links
-
-(defcustom org-e-odt-image-default-option "width=.9\\linewidth"
- "Default option for images."
- :group 'org-export-e-odt
- :type 'string)
-
-(defcustom org-e-odt-default-figure-position "htb"
- "Default position for latex figures."
- :group 'org-export-e-odt
- :type 'string)
-
-(defcustom org-e-odt-inline-image-rules
- '(("file" . "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\)\\'"))
- "Rules characterizing image files that can be inlined into HTML.
-
-A rule consists in an association whose key is the type of link
-to consider, and value is a regexp that will be matched against
-link's path.
-
-Note that, by default, the image extension *actually* allowed
-depend on the way the HTML file is processed. When used with
-pdflatex, pdf, jpg and png images are OK. When processing
-through dvi to Postscript, only ps and eps are allowed. The
-default we use here encompasses both."
- :group 'org-export-e-odt
- :type '(alist :key-type (string :tag "Type")
- :value-type (regexp :tag "Path")))
-
-;;;; Tables
-
-(defcustom org-e-odt-table-caption-above t
- "When non-nil, place caption string at the beginning of the table.
-Otherwise, place it near the end."
- :group 'org-export-e-odt
- :type 'boolean)
-
-;;;; Drawers
-
-(defcustom org-e-odt-format-drawer-function nil
- "Function called to format a drawer in HTML code.
-
-The function must accept two parameters:
- NAME the drawer name, like \"LOGBOOK\"
- CONTENTS the contents of the drawer.
-
-The function should return the string to be exported.
-
-For example, the variable could be set to the following function
-in order to mimic default behaviour:
-
-\(defun org-e-odt-format-drawer-default \(name contents\)
- \"Format a drawer element for HTML export.\"
- contents\)"
- :group 'org-export-e-odt
- :type 'function)
-
-
-;;;; Inlinetasks
-
-(defcustom org-e-odt-format-inlinetask-function nil
- "Function called to format an inlinetask in HTML code.
-
-The function must accept six parameters:
- TODO the todo keyword, as a string
- TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
- PRIORITY the inlinetask priority, as a string
- NAME the inlinetask name, as a string.
- TAGS the inlinetask tags, as a string.
- CONTENTS the contents of the inlinetask, as a string.
-
-The function should return the string to be exported.
-
-For example, the variable could be set to the following function
-in order to mimic default behaviour:
-
-\(defun org-e-odt-format-inlinetask \(todo type priority name tags contents\)
-\"Format an inline task element for HTML export.\"
- \(let \(\(full-title
- \(concat
- \(when todo
- \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
- \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
- title
- \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
- \(format \(concat \"\\\\begin{center}\\n\"
- \"\\\\fbox{\\n\"
- \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
- \"%s\\n\\n\"
- \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
- \"%s\"
- \"\\\\end{minipage}}\"
- \"\\\\end{center}\"\)
- full-title contents\)\)"
- :group 'org-export-e-odt
- :type 'function)
-
-
-;; Src blocks
-
-;;;; Plain text
-
-(defcustom org-e-odt-quotes
- '(("fr" ("\\(\\s-\\|[[(]\\)\"" . "«~") ("\\(\\S-\\)\"" . "~»") ("\\(\\s-\\|(\\)'" . "'"))
- ("en" ("\\(\\s-\\|[[(]\\)\"" . "``") ("\\(\\S-\\)\"" . "''") ("\\(\\s-\\|(\\)'" . "`")))
- "Alist for quotes to use when converting english double-quotes.
-
-The CAR of each item in this alist is the language code.
-The CDR of each item in this alist is a list of three CONS:
-- the first CONS defines the opening quote;
-- the second CONS defines the closing quote;
-- the last CONS defines single quotes.
-
-For each item in a CONS, the first string is a regexp
-for allowed characters before/after the quote, the second
-string defines the replacement string for this quote."
- :group 'org-export-e-odt
- :type '(list
- (cons :tag "Opening quote"
- (string :tag "Regexp for char before")
- (string :tag "Replacement quote "))
- (cons :tag "Closing quote"
- (string :tag "Regexp for char after ")
- (string :tag "Replacement quote "))
- (cons :tag "Single quote"
- (string :tag "Regexp for char before")
- (string :tag "Replacement quote "))))
-
-
-;;;; Compilation
-
-
-\f
-;;; Internal Functions (HTML)
-
-;; (defun org-e-odt-format-inline-image (path &optional caption label attr)
-;; ;; FIXME: alt text missing here?
-;; (let ((inline-image (format "<img src=\"%s\" alt=\"%s\"/>"
-;; path (file-name-nondirectory path))))
-;; (if (not label) inline-image
-;; (org-e-odt-format-section inline-image "figure" label))))
-
-(defun org-e-odt-format-image (src)
- "Create image tag with source and attributes."
- (save-match-data
- (let* ((caption (org-find-text-property-in-string 'org-caption src))
- (attr (org-find-text-property-in-string 'org-attributes src))
- (label (org-find-text-property-in-string 'org-label src))
- (caption (and caption (org-xml-encode-org-text caption)))
- (img-extras (if (string-match "^ltxpng/" src)
- (format " alt=\"%s\""
- (org-find-text-property-in-string
- 'org-latex-src src))
- (if (string-match "\\<alt=" (or attr ""))
- (concat " " attr )
- (concat " " attr " alt=\"" src "\""))))
- (img (format "<img src=\"%s\"%s />" src img-extras))
- (extra (concat
- (and label
- (format "id=\"%s\" " (org-solidify-link-text label)))
- "class=\"figure\"")))
- (if caption
- (with-temp-buffer
- (with-org-lparse-preserve-paragraph-state
- (insert
- (org-lparse-format
- '("<div %s>" . "\n</div>")
- (concat
- (org-lparse-format '("\n<p>" . "</p>") img)
- (org-lparse-format '("\n<p>" . "</p>") caption))
- extra)))
- (buffer-string))
- img))))
-
-;;;; Bibliography
-
-(defun org-e-odt-bibliography ()
- "Find bibliography, cut it out and return it."
- (catch 'exit
- (let (beg end (cnt 1) bib)
- (save-excursion
- (goto-char (point-min))
- (when (re-search-forward
- "^[ \t]*<div \\(id\\|class\\)=\"bibliography\"" nil t)
- (setq beg (match-beginning 0))
- (while (re-search-forward "</?div\\>" nil t)
- (setq cnt (+ cnt (if (string= (match-string 0) "<div") +1 -1)))
- (when (= cnt 0)
- (and (looking-at ">") (forward-char 1))
- (setq bib (buffer-substring beg (point)))
- (delete-region beg (point))
- (throw 'exit bib))))
- nil))))
-
-;;;; Table
-
-(defun org-e-odt-format-table (lines olines)
- (let ((org-e-odt-format-table-no-css nil))
- (org-lparse-format-table lines olines)))
-
-(defun org-e-odt-splice-attributes (tag attributes)
- "Read attributes in string ATTRIBUTES, add and replace in HTML tag TAG."
- (if (not attributes)
- tag
- (let (oldatt newatt)
- (setq oldatt (org-extract-attributes-from-string tag)
- tag (pop oldatt)
- newatt (cdr (org-extract-attributes-from-string attributes)))
- (while newatt
- (setq oldatt (plist-put oldatt (pop newatt) (pop newatt))))
- (if (string-match ">" tag)
- (setq tag
- (replace-match (concat (org-attributes-to-string oldatt) ">")
- t t tag)))
- tag)))
-
-(defun org-export-splice-style (style extra)
- "Splice EXTRA into STYLE, just before \"</style>\"."
- (if (and (stringp extra)
- (string-match "\\S-" extra)
- (string-match "</style>" style))
- (concat (substring style 0 (match-beginning 0))
- "\n" extra "\n"
- (substring style (match-beginning 0)))
- style))
-
-;; (defun org-e-odt-format-toc-entry (snumber todo headline tags href)
-;; (setq headline (concat
-;; ;; section number
-;; (and org-export-with-section-numbers (concat snumber " "))
-;; ;; headline
-;; headline
-;; ;; tags
-;; (and tags (concat
-;; (org-e-odt-format-spaces 3)
-;; (org-e-odt-format-fontify tags "tag")))))
-;; ;; fontify headline based on TODO keyword
-;; (when todo (setq headline (org-e-odt-format-fontify headline "todo")))
-;; (org-e-odt-format-link headline (concat "#" href)))
-
-(defun org-e-odt-toc-entry-formatter
- (level snumber todo todo-type priority
- headline tags target extra-targets extra-class)
- (org-e-odt-format-toc-entry snumber todo headline tags target))
-
-(defun org-e-odt-make-string (n string)
- (let (out) (dotimes (i n out) (setq out (concat string out)))))
-
-(defun org-e-odt-toc-text (toc-entries)
- (let* ((prev-level (1- (nth 1 (car toc-entries))))
- (start-level prev-level))
- (mapconcat
- (lambda (entry)
- (let ((headline (nth 0 entry))
- (level (nth 1 entry)))
- (prog1 (org-e-odt-format-toc-item headline level prev-level)
- (setq prev-level level))))
- toc-entries "")))
-
-(defun org-e-odt-toc (depth info)
- (assert (wholenump depth))
- (let* ((headlines (org-export-collect-headlines info depth))
- (toc-entries
- (loop for headline in headlines collect
- (list (org-e-odt-headline-text
- headline info 'org-e-odt-toc-entry-formatter)
- (org-export-get-relative-level headline info)))))
- (when toc-entries
- (let* ((lang-specific-heading "Table of Contents")) ; FIXME
- (concat
- (org-e-odt-begin-toc lang-specific-heading depth)
- (org-e-odt-toc-text toc-entries)
- (org-e-odt-end-toc))))))
-
-(defun org-e-odt-begin-outline (level1 snumber title tags
- target extra-targets extra-class)
- (let* ((class (format "outline-%d" level1))
- (class (if extra-class (concat class " " extra-class) class))
- (id (format "outline-container-%s"
- (org-lparse-suffix-from-snumber snumber)))
- (extra (concat (when id (format " id=\"%s\"" id))
- (when class (format " class=\"%s\"" class)))))
- (org-lparse-insert-tag "<div%s>" extra)
- (insert
- (org-lparse-format 'HEADING
- (org-lparse-format
- 'HEADLINE title extra-targets tags snumber level1)
- level1 target))))
-
-(defun org-e-odt-end-outline ()
- (org-lparse-insert-tag "</div>"))
-
-(defun org-e-odt-suffix-from-snumber (snumber)
- (let* ((snu (replace-regexp-in-string "\\." "-" snumber))
- (href (cdr (assoc (concat "sec-" snu)
- org-export-preferred-target-alist))))
- (org-solidify-link-text (or href snu))))
-
-(defun org-e-odt-format-outline (contents level1 snumber title
- tags target extra-targets extra-class)
- (concat
- (org-e-odt-format-heading
- (org-e-odt-format-headline title extra-targets tags snumber level1)
- level1 target)
- contents))
-
-;; (defun org-e-odt-format-line (line)
-;; (case org-lparse-dyn-current-environment
-;; ((quote fixedwidth) (concat (org-e-odt-encode-plain-text line) "\n"))
-;; (t (concat line "\n"))))
-
-(defun org-e-odt-fix-class-name (kwd) ; audit callers of this function
- "Turn todo keyword into a valid class name.
-Replaces invalid characters with \"_\"."
- (save-match-data
- (while (string-match "[^a-zA-Z0-9_]" kwd)
- (setq kwd (replace-match "_" t t kwd))))
- kwd)
-
-(defun org-e-odt-format-internal-link (text href &optional extra)
- (org-e-odt-format-link text (concat "#" href) extra))
-
-(defun org-e-odt-format-extra-targets (extra-targets)
- (if (not extra-targets) ""
- (mapconcat (lambda (x)
- (when x
- (setq x (org-solidify-link-text
- (if (org-uuidgen-p x) (concat "ID-" x) x)))
- (org-e-odt-format-anchor "" x))) extra-targets "")))
-
-(defun org-e-odt-format-org-tags (tags)
- (if (not tags) ""
- (org-e-odt-format-fontify
- (mapconcat
- (lambda (x)
- (org-e-odt-format-fontify
- x (concat "" ;; org-e-odt-tag-class-prefix
- (org-e-odt-fix-class-name x))))
- (org-split-string tags ":")
- (org-e-odt-format-spaces 1)) "tag")))
-
-(defun org-e-odt-format-section-number (&optional snumber level)
- ;; FIXME
- (and nil org-export-with-section-numbers
- ;; (not org-lparse-body-only)
- snumber level
- (org-e-odt-format-fontify snumber (format "section-number-%d" level))))
-
-;; (defun org-e-odt-format-headline (title extra-targets tags
-;; &optional snumber level)
-;; (concat
-;; (org-e-odt-format-extra-targets extra-targets)
-;; (concat (org-e-odt-format-section-number snumber level) " ")
-;; title
-;; (and tags (concat (org-e-odt-format-spaces 3)
-;; (org-e-odt-format-org-tags tags)))))
-
-(defun org-e-odt-get-coding-system-for-write ()
- (or org-e-odt-coding-system
- (and (boundp 'buffer-file-coding-system) buffer-file-coding-system)))
-
-(defun org-e-odt-get-coding-system-for-save ()
- (or org-e-odt-coding-system
- (and (boundp 'buffer-file-coding-system) buffer-file-coding-system)))
-
-;; (defun org-e-odt-format-date (info)
-;; (let ((date (plist-get info :date)))
-;; (cond
-;; ((and date (string-match "%" date))
-;; (format-time-string date))
-;; (date date)
-;; (t (format-time-string "%Y-%m-%d %T %Z")))))
-
-
-\f
-;;; Internal Functions (Ngz)
-
-(defun org-e-odt--caption/label-string (caption label info)
- "Return caption and label HTML string for floats.
-
-CAPTION is a cons cell of secondary strings, the car being the
-standard caption and the cdr its short form. LABEL is a string
-representing the label. INFO is a plist holding contextual
-information.
-
-If there's no caption nor label, return the empty string.
-
-For non-floats, see `org-e-odt--wrap-label'."
- (setq label nil) ;; FIXME
-
- (let ((label-str (if label (format "\\label{%s}" label) "")))
- (cond
- ((and (not caption) (not label)) "")
- ((not caption) (format "\\label{%s}\n" label))
- ;; Option caption format with short name.
- ((cdr caption)
- (format "\\caption[%s]{%s%s}\n"
- (org-export-secondary-string (cdr caption) 'e-odt info)
- label-str
- (org-export-secondary-string (car caption) 'e-odt info)))
- ;; Standard caption format.
- ;; (t (format "\\caption{%s%s}\n"
- ;; label-str
- ;; (org-export-secondary-string (car caption) 'e-odt info)))
-
- (t (org-export-secondary-string (car caption) 'e-odt info)))))
-
-(defun org-e-odt--find-verb-separator (s)
- "Return a character not used in string S.
-This is used to choose a separator for constructs like \\verb."
- (let ((ll "~,./?;':\"|!@#%^&-_=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>()[]{}"))
- (loop for c across ll
- when (not (string-match (regexp-quote (char-to-string c)) s))
- return (char-to-string c))))
-
-(defun org-e-odt--make-option-string (options)
- "Return a comma separated string of keywords and values.
-OPTIONS is an alist where the key is the options keyword as
-a string, and the value a list containing the keyword value, or
-nil."
- (mapconcat (lambda (pair)
- (concat (first pair)
- (when (> (length (second pair)) 0)
- (concat "=" (second pair)))))
- options
- ","))
-
-(defun org-e-odt--quotation-marks (text info)
- "Export quotation marks depending on language conventions.
-TEXT is a string containing quotation marks to be replaced. INFO
-is a plist used as a communication channel."
- (mapc (lambda(l)
- (let ((start 0))
- (while (setq start (string-match (car l) text start))
- (let ((new-quote (concat (match-string 1 text) (cdr l))))
- (setq text (replace-match new-quote t t text))))))
- (cdr (or (assoc (plist-get info :language) org-e-odt-quotes)
- ;; Falls back on English.
- (assoc "en" org-e-odt-quotes))))
- text)
-
-(defun org-e-odt--wrap-label (element output)
- "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
-This function shouldn't be used for floats. See
-`org-e-odt--caption/label-string'."
- ;; (let ((label (org-element-property :name element)))
- ;; (if (or (not output) (not label) (string= output "") (string= label ""))
- ;; output
- ;; (concat (format "\\label{%s}\n" label) output)))
- output)
-
-
-\f
-;;; Transcode Helpers
-
-;;;; Src Code
-
-(defun org-e-odt-htmlfontify-string (line)
- (let* ((hfy-html-quote-regex "\\([<\"&> ]\\)")
- (hfy-html-quote-map '(("\"" """)
- ("<" "<")
- ("&" "&")
- (">" ">")
- (" " "<text:s/>")
- (" " "<text:tab/>")))
- (hfy-face-to-css 'org-e-odt-hfy-face-to-css)
- (hfy-optimisations-1 (copy-seq hfy-optimisations))
- (hfy-optimisations (add-to-list 'hfy-optimisations-1
- 'body-text-only))
- (hfy-begin-span-handler
- (lambda (style text-block text-id text-begins-block-p)
- (insert (format "<text:span text:style-name=\"%s\">" style))))
- (hfy-end-span-handler (lambda nil (insert "</text:span>"))))
- (htmlfontify-string line)))
-
-(defun org-e-odt-do-format-code
- (code &optional lang refs retain-labels num-start)
- (let* ((lang (or (assoc-default lang org-src-lang-modes) lang))
- (lang-mode (and lang (intern (format "%s-mode" lang))))
- (code-lines (org-split-string code "\n"))
- (code-length (length code-lines))
- (use-htmlfontify-p (and (functionp lang-mode)
- org-export-e-odt-fontify-srcblocks
- (require 'htmlfontify nil t)
- (fboundp 'htmlfontify-string)))
- (code (if (not use-htmlfontify-p) code
- (with-temp-buffer
- (insert code)
- (funcall lang-mode)
- (font-lock-fontify-buffer)
- (buffer-string))))
- (fontifier (if use-htmlfontify-p 'org-e-odt-htmlfontify-string
- 'org-e-odt-encode-plain-text))
- (par-style (if use-htmlfontify-p "OrgSrcBlock"
- "OrgFixedWidthBlock"))
- (i 0))
- (assert (= code-length (length (org-split-string code "\n"))))
- (setq code
- (org-export-format-code
- code
- (lambda (loc line-num ref)
- (setq par-style
- (concat par-style (and (= (incf i) code-length) "LastLine")))
-
- (setq loc (concat loc (and ref retain-labels (format " (%s)" ref))))
- (setq loc (funcall fontifier loc))
- (when ref
- (setq loc (org-e-odt-format-target loc (concat "coderef-" ref))))
- (setq loc (org-e-odt-format-stylized-paragraph par-style loc))
- (if (not line-num) loc
- (org-e-odt-format-tags
- '("<text:list-item>" . "</text:list-item>") loc)))
- num-start refs))
- (cond
- ((not num-start) code)
- ((equal num-start 0)
- (org-e-odt-format-tags
- '("<text:list text:style-name=\"OrgSrcBlockNumberedLine\"%s>"
- . "</text:list>") code " text:continue-numbering=\"false\""))
- (t (org-e-odt-format-tags
- '("<text:list text:style-name=\"OrgSrcBlockNumberedLine\"%s>"
- . "</text:list>") code " text:continue-numbering=\"true\"")))))
-
-(defun org-e-odt-format-code (element info)
- (let* ((lang (org-element-property :language element))
- ;; Extract code and references.
- (code-info (org-export-unravel-code element))
- (code (car code-info))
- (refs (cdr code-info))
- ;; Does the src block contain labels?
- (retain-labels (org-element-property :retain-labels element))
- ;; Does it have line numbers?
- (num-start (case (org-element-property :number-lines element)
- (continued (org-export-get-loc element info))
- (new 0))))
- (org-e-odt-do-format-code code lang refs retain-labels num-start)))
-
-
-\f
-;;; Template
-
-(defun org-e-odt-template (contents info)
- "Return complete document string after HTML conversion.
-CONTENTS is the transcoded contents string. RAW-DATA is the
-original parsed data. INFO is a plist holding export options."
-
-
- ;; write meta file
- (org-e-odt-update-meta-file info)
-
-
- (with-temp-buffer
- (insert-file-contents
- (or org-export-e-odt-content-template-file
- (expand-file-name "OrgOdtContentTemplate.xml"
- org-e-odt-styles-dir)))
- (goto-char (point-min))
- (re-search-forward "</office:text>" nil nil)
- (goto-char (match-beginning 0))
-
- ;; Title
- (insert (org-e-odt-format-preamble info))
- ;; Table of Contents
- (let ((depth (plist-get info :with-toc)))
- (when (wholenump depth) (org-e-odt-toc depth info)))
-
- ;; Contents
- (insert contents)
- (buffer-substring-no-properties (point-min) (point-max))))
-
-
-\f
-;;; Transcode Functions
-
-;;;; Block
-
-(defun org-e-odt-center-block (center-block contents info)
- "Transcode a CENTER-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (org-e-odt--wrap-label center-block contents))
-
-
-;;;; Comment
-
-;; Comments are ignored.
-
-
-;;;; Comment Block
-
-;; Comment Blocks are ignored.
-
-
-;;;; Drawer
-
-(defun org-e-odt-drawer (drawer contents info)
- "Transcode a DRAWER element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let* ((name (org-element-property :drawer-name drawer))
- (output (if (functionp org-e-odt-format-drawer-function)
- (funcall org-e-odt-format-drawer-function
- name contents)
- ;; If there's no user defined function: simply
- ;; display contents of the drawer.
- contents)))
- (org-e-odt--wrap-label drawer output)))
-
-
-;;;; Dynamic Block
-
-(defun org-e-odt-dynamic-block (dynamic-block contents info)
- "Transcode a DYNAMIC-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information. See
-`org-export-data'."
- (org-e-odt--wrap-label dynamic-block contents))
-
-
-;;;; Emphasis
-
-(defun org-e-odt-emphasis (emphasis contents info)
- "Transcode EMPHASIS from Org to HTML.
-CONTENTS is the contents of the emphasized text. INFO is a plist
-holding contextual information.."
- ;; (format (cdr (assoc (org-element-property :marker emphasis)
- ;; org-e-odt-emphasis-alist))
- ;; contents)
- (org-e-odt-format-fontify
- contents (cadr (assoc
- (org-element-property :marker emphasis)
- '(("*" bold)
- ("/" emphasis)
- ("_" underline)
- ("=" code)
- ("~" verbatim)
- ("+" strike))))))
-
-
-;;;; Entity
-
-(defun org-e-odt-entity (entity contents info)
- "Transcode an ENTITY object from Org to HTML.
-CONTENTS are the definition itself. INFO is a plist holding
-contextual information."
- ;; (let ((ent (org-element-property :latex entity)))
- ;; (if (org-element-property :latex-math-p entity)
- ;; (format "$%s$" ent)
- ;; ent))
- (org-element-property :utf-8 entity))
-
-
-;;;; Example Block
-
-(defun org-e-odt-example-block (example-block contents info)
- "Transcode a EXAMPLE-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((options (or (org-element-property :options example-block) ""))
- (value (org-export-handle-code example-block info nil nil t)))
- (org-e-odt--wrap-label
- example-block (org-e-odt-format-source-code-or-example value nil))))
-
-
-;;;; Export Snippet
-
-(defun org-e-odt-export-snippet (export-snippet contents info)
- "Transcode a EXPORT-SNIPPET object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (when (eq (org-export-snippet-backend export-snippet) 'e-odt)
- (org-element-property :value export-snippet)))
-
-
-;;;; Export Block
-
-(defun org-e-odt-export-block (export-block contents info)
- "Transcode a EXPORT-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (when (string= (org-element-property :type export-block) "latex")
- (org-remove-indentation (org-element-property :value export-block))))
-
-
-;;;; Fixed Width
-
-(defun org-e-odt-fixed-width (fixed-width contents info)
- "Transcode a FIXED-WIDTH element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((value (org-element-normalize-string
- (replace-regexp-in-string
- "^[ \t]*: ?" ""
- (org-element-property :value fixed-width)))))
- (org-e-odt--wrap-label
- fixed-width (org-e-odt-format-source-code-or-example value nil))))
-
-
-;;;; Footnote Definition
-
-;; Footnote Definitions are ignored.
-
-
-;;;; Footnote Reference
-
-(defun org-e-odt-footnote-def (raw info) ; FIXME
- (if (equal (org-element-type raw) 'org-data)
- (org-trim (org-export-data raw 'e-odt info)) ; fix paragraph
- ; style
- (org-odt-format-stylized-paragraph
- 'footnote (org-trim (org-export-secondary-string raw 'e-odt info)))))
-
-(defvar org-e-odt-footnote-separator
- (org-e-odt-format-fontify "," 'superscript))
-
-(defun org-e-odt-footnote-reference (footnote-reference contents info)
- "Transcode a FOOTNOTE-REFERENCE element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (concat
- ;; Insert separator between two footnotes in a row.
- (let ((prev (org-export-get-previous-element footnote-reference info)))
- (when (eq (org-element-type prev) 'footnote-reference)
- org-e-odt-footnote-separator))
- (cond
- ((not (org-export-footnote-first-reference-p footnote-reference info))
- (let* ((n (org-export-get-footnote-number footnote-reference info)))
- (org-e-odt-format-footnote-reference n "IGNORED" 100)))
- ;; Inline definitions are secondary strings.
- ((eq (org-element-property :type footnote-reference) 'inline)
- (let* ((raw (org-export-get-footnote-definition footnote-reference info))
- (n (org-export-get-footnote-number footnote-reference info))
- (def (org-e-odt-footnote-def raw info)))
- (org-e-odt-format-footnote-reference n def 1)))
- ;; Non-inline footnotes definitions are full Org data.
- (t
- (let* ((raw (org-export-get-footnote-definition footnote-reference info))
- (n (org-export-get-footnote-number footnote-reference info))
- (def (org-e-odt-footnote-def raw info)))
- (org-e-odt-format-footnote-reference n def 1))))))
-
-
-;;;; Headline
-
-(defun org-e-odt-todo (todo)
- (when todo
- (org-e-odt-format-fontify
- (concat
- "" ; org-e-odt-todo-kwd-class-prefix
- (org-e-odt-fix-class-name todo))
- (list (if (member todo org-done-keywords) "done" "todo")
- todo))))
-
-(defun org-e-odt-headline-text (headline info &optional formatter)
- "Transcode an HEADLINE element from Org to HTML.
-CONTENTS holds the contents of the headline. INFO is a plist
-holding contextual information."
- (let* ((numberedp (org-export-numbered-headline-p headline info))
- (level (org-export-get-relative-level headline info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property
- :todo-keyword headline)))
- (and todo
- (org-export-secondary-string todo 'e-odt info)))))
- (todo-type (and todo (org-element-property :todo-type headline)))
- (priority (and (plist-get info :with-priority)
- (org-element-property :priority headline)))
- (text (org-export-secondary-string
- (org-element-property :title headline) 'e-odt info))
- (tags (and (plist-get info :with-tags)
- (org-element-property :tags headline)))
-
- (headline-no (org-export-get-headline-number headline info))
- (headline-label
- (format "sec-%s" (mapconcat 'number-to-string headline-no "-")))
- (headline-labels (list headline-label))
- (headline-no (org-export-get-headline-number headline info))
- (section-no (mapconcat 'number-to-string headline-no "."))
- (primary-target (car (last headline-labels)))
- (secondary-targets (butlast headline-labels))
- (extra-class nil)
- (formatter (or (and (functionp formatter) formatter)
- org-e-odt-headline-formatter)))
- (funcall formatter level section-no todo todo-type priority
- text tags primary-target secondary-targets extra-class)))
-
-(defun org-e-odt-headline (headline contents info)
- "Transcode an HEADLINE element from Org to HTML.
-CONTENTS holds the contents of the headline. INFO is a plist
-holding contextual information."
- (let* ((class (plist-get info :latex-class))
- (numberedp (org-export-numbered-headline-p headline info))
- ;; Get level relative to current parsed data.
- (level (org-export-get-relative-level headline info))
- ;; (class-sectionning (assoc class org-e-odt-classes))
- ;; Section formatting will set two placeholders: one for the
- ;; title and the other for the contents.
- ;; (section-fmt
- ;; (let ((sec (if (and (symbolp (nth 2 class-sectionning))
- ;; (fboundp (nth 2 class-sectionning)))
- ;; (funcall (nth 2 class-sectionning) level numberedp)
- ;; (nth (1+ level) class-sectionning))))
- ;; (cond
- ;; ;; No section available for that LEVEL.
- ;; ((not sec) nil)
- ;; ;; Section format directly returned by a function.
- ;; ((stringp sec) sec)
- ;; ;; (numbered-section . unnumbered-section)
- ;; ((not (consp (cdr sec)))
- ;; (concat (funcall (if numberedp #'car #'cdr) sec) "\n%s"))
- ;; ;; (numbered-open numbered-close)
- ;; ((= (length sec) 2)
- ;; (when numberedp (concat (car sec) "\n%s" (nth 1 sec))))
- ;; ;; (num-in num-out no-num-in no-num-out)
- ;; ((= (length sec) 4)
- ;; (if numberedp
- ;; (concat (car sec) "\n%s" (nth 1 sec))
- ;; (concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
- (text (org-export-secondary-string
- (org-element-property :title headline) 'e-odt info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property
- :todo-keyword headline)))
- (and todo
- (org-export-secondary-string todo 'e-odt info)))))
- (todo-type (and todo (org-element-property :todo-type headline)))
- (tags (and (plist-get info :with-tags)
- (org-element-property :tags headline)))
- (priority (and (plist-get info :with-priority)
- (org-element-property :priority headline)))
- ;; Create the headline text.
- (full-text (if (functionp org-e-odt-format-headline-function)
- ;; User-defined formatting function.
- (funcall org-e-odt-format-headline-function
- todo todo-type priority text tags)
- ;; Default formatting.
- (concat
- ;; (when todo
- ;; (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
- (org-e-odt-todo todo) " "
- (when priority (format "\\framebox{\\#%c} " priority))
- text
- ;; (when tags (format "\\hfill{}\\textsc{%s}" tags))
- )))
- ;; Associate some \label to the headline for internal links.
- ;; (headline-label
- ;; (format "\\label{sec-%s}\n"
- ;; (mapconcat 'number-to-string
- ;; (org-export-get-headline-number headline info)
- ;; "-")))
-
- ;; FIXME - begin
- (headline-no (org-export-get-headline-number headline info))
- (headline-label
- (format "sec-%s" (mapconcat 'number-to-string headline-no "-")))
- (headline-labels (list headline-label))
- (headline-no (org-export-get-headline-number headline info))
- (section-no (mapconcat 'number-to-string headline-no "."))
- ;; FIXME - end
-
- (pre-blanks (make-string
- (org-element-property :pre-blank headline) 10)))
- (cond
- ;; Case 1: This is a footnote section: ignore it.
- ((org-element-property :footnote-section-p headline) nil)
- ;; Case 2. This is a deep sub-tree: export it as a list item.
- ;; Also export as items headlines for which no section
- ;; format has been found.
- ((org-export-low-level-p headline info) ; FIXME (or (not section-fmt))
- ;; Build the real contents of the sub-tree.
- (let* ((type (if numberedp 'unordered 'unordered)) ; FIXME
- (itemized-body (org-e-odt-format-list-item
- contents type nil nil full-text)))
- (concat
- (and (org-export-first-sibling-p headline info)
- (org-e-odt-begin-plain-list type))
- itemized-body
- (and (org-export-last-sibling-p headline info)
- (org-e-odt-end-plain-list type)))))
- ;; Case 3. Standard headline. Export it as a section.
- (t
- ;; (format section-fmt full-text
- ;; (concat headline-label pre-blanks contents))
-
- (org-e-odt-format-outline contents level section-no full-text tags
- (car (last headline-labels))
- (butlast headline-labels) nil)))))
-
-
-;;;; Horizontal Rule
-
-(defun org-e-odt-horizontal-rule (horizontal-rule contents info)
- "Transcode an HORIZONTAL-RULE object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((attr (mapconcat #'identity
- (org-element-property :attr_odt horizontal-rule)
- " ")))
- (org-e-odt--wrap-label horizontal-rule
- (org-e-odt-format-horizontal-line))))
-
-
-;;;; Inline Babel Call
-
-;; Inline Babel Calls are ignored.
-
-
-;;;; Inline Src Block
-
-(defun org-e-odt-inline-src-block (inline-src-block contents info)
- "Transcode an INLINE-SRC-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (let* ((org-lang (org-element-property :language inline-src-block))
- (code (org-element-property :value inline-src-block))
- (separator (org-e-odt--find-verb-separator code)))
- (error "FIXME")))
-
-
-;;;; Inlinetask
-
-(defun org-e-odt-format-section (text class &optional id)
- (let ((extra (concat (when id (format " id=\"%s\"" id)))))
- (concat (format "<div class=\"%s\"%s>\n" class extra) text "</div>\n")))
-
-(defun org-e-odt-inlinetask (inlinetask contents info)
- "Transcode an INLINETASK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let ((title (org-export-secondary-string
- (org-element-property :title inlinetask) 'e-odt info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-property
- :todo-keyword inlinetask)))
- (and todo
- (org-export-secondary-string todo 'e-odt info)))))
- (todo-type (org-element-property :todo-type inlinetask))
- (tags (and (plist-get info :with-tags)
- (org-element-property :tags inlinetask)))
- (priority (and (plist-get info :with-priority)
- (org-element-property :priority inlinetask))))
- ;; If `org-e-odt-format-inlinetask-function' is provided, call it
- ;; with appropriate arguments.
- (if (functionp org-e-odt-format-inlinetask-function)
- (funcall org-e-odt-format-inlinetask-function
- todo todo-type priority title tags contents)
- ;; Otherwise, use a default template.
- (org-e-odt--wrap-label
- inlinetask
- (let ((full-title
- (concat
- (when todo (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
- (when priority (format "\\framebox{\\#%c} " priority))
- title
- (when tags (format "\\hfill{}\\textsc{%s}" tags)))))
- (format (concat "\\begin{center}\n"
- "\\fbox{\n"
- "\\begin{minipage}[c]{.6\\textwidth}\n"
- "%s\n\n"
- "\\rule[.8em]{\\textwidth}{2pt}\n\n"
- "%s"
- "\\end{minipage}\n"
- "}\n"
- "\\end{center}")
- full-title contents))))))
-
-
-;;;; Item
-
-(defun org-e-odt-format-list-item (contents type checkbox
- &optional term-counter-id
- headline)
- (when checkbox
- (setq checkbox
- (org-e-odt-format-fontify (case checkbox
- (on "[X]")
- (off "[ ]")
- (trans "[-]")) 'code)))
- (concat
- (org-e-odt-begin-list-item type term-counter-id headline)
- ;; FIXME checkbox (and checkbox " ")
- contents
- (org-e-odt-end-list-item type)))
-
-(defun org-e-odt-item (item contents info)
- "Transcode an ITEM element from Org to HTML.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- ;; Grab `:level' from plain-list properties, which is always the
- ;; first element above current item.
- (let* ((plain-list (org-export-get-parent item info))
- (type (org-element-property :type plain-list))
- (level (org-element-property :level plain-list))
- (counter (org-element-property :counter item))
- (checkbox (org-element-property :checkbox item))
- (tag (let ((tag (org-element-property :tag item)))
- (and tag (org-export-secondary-string tag 'e-odt info)))))
- (org-e-odt-format-list-item
- contents type checkbox (or tag counter))))
-
-
-;;;; Keyword
-
-(defun org-e-odt-keyword (keyword contents info)
- "Transcode a KEYWORD element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((key (downcase (org-element-property :key keyword)))
- (value (org-element-property :value keyword)))
- (cond
- ((string= key "latex") value)
- ((string= key "index") (format "\\index{%s}" value))
- ((string= key "target") nil ; FIXME
- ;; (format "\\label{%s}" (org-export-solidify-link-text value))
- )
- ((string= key "toc")
- (let ((value (downcase value)))
- (cond
- ((string-match "\\<headlines\\>" value)
- (let ((depth (or (and (string-match "[0-9]+" value)
- (string-to-number (match-string 0 value)))
- (plist-get info :with-toc))))
- (when (wholenump depth) (org-e-odt-toc depth info))))
- ((string= "tables" value) "FIXME")
- ((string= "figures" value) "FIXME")
- ((string= "listings" value)
- (cond
- ;; At the moment, src blocks with a caption are wrapped
- ;; into a figure environment.
- (t "FIXME")))))))))
-
-
-;;;; Latex Environment
-
-(defun org-e-odt-format-latex (latex-frag processing-type)
- (let* ((prefix (case processing-type
- (dvipng "ltxpng/")
- (mathml "ltxmathml/")))
- (cache-relpath
- (concat prefix (file-name-sans-extension
- (file-name-nondirectory (buffer-file-name)))))
- (cache-dir (file-name-directory (buffer-file-name )))
- (display-msg (case processing-type
- (dvipng "Creating LaTeX Image...")
- (mathml "Creating MathML snippet..."))))
- (with-temp-buffer
- (insert latex-frag)
- (org-format-latex cache-relpath cache-dir nil display-msg
- nil nil processing-type)
- (buffer-string))))
-
-(defun org-e-odt-latex-environment (latex-environment contents info)
- "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-odt--wrap-label
- latex-environment
- (let ((latex-frag
- (org-remove-indentation
- (org-element-property :value latex-environment)))
- (processing-type (plist-get info :LaTeX-fragments)))
- (cond
- ((member processing-type '(t mathjax))
- (org-e-odt-format-latex latex-frag 'mathml))
- ((equal processing-type 'dvipng)
- (let* ((formula-link (org-e-odt-format-latex
- latex-frag processing-type)))
- (when (and formula-link
- (string-match "file:\\([^]]*\\)" formula-link))
- (org-e-odt-format-inline-image (match-string 1 formula-link)))))
- (t
- latex-frag)))))
-
-
-;;;; Latex Fragment
-
-(defun org-e-odt-latex-fragment (latex-fragment contents info)
- "Transcode a LATEX-FRAGMENT object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- ;; (org-element-property :value latex-fragment)
- (let* ((latex-frag (org-element-property :value latex-fragment)))
- (cond
- ((string-match "\\\\ref{\\([^{}\n]+\\)}" latex-frag)
- (let* ((label (match-string 1 latex-frag))
- (href (and label (org-export-solidify-link-text label)))
- (text (if (string-match "\\`[a-z]\\{1,10\\}:\\(.+\\)" label)
- (substring label (match-beginning 1))
- label)))
- (org-e-odt-format-internal-link text href)))
- (t (let ((processing-type (plist-get info :LaTeX-fragments)))
- (cond
- ((member processing-type '(t mathjax))
- (org-e-odt-format-latex latex-frag 'mathjax))
- ((equal processing-type 'dvipng)
- (let* ((formula-link (org-e-odt-format-latex
- latex-frag processing-type)))
- (when (and formula-link
- (string-match "file:\\([^]]*\\)" formula-link))
- (org-e-odt-format-inline-image
- (match-string 1 formula-link)))))
- (t latex-frag)))))))
-
-
-;;;; Line Break
-
-(defun org-e-odt-line-break (line-break contents info)
- "Transcode a LINE-BREAK object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- "<text:line-break/>\n")
-
-
-;;;; Link
-
-(defun org-e-odt-link--inline-image (link info)
- "Return HTML code for an inline image.
-LINK is the link pointing to the inline image. INFO is a plist
-used as a communication channel."
- (let* ((parent (org-export-get-parent-paragraph link info))
- (path (let ((raw-path (org-element-property :path link)))
- (if (not (file-name-absolute-p raw-path)) raw-path
- (expand-file-name raw-path))))
- (caption (org-e-odt--caption/label-string
- (org-element-property :caption parent)
- (org-element-property :name parent)
- info))
- (label (org-element-property :name parent))
- ;; Retrieve latex attributes from the element around.
- (attr (let ((raw-attr
- (mapconcat #'identity
- (org-element-property :attr_odt parent)
- " ")))
- (unless (string= raw-attr "") raw-attr))))
- ;; Now clear ATTR from any special keyword and set a default
- ;; value if nothing is left.
- (setq attr (if (not attr) "" (org-trim attr)))
- ;; Return proper string, depending on DISPOSITION.
- (let ((href (and label (org-export-solidify-link-text label))))
- (org-e-odt-format-inline-image path caption href attr))))
-
-(defun org-e-odt-link (link desc info)
- "Transcode a LINK object from Org to HTML.
-
-DESC is the description part of the link, or the empty string.
-INFO is a plist holding contextual information. See
-`org-export-data'."
- (let* ((type (org-element-property :type link))
- (raw-path (org-element-property :path link))
- ;; Ensure DESC really exists, or set it to nil.
- (desc (and (not (string= desc "")) desc))
- (imagep (org-export-inline-image-p
- link org-e-odt-inline-image-rules))
- (path (cond
- ((member type '("http" "https" "ftp" "mailto"))
- (concat type ":" raw-path))
- ((string= type "file")
- (when (string-match "\\(.+\\)::.+" raw-path)
- (setq raw-path (match-string 1 raw-path)))
- (if (file-name-absolute-p raw-path)
- (concat "file://" (expand-file-name raw-path))
- ;; TODO: Not implemented yet. Concat also:
- ;; (org-export-directory :HTML info)
- (concat "file://" raw-path)))
- (t raw-path)))
- protocol)
- (cond
- ;; Image file.
- (imagep (org-e-odt-link--inline-image link info))
- ;; Radioed target: Target's name is obtained from original raw
- ;; link. Path is parsed and transcoded in order to have a proper
- ;; display of the contents.
- ((string= type "radio")
- (org-e-odt-format-internal-link
- (org-export-secondary-string
- (org-element-parse-secondary-string
- path (cdr (assq 'radio-target org-element-object-restrictions)))
- 'e-odt info)
- (org-export-solidify-link-text path)))
- ;; Links pointing to an headline: Find destination and build
- ;; appropriate referencing command.
- ((member type '("custom-id" "fuzzy" "id"))
- (let ((destination (if (string= type "fuzzy")
- (org-export-resolve-fuzzy-link link info)
- (org-export-resolve-id-link link info))))
- (case (org-element-type destination)
- ;; Fuzzy link points nowhere.
- ('nil
- (org-e-odt-format-fontify
- (or desc (org-export-secondary-string
- (org-element-property :raw-link link)
- 'e-odt info)) 'emphasis))
- ;; Fuzzy link points to an invisible target.
- (keyword nil)
- ;; LINK points to an headline. If headlines are numbered
- ;; and the link has no description, display headline's
- ;; number. Otherwise, display description or headline's
- ;; title.
- (headline
- (let* ((headline-no (org-export-get-headline-number destination info))
- (label (format "sec-%s" (mapconcat 'number-to-string
- headline-no "-")))
- (section-no (mapconcat 'number-to-string headline-no ".")))
- (setq desc
- (cond
- (desc desc)
- ((plist-get info :section-numbers) section-no)
- (t (org-export-secondary-string
- (org-element-property :title destination)
- 'e-odt info))))
- (org-e-odt-format-internal-link desc label)))
- ;; Fuzzy link points to a target. Do as above.
- (otherwise
- (let ((path (org-export-solidify-link-text path)))
- (unless desc
- (setq desc (let ((number (org-export-get-ordinal
- destination info)))
- (when number
- (if (atom number) (number-to-string number)
- (mapconcat 'number-to-string number "."))))))
- (org-e-odt-format-internal-link (or desc "FIXME") path))))))
- ;; Coderef: replace link with the reference name or the
- ;; equivalent line number.
- ((string= type "coderef")
- (let* ((fmt (org-export-get-coderef-format path (or desc "%s")))
- (res (org-export-resolve-coderef path info))
- (org-e-odt-suppress-xref nil)
- (href (org-xml-format-href (concat "#coderef-" path))))
- (format fmt (org-e-odt-format-link res href))))
- ;; Link type is handled by a special function.
- ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
- (funcall protocol (org-link-unescape path) desc 'html))
- ;; External link with a description part.
- ((and path desc) (org-e-odt-format-link desc path))
- ;; External link without a description part.
- (path (org-e-odt-format-link path path))
- ;; No path, only description. Try to do something useful.
- (t (org-e-odt-format-fontify desc 'emphasis)))))
-
-
-;;;; Babel Call
-
-;; Babel Calls are ignored.
-
-
-;;;; Macro
-
-(defun org-e-odt-macro (macro contents info)
- "Transcode a MACRO element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- ;; Use available tools.
- (org-export-expand-macro macro info))
-
-
-;;;; Paragraph
-
-(defun org-e-odt-paragraph (paragraph contents info)
- "Transcode a PARAGRAPH element from Org to HTML.
-CONTENTS is the contents of the paragraph, as a string. INFO is
-the plist used as a communication channel."
- (let* ((style nil) ; FIXME
- (class (cdr (assoc style '((footnote . "footnote")
- (verse . nil)))))
- (extra (if class (format " class=\"%s\"" class) ""))
- (parent (org-export-get-parent paragraph info))
- (parent-type (org-element-type parent))
- (style (case parent-type
- (quote-block 'quote)
- (center-block 'center)
- (t nil))))
- (org-e-odt-format-stylized-paragraph style contents)))
-
-
-;;;; Plain List
-
-(defun org-e-odt-plain-list (plain-list contents info)
- "Transcode a PLAIN-LIST element from Org to HTML.
-CONTENTS is the contents of the list. INFO is a plist holding
-contextual information."
- (let* (arg1 ;; FIXME
- (type (org-element-property :type plain-list))
- (attr (mapconcat #'identity
- (org-element-property :attr_odt plain-list)
- " ")))
- (org-e-odt--wrap-label
- plain-list (format "%s\n%s%s"
- (org-e-odt-begin-plain-list type)
- contents (org-e-odt-end-plain-list type)))))
-
-;;;; Plain Text
-
-(defun org-e-odt-convert-special-strings (string)
- "Convert special characters in STRING to ODT."
- (let ((all org-export-e-odt-special-string-regexps)
- e a re rpl start)
- (while (setq a (pop all))
- (setq re (car a) rpl (cdr a) start 0)
- (while (string-match re string start)
- (setq string (replace-match rpl t nil string))))
- string))
-
-;; (defun org-e-odt-encode-plain-text (s)
-;; "Convert plain text characters to HTML equivalent.
-;; Possible conversions are set in `org-export-html-protect-char-alist'."
-;; (let ((cl org-e-odt-protect-char-alist) c)
-;; (while (setq c (pop cl))
-;; (let ((start 0))
-;; (while (string-match (car c) s start)
-;; (setq s (replace-match (cdr c) t t s)
-;; start (1+ (match-beginning 0))))))
-;; s))
-
-(defun org-e-odt-plain-text (text info)
- "Transcode a TEXT string from Org to HTML.
-TEXT is the string to transcode. INFO is a plist holding
-contextual information."
- (setq text (org-e-odt-encode-plain-text text t))
- ;; Protect %, #, &, $, ~, ^, _, { and }.
- ;; (while (string-match "\\([^\\]\\|^\\)\\([%$#&{}~^_]\\)" text)
- ;; (setq text
- ;; (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
- ;; Protect \
- ;; (setq text (replace-regexp-in-string
- ;; "\\(?:[^\\]\\|^\\)\\(\\\\\\)\\(?:[^%$#&{}~^_\\]\\|$\\)"
- ;; "$\\backslash$" text nil t 1))
- ;; HTML into \HTML{} and TeX into \TeX{}.
- ;; (let ((case-fold-search nil)
- ;; (start 0))
- ;; (while (string-match "\\<\\(\\(?:La\\)?TeX\\)\\>" text start)
- ;; (setq text (replace-match
- ;; (format "\\%s{}" (match-string 1 text)) nil t text)
- ;; start (match-end 0))))
- ;; Handle quotation marks
- ;; (setq text (org-e-odt--quotation-marks text info))
- ;; Convert special strings.
- ;; (when (plist-get info :with-special-strings)
- ;; (while (string-match (regexp-quote "...") text)
- ;; (setq text (replace-match "\\ldots{}" nil t text))))
- (when (plist-get info :with-special-strings)
- (setq text (org-e-odt-convert-special-strings text)))
- ;; Handle break preservation if required.
- (when (plist-get info :preserve-breaks)
- (setq text (replace-regexp-in-string "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
- text)))
- ;; Return value.
- text)
-
-
-;;;; Property Drawer
-
-(defun org-e-odt-property-drawer (property-drawer contents info)
- "Transcode a PROPERTY-DRAWER element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- ;; The property drawer isn't exported but we want separating blank
- ;; lines nonetheless.
- "")
-
-
-;;;; Quote Block
-
-(defun org-e-odt-quote-block (quote-block contents info)
- "Transcode a QUOTE-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (org-e-odt--wrap-label quote-block contents))
-
-
-;;;; Quote Section
-
-(defun org-e-odt-quote-section (quote-section contents info)
- "Transcode a QUOTE-SECTION element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((value (org-remove-indentation
- (org-element-property :value quote-section))))
- (when value (org-e-odt-format-source-code-or-example value nil))))
-
-
-;;;; Section
-
-(defun org-e-odt-section (section contents info) ; FIXME
- "Transcode a SECTION element from Org to HTML.
-CONTENTS holds the contents of the section. INFO is a plist
-holding contextual information."
- contents)
-
-;;;; Radio Target
-
-(defun org-e-odt-radio-target (radio-target text info)
- "Transcode a RADIO-TARGET object from Org to HTML.
-TEXT is the text of the target. INFO is a plist holding
-contextual information."
- (org-e-odt-format-anchor
- text (org-export-solidify-link-text
- (org-element-property :raw-value radio-target))))
-
-
-;;;; Special Block
-
-(defun org-e-odt-special-block (special-block contents info)
- "Transcode a SPECIAL-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the block. INFO is a plist
-holding contextual information."
- (let ((type (downcase (org-element-property :type special-block))))
- (org-e-odt--wrap-label
- special-block
- (format "\\begin{%s}\n%s\\end{%s}" type contents type))))
-
-
-;;;; Src Block
-
-(defun org-e-odt-src-block (src-block contents info)
- "Transcode a SRC-BLOCK element from Org to HTML.
-CONTENTS holds the contents of the item. INFO is a plist holding
-contextual information."
- (let* ((lang (org-element-property :language src-block))
- (caption (org-element-property :caption src-block))
- (label (org-element-property :name src-block)))
- ;; FIXME: Handle caption
-
- ;; caption-str (when caption)
- ;; (main (org-export-secondary-string (car caption) 'e-odt info))
- ;; (secondary (org-export-secondary-string (cdr caption) 'e-odt info))
- ;; (caption-str (org-e-odt--caption/label-string caption label info))
- (org-e-odt-format-code src-block info)))
-
-
-;;;; Statistics Cookie
-
-(defun org-e-odt-statistics-cookie (statistics-cookie contents info)
- "Transcode a STATISTICS-COOKIE object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((cookie-value (org-element-property :value statistics-cookie)))
- (org-e-odt-format-fontify cookie-value 'code)))
-
-
-;;;; Subscript
-
-(defun org-e-odt-subscript (subscript contents info)
- "Transcode a SUBSCRIPT object from Org to HTML.
-CONTENTS is the contents of the object. INFO is a plist holding
-contextual information."
- ;; (format (if (= (length contents) 1) "$_%s$" "$_{\\mathrm{%s}}$") contents)
- (org-e-odt-format-fontify contents 'subscript))
-
-
-;;;; Superscript
-
-(defun org-e-odt-superscript (superscript contents info)
- "Transcode a SUPERSCRIPT object from Org to HTML.
-CONTENTS is the contents of the object. INFO is a plist holding
-contextual information."
- ;; (format (if (= (length contents) 1) "$^%s$" "$^{\\mathrm{%s}}$") contents)
- (org-e-odt-format-fontify contents 'superscript))
-
-
-;;;; Table
-
-(defun org-e-odt-get-colwidth (c)
- (let ((col-widths (plist-get table-info :width)))
- (or (and org-lparse-table-is-styled (aref col-widths c)) 0)))
-
-(defun org-e-odt-table-row (fields &optional text-for-empty-fields)
- (incf org-e-odt-table-rownum)
- (let ((i -1))
- (org-e-odt-format-table-row
- (mapconcat
- (lambda (x)
- (when (and (string= x "") text-for-empty-fields)
- (setq x text-for-empty-fields))
- (incf i)
- (let ((horiz-span (org-e-odt-get-colwidth i)))
- (org-e-odt-format-table-cell
- x org-e-odt-table-rownum i horiz-span)))
- fields "\n"))))
-
-(defun org-e-odt-table-preamble ()
- (let ((colgroup-vector (plist-get table-info :column-groups)) ;; FIXME
- c gr colgropen preamble)
- (unless (aref colgroup-vector 0)
- (setf (aref colgroup-vector 0) 'start))
- (dotimes (c columns-number preamble)
- (setq gr (aref colgroup-vector c))
- (setq preamble
- (concat
- preamble
- (when (memq gr '(start start-end))
- (prog1 (if colgropen "</colgroup>\n<colgroup>" "\n<colgroup>")
- (setq colgropen t)))
- (let* ((colalign-vector (plist-get table-info :alignment)) ;; FIXME
- (align (cdr (assoc (aref colalign-vector c)
- '(("l" . "left")
- ("r" . "right")
- ("c" . "center")))))
- (alignspec (if (and (boundp 'org-e-odt-format-table-no-css)
- org-e-odt-format-table-no-css)
- " align=\"%s\"" " class=\"%s\""))
- (extra (format alignspec align)))
- (format "<col%s />" extra))
- (when (memq gr '(end start-end))
- (setq colgropen nil)
- "</colgroup>"))))
- (concat preamble (if colgropen "</colgroup>"))))
-
-(defun org-e-odt-list-table (lines caption label attributes)
- (setq lines (org-e-odt-org-table-to-list-table lines))
- (let* ((splice nil) head
- (org-e-odt-table-rownum -1)
- i (cnt 0)
- fields line
- org-e-odt-table-cur-rowgrp-is-hdr
- org-e-odt-table-rowgrp-open
- n
- (org-lparse-table-style 'org-table)
- org-lparse-table-is-styled)
- (cond
- (splice
- (setq org-lparse-table-is-styled nil)
- (mapconcat 'org-e-odt-table-row lines "\n"))
- (t
- (setq org-lparse-table-is-styled t)
-
- (concat
- (org-e-odt-begin-table caption label attributes)
- ;; FIXME (org-e-odt-table-preamble)
- (org-e-odt-begin-table-rowgroup head)
-
- (mapconcat
- (lambda (line)
- (cond
- ((equal line 'hline) (org-e-odt-begin-table-rowgroup))
- (t (org-e-odt-table-row line))))
- lines "\n")
-
- (org-e-odt-end-table-rowgroup)
- (org-e-odt-end-table))))))
-
-(defun org-e-odt-transcode-table-row (row)
- (if (string-match org-table-hline-regexp row) 'hline
- (mapcar
- (lambda (cell)
- (org-export-secondary-string
- (let ((cell (org-element-parse-secondary-string
- cell
- (cdr (assq 'table org-element-string-restrictions)))))
- cell)
- 'e-odt info))
- (org-split-string row "[ \t]*|[ \t]*"))))
-
-(defun org-e-odt-org-table-to-list-table (lines &optional splice)
- "Convert org-table to list-table.
-LINES is a list of the form (ROW1 ROW2 ROW3 ...) where each
-element is a `string' representing a single row of org-table.
-Thus each ROW has vertical separators \"|\" separating the table
-fields. A ROW could also be a row-group separator of the form
-\"|---...|\". Return a list of the form (ROW1 ROW2 ROW3
-...). ROW could either be symbol `'hline' or a list of the
-form (FIELD1 FIELD2 FIELD3 ...) as appropriate."
- (let (line lines-1)
- (cond
- (splice
- (while (setq line (pop lines))
- (unless (string-match "^[ \t]*|-" line)
- (push (org-e-odt-transcode-table-row line) lines-1))))
- (t (while (setq line (pop lines))
- (cond
- ((string-match "^[ \t]*|-" line)
- (when lines (push 'hline lines-1)))
- (t (push (org-e-odt-transcode-table-row line) lines-1))))))
- (nreverse lines-1)))
-
-(defun org-e-odt-table-table (raw-table)
- (require 'table)
- (with-current-buffer (get-buffer-create "*org-export-table*")
- (erase-buffer))
- (let ((output (with-temp-buffer
- (insert raw-table)
- (goto-char 1)
- (re-search-forward "^[ \t]*|[^|]" nil t)
- (table-generate-source 'html "*org-export-table*")
- (with-current-buffer "*org-export-table*"
- (org-trim (buffer-string))))))
- (kill-buffer (get-buffer "*org-export-table*"))
- output))
-
-(defun org-e-odt-table (table contents info)
- "Transcode a TABLE element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((label (org-element-property :name table))
- (caption (org-e-odt--caption/label-string
- (org-element-property :caption table) label info))
- (attr (mapconcat #'identity
- (org-element-property :attr_odt table)
- " "))
- (raw-table (org-element-property :raw-table table))
- (table-type (org-element-property :type table)))
- (case table-type
- (table.el
- ;; (org-e-odt-table-table raw-table)
- )
- (t
- (let* ((table-info (org-export-table-format-info raw-table))
- (columns-number (length (plist-get table-info :alignment)))
- (lines (org-split-string
- (org-export-clean-table
- raw-table (plist-get table-info :special-column-p)) "\n"))
-
- (genealogy (org-export-get-genealogy table info))
- (parent (car genealogy))
- (parent-type (org-element-type parent)))
- (org-e-odt-list-table lines caption label attr))))))
-
-
-;;;; Target
-
-(defun org-e-odt-target (target contents info)
- "Transcode a TARGET object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- (org-e-odt-format-anchor
- "" (org-export-solidify-link-text (org-element-property :value target))))
-
-
-;;;; Time-stamp
-
-(defun org-e-odt-time-stamp (time-stamp contents info)
- "Transcode a TIME-STAMP object from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual
-information."
- ;; (let ((value (org-element-property :value time-stamp))
- ;; (type (org-element-property :type time-stamp))
- ;; (appt-type (org-element-property :appt-type time-stamp)))
- ;; (concat (cond ((eq appt-type 'scheduled)
- ;; (format "\\textbf{\\textsc{%s}} " org-scheduled-string))
- ;; ((eq appt-type 'deadline)
- ;; (format "\\textbf{\\textsc{%s}} " org-deadline-string))
- ;; ((eq appt-type 'closed)
- ;; (format "\\textbf{\\textsc{%s}} " org-closed-string)))
- ;; (cond ((memq type '(active active-range))
- ;; (format org-e-odt-active-timestamp-format value))
- ;; ((memq type '(inactive inactive-range))
- ;; (format org-e-odt-inactive-timestamp-format value))
- ;; (t
- ;; (format org-e-odt-diary-timestamp-format value)))))
- (let ((value (org-element-property :value time-stamp))
- (type (org-element-property :type time-stamp))
- (appt-type (org-element-property :appt-type time-stamp)))
- (setq value (org-export-secondary-string value 'e-odt info))
- (org-e-odt-format-fontify
- (concat
- (org-e-odt-format-fontify
- (cond ((eq appt-type 'scheduled) org-scheduled-string)
- ((eq appt-type 'deadline) org-deadline-string)
- ((eq appt-type 'closed) org-closed-string)) "timestamp-kwd")
- ;; FIXME: (org-translate-time value)
- (org-e-odt-format-fontify value "timestamp"))
- "timestamp-wrapper")))
-
-
-;;;; Verbatim
-
-(defun org-e-odt-verbatim (verbatim contents info)
- "Transcode a VERBATIM object from Org to HTML.
-CONTENTS is nil. INFO is a plist used as a communication
-channel."
- (org-e-odt-emphasis
- verbatim (org-element-property :value verbatim) info))
-
-
-;;;; Verse Block
-
-(defun org-e-odt-verse-block (verse-block contents info)
- "Transcode a VERSE-BLOCK element from Org to HTML.
-CONTENTS is nil. INFO is a plist holding contextual information."
- ;; Replace each newline character with line break. Also replace
- ;; each blank line with a line break.
- (setq contents (replace-regexp-in-string
- "^ *\\\\\\\\$" "<br/>\n"
- (replace-regexp-in-string
- "\\(\\\\\\\\\\)?[ \t]*\n" " <br/>\n"
- (org-remove-indentation
- (org-export-secondary-string
- (org-element-property :value verse-block)
- 'e-odt info)))))
-
- ;; Replace each white space at beginning of a line with a
- ;; non-breaking space.
- (while (string-match "^[ \t]+" contents)
- (let ((new-str (org-e-odt-format-spaces
- (length (match-string 0 contents)))))
- (setq contents (replace-match new-str nil t contents))))
-
- (org-e-odt--wrap-label
- verse-block (format "<p class=\"verse\">\n%s</p>" contents)))
-
-
-\f
-
-;;; Filter Functions
-
-;;;; Filter Settings
-;;;; Filters
-
-;;; Interactive functions
-
-(defun org-e-odt-export-to-odt
- (&optional subtreep visible-only body-only ext-plist pub-dir)
- "Export current buffer to a HTML file.
-
-If narrowing is active in the current buffer, only export its
-narrowed part.
-
-If a region is active, export that region.
-
-When optional argument SUBTREEP is non-nil, export the sub-tree
-at point, extracting information from the headline properties
-first.
-
-When optional argument VISIBLE-ONLY is non-nil, don't export
-contents of hidden elements.
-
-When optional argument BODY-ONLY is non-nil, only write code
-between \"\\begin{document}\" and \"\\end{document}\".
-
-EXT-PLIST, when provided, is a property list with external
-parameters overriding Org default settings, but still inferior to
-file-local settings.
-
-When optional argument PUB-DIR is set, use it as the publishing
-directory.
-
-Return output file's name."
- (interactive)
-
- ;; FIXME
- (with-current-buffer (get-buffer-create "*debug*")
- (erase-buffer))
-
- ;; (let* ((outfile (org-export-output-file-name ".html" subtreep pub-dir))
- ;; (outfile "content.xml"))
- ;; (org-export-to-file
- ;; 'e-odt outfile subtreep visible-only body-only ext-plist))
-
- (let* ((outbuf (org-e-odt-init-outfile))
- (target (org-export-output-file-name ".odt" subtreep pub-dir))
- (outdir (file-name-directory (buffer-file-name outbuf)))
- (default-directory outdir))
-
- ;; FIXME: for copying embedded images
- (setq org-current-export-file
- (file-name-directory
- (org-export-output-file-name ".odt" subtreep nil)))
-
- (org-export-to-buffer
- 'e-odt outbuf
- (memq 'subtree optns) (memq 'visible optns) (memq 'body optns))
-
- (setq org-lparse-opt-plist nil) ; FIXME
- (org-e-odt-save-as-outfile target ;; info
- nil
- )
-
- ;; return outfile
- target))
-
-
-
-\f
-;;; FIXMES, TODOS, FOR REVIEW etc
-
-;;;; org-format-table-html
-;;;; org-format-org-table-html
-;;;; org-format-table-table-html
-;;;; org-table-number-fraction
-;;;; org-table-number-regexp
-;;;; org-e-odt-table-caption-above
-
-;;;; org-whitespace
-;;;; "<span style=\"visibility:hidden;\">%s</span>"
-;;;; Remove display properties
-;;;; org-e-odt-final-hook
-
-;;;; org-e-odt-with-timestamp
-;;;; org-e-odt-html-helper-timestamp
-
-;;;; org-export-as-html-and-open
-;;;; org-export-as-html-batch
-;;;; org-export-as-html-to-buffer
-;;;; org-replace-region-by-html
-;;;; org-export-region-as-html
-;;;; org-export-as-html
-
-;;;; (org-export-directory :html opt-plist)
-;;;; (plist-get opt-plist :html-extension)
-;;;; org-e-odt-toplevel-hlevel
-;;;; org-e-odt-special-string-regexps
-;;;; org-e-odt-coding-system
-;;;; org-e-odt-coding-system
-;;;; org-e-odt-inline-images
-;;;; org-e-odt-inline-image-extensions
-;;;; org-e-odt-protect-char-alist
-;;;; org-e-odt-table-use-header-tags-for-first-column
-;;;; org-e-odt-todo-kwd-class-prefix
-;;;; org-e-odt-tag-class-prefix
-;;;; org-e-odt-footnote-separator
-
-
-;;; Library Initializations
-
-(mapc
- (lambda (desc)
- ;; Let Org open all OpenDocument files using system-registered app
- (add-to-list 'org-file-apps
- (cons (concat "\\." (car desc) "\\'") 'system))
- ;; Let Emacs open all OpenDocument files in archive mode
- (add-to-list 'auto-mode-alist
- (cons (concat "\\." (car desc) "\\'") 'archive-mode)))
- org-e-odt-file-extensions)
-
-;; FIXME
-;; (eval-after-load 'org-exp
-;; '(add-to-list 'org-export-inbuffer-options-extra
-;; '("ODT_STYLES_FILE" :odt-styles-file)))
-
-(provide 'org-e-odt)
-
-;;; org-e-odt.el ends here
diff --git a/EXPERIMENTAL/org-e-publish.el b/EXPERIMENTAL/org-e-publish.el
deleted file mode 100644
index 92e58f9..0000000
--- a/EXPERIMENTAL/org-e-publish.el
+++ /dev/null
@@ -1,1211 +0,0 @@
-;;; org-e-publish.el --- publish related org-mode files as a website
-;; Copyright (C) 2006-2012 Free Software Foundation, Inc.
-
-;; Author: David O'Toole <dto@gnu.org>
-;; Maintainer: Carsten Dominik <carsten DOT dominik AT gmail DOT com>
-;; Keywords: hypermedia, outlines, wp
-
-;; This file is part of GNU Emacs.
-;;
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This program allow configurable publishing of related sets of
-;; Org mode files as a complete website.
-;;
-;; org-e-publish.el can do the following:
-;;
-;; + Publish all one's Org files to HTML or PDF
-;; + Upload HTML, images, attachments and other files to a web server
-;; + Exclude selected private pages from publishing
-;; + Publish a clickable sitemap of pages
-;; + Manage local timestamps for publishing only changed files
-;; + Accept plugin functions to extend range of publishable content
-;;
-;; Documentation for publishing is in the manual.
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-(require 'format-spec)
-
-(declare-function org-element-property "org-element" (property element))
-(declare-function org-element-map "org-element"
- (data types fun &optional info first-match))
-
-(declare-function org-export-output-file-name "org-export"
- (extension &optional subtreep pub-dir))
-(declare-function
- org-export-to-file "org-export"
- (backend file &optional subtreep visible-only body-only ext-plist))
-(declare-function org-export-get-parent-headline "org-export" (blob info))
-(declare-function org-export-get-environment "org-export"
- (&optional backend subtreep ext-plist))
-(declare-function org-export-get-inbuffer-options "org-export"
- (&optional backend files))
-
-
-\f
-;;; Variables
-(defvar org-e-publish-initial-buffer nil
- "The buffer `org-e-publish' has been called from.")
-
-(defvar org-e-publish-temp-files nil
- "Temporary list of files to be published.")
-
-;; Here, so you find the variable right before it's used the first time:
-(defvar org-e-publish-cache nil
- "This will cache timestamps and titles for files in publishing projects.
-Blocks could hash sha1 values here.")
-
-(defgroup org-e-publish nil
- "Options for publishing a set of Org-mode and related files."
- :tag "Org Publishing"
- :group 'org)
-
-(defcustom org-e-publish-project-alist nil
- "Association list to control publishing behavior.
-Each element of the alist is a publishing 'project.' The CAR of
-each element is a string, uniquely identifying the project. The
-CDR of each element is in one of the following forms:
-
-1. A well-formed property list with an even number of elements,
- alternating keys and values, specifying parameters for the
- publishing process.
-
- \(:property value :property value ... )
-
-2. A meta-project definition, specifying of a list of
- sub-projects:
-
- \(:components \(\"project-1\" \"project-2\" ...))
-
-When the CDR of an element of org-e-publish-project-alist is in
-this second form, the elements of the list after `:components'
-are taken to be components of the project, which group together
-files requiring different publishing options. When you publish
-such a project with \\[org-e-publish], the components all
-publish.
-
-When a property is given a value in
-`org-e-publish-project-alist', its setting overrides the value of
-the corresponding user variable \(if any) during publishing.
-However, options set within a file override everything.
-
-Most properties are optional, but some should always be set:
-
- `:base-directory'
-
- Directory containing publishing source files.
-
- `:base-extension'
-
- Extension \(without the dot!) of source files. This can be
- a regular expression. If not given, \"org\" will be used as
- default extension.
-
- `:publishing-directory'
-
- Directory \(possibly remote) where output files will be
- published.
-
-The `:exclude' property may be used to prevent certain files from
-being published. Its value may be a string or regexp matching
-file names you don't want to be published.
-
-The `:include' property may be used to include extra files. Its
-value may be a list of filenames to include. The filenames are
-considered relative to the base directory.
-
-When both `:include' and `:exclude' properties are given values,
-the exclusion step happens first.
-
-One special property controls which back-end function to use for
-publishing files in the project. This can be used to extend the
-set of file types publishable by `org-e-publish', as well as the
-set of output formats.
-
- `:publishing-function'
-
- Function to publish file. The default is
- `org-e-publish-org-to-ascii', but other values are possible.
- May also be a list of functions, in which case each function
- in the list is invoked in turn.
-
-Another property allows you to insert code that prepares
-a project for publishing. For example, you could call GNU Make
-on a certain makefile, to ensure published files are built up to
-date.
-
- `:preparation-function'
-
- Function to be called before publishing this project. This
- may also be a list of functions.
-
- `:completion-function'
-
- Function to be called after publishing this project. This
- may also be a list of functions.
-
-Some properties control details of the Org publishing process,
-and are equivalent to the corresponding user variables listed in
-the right column. Back-end specific properties may also be
-included. See the back-end documentation for more information.
-
- :author `user-full-name'
- :creator `org-export-creator-string'
- :email `user-mail-address'
- :exclude-tags `org-export-exclude-tags'
- :headline-levels `org-export-headline-levels'
- :language `org-export-default-language'
- :preserve-breaks `org-export-preserve-breaks'
- :section-numbers `org-export-with-section-numbers'
- :select-tags `org-export-select-tags'
- :time-stamp-file `org-export-time-stamp-file'
- :with-archived-trees `org-export-with-archived-trees'
- :with-author `org-export-with-author'
- :with-creator `org-export-with-creator'
- :with-drawers `org-export-with-drawers'
- :with-email `org-export-with-email'
- :with-emphasize `org-export-with-emphasize'
- :with-entities `org-export-with-entities'
- :with-fixed-width `org-export-with-fixed-width'
- :with-footnotes `org-export-with-footnotes'
- :with-priority `org-export-with-priority'
- :with-special-strings `org-export-with-special-strings'
- :with-sub-superscript `org-export-with-sub-superscripts'
- :with-toc `org-export-with-toc'
- :with-tables `org-export-with-tables'
- :with-tags `org-export-with-tags'
- :with-tasks `org-export-with-tasks'
- :with-timestamps `org-export-with-timestamps'
- :with-todo-keywords `org-export-with-todo-keywords'
-
-The following properties may be used to control publishing of
-a site-map of files or summary page for a given project.
-
- `:auto-sitemap'
-
- Whether to publish a site-map during
- `org-e-publish-current-project' or `org-e-publish-all'.
-
- `:sitemap-filename'
-
- Filename for output of sitemap. Defaults to \"sitemap.org\".
-
- `:sitemap-title'
-
- Title of site-map page. Defaults to name of file.
-
- `:sitemap-function'
-
- Plugin function to use for generation of site-map. Defaults to
- `org-e-publish-org-sitemap', which generates a plain list of
- links to all files in the project.
-
- `:sitemap-style'
-
- Can be `list' \(site-map is just an itemized list of the
- titles of the files involved) or `tree' \(the directory
- structure of the source files is reflected in the site-map).
- Defaults to `tree'.
-
- `:sitemap-sans-extension'
-
- Remove extension from site-map's file-names. Useful to have
- cool URIs \(see http://www.w3.org/Provider/Style/URI).
- Defaults to nil.
-
-If you create a site-map file, adjust the sorting like this:
-
- `:sitemap-sort-folders'
-
- Where folders should appear in the site-map. Set this to
- `first' \(default) or `last' to display folders first or
- last, respectively. Any other value will mix files and
- folders.
-
- `:sitemap-sort-files'
-
- The site map is normally sorted alphabetically. You can
- change this behaviour setting this to `anti-chronologically',
- `chronologically', or nil.
-
- `:sitemap-ignore-case'
-
- Should sorting be case-sensitive? Default nil.
-
-The following properties control the creation of a concept index.
-
- `:makeindex'
-
- Create a concept index.
-
-Other properties affecting publication.
-
- `:body-only'
-
- Set this to t to publish only the body of the documents."
- :group 'org-e-publish
- :type 'alist)
-
-(defcustom org-e-publish-use-timestamps-flag t
- "Non-nil means use timestamp checking to publish only changed files.
-When nil, do no timestamp checking and always publish all files."
- :group 'org-e-publish
- :type 'boolean)
-
-(defcustom org-e-publish-timestamp-directory
- (convert-standard-filename "~/.org-timestamps/")
- "Name of directory in which to store publishing timestamps."
- :group 'org-e-publish
- :type 'directory)
-
-(defcustom org-e-publish-list-skipped-files t
- "Non-nil means show message about files *not* published."
- :group 'org-e-publish
- :type 'boolean)
-
-(defcustom org-e-publish-sitemap-sort-files 'alphabetically
- "Method to sort files in site-maps.
-Possible values are `alphabetically', `chronologically',
-`anti-chronologically' and nil.
-
-If `alphabetically', files will be sorted alphabetically. If
-`chronologically', files will be sorted with older modification
-time first. If `anti-chronologically', files will be sorted with
-newer modification time first. nil won't sort files.
-
-You can overwrite this default per project in your
-`org-e-publish-project-alist', using `:sitemap-sort-files'."
- :group 'org-e-publish
- :type 'symbol)
-
-(defcustom org-e-publish-sitemap-sort-folders 'first
- "A symbol, denoting if folders are sorted first in sitemaps.
-Possible values are `first', `last', and nil.
-If `first', folders will be sorted before files.
-If `last', folders are sorted to the end after the files.
-Any other value will not mix files and folders.
-
-You can overwrite this default per project in your
-`org-e-publish-project-alist', using `:sitemap-sort-folders'."
- :group 'org-e-publish
- :type 'symbol)
-
-(defcustom org-e-publish-sitemap-sort-ignore-case nil
- "Non-nil when site-map sorting should ignore case.
-
-You can overwrite this default per project in your
-`org-e-publish-project-alist', using `:sitemap-ignore-case'."
- :group 'org-e-publish
- :type 'boolean)
-
-(defcustom org-e-publish-sitemap-date-format "%Y-%m-%d"
- "Format for `format-time-string' which is used to print a date
-in the sitemap."
- :group 'org-e-publish
- :type 'string)
-
-(defcustom org-e-publish-sitemap-file-entry-format "%t"
- "Format string for site-map file entry.
-You could use brackets to delimit on what part the link will be.
-
-%t is the title.
-%a is the author.
-%d is the date formatted using `org-e-publish-sitemap-date-format'."
- :group 'org-e-publish
- :type 'string)
-
-
-\f
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Timestamp-related functions
-
-(defun org-e-publish-timestamp-filename (filename &optional pub-dir pub-func)
- "Return path to timestamp file for filename FILENAME."
- (setq filename (concat filename "::" (or pub-dir "") "::"
- (format "%s" (or pub-func ""))))
- (concat "X" (if (fboundp 'sha1) (sha1 filename) (md5 filename))))
-
-(defun org-e-publish-needed-p (filename &optional pub-dir pub-func true-pub-dir)
- "Return t if FILENAME should be published in PUB-DIR using PUB-FUNC.
-TRUE-PUB-DIR is where the file will truly end up. Currently we
-are not using this - maybe it can eventually be used to check if
-the file is present at the target location, and how old it is.
-Right now we cannot do this, because we do not know under what
-file name the file will be stored - the publishing function can
-still decide about that independently."
- (let ((rtn (if (not org-e-publish-use-timestamps-flag) t
- (org-e-publish-cache-file-needs-publishing
- filename pub-dir pub-func))))
- (if rtn (message "Publishing file %s using `%s'" filename pub-func)
- (when org-e-publish-list-skipped-files
- (message "Skipping unmodified file %s" filename)))
- rtn))
-
-(defun org-e-publish-update-timestamp (filename &optional pub-dir pub-func)
- "Update publishing timestamp for file FILENAME.
-If there is no timestamp, create one."
- (let ((key (org-e-publish-timestamp-filename filename pub-dir pub-func))
- (stamp (org-e-publish-cache-ctime-of-src filename)))
- (org-e-publish-cache-set key stamp)))
-
-(defun org-e-publish-remove-all-timestamps ()
- "Remove all files in the timestamp directory."
- (let ((dir org-e-publish-timestamp-directory)
- files)
- (when (and (file-exists-p dir) (file-directory-p dir))
- (mapc 'delete-file (directory-files dir 'full "[^.]\\'"))
- (org-e-publish-reset-cache))))
-
-
-\f
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Getting project information out of `org-e-publish-project-alist'
-
-(defun org-e-publish-expand-projects (projects-alist)
- "Expand projects in PROJECTS-ALIST.
-This splices all the components into the list."
- (let ((rest projects-alist) rtn p components)
- (while (setq p (pop rest))
- (if (setq components (plist-get (cdr p) :components))
- (setq rest (append
- (mapcar (lambda (x) (assoc x org-e-publish-project-alist))
- components)
- rest))
- (push p rtn)))
- (nreverse (delete-dups (delq nil rtn)))))
-
-(defvar org-sitemap-sort-files)
-(defvar org-sitemap-sort-folders)
-(defvar org-sitemap-ignore-case)
-(defvar org-sitemap-requested)
-(defvar org-sitemap-date-format)
-(defvar org-sitemap-file-entry-format)
-(defun org-e-publish-compare-directory-files (a b)
- "Predicate for `sort', that sorts folders and files for sitemap."
- (let ((retval t))
- (when (or org-sitemap-sort-files org-sitemap-sort-folders)
- ;; First we sort files:
- (when org-sitemap-sort-files
- (case org-sitemap-sort-files
- (alphabetically
- (let* ((adir (file-directory-p a))
- (aorg (and (string-match "\\.org$" a) (not adir)))
- (bdir (file-directory-p b))
- (borg (and (string-match "\\.org$" b) (not bdir)))
- (A (if aorg (concat (file-name-directory a)
- (org-e-publish-find-title a)) a))
- (B (if borg (concat (file-name-directory b)
- (org-e-publish-find-title b)) b)))
- (setq retval (if org-sitemap-ignore-case
- (not (string-lessp (upcase B) (upcase A)))
- (not (string-lessp B A))))))
- ((anti-chronologically chronologically)
- (let* ((adate (org-e-publish-find-date a))
- (bdate (org-e-publish-find-date b))
- (A (+ (lsh (car adate) 16) (cadr adate)))
- (B (+ (lsh (car bdate) 16) (cadr bdate))))
- (setq retval
- (if (eq org-sitemap-sort-files 'chronologically) (<= A B)
- (>= A B)))))))
- ;; Directory-wise wins:
- (when org-sitemap-sort-folders
- ;; a is directory, b not:
- (cond
- ((and (file-directory-p a) (not (file-directory-p b)))
- (setq retval (equal org-sitemap-sort-folders 'first)))
- ;; a is not a directory, but b is:
- ((and (not (file-directory-p a)) (file-directory-p b))
- (setq retval (equal org-sitemap-sort-folders 'last))))))
- retval))
-
-(defun org-e-publish-get-base-files-1
- (base-dir &optional recurse match skip-file skip-dir)
- "Set `org-e-publish-temp-files' with files from BASE-DIR directory.
-If RECURSE is non-nil, check BASE-DIR recursively. If MATCH is
-non-nil, restrict this list to the files matching the regexp
-MATCH. If SKIP-FILE is non-nil, skip file matching the regexp
-SKIP-FILE. If SKIP-DIR is non-nil, don't check directories
-matching the regexp SKIP-DIR when recursing through BASE-DIR."
- (mapc (lambda (f)
- (let ((fd-p (file-directory-p f))
- (fnd (file-name-nondirectory f)))
- (if (and fd-p recurse
- (not (string-match "^\\.+$" fnd))
- (if skip-dir (not (string-match skip-dir fnd)) t))
- (org-e-publish-get-base-files-1
- f recurse match skip-file skip-dir)
- (unless (or fd-p ;; this is a directory
- (and skip-file (string-match skip-file fnd))
- (not (file-exists-p (file-truename f)))
- (not (string-match match fnd)))
-
- (pushnew f org-e-publish-temp-files)))))
- (if org-sitemap-requested
- (sort (directory-files base-dir t (unless recurse match))
- 'org-e-publish-compare-directory-files)
- (directory-files base-dir t (unless recurse match)))))
-
-(defun org-e-publish-get-base-files (project &optional exclude-regexp)
- "Return a list of all files in PROJECT.
-If EXCLUDE-REGEXP is set, this will be used to filter out
-matching filenames."
- (let* ((project-plist (cdr project))
- (base-dir (file-name-as-directory
- (plist-get project-plist :base-directory)))
- (include-list (plist-get project-plist :include))
- (recurse (plist-get project-plist :recursive))
- (extension (or (plist-get project-plist :base-extension) "org"))
- ;; sitemap-... variables are dynamically scoped for
- ;; org-e-publish-compare-directory-files:
- (org-sitemap-requested
- (plist-get project-plist :auto-sitemap))
- (sitemap-filename
- (or (plist-get project-plist :sitemap-filename) "sitemap.org"))
- (org-sitemap-sort-folders
- (if (plist-member project-plist :sitemap-sort-folders)
- (plist-get project-plist :sitemap-sort-folders)
- org-e-publish-sitemap-sort-folders))
- (org-sitemap-sort-files
- (cond ((plist-member project-plist :sitemap-sort-files)
- (plist-get project-plist :sitemap-sort-files))
- ;; For backward compatibility:
- ((plist-member project-plist :sitemap-alphabetically)
- (if (plist-get project-plist :sitemap-alphabetically)
- 'alphabetically nil))
- (t org-e-publish-sitemap-sort-files)))
- (org-sitemap-ignore-case
- (if (plist-member project-plist :sitemap-ignore-case)
- (plist-get project-plist :sitemap-ignore-case)
- org-e-publish-sitemap-sort-ignore-case))
- (match (if (eq extension 'any) "^[^\\.]"
- (concat "^[^\\.].*\\.\\(" extension "\\)$"))))
- ;; Make sure `org-sitemap-sort-folders' has an accepted value
- (unless (memq org-sitemap-sort-folders '(first last))
- (setq org-sitemap-sort-folders nil))
-
- (setq org-e-publish-temp-files nil)
- (if org-sitemap-requested
- (pushnew (expand-file-name (concat base-dir sitemap-filename))
- org-e-publish-temp-files))
- (org-e-publish-get-base-files-1 base-dir recurse match
- ;; FIXME distinguish exclude regexp
- ;; for skip-file and skip-dir?
- exclude-regexp exclude-regexp)
- (mapc (lambda (f)
- (pushnew
- (expand-file-name (concat base-dir f))
- org-e-publish-temp-files))
- include-list)
- org-e-publish-temp-files))
-
-(defun org-e-publish-get-project-from-filename (filename &optional up)
- "Return the project that FILENAME belongs to."
- (let* ((filename (expand-file-name filename))
- project-name)
-
- (catch 'p-found
- (dolist (prj org-e-publish-project-alist)
- (unless (plist-get (cdr prj) :components)
- ;; [[info:org:Selecting%20files]] shows how this is supposed to work:
- (let* ((r (plist-get (cdr prj) :recursive))
- (b (expand-file-name (file-name-as-directory
- (plist-get (cdr prj) :base-directory))))
- (x (or (plist-get (cdr prj) :base-extension) "org"))
- (e (plist-get (cdr prj) :exclude))
- (i (plist-get (cdr prj) :include))
- (xm (concat "^" b (if r ".+" "[^/]+") "\\.\\(" x "\\)$")))
- (when
- (or (and i
- (member filename
- (mapcar (lambda (file)
- (expand-file-name file b))
- i)))
- (and (not (and e (string-match e filename)))
- (string-match xm filename)))
- (setq project-name (car prj))
- (throw 'p-found project-name))))))
- (when up
- (dolist (prj org-e-publish-project-alist)
- (if (member project-name (plist-get (cdr prj) :components))
- (setq project-name (car prj)))))
- (assoc project-name org-e-publish-project-alist)))
-
-
-\f
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Pluggable publishing back-end functions
-
-(defun org-e-publish-org-to (backend filename extension plist pub-dir)
- "Publish an Org file to a specified back-end.
-
-BACKEND is a symbol representing the back-end used for
-transcoding. FILENAME is the filename of the Org file to be
-published. EXTENSION is the extension used for the output
-string, with the leading dot. PLIST is the property list for the
-given project. PUB-DIR is the publishing directory.
-
-Return output file name."
- (unless (file-exists-p pub-dir) (make-directory pub-dir t))
- ;; Check if a buffer visiting FILENAME is already open.
- (let* ((visitingp (find-buffer-visiting filename))
- (work-buffer (or visitingp (find-file-noselect filename))))
- (prog1 (with-current-buffer work-buffer
- (let ((output-file
- (org-export-output-file-name extension nil pub-dir))
- (body-p (plist-get plist :body-only)))
- (org-export-to-file
- backend output-file nil nil body-p
- ;; Install `org-e-publish-collect-index' in parse tree
- ;; filters. It isn't dependent on `:makeindex', since
- ;; we want to keep it up-to-date in cache anyway.
- (org-combine-plists
- plist `(:filter-parse-tree
- (org-e-publish-collect-index
- ,@(plist-get plist :filter-parse-tree)))))))
- ;; Remove opened buffer in the process.
- (unless visitingp (kill-buffer work-buffer)))))
-
-(defvar project-plist)
-(defun org-e-publish-org-to-latex (plist filename pub-dir)
- "Publish an Org file to LaTeX.
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (org-e-publish-org-to 'e-latex filename ".tex" plist pub-dir))
-
-(defun org-e-publish-org-to-pdf (plist filename pub-dir)
- "Publish an Org file to PDF \(via LaTeX).
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (org-e-latex-compile
- (org-e-publish-org-to 'e-latex filename ".tex" plist pub-dir)))
-
-(defun org-e-publish-org-to-html (plist filename pub-dir)
- "Publish an org file to HTML.
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (org-e-publish-org-to 'e-html filename "html" plist pub-dir))
-
-;; TODO: Not implemented yet.
-;; (defun org-e-publish-org-to-org (plist filename pub-dir)
-;; "Publish an org file to HTML.
-;;
-;; FILENAME is the filename of the Org file to be published. PLIST
-;; is the property list for the given project. PUB-DIR is the
-;; publishing directory.
-;;
-;; Return output file name."
-;; (org-e-publish-org-to "org" plist filename pub-dir))
-
-(defun org-e-publish-org-to-ascii (plist filename pub-dir)
- "Publish an Org file to ASCII.
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (org-e-publish-org-to
- 'e-ascii filename ".txt" `(:ascii-charset ascii ,@plist) pub-dir))
-
-(defun org-e-publish-org-to-latin1 (plist filename pub-dir)
- "Publish an Org file to Latin-1.
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (org-e-publish-org-to
- 'e-ascii filename ".txt" `(:ascii-charset latin1 ,@plist) pub-dir))
-
-(defun org-e-publish-org-to-utf8 (plist filename pub-dir)
- "Publish an org file to UTF-8.
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (org-e-publish-org-to
- 'e-ascii filename ".txt" `(:ascii-charset utf-8 ,@plist) pub-dir))
-
-(defun org-e-publish-attachment (plist filename pub-dir)
- "Publish a file with no transformation of any kind.
-
-FILENAME is the filename of the Org file to be published. PLIST
-is the property list for the given project. PUB-DIR is the
-publishing directory.
-
-Return output file name."
- (unless (file-directory-p pub-dir)
- (make-directory pub-dir t))
- (or (equal (expand-file-name (file-name-directory filename))
- (file-name-as-directory (expand-file-name pub-dir)))
- (copy-file filename
- (expand-file-name (file-name-nondirectory filename) pub-dir)
- t)))
-
-
-\f
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Publishing files, sets of files, and indices
-
-(defun org-e-publish-file (filename &optional project no-cache)
- "Publish file FILENAME from PROJECT.
-If NO-CACHE is not nil, do not initialize org-e-publish-cache and
-write it to disk. This is needed, since this function is used to
-publish single files, when entire projects are published.
-See `org-e-publish-projects'."
- (let* ((project
- (or project
- (or (org-e-publish-get-project-from-filename filename)
- (error "File %s not part of any known project"
- (abbreviate-file-name filename)))))
- (project-plist (cdr project))
- (ftname (expand-file-name filename))
- (publishing-function
- (or (plist-get project-plist :publishing-function)
- 'org-e-publish-org-to-ascii))
- (base-dir
- (file-name-as-directory
- (expand-file-name
- (or (plist-get project-plist :base-directory)
- (error "Project %s does not have :base-directory defined"
- (car project))))))
- (pub-dir
- (file-name-as-directory
- (file-truename
- (or (eval (plist-get project-plist :publishing-directory))
- (error "Project %s does not have :publishing-directory defined"
- (car project))))))
- tmp-pub-dir)
-
- (unless no-cache (org-e-publish-initialize-cache (car project)))
-
- (setq tmp-pub-dir
- (file-name-directory
- (concat pub-dir
- (and (string-match (regexp-quote base-dir) ftname)
- (substring ftname (match-end 0))))))
- (if (listp publishing-function)
- ;; allow chain of publishing functions
- (mapc (lambda (f)
- (when (org-e-publish-needed-p filename pub-dir f tmp-pub-dir)
- (funcall f project-plist filename tmp-pub-dir)
- (org-e-publish-update-timestamp filename pub-dir f)))
- publishing-function)
- (when (org-e-publish-needed-p filename pub-dir publishing-function
- tmp-pub-dir)
- (funcall publishing-function project-plist filename tmp-pub-dir)
- (org-e-publish-update-timestamp
- filename pub-dir publishing-function)))
- (unless no-cache (org-e-publish-write-cache-file))))
-
-(defun org-e-publish-projects (projects)
- "Publish all files belonging to the PROJECTS alist.
-If `:auto-sitemap' is set, publish the sitemap too. If
-`:makeindex' is set, also produce a file theindex.org."
- (mapc
- (lambda (project)
- ;; Each project uses its own cache file:
- (org-e-publish-initialize-cache (car project))
- (let* ((project-plist (cdr project))
- (exclude-regexp (plist-get project-plist :exclude))
- (sitemap-p (plist-get project-plist :auto-sitemap))
- (sitemap-filename (or (plist-get project-plist :sitemap-filename)
- "sitemap.org"))
- (sitemap-function (or (plist-get project-plist :sitemap-function)
- 'org-e-publish-org-sitemap))
- (org-sitemap-date-format
- (or (plist-get project-plist :sitemap-date-format)
- org-e-publish-sitemap-date-format))
- (org-sitemap-file-entry-format
- (or (plist-get project-plist :sitemap-file-entry-format)
- org-e-publish-sitemap-file-entry-format))
- (preparation-function
- (plist-get project-plist :preparation-function))
- (completion-function (plist-get project-plist :completion-function))
- (files (org-e-publish-get-base-files project exclude-regexp)) file)
- (when preparation-function (run-hooks 'preparation-function))
- (if sitemap-p (funcall sitemap-function project sitemap-filename))
- (dolist (file files) (org-e-publish-file file project t))
- (when (plist-get project-plist :makeindex)
- (org-e-publish-index-generate-theindex
- project (plist-get project-plist :base-directory))
- (org-e-publish-file
- (expand-file-name
- "theindex.org" (plist-get project-plist :base-directory))
- project t))
- (when completion-function (run-hooks 'completion-function))
- (org-e-publish-write-cache-file)))
- (org-e-publish-expand-projects projects)))
-
-(defun org-e-publish-org-sitemap (project &optional sitemap-filename)
- "Create a sitemap of pages in set defined by PROJECT.
-Optionally set the filename of the sitemap with SITEMAP-FILENAME.
-Default for SITEMAP-FILENAME is 'sitemap.org'."
- (let* ((project-plist (cdr project))
- (dir (file-name-as-directory
- (plist-get project-plist :base-directory)))
- (localdir (file-name-directory dir))
- (indent-str (make-string 2 ?\ ))
- (exclude-regexp (plist-get project-plist :exclude))
- (files (nreverse
- (org-e-publish-get-base-files project exclude-regexp)))
- (sitemap-filename (concat dir (or sitemap-filename "sitemap.org")))
- (sitemap-title (or (plist-get project-plist :sitemap-title)
- (concat "Sitemap for project " (car project))))
- (sitemap-style (or (plist-get project-plist :sitemap-style)
- 'tree))
- (sitemap-sans-extension
- (plist-get project-plist :sitemap-sans-extension))
- (visiting (find-buffer-visiting sitemap-filename))
- (ifn (file-name-nondirectory sitemap-filename))
- file sitemap-buffer)
- (with-current-buffer (setq sitemap-buffer
- (or visiting (find-file sitemap-filename)))
- (erase-buffer)
- (insert (concat "#+TITLE: " sitemap-title "\n\n"))
- (while (setq file (pop files))
- (let ((fn (file-name-nondirectory file))
- (link (file-relative-name file dir))
- (oldlocal localdir))
- (when sitemap-sans-extension
- (setq link (file-name-sans-extension link)))
- ;; sitemap shouldn't list itself
- (unless (equal (file-truename sitemap-filename)
- (file-truename file))
- (if (eq sitemap-style 'list)
- (message "Generating list-style sitemap for %s" sitemap-title)
- (message "Generating tree-style sitemap for %s" sitemap-title)
- (setq localdir (concat (file-name-as-directory dir)
- (file-name-directory link)))
- (unless (string= localdir oldlocal)
- (if (string= localdir dir)
- (setq indent-str (make-string 2 ?\ ))
- (let ((subdirs
- (split-string
- (directory-file-name
- (file-name-directory
- (file-relative-name localdir dir))) "/"))
- (subdir "")
- (old-subdirs (split-string
- (file-relative-name oldlocal dir) "/")))
- (setq indent-str (make-string 2 ?\ ))
- (while (string= (car old-subdirs) (car subdirs))
- (setq indent-str (concat indent-str (make-string 2 ?\ )))
- (pop old-subdirs)
- (pop subdirs))
- (dolist (d subdirs)
- (setq subdir (concat subdir d "/"))
- (insert (concat indent-str " + " d "\n"))
- (setq indent-str (make-string
- (+ (length indent-str) 2) ?\ )))))))
- ;; This is common to 'flat and 'tree
- (let ((entry
- (org-e-publish-format-file-entry
- org-sitemap-file-entry-format file project-plist))
- (regexp "\\(.*\\)\\[\\([^][]+\\)\\]\\(.*\\)"))
- (cond ((string-match-p regexp entry)
- (string-match regexp entry)
- (insert (concat indent-str " + " (match-string 1 entry)
- "[[file:" link "]["
- (match-string 2 entry)
- "]]" (match-string 3 entry) "\n")))
- (t
- (insert (concat indent-str " + [[file:" link "]["
- entry
- "]]\n"))))))))
- (save-buffer))
- (or visiting (kill-buffer sitemap-buffer))))
-
-(defun org-e-publish-format-file-entry (fmt file project-plist)
- (format-spec fmt
- `((?t . ,(org-e-publish-find-title file t))
- (?d . ,(format-time-string org-sitemap-date-format
- (org-e-publish-find-date file)))
- (?a . ,(or (plist-get project-plist :author) user-full-name)))))
-
-(defun org-e-publish-find-title (file &optional reset)
- "Find the title of FILE in project."
- (or
- (and (not reset) (org-e-publish-cache-get-file-property file :title nil t))
- (let* ((visiting (find-buffer-visiting file))
- (buffer (or visiting (find-file-noselect file)))
- title)
- (with-current-buffer buffer
- (org-mode)
- (setq title
- (or (plist-get (org-export-get-environment) :title)
- (file-name-nondirectory (file-name-sans-extension file)))))
- (unless visiting (kill-buffer buffer))
- (org-e-publish-cache-set-file-property file :title title)
- title)))
-
-(defun org-e-publish-find-date (file)
- "Find the date of FILE in project.
-If FILE provides a #+date keyword use it else use the file
-system's modification time.
-
-It returns time in `current-time' format."
- (let* ((visiting (find-buffer-visiting file))
- (file-buf (or visiting (find-file-noselect file nil)))
- (date (plist-get
- (with-current-buffer file-buf
- (org-mode)
- (org-export-get-inbuffer-options))
- :date)))
- (unless visiting (kill-buffer file-buf))
- (if date (org-time-string-to-time date)
- (when (file-exists-p file)
- (nth 5 (file-attributes file))))))
-
-
-\f
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Interactive publishing functions
-
-;;;###autoload
-(defalias 'org-e-publish-project 'org-e-publish)
-
-;;;###autoload
-(defun org-e-publish (project &optional force)
- "Publish PROJECT."
- (interactive
- (list
- (assoc (org-icompleting-read
- "Publish project: "
- org-e-publish-project-alist nil t)
- org-e-publish-project-alist)
- current-prefix-arg))
- (setq org-e-publish-initial-buffer (current-buffer))
- (save-window-excursion
- (let* ((org-e-publish-use-timestamps-flag
- (if force nil org-e-publish-use-timestamps-flag)))
- (org-e-publish-projects
- (if (stringp project)
- ;; If this function is called in batch mode, project is
- ;; still a string here.
- (list (assoc project org-e-publish-project-alist))
- (list project))))))
-
-;;;###autoload
-(defun org-e-publish-all (&optional force)
- "Publish all projects.
-With prefix argument, remove all files in the timestamp
-directory and force publishing all files."
- (interactive "P")
- (when force (org-e-publish-remove-all-timestamps))
- (save-window-excursion
- (let ((org-e-publish-use-timestamps-flag
- (if force nil org-e-publish-use-timestamps-flag)))
- (org-e-publish-projects org-e-publish-project-alist))))
-
-
-;;;###autoload
-(defun org-e-publish-current-file (&optional force)
- "Publish the current file.
-With prefix argument, force publish the file."
- (interactive "P")
- (save-window-excursion
- (let ((org-e-publish-use-timestamps-flag
- (if force nil org-e-publish-use-timestamps-flag)))
- (org-e-publish-file (buffer-file-name (buffer-base-buffer))))))
-
-;;;###autoload
-(defun org-e-publish-current-project (&optional force)
- "Publish the project associated with the current file.
-With a prefix argument, force publishing of all files in
-the project."
- (interactive "P")
- (save-window-excursion
- (let ((project (org-e-publish-get-project-from-filename
- (buffer-file-name (buffer-base-buffer)) 'up))
- (org-e-publish-use-timestamps-flag
- (if force nil org-e-publish-use-timestamps-flag)))
- (if project (org-e-publish project)
- (error "File %s is not part of any known project"
- (buffer-file-name (buffer-base-buffer)))))))
-
-
-\f
-;;; Index generation
-
-(defun org-e-publish-collect-index (tree backend info)
- "Update index for a file with TREE in cache.
-
-BACKEND is the back-end being used for transcoding. INFO is
-a plist containing publishing options.
-
-The index relative to current file is stored as an alist. An
-association has the following shape: \(TERM FILE-NAME PARENT),
-where TERM is the indexed term, as a string, FILE-NAME is the
-original full path of the file where the term in encountered, and
-PARENT is the headline element containing the original index
-keyword."
- (org-e-publish-cache-set-file-property
- (plist-get info :input-file) :index
- (delete-dups
- (org-element-map
- tree 'keyword
- (lambda (k)
- (when (string= (downcase (org-element-property :key k))
- "index")
- (let ((index (org-element-property :value k))
- (parent (org-export-get-parent-headline k info)))
- (list index (plist-get info :input-file) parent))))
- info)))
- ;; Return parse-tree to avoid altering output.
- tree)
-
-(defun org-e-publish-index-generate-theindex (project directory)
- "Retrieve full index from cache and build \"theindex.org\".
-PROJECT is the project the index relates to. DIRECTORY is the
-publishing directory."
- (let ((all-files (org-e-publish-get-base-files
- project (plist-get (cdr project) :exclude)))
- full-index)
- ;; Compile full index.
- (mapc
- (lambda (file)
- (let ((index (org-e-publish-cache-get-file-property file :index)))
- (dolist (term index)
- (unless (member term full-index) (push term full-index)))))
- all-files)
- ;; Sort it alphabetically.
- (setq full-index
- (sort full-index (lambda (a b) (string< (downcase (car a))
- (downcase (car b))))))
- ;; Fill "theindex.org".
- (with-temp-buffer
- (insert "#+TITLE: Index\n#+OPTIONS: num:nil author:nil\n")
- (let ((current-letter nil) (last-entry nil))
- (dolist (idx full-index)
- (let* ((entry (org-split-string (car idx) "!"))
- (letter (upcase (substring (car entry) 0 1)))
- ;; Transform file into a path relative to publishing
- ;; directory.
- (file (file-relative-name
- (nth 1 idx)
- (plist-get (cdr project) :base-directory))))
- ;; Check if another letter has to be inserted.
- (unless (string= letter current-letter)
- (insert (format "* %s\n" letter)))
- ;; Compute the first difference between last entry and
- ;; current one: it tells the level at which new items
- ;; should be added.
- (let* ((rank (loop for n from 0 to (length entry)
- unless (equal (nth n entry) (nth n last-entry))
- return n))
- (len (length (nthcdr rank entry))))
- ;; For each term after the first difference, create
- ;; a new sub-list with the term as body. Moreover,
- ;; linkify the last term.
- (dotimes (n len)
- (insert
- (concat
- (make-string (* (+ rank n) 2) ? ) " - "
- (if (not (= (1- len) n)) (nth (+ rank n) entry)
- ;; Last term: Link it to TARGET, if possible.
- (let ((target (nth 2 idx)))
- (format
- "[[%s][%s]]"
- ;; Destination.
- (cond
- ((not target) (format "file:%s" file))
- ((let ((id (org-element-property :id target)))
- (and id (format "id:%s" id))))
- ((let ((id (org-element-property :custom-id target)))
- (and id (format "file:%s::#%s" file id))))
- (t (format "file:%s::*%s" file
- (org-element-property :raw-value target))))
- ;; Description.
- (car (last entry)))))
- "\n"))))
- (setq current-letter letter last-entry entry))))
- ;; Write index.
- (write-file (expand-file-name "theindex.org" directory)))))
-
-
-\f
-;;; Caching functions
-
-(defun org-e-publish-write-cache-file (&optional free-cache)
- "Write `org-e-publish-cache' to file.
-If FREE-CACHE, empty the cache."
- (unless org-e-publish-cache
- (error "`org-e-publish-write-cache-file' called, but no cache present"))
-
- (let ((cache-file (org-e-publish-cache-get ":cache-file:")))
- (unless cache-file
- (error "Cannot find cache-file name in `org-e-publish-write-cache-file'"))
- (with-temp-file cache-file
- (let (print-level print-length)
- (insert "(setq org-e-publish-cache (make-hash-table :test 'equal :weakness nil :size 100))\n")
- (maphash (lambda (k v)
- (insert
- (format (concat "(puthash %S "
- (if (or (listp v) (symbolp v))
- "'" "")
- "%S org-e-publish-cache)\n") k v)))
- org-e-publish-cache)))
- (when free-cache (org-e-publish-reset-cache))))
-
-(defun org-e-publish-initialize-cache (project-name)
- "Initialize the projects cache if not initialized yet and return it."
-
- (unless project-name
- (error "%s%s" "Cannot initialize `org-e-publish-cache' without projects name"
- " in `org-e-publish-initialize-cache'"))
-
- (unless (file-exists-p org-e-publish-timestamp-directory)
- (make-directory org-e-publish-timestamp-directory t))
- (unless (file-directory-p org-e-publish-timestamp-directory)
- (error "Org publish timestamp: %s is not a directory"
- org-e-publish-timestamp-directory))
-
- (unless (and org-e-publish-cache
- (string= (org-e-publish-cache-get ":project:") project-name))
- (let* ((cache-file
- (concat
- (expand-file-name org-e-publish-timestamp-directory)
- project-name ".cache"))
- (cexists (file-exists-p cache-file)))
-
- (when org-e-publish-cache (org-e-publish-reset-cache))
-
- (if cexists (load-file cache-file)
- (setq org-e-publish-cache
- (make-hash-table :test 'equal :weakness nil :size 100))
- (org-e-publish-cache-set ":project:" project-name)
- (org-e-publish-cache-set ":cache-file:" cache-file))
- (unless cexists (org-e-publish-write-cache-file nil))))
- org-e-publish-cache)
-
-(defun org-e-publish-reset-cache ()
- "Empty org-e-publish-cache and reset it nil."
- (message "%s" "Resetting org-e-publish-cache")
- (when (hash-table-p org-e-publish-cache)
- (clrhash org-e-publish-cache))
- (setq org-e-publish-cache nil))
-
-(defun org-e-publish-cache-file-needs-publishing
- (filename &optional pub-dir pub-func)
- "Check the timestamp of the last publishing of FILENAME.
-Return `t', if the file needs publishing. The function also
-checks if any included files have been more recently published,
-so that the file including them will be republished as well."
- (unless org-e-publish-cache
- (error
- "`org-e-publish-cache-file-needs-publishing' called, but no cache present"))
- (let* ((key (org-e-publish-timestamp-filename filename pub-dir pub-func))
- (pstamp (org-e-publish-cache-get key))
- (visiting (find-buffer-visiting filename))
- included-files-ctime buf)
-
- (when (equal (file-name-extension filename) "org")
- (setq buf (find-file (expand-file-name filename)))
- (with-current-buffer buf
- (goto-char (point-min))
- (while (re-search-forward
- "^#\\+INCLUDE:[ \t]+\"?\\([^ \t\n\r\"]*\\)\"?[ \t]*.*$" nil t)
- (let* ((included-file (expand-file-name (match-string 1))))
- (add-to-list 'included-files-ctime
- (org-e-publish-cache-ctime-of-src included-file) t))))
- ;; FIXME: don't kill current buffer.
- (unless visiting (kill-buffer buf)))
- (if (null pstamp)
- t
- (let ((ctime (org-e-publish-cache-ctime-of-src filename)))
- (or (< pstamp ctime)
- (when included-files-ctime
- (not (null (delq nil (mapcar (lambda(ct) (< ctime ct))
- included-files-ctime))))))))))
-
-(defun org-e-publish-cache-set-file-property
- (filename property value &optional project-name)
- "Set the VALUE for a PROPERTY of file FILENAME in publishing cache to VALUE.
-Use cache file of PROJECT-NAME. If the entry does not exist, it
-will be created. Return VALUE."
- ;; Evtl. load the requested cache file:
- (if project-name (org-e-publish-initialize-cache project-name))
- (let ((pl (org-e-publish-cache-get filename)))
- (if pl (progn (plist-put pl property value) value)
- (org-e-publish-cache-get-file-property
- filename property value nil project-name))))
-
-(defun org-e-publish-cache-get-file-property
- (filename property &optional default no-create project-name)
- "Return the value for a PROPERTY of file FILENAME in publishing cache.
-Use cache file of PROJECT-NAME. Return the value of that PROPERTY
-or DEFAULT, if the value does not yet exist. If the entry will
-be created, unless NO-CREATE is not nil."
- ;; Evtl. load the requested cache file:
- (if project-name (org-e-publish-initialize-cache project-name))
- (let ((pl (org-e-publish-cache-get filename)) retval)
- (if pl
- (if (plist-member pl property)
- (setq retval (plist-get pl property))
- (setq retval default))
- ;; no pl yet:
- (unless no-create
- (org-e-publish-cache-set filename (list property default)))
- (setq retval default))
- retval))
-
-(defun org-e-publish-cache-get (key)
- "Return the value stored in `org-e-publish-cache' for key KEY.
-Returns nil, if no value or nil is found, or the cache does not
-exist."
- (unless org-e-publish-cache
- (error "`org-e-publish-cache-get' called, but no cache present"))
- (gethash key org-e-publish-cache))
-
-(defun org-e-publish-cache-set (key value)
- "Store KEY VALUE pair in `org-e-publish-cache'.
-Returns value on success, else nil."
- (unless org-e-publish-cache
- (error "`org-e-publish-cache-set' called, but no cache present"))
- (puthash key value org-e-publish-cache))
-
-(defun org-e-publish-cache-ctime-of-src (filename)
- "Get the FILENAME ctime as an integer."
- (let* ((symlink-maybe (or (file-symlink-p filename) filename))
- (src-attr
- (file-attributes
- (if (file-name-absolute-p symlink-maybe) symlink-maybe
- (expand-file-name symlink-maybe (file-name-directory filename))))))
- (+ (lsh (car (nth 5 src-attr)) 16)
- (cadr (nth 5 src-attr)))))
-
-
-(provide 'org-e-publish)
-
-;;; org-e-publish.el ends here
diff --git a/contrib/lisp/org-bibtex-extras.el b/contrib/lisp/org-bibtex-extras.el
deleted file mode 100644
index 8424e62..0000000
--- a/contrib/lisp/org-bibtex-extras.el
+++ /dev/null
@@ -1,155 +0,0 @@
-;;; org-bibtex-extras --- extras for working with org-bibtex entries
-
-;; Copyright (C) 2008-2012 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte <eric dot schulte at gmx dot com>
-;; Keywords: outlines, hypermedia, bibtex, d3
-;; Homepage: http://orgmode.org
-;; Version: 0.01
-
-;; This file is not yet part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Warning: This should certainly be considered EXPERIMENTAL and still
-;; in development, feedback is welcome, but don't expect it
-;; to work.
-
-;; This file add some extra functionality to your bibtex entries which
-;; are stored as Org-mode headlines using org-bibtex.el. Most
-;; features expect that you keep all of your reading notes in a single
-;; file, set the `obe-bibtex-file' variable to the path to this file.
-;;
-;; - d3 view :: d3 is a Javascript library which supports interactive
-;; display of graphs. To view your citations as a d3
-;; graph, execute the following which will create a .json
-;; export of your references file, then grab a copy of
-;; d3, edit examples/force/force.js to replace
-;;
-;; var source`"miserables.json";
-;;
-;; with
-;;
-;; var source`"your-references.json";
-;;
-;; then view examples/force/force.html in your browser.
-;;
-;; - HTML export :: Customize the `obe-html-link-base' variable so
-;; that it points to an html export of your
-;; references, then add the following to your html
-;; export hook, and citations will be resolved during
-;; html export.
-;;
-;; (add-hook 'org-export-first-hook
-;; (lambda ()
-;; (when (equal org-export-current-backend 'html)
-;; (obe-html-export-citations))))
-
-;;; Code:
-(require 'org-bibtex)
-
-(defcustom obe-bibtex-file nil "File holding bibtex entries.")
-
-(defcustom obe-html-link-base nil
- "Base of citation links.
-For example, to point to your `obe-bibtex-file' use the following.
-
- (setq obe-html-link-base (format \"file:%s\" obe-bibtex-file))
-")
-
-(defvar obe-citations nil)
-(defun obe-citations ()
- "Return all citations from `obe-bibtex-file'."
- (or obe-citations
- (save-window-excursion
- (find-file obe-bibtex-file)
- (goto-char (point-min))
- (while (re-search-forward " :CUSTOM_ID: \\(.+\\)$" nil t)
- (push (org-babel-clean-text-properties (match-string 1))
- obe-citations))
- obe-citations)))
-
-(defun obe-goto-citation (&optional citation)
- "Visit a citation given its ID."
- (interactive)
- (let ((citation (or citation
- (org-icompleting-read "Citation: "
- (obe-citations)))))
- (find-file obe-bibtex-file)
- (goto-char (point-min))
- (when (re-search-forward (format " :CUSTOM_ID: %s" citation) nil t)
- (outline-previous-visible-heading 1)
- t)))
-
-(defun obe-html-export-citations ()
- "Convert all \\cite{...} citations in the current file into HTML links."
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "\\\\cite{\\([^\000}]+\\)}" nil t)
- (replace-match
- (save-match-data
- (mapconcat (lambda (c) (format "[[%s#%s][%s]]" obe-html-link-base c c))
- (mapcar #'org-babel-trim
- (split-string (match-string 1) ",")) ", "))))))
-
-(defun obe-get-meta-data (citation)
- "Collect meta-data for CITATION."
- (save-excursion
- (when (obe-goto-citation citation)
- (let ((pt (point)))
- `((:authors . ,(split-string (org-entry-get pt "AUTHOR") " and " t))
- (:title . ,(org-babel-clean-text-properties (org-get-heading 1 1)))
- (:journal . ,(org-entry-get pt "JOURNAL")))))))
-
-(defun obe-meta-to-json (meta &optional fields)
- "Turn a list of META data from citations into a string of json."
- (let ((counter 1) nodes links)
- (flet ((id (it) (position it nodes :test #'string= :key #'car))
- (col (k) (mapcar (lambda (r) (cdr (assoc k r))) meta))
- (add (lst)
- (dolist (el lst) (push (cons el counter) nodes))
- (incf counter)))
- ;; build the nodes of the graph
- (add (col :title))
- (add (remove-if (lambda (author) (string-match "others" author))
- (remove-duplicates (apply #'append (col :authors))
- :test #'string=)))
- (dolist (field fields)
- (add (remove-duplicates (col field) :test #'string=)))
- ;; build the links in the graph
- (dolist (citation meta)
- (let ((dest (id (cdr (assoc :title citation)))))
- (dolist (author (mapcar #'id (cdr (assoc :authors citation))))
- (when author (push (cons author dest) links)))
- (let ((jid (id (cdr (assoc :journal citation)))))
- (when jid (push (cons jid dest) links)))
- (let ((cid (id (cdr (assoc :category citation)))))
- (when cid (push (cons cid dest) links)))))
- ;; build the json string
- (format "{\"nodes\":[%s],\"links\":[%s]}"
- (mapconcat
- (lambda (pair)
- (format "{\"name\":%S,\"group\":%d}"
- (car pair) (cdr pair)))
- nodes ",")
- (mapconcat
- (lambda (link)
- (format "{\"source\":%d,\"target\":%d,\"value\":1}"
- (car link) (cdr link)))
- (meta-to-links meta nodes) ",")))))
-
-(provide 'org-bibtex-extras)
-;;; org-bibtex-extras ends here
diff --git a/contrib/odt/BasicODConverter/BasicODConverter-0.8.0.oxt b/contrib/odt/BasicODConverter/BasicODConverter-0.8.0.oxt
new file mode 100644
index 0000000000000000000000000000000000000000..511187a32f53bfdd27e17d84bd96809e5b16f483
GIT binary patch
literal 8009
zcmaJ`by(ET_Fftm7m$<&X^>vJL%O6xkcJhOT98f&NpUHq8|elSX~9KYVL`gPQxKK<
zt@l3P>%HFZ{muR{^XzlZJD)i-?|J6TtEY*DO%4Fy;{)c+hGcUx6DR#J001#e0Dukv
z0C>1K@!C7U?D+p0ctJe8A?|K`-hSSe543gZ1aEbyuE?3<moo_tj*`t-*iaR;c(Y+|
za;F@B!iM{i2YxH+>KyEjrMo*@pSKv;*0?wC2GfN+Hxm%!39dBBOe#EpNIJ+RU}hWu
zJ8RwCmdX<Mv#SzBd-zLa%ku9_FtJa~?m-;4g5|fkRC#Vm>ylAy5zUb8v1_$=o)d|1
zo_)j@nwTKjS{egL+u|>As${(dK3H*34c-&JpRXg2FX?5jAVbyN#H5(Q$)eeoe+)UC
zZjDkEF5Jfy>ho{n8=JWUJHOu?(jdD%eA+NtYv~3pUfOOrdArwsZO-3Z2`jly4nn+)
zr`uUR`ys~v#U-@iwi(ZvP(bw3tm{_-jVb^1z1g;(w$$tvuJ;<p^FVD9ws0zG;F6~x
zKY!Tl-LS46KH?XW_g)j1IJbX}FSEz`ergji7<StTs|aDp>6EQzFmaG4ap$9w!Dhx%
z_4R9pcP~ZtE_{Lg_+Q^#)thAvzV(%2%G!j>LeDq_U$1AE-{}3vj$Jx2CJmu?Y8t(3
z6zE?2zM%rIx{eAz)W!|s=m7KP^Mkskz36$|CvYqJFgR|hJ!fB3WwfE@^zG0$KwPzb
zVUnwB8>@Sly`In%m)No9<s#l=ow2P-sZy<Qi!;|;!zkCMEDYvnXa3{-JKoY@7J;*u
z>t}*=#N(9T)*i5EW>)g@EbQW+%vT88H!x<LcN3}!j6as5McsCO#nJ+_J+)V$O#Auy
z^I9)EA?sK*&Wu3@6S88VFR4{Q>QhU|t=JWyfY6{-BK|jAteu)Vi~P`;ZxS66RN`5K
z=^ePD9=b~ET|E2p)@)*DH|Ljt|6F|vWvu26dey7w)f1!pUuX5NBZ^*kNwT)rQ-NDi
zlY?3ZO96c!Mb(`o!^0gXp`!a3bR^0kM8ZDcLoKshiv4U!?x~DA|7;?(FQASHw2m?#
zxQ)fF6>GSO8a~gMQfVI^7vkxmpp;@9FxI4G@{*7XSS-<aMT9V<pkzv{rbu9LK7s9o
z>t~5yFNulr7F<xtiK>;gql50{m$&T$XMKEd;&Fbrj}&1SWo=fQCA{{oO#gc4n+N;;
z^GuzSeER4NLM3K=;`GW_?@GP;Y}?X~o6p#>3139EKMf3DV)uEm|Fo`4?yfnjs}GA+
zf~XhLEX-gO%9+P3>cg-3Wek)3eU<rZlz(NJ7M~rz#<!Q|uW$Z{)iDY{(Q*p_aDn}k
z+ln?Yh@GyolDpdz2QP02FMbt>E4qX6`Ptfx=a|7}#Yw~RN*;xeD``w?6l=K-J7$X;
zc(OXYv-?nih!xi5%Z#+wVU5sKr2KkFwZwLWnF+A0G%_L@O2m~FO;Qmf=)91bsY0<3
zDQ5UNJ$<B7i;Ev9>iN*!NA!DuaNrNeql=5{_E4=FxrIxSyuuNphk3bf&l)Z5z&8OQ
z{>QgLR!JWwWxv&AXig5WkX8+>4kEGH<aD2P%v(RdTN*5#8^VyUpdYlR=hU4_<<o%c
zzYIB<pI!>rzwwr4*OHoc3BB4Guk^etgveYoqYV;$+2-=m`NVxPy>-T%=UWy|a|DdX
zd%x#`e~c&cdQc8OC)89RVy!GBbj6Lt<q)aM7;|+k?ZL<!*XZu1R&n+51QkOPJRo)Y
zqH1!gbZ=*Uv^9Jvvh;;6W+tVc#^Oq#bNKU#ndpyJu9tuqX2T#-Q>nDQ>k4vKe(C6C
zj~_6_i7DHN_<fm`M^tM+JK`OngIRccXMr7%HU0M*-vSMW6{v<n7|(>B<_n)P<5%VN
zNwH5U4PQ61omOj$7J2L@DmpIQ?!QexU)R+jn}K*IpUBpWm$2>J!<VxD{su2&%_M!$
z?6M+ZqnFqkMASa#nw`i#*j3`?r8Z#`cM|*kYsle539(Ob@>R%bkLO6<cMeGzO^U_#
z^TANP6aR2N&V{-~4yw1@r+0b%4i*-d4x<{Na`%mV)l<?+;6lSL5IWmRh;l&{fk_R0
za`HW{w`}20LoQ5&`hxQMFknXUT6o2&5gR7;A(oksRBO#=)r&nlv=W(-?i`9zO;Ffq
z=a`Wz43n!Qzl~!pW@L(nrUh=~Je4m)Mff;Kqk@EXaVlXW9LNhTydBlRe(4GGi9I<B
zHa*1{Ro`mMZq9#<pxSPFDT>VG)p=1-Rt+(%N0#(&FrU)U-YLrmN|vZYM5jEbPmcPu
zEsQjkSj_3g-YxBS=3{8r01Y)%l<3Tzb$AmwQ$>~ogp`78RQru|V;re0)<JctsnN<&
z;aIsi-(coK4@np$wl2m?t^@igt5|A!!lD&jm0Vo=X!C|K=QL(^wI63m8P^YgsFzJV
zyf+Rm)SHNufW4}^5LqBYs@2uc2v9%{OnH4{c}lg(^Z@^uFWyCt6{}3-{;Sd|4J!>5
zGD#_sU;o>5N#~P+YE_E4D)iIzN9edrba9Xme8H*%;18wX5A!HG+EG0<-6Eq*KOM55
zSC34kfV;#OT(1gg)HNFcF&g9x^$^K3(1F`WvYb@*h!JHP@MBnPi#io==gh73h0KKL
zbV^{I6IpA}$0EZil(!qOB3c~9<||<YzHNQxS|~V8lnUu)qy}9SmHvu&(Aiu`e9os@
zb(6S;as}|CS|?8hSf(oJYxJH+-&d4aV*|4pEvnVE82de>zG0#{3n<E$*h$(zyj1B}
z;B-!EFOm=~iq)`y9O?WFwBdm^1+Z7>GdOrKl`S6|Gf3@~F~8Rkcq1G3=6GC5ll-H(
z|84-$bkx>d3GI*==7#4NDPz3%gXvks?f|!zU*Xx2G0jD8bns|Zv$b#RhXcV?Nkq<<
zB=Riy`w-V5;?{SEQqDSxZ=a=bNh<La94o;x(+KPS5pV<RAH+5Eg@n(2?6RmIM_C+1
zqn(LhnH<2jV}(lmH)+m(^h|Wr$i-_7DD4AIm)@?}A<hlrNVt(LdoEos1_)Ia=F0q4
zF+6(Q#w`nkD=t^4ci_lBPz!Pl1A;31vZKY5GF8Y)#X$b5nlMA&0%aQKZf%NU%v10K
zHI=bZ2<Heu$uN#-{7OZe1!xpu_;bjqpsZf<Q(&e$)&TkwKM3&BA}wd_X$_0(rS6Eu
zkjQH}TQ4i&Ac3P}#_-&MbW~n|Wwl!4PGOmUn3+6z#YoVAw`v3<rw>sRbk(PB;k)d6
z(a!gxFtJ`2-c@qQC6OzcDWKMX{G+dp1#xh_Vy8>nRNYkuMAy#e<ya(nT|k`TN`OJ!
zn`TQNAh_g+dC~~Pzzt!*SXCka2(`1=eNz_PC(5QE>Z&;J*|)RRE&4pnlLZ)iaplgp
z;L~hj=i@Ekh*c$4m|Pct%c?_GG(7`k9P#j!GH}Dpgrq-=h4gYKFs-sb7Iy1a)-Krb
zgB5FHsU3eAIbuJ0+)O5YR`I2T9L(VeemmG2VB`q?V#$|=rVaydt1-_WtBW=%hw#@i
zXDUyOB0ZlF1)qolP{pYAYth7z*OG^O^eDPlqkBxK9!qU+fp{O9NL-){bn?D833&x&
z6!6#qx%{Y5y=Y-hGOT^77)-(_S#ey@1>5|gA&hBR91A6DJ}bBw9|@d?&f?Jq`=$(F
zVjT(5GAN$P6oum~m4NX`f`=jU7=F}9X5~d;8dHFk%2#F7x%b@1;6owMJpg}^MC4YW
z3Kn7akTVhU&s<bD=8+K1iu}sBj`q6%p&=|>CA|;&sCR9vgsBaw*|>EJ&lK+_eosgU
z$4f<ZYp6pwBcm%IVCgS$Q2A|a^ek(n4W3w<9BL3Eri|pVuu%g2Oe_T38aUrOB6S1c
zMIZs<%wZ~#2z#iggQbBsV-h>~AtH9L+~g`Q}m-lZ;-gh;5L;5jR~H^O)Rmv_Qi
z3kGy=4NNloy&8&T<I<FP%2G0oVXXUrvlThha9mAsN7^Z^{G_dd-oPOUZ;08xx*-==
z^WmVg;s^b)XNt`Qa@G6VPr0uRj5}pOtQmSRym-BGH^f_ow8GQ~+><xYq%%g+ph=Q-
zpf%6iZBTF?6-3X$mUag-Ad`u8(7bt`Db*=lzgG<B-ewRwq{;h8XKR8-6383b+4eHQ
zGaMr3*(_8yX{UbXL1V`fwT_@0`<WoI1jwH9nfWj#^s>q8z+6<0F(d@s2)cKlyJ(s;
zY?2G;p#3^jV9?zz_u=?im7ZP*$R4aRZH1yosl5;_hnJ~Qfax6rXWPU_UEPafit<sR
z0_xtXk`2iEa_E=yps+(8fhJ^ZIh2T*EDs5(vwxR>n;u&$p;Gu&D`;ZUaL|tniDADY
zJlhRFrq&j@{Yb*4I(>?War}LuUT5z~nS~r*r;j{cWk9U+rC22owaL3HAHJubLO#n_
zyT&U1*eBj(q#Sb#D1x~~g$XAzfs@}g8>F=6ntl;Nn8kxr;?3e+n2P)h-}%gG8`|R-
zjV|DnFcUFtumfX%h%F;zb7V8hZKW*Ri#Sp~5o2Ylh+1uO{BZtGXc7-63Z?<pgN$Yd
z-e1H*$B-~%yyVbT@VxX8nPiw9(S2qV#_H3Sq6=SPqaA%9jheKf;ux}H{1vy|KgLCY
zemWi8N||TG^12o`uSYL^ew4l9(bL1>XDca4_Ef5DDUaQ4%2@$6%5y3ALraeD>0%ee
z&WwgtO^}zs1F?lNc`<%bUAl&>1%q@|Qc<B_BpG$5-{%A}e%X2cFl|LGg(G2iZS1is
zIBeB1SD+?Ew~`(ONXq&V+7>UjA=nWg3VMm7T)@s~zKXpWM+}neF;gf?YEy6q&ou)<
zV}i!HfmQhr7?*A}XkU<JSGI&_FWoD{n2TotmIs>eZU*${mS$rcf|GMgOHrmzG6OQR
z)fBL{A%NNJrrfgK0Gc_`aeUjWUHToyJ6t*NG9L!pKIS>Q2~4xdvi!%P422#HzEuSn
z7u$+P0fdGM6yF=m{2hO=23^=Mi}5Zp8>D5kzwJABKNx*_-vNU(Eh^+TC8dBi68A2y
zYmZTJo1Hjlv#7zUb&+P!nP?~5d%@L#i#jo+`>~J`|BDAx6$7GSb!iEuMPGB9H(J<@
zehOQtZp!%HhuLe5_4^N7qUf?vFLSu6TA!ptNR7O3#S^`vYl_NW6~xDwRH_#UgR^l@
z5AXnqN#!&qy5;vB!1UQ%pDZdVwqCr3f3E=2j2ZZ?vTsGIuvP%TB6yR=ixb9qEqEOg
z_d1A{#2z;XwwspH`xS*xTznXn?2Z98`Kg*MgiP7=giXFo<M;E~OwDRHIj3n8_9k=n
z%p*K*MVvWV@Q1k5YrLnNV98Y>54;SH>2tW8$L2T$vSQH4I`tK)2pR9XapOeSnqpX)
z7;BgG%H10_Ta`CA;vO>{+}+TST}}<%V(qxbxoffG4p}*@=l)I$%Ghq+J+F}ggD^uh
z#R{-3+iVaCna*41`hpWlnart1-G)~1af)5_%Y$lf$LE#GL#*EpqPHivUNs*tQqp`m
zT<3KhFQy=h*FMmF7NdJHSP3})6g7|=SFKi7HjKTD0C9Esi!0e^+devR>+RwN^Q^0f
zYJ~RlY1qx?QPJM`w_BYDKJq{W@ULj|O>fP=IkFl$zrp#>+R)o`_V^eN09d310I1Qm
z;eXXT+BOikU&T(fsfGKjBxy)X2+rh`!4zK2Ua`1*)&wtH+zo3jdTM%47N<#hR@q)Z
zrg-%G;^EQVxYYe7Vh-YZ<<GY^PmobRPxgHb@~Q5!uDj03XsB8$n-0J}8m}Jo1^v9X
zJD;6g8|q?j-TZnpZ^`tEz`P;_G+Y^x-yYLgIRyI>EJwGH9y!mK0cPQ%s$BLE%452a
zT{dfG)?!YUrL&szelXck*7mWTNjjYXDCloHIWXU>zdq=JP>^&lW_+$vRKT`9!7ccX
zdG$b~^b<eD%WCd-5$msdS8i!$`gAQkddPBGcCECv=Z(8F+sgWC1oYNE4nLdgr{YMt
zvQst{ws7Owv+_)@7p!A(7#L1l*}@(<JM-y3DX5+`aPcDguEqgBn%Q{e*Q!{}>JU8Z
zoEPe<gk`tpz;$w8q3XD5SwS&43kZylK)%5eHZGhOOWIXzJ&JJeg=P5Au(OI`zO0dj
zvH_fEgyNAU8CMVS>$MVPqga8NsWk9*B;|7yITbui%jsSfU1BB+AGHxDN4^;mXMr+1
z{pvW+TN2amz<_>Fx5btY-%yi>!MRTfOM>?T6}r}b)^=MU&4i<kBQU6H*{DALFlK*U
zB+?jf(7GW(SG~fyNp0>`-vi`rvHn165;gis)0?ZdJT>g66<MupW-WoHq@&ys++rV`
zx>TxZY`l}uC3$sKz=4=uXdCH-3eQ0Gkh0D~=|w{hE1@hWZTVSxs&$PDF~ruc@R*WT
zMB7HDW)$$JR@^?ITts0~oQ&>4ta3jfVPV5It8h$<nL)tiXBDYp*^>h=y6p1joy$O-
z!jo)wjnCFHSK;dv!?&CRt>SgCv^PZ`@p$R5HsWzL4J`R206FqKoj0Xo>U0EoxfN)J
zd&qnao;3;Vex|5%avnWY7RkiuXK-itS<7ChsTl}ze^Le;8i^uF7UWIK1mk*^VOr0(
z4-BvAbVuvW-YgYXB;F{%)OaqW!{kkh<;0Z(bv;6c;-Fg9sHN07n48>DJl`|2yLlA+
zW0;?gWix@D80V)E`i{eX=JFE3HN&*qw#IoQyNBXByD8w~XG?d;yJ!fIq(_R%OUo}R
zMD9I$$KC7g3)G_{Y$-QpDcj_Rm_9kDb1no|Hr!gGdNzw;&$6Lb7G<e?cvO0suyQY<
zQd<W`yhwpphi_Fq!NofDM4@n=Evip2pa%z;gJ`<#+sQsH{IiW6AZ8=LfmoynZ^D6g
zM}BHyA`#%IP0qv2Wf<)JdJ&0fo^TMcu-v*Nu=u3ve3!n%_G(%z_aMr9f`WRnxWTp@
zTe<{jsMgHT4A`u(2+xHRMRYCR2JC#ely#Ouc{VfL^|*BO-hsOy8y|MaY{qnmbi~s_
z^GEX8=JGE}xq&7x7dbtiV{<wCOIYjY<GdFf@Am>h!bKmF%$5XkOqILWgzr7eiLa(C
zz+lEVX3ZoGdZmF%H3@4Wae2$!xh}q#u!pKwly$c~S~RZ6|8$2;QgD0CFx}L_g^Zwb
z8*5egu9bDeELAdFDivIZZkAYIp80gW>qR=;1a1`fC6e;>cH6#=Kq*&GJmyxZxs@eq
zH10Ts`je2(qQs=pu~$(r$FAD!V*Xy6IZbg;F!x=4$+4pdrFKm572YAHL+V=l$EB*P
zE(z&t9B^zQu?)xiPR$MtnB7o4^4AY%1*=SkZ9{wSiPGTU<?*HQ0GoMmADDdJDRgU!
z6<BrvPXXu@5fcJ*sMZU9&Jh|#Us`AiY4yq6N|gZ@_o!!@+lV9c6g)Y1w{uJwRHsnP
zv(FKz@pjfc!plNA;Yspy54}_z1y#&?l@|n4xMN*LPI+qq+&IAG?}00)H)N}|`Js|u
zw-qi<b%R0bq*NNdCK0o=?~~Hm9tfq0w%X6URgeJ!t$gLSMQ-y1>tY31yAD>$4=6}P
zf-ri=9lt9M>fT{@PEX%Gne_^i7K*Msj?vAN4f*b*%pmdN1LO5ik1wJZ9Koe{4m(Jj
zM1`l>1#K5H!L`mh(URa3g2qdTBF-TBWGlQ(E=g{|L<<G-_sU2?kJ);z+?`Isc)GLt
zR6UBkTV;oA+=J2yZRuh`r6X9vj+_qeSgo^H0Yr@yuER1PB))u8wG?(u+Pc=r7-{O2
zovCXrTaBI<-r1!zdh+OQu)*RY{QO6sNTGA8y)avZ;3(B;fYqHM)WV>UUp<8SxJ{&T
z=+<K^;lQ_@*AvBe5N^-!E<?KrsJz9uzQeAW;t=Vr`~=4Bv>rC|DSID@<@vqen2&Y3
z={ZwrJmHfwY+K-rDCkQ5!j`(mS{qnjZTnMti(cF2r%(0eJQ-B`tokNbtqzes@`h4$
z+JA|L*@qG{#M;Vh(F%|@f_ejP^&>#Qq4LyU%z(sIS1aL)qJ5*xaGnOkpX9tJGLn*p
zlS&4KsT)sNCzX0|qI+0;2X&E#wTvb7njp3WgOVpLRd~Fr3#ZdMy8t~DY6~g;8mZ=2
z<W86CW)ey3N=)4x?{VX=^*Bh(6DXUlt_0zRfI0c{OFx21ot_RAi6DKkRww!W_f43u
z=!@D~X{s}MT;3<sBz`c4k$rw^+H5a=bxv3>nUs^3_|np3o92TBcPpulF>i!>sLXkP
zZ64kC>=O4;%o<D_t#%%SIPvLc`uFl}33XQ-8fJYIYdeFVMX7F*8rz&|@T4N|D~~V!
zVA=qCrYoys4MYq+ibl1r)!yL!=RG0Z4H%9<-w!y@Z^*QNcTcc~*toho@%g#hT0Ylx
zK|ksCA6}5>9wd(Ds6fn}=X&$+$rQ)X%UD1_vE;74p`BN^G^wW4r5DBy)pz$NM=FVd
zC_<CEdm4K0jk7m3aW=oz`9<$<*j&BNdK)aYZ*;i$lwh$EQZeT58&pnlk0k5Gn{7$=
z@?;N%FV)6f=J6e%_v#L^E7ug{S{G58L_#-mqL2EIYq;N(f@?_F#1L~whUsiN)Zg0^
zkn$9JTBj|jW{(iQ2QRPW2MEqz&AgHwbxmL&&?RuY1xK)ZonyO&{P8f{jo^bVqZgj=
zzXI^jH}ziuh|(R>=@TG%ch2)^Aq$kPmsYHwVyuWcsuZx~yr*5i=EpMo?wSD$!V<9D
zM1$OujywBc-B0_&dMeE$XPpVbH8DW1Dem3A&RbP^-*ddl=e%hV=#txUnpe3UcVz<$
zH6b*;+rrY;a+p|{aCN(Wo8~y4*0>g{jT0`n^6fUZ*3GLV8u(2K^znKxLD~`N>Knzi
z)NWX>cJ8J)WNGfxV7SH<!rE~5%iic4wU7-Nb>wIENvj!oVZo0i3)8zO7%PQ(9{IRp
zHX*zuk1ceJq1ZF*X7|ZJDc`b%`BMMJ4&h%%0{~b;%VFrC{Hx)jM-V%AHyHo_wgIAT
zbR8Wbb`JbT>i>@&2yN%(-~@qrd)fSw)Ba`pPZbVIr(oBHHlajs$S+6*dwcY}e13L5
z4$qOmUICKGVPJ5~sHP6I!m79_j!HpK`t_0stINI2c{p~ZyL-j=r@54l8?*CVWhSsB
zerro@(|U#U#yfiOiU%gHtvO|OqB+V}a0De>O9_9=fbHG0q7XW3@B2p;Yg@qv9y%Z<
zdZOmYgsP1`X+{siw@(%p;9{OW?)lK!D*E8wi*YZO=hn&@2Q`HPdThca`16`Bk<tY8
zYhezLI3}OJh>QtjgGVglwD*s#=1h;T+;l_)p(%%fNe=kmLL+*W|JMFe8~;vr{1fR<
z0qi$S13G+vD~J6F@u!OP8=?-agZ`l@{ptLttn%A=4(o4<j(-zb{zUq-VEK*oiR5pP
z{wiPog!wa{{f0Tc^EWWRv)i9Qf98eXKxgQB>c7gV-&x`}(BISOHxMy8;r>OczYfTM
z`~2d-?<S1)`FE22Z@*tO``s+iet(eeFW0}P-EY@uwCisY>S^NqN(KNz^zRe;fH?h9
H$^rie=t~1D
literal 0
HcmV?d00001
diff --git a/contrib/odt/BasicODConverter/Filters.bas b/contrib/odt/BasicODConverter/Filters.bas
new file mode 100644
index 0000000..5912f65
--- /dev/null
+++ b/contrib/odt/BasicODConverter/Filters.bas
@@ -0,0 +1,213 @@
+REM ***** BASIC *****
+
+Dim DocTypes
+
+Private DocTypeToFiltersMap As New Collection
+Private WriterExportFilters As New Collection
+Private WriterWebExportFilters As New Collection
+Private CalcExportFilters As New Collection
+Private ImpressExportFilters As New Collection
+Private DrawExportFilters As New Collection
+
+
+Private ExportFiltersInited As Boolean
+
+Sub InitExportFilters
+ If ExportFiltersInited Then
+ Exit Sub
+ End If
+
+ DocTypes = Array(_
+ "com.sun.star.text.TextDocument", _
+ "com.sun.star.sheet.SpreadsheetDocument", _
+ "com.sun.star.presentation.PresentationDocument", _
+ "com.sun.star.drawing.DrawingDocument",_
+ "com.sun.star.text.WebDocument"_
+ )
+ With WriterExportFilters
+ .Add Key := "bib" , Item :=Array("bib" , "BibTeX" , "BibTeX_Writer ")
+ .Add Key := "doc" , Item :=Array("doc" , "Microsoft Word 97/2000/XP" , "MS Word 97 ")
+ .Add Key := "doc6" , Item :=Array("doc" , "Microsoft Word 6.0" , "MS WinWord 6.0 ")
+ .Add Key := "doc95" , Item :=Array("doc" , "Microsoft Word 95" , "MS Word 95 ")
+ .Add Key := "docbook" , Item :=Array("xml" , "DocBook" , "DocBook File ")
+ .Add Key := "html" , Item :=Array("html" , "HTML Document (OpenOffice.org Writer)" , "HTML (StarWriter) ")
+ .Add Key := "latex" , Item :=Array("ltx" , "LaTeX 2e" , "LaTeX_Writer ")
+ .Add Key := "mediawiki" , Item :=Array("txt" , "MediaWiki" , "MediaWiki ")
+ .Add Key := "odt" , Item :=Array("odt" , "ODF Text Document" , "writer8 ")
+ .Add Key := "ooxml" , Item :=Array("xml" , "Microsoft Office Open XML" , "MS Word 2003 XML ")
+ .Add Key := "ott" , Item :=Array("ott" , "Open Document Text" , "writer8_template ")
+ .Add Key := "pdf" , Item :=Array("pdf" , "Portable Document Format" , "writer_pdf_Export ")
+ .Add Key := "rtf" , Item :=Array("rtf" , "Rich Text Format" , "Rich Text Format ")
+ .Add Key := "sdw" , Item :=Array("sdw" , "StarWriter 5.0" , "StarWriter 5.0 ")
+ .Add Key := "sdw3" , Item :=Array("sdw" , "StarWriter 3.0" , "StarWriter 3.0 ")
+ .Add Key := "sdw4" , Item :=Array("sdw" , "StarWriter 4.0" , "StarWriter 4.0 ")
+ .Add Key := "stw" , Item :=Array("stw" , "Open Office.org 1.0 Text Document Template" , "writer_StarOffice_XML_Writer_Template ")
+ .Add Key := "sxw" , Item :=Array("sxw" , "Open Office.org 1.0 Text Document" , "StarOffice XML (Writer) ")
+ .Add Key := "text" , Item :=Array("txt" , "Text Encoded" , "Text (encoded) ")
+ .Add Key := "txt" , Item :=Array("txt" , "Text" , "Text ")
+ .Add Key := "uot" , Item :=Array("uot" , "Unified Office Format text" , "UOF text ")
+ .Add Key := "vor" , Item :=Array("vor" , "StarWriter 5.0 Template" , "StarWriter 5.0 Vorlage/Template ")
+ .Add Key := "vor3" , Item :=Array("vor" , "StarWriter 3.0 Template" , "StarWriter 3.0 Vorlage/Template ")
+ .Add Key := "vor4" , Item :=Array("vor" , "StarWriter 4.0 Template" , "StarWriter 4.0 Vorlage/Template ")
+ .Add Key := "xhtml" , Item :=Array("html" , "XHTML Document" , "XHTML Writer File ")
+ End With
+
+ With DrawExportFilters
+ .Add Key := "bmp" , Item :=Array("bmp" , "Windows Bitmap" , "draw_bmp_Export ")
+ .Add Key := "emf" , Item :=Array("emf" , "Enhanced Metafile" , "draw_emf_Export ")
+ .Add Key := "eps" , Item :=Array("eps" , "Encapsulated PostScript" , "draw_eps_Export ")
+ .Add Key := "gif" , Item :=Array("gif" , "Graphics Interchange Format" , "draw_gif_Export ")
+ .Add Key := "html" , Item :=Array("html" , "HTML Document (OpenOffice.org Draw)" , "draw_html_Export ")
+ .Add Key := "jpg" , Item :=Array("jpg" , "Joint Photographic Experts Group" , "draw_jpg_Export ")
+ .Add Key := "met" , Item :=Array("met" , "OS/2 Metafile" , "draw_met_Export ")
+ .Add Key := "odd" , Item :=Array("odd" , "OpenDocument Drawing" , "draw8 ")
+ .Add Key := "otg" , Item :=Array("otg" , "OpenDocument Drawing Template" , "draw8_template ")
+ .Add Key := "pbm" , Item :=Array("pbm" , "Portable Bitmap" , "draw_pbm_Export ")
+ .Add Key := "pct" , Item :=Array("pct" , "Mac Pict" , "draw_pct_Export ")
+ .Add Key := "pdf" , Item :=Array("pdf" , "Portable Document Format" , "draw_pdf_Export ")
+ .Add Key := "pgm" , Item :=Array("pgm" , "Portable Graymap" , "draw_pgm_Export ")
+ .Add Key := "png" , Item :=Array("png" , "Portable Network Graphic" , "draw_png_Export ")
+ .Add Key := "ppm" , Item :=Array("ppm" , "Portable Pixelmap" , "draw_ppm_Export ")
+ .Add Key := "ras" , Item :=Array("ras" , "Sun Raster Image" , "draw_ras_Export ")
+ .Add Key := "std" , Item :=Array("std" , "OpenOffice.org 1.0 Drawing Template" , "draw_StarOffice_XML_Draw_Template ")
+ .Add Key := "svg" , Item :=Array("svg" , "Scalable Vector Graphics" , "draw_svg_Export ")
+ .Add Key := "svm" , Item :=Array("svm" , "StarView Metafile" , "draw_svm_Export ")
+ .Add Key := "swf" , Item :=Array("swf" , "Macromedia Flash (SWF)" , "draw_flash_Export ")
+ .Add Key := "sxd" , Item :=Array("sxd" , "OpenOffice.org 1.0 Drawing" , "StarOffice XML (Draw) ")
+ .Add Key := "sxd3" , Item :=Array("sxd" , "StarDraw 3.0" , "StarDraw 3.0 ")
+ .Add Key := "sxd5" , Item :=Array("sxd" , "StarDraw 5.0" , "StarDraw 5.0 ")
+ .Add Key := "tiff" , Item :=Array("tiff" , "Tagged Image File Format" , "draw_tif_Export ")
+ .Add Key := "vor" , Item :=Array("vor" , "StarDraw 5.0 Template" , "StarDraw 5.0 Vorlage ")
+ .Add Key := "vor3" , Item :=Array("vor" , "StarDraw 3.0 Template" , "StarDraw 3.0 Vorlage ")
+ .Add Key := "wmf" , Item :=Array("wmf" , "Windows Metafile" , "draw_wmf_Export ")
+ .Add Key := "xhtml" , Item :=Array("xhtml" , "XHTML" , "XHTML Draw File ")
+ .Add Key := "xpm" , Item :=Array("xpm" , "X PixMap" , "draw_xpm_Export ")
+
+
+ End With
+
+ With ImpressExportFilters
+ .Add Key := "bmp" , Item :=Array("bmp" , "Windows Bitmap" , "impress_bmp_Export ")
+ .Add Key := "emf" , Item :=Array("emf" , "Enhanced Metafile" , "impress_emf_Export ")
+ .Add Key := "eps" , Item :=Array("eps" , "Encapsulated PostScript" , "impress_eps_Export ")
+ .Add Key := "gif" , Item :=Array("gif" , "Graphics Interchange Format" , "impress_gif_Export ")
+ .Add Key := "html" , Item :=Array("html" , "HTML Document (OpenOffice.org Impress)" , "impress_html_Export ")
+ .Add Key := "jpg" , Item :=Array("jpg" , "Joint Photographic Experts Group" , "impress_jpg_Export ")
+ .Add Key := "met" , Item :=Array("met" , "OS/2 Metafile" , "impress_met_Export ")
+ .Add Key := "odg" , Item :=Array("odg" , "ODF Drawing (Impress)" , "impress8_draw ")
+ .Add Key := "odp" , Item :=Array("odp" , "ODF Presentation" , "impress8 ")
+ .Add Key := "otp" , Item :=Array("otp" , "ODF Presentation Template" , "impress8_template ")
+ .Add Key := "pbm" , Item :=Array("pbm" , "Portable Bitmap" , "impress_pbm_Export ")
+ .Add Key := "pct" , Item :=Array("pct" , "Mac Pict" , "impress_pct_Export ")
+ .Add Key := "pdf" , Item :=Array("pdf" , "Portable Document Format" , "impress_pdf_Export ")
+ .Add Key := "pgm" , Item :=Array("pgm" , "Portable Graymap" , "impress_pgm_Export ")
+ .Add Key := "png" , Item :=Array("png" , "Portable Network Graphic" , "impress_png_Export ")
+ .Add Key := "pot" , Item :=Array("pot" , "Microsoft PowerPoint 97/2000/XP Template" , "MS PowerPoint 97 Vorlage ")
+ .Add Key := "ppm" , Item :=Array("ppm" , "Portable Pixelmap" , "impress_ppm_Export ")
+ .Add Key := "ppt" , Item :=Array("ppt" , "Microsoft PowerPoint 97/2000/XP" , "MS PowerPoint 97 ")
+ .Add Key := "pwp" , Item :=Array("pwp" , "PlaceWare" , "placeware_Export ")
+ .Add Key := "ras" , Item :=Array("ras" , "Sun Raster Image" , "impress_ras_Export ")
+ .Add Key := "sda" , Item :=Array("sda" , "StarDraw 5.0 (OpenOffice.org Impress)" , "StarDraw 5.0 (StarImpress) ")
+ .Add Key := "sdd" , Item :=Array("sdd" , "StarImpress 5.0" , "StarImpress 5.0 ")
+ .Add Key := "sdd3" , Item :=Array("sdd" , "StarDraw 3.0 (OpenOffice.org Impress)" , "StarDraw 3.0 (StarImpress) ")
+ .Add Key := "sdd4" , Item :=Array("sdd" , "StarImpress 4.0" , "StarImpress 4.0 ")
+ .Add Key := "sti" , Item :=Array("sti" , "OpenOffice.org 1.0 Presentation Template" , "impress_StarOffice_XML_Impress_Template ")
+ .Add Key := "svg" , Item :=Array("svg" , "Scalable Vector Graphics" , "impress_svg_Export ")
+ .Add Key := "svm" , Item :=Array("svm" , "StarView Metafile" , "impress_svm_Export ")
+ .Add Key := "swf" , Item :=Array("swf" , "Macromedia Flash (SWF)" , "impress_flash_Export ")
+ .Add Key := "sxd" , Item :=Array("sxd" , "OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)" , "impress_StarOffice_XML_Draw ")
+ .Add Key := "sxi" , Item :=Array("sxi" , "OpenOffice.org 1.0 Presentation" , "StarOffice XML (Impress) ")
+ .Add Key := "tiff" , Item :=Array("tiff" , "Tagged Image File Format" , "impress_tif_Export ")
+ .Add Key := "uop" , Item :=Array("uop" , "Unified Office Format presentation" , "UOF presentation ")
+ .Add Key := "vor" , Item :=Array("vor" , "StarImpress 5.0 Template" , "StarImpress 5.0 Vorlage ")
+ .Add Key := "vor3" , Item :=Array("vor" , "StarDraw 3.0 Template (OpenOffice.org Impress)" , "StarDraw 3.0 Vorlage (StarImpress) ")
+ .Add Key := "vor4" , Item :=Array("vor" , "StarImpress 4.0 Template" , "StarImpress 4.0 Vorlage ")
+ .Add Key := "vor5" , Item :=Array("vor" , "StarDraw 5.0 Template (OpenOffice.org Impress)" , "StarDraw 5.0 Vorlage (StarImpress) ")
+ .Add Key := "wmf" , Item :=Array("wmf" , "Windows Metafile" , "impress_wmf_Export ")
+ .Add Key := "xhtml" , Item :=Array("xml" , "XHTML" , "XHTML Impress File ")
+ .Add Key := "xpm" , Item :=Array("xpm" , "X PixMap" , "impress_xpm_Export ")
+
+ End With
+
+ With CalcExportFilters
+ .Add Key := "csv" , Item :=Array("csv" , "Text CSV" , "Text - txt - csv (StarCalc) ")
+ .Add Key := "dbf" , Item :=Array("dbf" , "dBASE" , "dBase ")
+ .Add Key := "dif" , Item :=Array("dif" , "Data Interchange Format" , "DIF ")
+ .Add Key := "html" , Item :=Array("html" , "HTML Document (OpenOffice.org Calc)" , "HTML (StarCalc) ")
+ .Add Key := "ods" , Item :=Array("ods" , "ODF Spreadsheet" , "calc8 ")
+ .Add Key := "ooxml" , Item :=Array("xml" , "Microsoft Excel 2003 XML" , "MS Excel 2003 XML ")
+ .Add Key := "ots" , Item :=Array("ots" , "ODF Spreadsheet Template" , "calc8_template ")
+ .Add Key := "pdf" , Item :=Array("pdf" , "Portable Document Format" , "calc_pdf_Export ")
+ .Add Key := "sdc" , Item :=Array("sdc" , "StarCalc 5.0" , "StarCalc 5.0 ")
+ .Add Key := "sdc3" , Item :=Array("sdc" , "StarCalc 3.0" , "StarCalc 3.0 ")
+ .Add Key := "sdc4" , Item :=Array("sdc" , "StarCalc 4.0" , "StarCalc 4.0 ")
+ .Add Key := "slk" , Item :=Array("slk" , "SYLK" , "SYLK ")
+ .Add Key := "stc" , Item :=Array("stc" , "OpenOffice.org 1.0 Spreadsheet Template" , "calc_StarOffice_XML_Calc_Template ")
+ .Add Key := "sxc" , Item :=Array("sxc" , "OpenOffice.org 1.0 Spreadsheet" , "StarOffice XML (Calc) ")
+ .Add Key := "uos" , Item :=Array("uos" , "Unified Office Format spreadsheet" , "UOF spreadsheet ")
+ .Add Key := "vor" , Item :=Array("vor" , "StarCalc 5.0 Template" , "StarCalc 5.0 Vorlage/Template ")
+ .Add Key := "vor3" , Item :=Array("vor" , "StarCalc 3.0 Template" , "StarCalc 3.0 Vorlage/Template ")
+ .Add Key := "vor4" , Item :=Array("vor" , "StarCalc 4.0 Template" , "StarCalc 4.0 Vorlage/Template ")
+ .Add Key := "xhtml" , Item :=Array("xhtml" , "XHTML" , "XHTML Calc File ")
+ .Add Key := "xls" , Item :=Array("xls" , "Microsoft Excel 97/2000/XP" , "MS Excel 97 ")
+ .Add Key := "xls5" , Item :=Array("xls" , "Microsoft Excel 5.0" , "MS Excel 5.0/95 ")
+ .Add Key := "xls95" , Item :=Array("xls" , "Microsoft Excel 95" , "MS Excel 95 ")
+ .Add Key := "xlt" , Item :=Array("xlt" , "Microsoft Excel 97/2000/XP Template" , "MS Excel 97 Vorlage/Template ")
+ .Add Key := "xlt5" , Item :=Array("xlt" , "Microsoft Excel 5.0 Template" , "MS Excel 5.0/95 Vorlage/Template ")
+ .Add Key := "xlt95" , Item :=Array("xlt" , "Microsoft Excel 95 Template" , "MS Excel 95 Vorlage/Template ")
+
+ End With
+
+ With WriterWebExportFilters
+ .Add Key := "etext" , Item :=Array("txt" , "Text Encoded (OpenOffice.org Writer/Web)" , "Text (encoded) (StarWriter/Web) ")
+ .Add Key := "html" , Item :=Array("html" , "HTML Document" , "HTML ")
+ '.Add Key := "html" , Item :=Array("html" , "HTML Document Template" , "writerweb8_writer_template ")
+ .Add Key := "html10" , Item :=Array("html" , "OpenOffice.org 1.0 HTML Template" , "writer_web_StarOffice_XML_Writer_Web_Template ")
+ .Add Key := "mediawiki" , Item :=Array("txt" , "MediaWiki" , "MediaWiki_Web ")
+ .Add Key := "pdf" , Item :=Array("pdf" , "PDF - Portable Document Format" , "writer_web_pdf_Export ")
+ .Add Key := "sdw" , Item :=Array("sdw" , "StarWriter 5.0 (OpenOffice.org Writer/Web)" , "StarWriter 5.0 (StarWriter/Web) ")
+ .Add Key := "sdw3" , Item :=Array("sdw" , "StarWriter 3.0 (OpenOffice.org Writer/Web)" , "StarWriter 3.0 (StarWriter/Web) ")
+ .Add Key := "sdw4" , Item :=Array("sdw" , "StarWriter 4.0 (OpenOffice.org Writer/Web)" , "StarWriter 4.0 (StarWriter/Web) ")
+ .Add Key := "text" , Item :=Array("txt" , "Text (OpenOffice.org Writer/Web)" , "Text (StarWriter/Web) ")
+ .Add Key := "text10" , Item :=Array("txt" , "OpenOffice.org 1.0 Text Document (OpenOffice.org Writer/Web)" , "writer_web_StarOffice_XML_Writer ")
+ .Add Key := "odt" , Item :=Array("txt" , "OpenOffice.org Text (OpenOffice.org Writer/Web)" , "writerweb8_writer ")
+ .Add Key := "vor" , Item :=Array("vor" , "StarWriter/Web 5.0 Template" , "StarWriter/Web 5.0 Vorlage/Template ")
+ .Add Key := "vor4" , Item :=Array("vor" , "StarWriter/Web 4.0 Template" , "StarWriter/Web 4.0 Vorlage/Template ")
+
+ End With
+
+ With DocTypeToFiltersMap
+ .Add Key := "com.sun.star.text.TextDocument", Item := WriterExportFilters
+ .Add Key := "com.sun.star.sheet.SpreadsheetDocument", Item := CalcExportFilters
+ .Add Key := "com.sun.star.presentation.PresentationDocument", Item :=ImpressExportFilters
+ .Add Key := "com.sun.star.drawing.DrawingDocument", Item := DrawExportFilters
+ .Add Key := "com.sun.star.text.WebDocument", Item := WriterWebExportFilters
+ End With
+ ExportFiltersInited = True
+End Sub
+
+Function FilterSaveExtension(filterDescriptor ())
+ FilterSaveExtension = Trim(filterDescriptor(0))
+End Function
+
+Function FilterHandler(filterDescriptor ())
+ FilterHandler = Trim(filterDescriptor(2))
+End Function
+
+Function GetFilter(docType, outputFormat)
+ Dim filters
+
+ On Error Goto MissingFilter
+ filters = DocTypeToFiltersMap(docType)
+ LogMessage "output format is " & outputFormat
+ GetFilter = filters(outputFormat)
+
+Done:
+ Exit Function
+
+MissingFilter:
+ LogMessage("No existing filters for exporting " & docType & " to " & outputFormat)
+ GetFilter = Null
+ Resume Done
+End Function
+
diff --git a/contrib/odt/BasicODConverter/Main.bas b/contrib/odt/BasicODConverter/Main.bas
new file mode 100644
index 0000000..44838d3
--- /dev/null
+++ b/contrib/odt/BasicODConverter/Main.bas
@@ -0,0 +1,201 @@
+REM ***** BASIC *****
+
+Dim Interactive As Boolean
+Dim WaitFor
+
+Function Convert(Optional inFileURL, Optional filterSpec, Optional outFileURL)
+ Dim inDoc, inDocType, openParams, closeInDoc, presentationDoc
+
+ ' Set Interactivity i.e., LogMessage pops up a message.
+ Interactive = False
+
+ WaitFor = 10
+
+ ' Init dependencies
+ BasicLibraries.LoadLibrary("Tools")
+ ' BasicLibraries.LoadLibrary("XrayTool")
+
+ ' Setup Export filters
+ InitExportFilters
+
+ ' Export to doc format by default
+ If IsMissing(filterSpec) Then
+ If Interactive Then
+ filterSpec = InputBox("Export to: ")
+ Else
+ filterSpec = "doc"
+ End If
+ End If
+ filterSpec = Trim(filterSpec)
+
+ closeInDoc = False
+ If IsMissing(inFileURL) Then
+ ' Most likely, the Macro is run interactively. Act on
+ ' the current document
+ If Not ThisComponent.HasLocation() Then
+ LogMessage("Document doesn't have a location")
+ Goto Failure
+ End If
+
+ inDoc = ThisComponent
+ inFileURL = inDoc.GetLocation()
+ closeInDoc = False
+
+ Else
+ ' Load the document
+ On Error Goto Failure
+ openParams = Array(MakePropertyValue("Hidden", True),MakePropertyValue("ReadOnly", True),)
+
+ 'openParams = Array()
+ inDoc = StarDesktop.loadComponentFromURL(inFileURL, "_blank", 0, OpenParams())
+ closeInDoc = True
+ End If
+
+ If IsMissing(outFileURL) Then
+ outFileURL = GetURLWithoutExtension(inFileURL)
+ End If
+
+ If ExportDocument(inDoc, filterSpec, outFileURL) Then
+ Goto Success
+ End If
+
+ LogMessage("filterSpec1 is " & filterSpec)
+
+ ' Export didn't go through. Maybe didn't find a valid filter.
+
+ ' Check whether the request is to convert a Text or a Web
+ ' Document to a Presentation Document
+
+ inDocType = GetDocumentType(inDoc)
+ If (inDocType = "com.sun.star.text.TextDocument" Or _
+ inDocType = "com.sun.star.text.WebDocument") Then
+ LogMessage("Filterspec2 is " & filterSpec)
+ filter = GetFilter("com.sun.star.presentation.PresentationDocument", filterSpec)
+ If IsNull(filter) Then
+ LogMessage("We tried our best. Nothing more to do"
+ Goto Failure
+ Else
+ LogMessage("Trying to create presentation document. Found valid filter for " & filterSpec)
+ End If
+ Else
+ Goto Failure
+ End If
+
+ ' Export Outline to Presentation
+ dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
+ dispatcher.executeDispatch(inDoc.CurrentController.Frame, ".uno:SendOutlineToStarImpress", "", 0, Array())
+
+ ' Dispatch event above is aynchronous. Wait for a few seconds for the above event to finish
+ Wait(WaitFor * 1000)
+
+ ' After the dispatch, the current component is a presentation
+ ' document. Note that it doesn't have a location
+
+ presentationDoc = ThisComponent
+ If IsNull(ExportDocument(presentationDoc, filter, outFileURL)) Then
+ Goto Failure
+ Else
+ presentationDoc.Close(True)
+ End If
+
+Success:
+ LogMessage("Successfully exported to " & outFileURL )
+ Goto Done
+
+Failure:
+ LogMessage("Export failed " & outFileURL )
+ Goto Done
+
+Done:
+ If closeInDoc Then
+ inDoc.Close(True)
+ End If
+End Function
+
+' http://codesnippets.services.openoffice.org/Writer/Writer.MergeDocs.snip
+' http://user.services.openoffice.org/en/forum/viewtopic.php?f=20&t=39983
+' http://user.services.openoffice.org/en/forum/viewtopic.php?f=21&t=23531
+
+' http://wiki.services.openoffice.org/wiki/Documentation/BASIC_Guide/Files_and_Directories_%28Runtime_Library%29
+
+
+Function ExportDocument(inputDoc, filterSpec, outFileURL) As Boolean
+ Dim inputDocType, filter
+ ExportDocument = False
+
+ On Error Goto Failure
+ inputDocType = GetDocumentType(inputDoc)
+
+ If IsArray(filterSpec) Then
+ ' Filter is fully specified
+ filter = filterSpec
+ Else
+ ' Filter is specified by it's name
+ filter = GetFilter(inputDocType, filterSpec)
+ End If
+
+ If InStr(outFileURL, ".") = 0 Then
+ outFileURL = outFileURL & "." & FilterSaveExtension(filter)
+ End If
+
+ LogMessage("outFileURL is " & outFileURL)
+
+ inputDoc.storeToUrl(outFileURL, Array(MakePropertyValue("FilterName", FilterHandler(filter))))
+
+ ExportDocument = True
+ LogMessage("Export to " & outFileURL & " succeeded")
+Done:
+ Exit Function
+
+Failure:
+ LogMessage("Export to " & outFileURL & " failed")
+ Resume Done
+End Function
+
+
+Function GetURLWithoutExtension(s As String)
+ Dim pos
+ pos = Instr(s, ".")
+ If pos = 0 Then
+ GetURLWithoutExtension = s
+ Else
+ GetURLWithoutExtension = Left(s, pos - 1)
+ End If
+End Function
+
+Function GetDocumentType(oDoc)
+ For Each docType in DocTypes
+ If (oDoc.supportsService(docType)) Then
+ GetDocumentType = docType
+ Exit Function
+ End If
+ Next docType
+ GetDocumentType = Nothing
+End Function
+
+Function MakePropertyValue(Optional sName As String, Optional sValue) As com.sun.star.beans.PropertyValue
+ Dim oPropertyValue As New com.sun.star.beans.PropertyValue
+
+ If Not IsMissing(sName) Then
+ oPropertyValue.Name = sName
+ EndIf
+
+ If Not IsMissing(sValue) Then
+ oPropertyValue.Value = sValue
+ EndIf
+
+ MakePropertyValue() = oPropertyValue
+
+End Function
+
+
+Sub LogMessage(message)
+ If Interactive Then
+ If Err <> 0 Then
+ Print "Error " & Err & ": " & Error$ & " (line : " & Erl & ")"
+ End If
+ Print message
+ End If
+End Sub
+
+
diff --git a/lisp/ob-io.el b/lisp/ob-io.el
deleted file mode 100644
index 7742fc6..0000000
--- a/lisp/ob-io.el
+++ /dev/null
@@ -1,122 +0,0 @@
-;;; ob-io.el --- org-babel functions for Io evaluation
-
-;; Copyright (C) 2012 Free Software Foundation, Inc.
-
-;; Author: Andrzej Lichnerowicz
-;; Keywords: literate programming, reproducible research
-;; Homepage: http://orgmode.org
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;; Currently only supports the external execution. No session support yet.
-;; :results output -- runs in scripting mode
-;; :results output repl -- runs in repl mode
-
-;;; Requirements:
-;; - Io language :: http://iolanguage.org/
-;; - Io major mode :: Can be installed from Io sources
-;; https://github.com/stevedekorte/io/blob/master/extras/SyntaxHighlighters/Emacs/io-mode.el
-
-;;; Code:
-(require 'ob)
-(require 'ob-ref)
-(require 'ob-comint)
-(require 'ob-eval)
-(eval-when-compile (require 'cl))
-
-(add-to-list 'org-babel-tangle-lang-exts '("io" . "io"))
-(defvar org-babel-default-header-args:io '())
-(defvar org-babel-io-command "io"
- "Name of the command to use for executing Io code.")
-
-
-(defun org-babel-execute:io (body params)
- "Execute a block of Io code with org-babel. This function is
-called by `org-babel-execute-src-block'"
- (message "executing Io source code block")
- (let* ((processed-params (org-babel-process-params params))
- (session (org-babel-io-initiate-session (nth 0 processed-params)))
- (vars (nth 1 processed-params))
- (result-params (nth 2 processed-params))
- (result-type (cdr (assoc :result-type params)))
- (full-body (org-babel-expand-body:generic
- body params))
- (result (org-babel-io-evaluate
- session full-body result-type result-params)))
-
- (org-babel-reassemble-table
- result
- (org-babel-pick-name
- (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
- (org-babel-pick-name
- (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))
-
-
-(defun org-babel-io-table-or-string (results)
- "Convert RESULTS into an appropriate elisp value.
-If RESULTS look like a table, then convert them into an
-Emacs-lisp table, otherwise return the results as a string."
- (org-babel-script-escape results))
-
-
-(defvar org-babel-io-wrapper-method
- "(
-%s
-) asString print
-")
-
-
-(defun org-babel-io-evaluate (session body &optional result-type result-params)
- "Evaluate BODY in external Io process.
-If RESULT-TYPE equals 'output then return standard output as a string.
-If RESULT-TYPE equals 'value then return the value of the last statement
-in BODY as elisp."
- (when session (error "Sessions are not supported for Io. Yet."))
- (case result-type
- (output
- (if (member "repl" result-params)
- (org-babel-eval org-babel-io-command body)
- (let ((src-file (org-babel-temp-file "io-")))
- (progn (with-temp-file src-file (insert body))
- (org-babel-eval
- (concat org-babel-io-command " " src-file) "")))))
- (value (let* ((src-file (org-babel-temp-file "io-"))
- (wrapper (format org-babel-io-wrapper-method body)))
- (with-temp-file src-file (insert wrapper))
- ((lambda (raw)
- (if (member "code" result-params)
- raw
- (org-babel-io-table-or-string raw)))
- (org-babel-eval
- (concat org-babel-io-command " " src-file) ""))))))
-
-
-(defun org-babel-prep-session:io (session params)
- "Prepare SESSION according to the header arguments specified in PARAMS."
- (error "Sessions are not supported for Io. Yet."))
-
-(defun org-babel-io-initiate-session (&optional session)
- "If there is not a current inferior-process-buffer in SESSION
-then create. Return the initialized session. Sessions are not
-supported in Io."
- nil)
-
-(provide 'ob-io)
-
-
-
-;;; ob-io.el ends here
diff --git a/lisp/ob-scala.el b/lisp/ob-scala.el
deleted file mode 100644
index 8af4886..0000000
--- a/lisp/ob-scala.el
+++ /dev/null
@@ -1,120 +0,0 @@
-;;; ob-scala.el --- org-babel functions for Scala evaluation
-
-;; Copyright (C) 2012 Free Software Foundation, Inc.
-
-;; Author: Andrzej Lichnerowicz
-;; Keywords: literate programming, reproducible research
-;; Homepage: http://orgmode.org
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;; Currently only supports the external execution. No session support yet.
-
-;;; Requirements:
-;; - Scala language :: http://www.scala-lang.org/
-;; - Scala major mode :: Can be installed from Scala sources
-;; https://github.com/scala/scala-dist/blob/master/tool-support/src/emacs/scala-mode.el
-
-;;; Code:
-(require 'ob)
-(require 'ob-ref)
-(require 'ob-comint)
-(require 'ob-eval)
-(eval-when-compile (require 'cl))
-
-(add-to-list 'org-babel-tangle-lang-exts '("scala" . "scala"))
-(defvar org-babel-default-header-args:scala '())
-(defvar org-babel-scala-command "scala"
- "Name of the command to use for executing Scala code.")
-
-
-(defun org-babel-execute:scala (body params)
- "Execute a block of Scala code with org-babel. This function is
-called by `org-babel-execute-src-block'"
- (message "executing Scala source code block")
- (let* ((processed-params (org-babel-process-params params))
- (session (org-babel-scala-initiate-session (nth 0 processed-params)))
- (vars (nth 1 processed-params))
- (result-params (nth 2 processed-params))
- (result-type (cdr (assoc :result-type params)))
- (full-body (org-babel-expand-body:generic
- body params))
- (result (org-babel-scala-evaluate
- session full-body result-type result-params)))
-
- (org-babel-reassemble-table
- result
- (org-babel-pick-name
- (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
- (org-babel-pick-name
- (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))
-
-
-(defun org-babel-scala-table-or-string (results)
- "Convert RESULTS into an appropriate elisp value.
-If RESULTS look like a table, then convert them into an
-Emacs-lisp table, otherwise return the results as a string."
- (org-babel-script-escape results))
-
-
-(defvar org-babel-scala-wrapper-method
- "(
-%s
-) asString print
-")
-
-
-(defun org-babel-scala-evaluate
- (session body &optional result-type result-params)
- "Evaluate BODY in external Scala process.
-If RESULT-TYPE equals 'output then return standard output as a string.
-If RESULT-TYPE equals 'value then return the value of the last statement
-in BODY as elisp."
- (when session (error "Sessions are not supported for Scala. Yet."))
- (case result-type
- (output
- (let ((src-file (org-babel-temp-file "scala-")))
- (progn (with-temp-file src-file (insert body))
- (org-babel-eval
- (concat org-babel-scala-command " " src-file) ""))))
- (value
- (let* ((src-file (org-babel-temp-file "scala-"))
- (wrapper (format org-babel-scala-wrapper-method body)))
- (with-temp-file src-file (insert wrapper))
- ((lambda (raw)
- (if (member "code" result-params)
- raw
- (org-babel-scala-table-or-string raw)))
- (org-babel-eval
- (concat org-babel-scala-command " " src-file) ""))))))
-
-
-(defun org-babel-prep-session:scala (session params)
- "Prepare SESSION according to the header arguments specified in PARAMS."
- (error "Sessions are not supported for Scala. Yet."))
-
-(defun org-babel-scala-initiate-session (&optional session)
- "If there is not a current inferior-process-buffer in SESSION
-then create. Return the initialized session. Sessions are not
-supported in Scala."
- nil)
-
-(provide 'ob-scala)
-
-
-
-;;; ob-scala.el ends here
diff --git a/testing/README b/testing/README
deleted file mode 100644
index 4a68174..0000000
--- a/testing/README
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- mode:org -*-
-#+Title: Org-mode Testing
-#+Property: results silent
-
-* dependencies
-The only dependency is [[http://www.emacswiki.org/emacs/ErtTestLibrary][ERT]] the Emacs testing library which ships with
-Emacs24. If you are running an older version of Emacs and don't
-already have ERT installed it can be installed from its old [[https://github.com/ohler/ert][git
-repository]].
-
-* non-interactive batch testing from the command line
-The simplest way to run the Org-mode test suite is from the command
-line with the following invocation. Note that the paths below are
-relative to the base of the Org-mode directory.
-#+BEGIN_SRC sh
- emacs -Q --batch -l lisp/org.el -l testing/org-test.el \
- --eval "(progn (org-reload) (setq org-confirm-babel-evaluate nil))" \
- -f org-test-run-batch-tests
-#+END_SRC
-
-The options in the above command are explained below.
-| -Q | ignores any personal configuration ensuring a vanilla Emacs instance is used |
-| --batch | runs Emacs in "batch" mode with no gui and termination after execution |
-| -l | loads Org-mode and the org mode test suite defined in testing/org-test.el |
-| --eval | reloads Org-mode and allows evaluation of code blocks by the tests |
-| -f | actually runs the tests using the `org-test-run-batch-tests' function |
-
-* interactive testing from within Emacs
-To run the Org-mode test suite from a current Emacs instance simply
-load and run the test suite with the following commands.
-
-1) First load the test suite.
- #+BEGIN_SRC emacs-lisp :var here=(buffer-file-name)
- (add-to-list 'load-path (file-name-directory here))
- (require 'org-test)
- #+END_SRC
-
-2) Then run the test suite.
- #+BEGIN_SRC emacs-lisp
- (org-test-run-all-tests)
- #+END_SRC
-* troubleshooting
-- If the value of the =org-babel-no-eval-on-ctrl-c-ctrl-c= is non-nil
- then it will result in some test failure, as there are tests which
- rely on this behavior.
diff --git a/testing/README.org b/testing/README.org
new file mode 100644
index 0000000..faa0dd5
--- /dev/null
+++ b/testing/README.org
@@ -0,0 +1,115 @@
+#+Title: Org-mode Testing
+#+Babel: results silent
+
+The following instructions describe how to get started using the
+Org-mode test framework.
+
+* To run the tests interactively
+ :PROPERTIES:
+ :tangle: no
+ :END:
+1) Install the jump.el testing dependency which is included as a git
+ submodule in the org-mode repository. To do so run the following
+ git submodule commands from inside the base of the Org-mode
+ directory (or just execute the following code block).
+
+ #+begin_src sh
+ cd ..
+ git submodule init
+ git submodule update
+ #+end_src
+
+2) Load the [[file:org-test.el][org-test.el]] file
+ #+begin_src emacs-lisp
+ (load-file "org-test.el")
+ #+end_src
+
+3) The =org-test-jump= command is now bound to =M-C-j= in all
+ emacs-lisp files. Call this command from any file in the =lisp/=
+ directory of the org-mode repository to jump to the related test
+ file in the =testing/= directory. Call this functions with a
+ prefix argument, and the corresponding test file will be stubbed
+ out if it doesn't already exist.
+
+4) Ingest the library-of-babel.org file since some tests require this.
+ #+begin_src emacs-lisp
+ (org-babel-lob-ingest "../contrib/babel/library-of-babel.org")
+ #+end_src
+
+5) [[info:ert#Top][Review the ERT documentation]]
+
+6) A number of org-mode-specific functions and macros are provided in
+ =org-test.el= see the [[file:org-test.el::%3B%3B%3B%20Functions%20for%20writing%20tests][;;; Functions for Writing Tests]] subsection of
+ that file. Some of these functions make use of example org-mode
+ files located in the [[file:examples][examples/]] directory.
+
+7) Functions for loading and running the Org-mode tests are provided
+ in the [[file:org-test.el::%3B%3B%3B%20Load%20and%20Run%20tests][;;; Load and Run Tests]] subsection, the most important of
+ which are
+ - =org-test-load= which loads the entire Org-mode test suite
+ - =org-test-current-defun= which runs all tests for the current
+ function around point (should be called from inside of an
+ Org-mode elisp file)
+ - =org-test-run-all-tests= which runs the entire Org-mode test suite
+ - also note that the =ert= command can also be used to run tests
+
+8) Load and run all tests
+ #+begin_src emacs-lisp
+ (load-file "org-test.el")
+ (org-babel-lob-ingest "../contrib/babel/library-of-babel.org")
+ (org-test-load)
+ (org-test-run-all-tests)
+ #+end_src
+
+* To run the tests in batch mode
+First tangle this file out to your desktop.
+#+headers: :tangle ~/Desktop/run-org-tests.el
+#+begin_src emacs-lisp :var org-dir=(expand-file-name ".." (file-name-directory (or load-file-name (buffer-file-name))))
+ ;; add to the load path
+ (add-to-list 'load-path (concat org-dir "/lisp/"))
+ (add-to-list 'load-path (concat org-dir "/lisp/testing/"))
+ (add-to-list 'load-path (concat org-dir "/lisp/testing/ert/"))
+
+ ;; load Org-mode
+ (require 'org)
+
+ ;; setup the ID locations used in tests
+ (require 'org-id)
+ (org-id-update-id-locations
+ (list (concat org-dir "/testing/examples/babel.org")
+ (concat org-dir "/testing/examples/ob-C-test.org")
+ (concat org-dir "/testing/examples/normal.org")
+ (concat org-dir "/testing/examples/ob-awk-test.org")
+ (concat org-dir "/testing/examples/ob-octave.org")
+ (concat org-dir "/testing/examples/ob-fortran-test.org")
+ (concat org-dir "/testing/examples/ob-maxima-test.org")
+ (concat org-dir "/testing/examples/link-in-heading.org")
+ (concat org-dir "/testing/examples/links.org")))
+
+ ;; ensure that the latest Org-mode is loaded
+ (org-reload)
+
+ ;; load the test suite
+ (load-file (concat org-dir "/testing/org-test.el"))
+
+ ;; configure Babel
+ (org-babel-lob-ingest (concat org-dir "/contrib/babel/library-of-babel.org"))
+ (org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((emacs-lisp . t)
+ (sh . t)))
+ (setq org-confirm-babel-evaluate nil)
+
+ ;; run the test suite
+ (org-test-run-all-tests)
+
+ ;; print the results
+ (with-current-buffer "*ert*"
+ (print (buffer-string)))
+#+end_src
+
+Then run the test suite with the following command which could use any
+version of Emacs.
+#+begin_src sh :results output silent
+ emacs --batch -Q -l ~/Desktop/run-org-tests.el
+#+end_src
diff --git a/testing/contrib/lisp/.gitignore b/testing/contrib/lisp/.gitignore
new file mode 100644
index 0000000..6e7ef91
--- /dev/null
+++ b/testing/contrib/lisp/.gitignore
@@ -0,0 +1 @@
+# this file ensures that the testing/contrib/lisp directory is created by git
\ No newline at end of file
diff --git a/testing/examples/include.org b/testing/examples/include.org
deleted file mode 100644
index 186facb..0000000
--- a/testing/examples/include.org
+++ /dev/null
@@ -1,10 +0,0 @@
-Small Org file with an include keyword.
-
-#+BEGIN_SRC emacs-lisp :exports results
-(+ 2 1)
-#+END_SRC
-
-#+INCLUDE: "include2.org"
-
-* Heading
-body
diff --git a/testing/examples/include2.org b/testing/examples/include2.org
deleted file mode 100644
index f985b46..0000000
--- a/testing/examples/include2.org
+++ /dev/null
@@ -1 +0,0 @@
-Success!
diff --git a/testing/examples/table.org b/testing/examples/table.org
new file mode 100644
index 0000000..3c6caed
--- /dev/null
+++ b/testing/examples/table.org
@@ -0,0 +1,19 @@
+#+TITLE: example file with tables
+#+OPTIONS: num:nil ^:nil
+
+This is an example file for use by the Org-mode tests defined in
+file:../lisp/test-org-table.el.
+
+* simple formula
+ :PROPERTIES:
+ :ID: 563523f7-3f3e-49c9-9622-9216cc9a5d95
+ :END:
+
+#+tblname: simple-formula
+| 1 |
+| 2 |
+| 3 |
+| 4 |
+|----|
+| 10 |
+ #+TBLFM: $1=vsum(@1..@-1)
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
deleted file mode 100644
index db46f81..0000000
--- a/testing/lisp/test-org-element.el
+++ /dev/null
@@ -1,436 +0,0 @@
-;;; test-org-element.el --- Tests for org-element.el
-
-;; Copyright (C) 2012 Nicolas Goaziou
-
-;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(unless (featurep 'org-element)
- (signal 'missing-test-dependency "org-element"))
-
-
-\f
-;;; Tests:
-
-
-\f
-;;;; Headlines
-
-(ert-deftest test-org-element/headline-quote-keyword ()
- "Test QUOTE keyword recognition."
- ;; Reference test.
- (org-test-with-temp-text "* Headline"
- (let ((org-quote-string "QUOTE"))
- (should-not (org-element-property :quotedp (org-element-at-point)))))
- ;; Standard position.
- (org-test-with-temp-text "* QUOTE Headline"
- (let ((org-quote-string "QUOTE"))
- (let ((headline (org-element-at-point)))
- (should (org-element-property :quotedp headline))
- ;; Test removal from raw value.
- (should (equal (org-element-property :raw-value headline) "Headline"))))
- ;; Case sensitivity.
- (let ((org-quote-string "Quote"))
- (should-not (org-element-property :quotedp (org-element-at-point)))))
- ;; With another keyword.
- (org-test-with-temp-text "* TODO QUOTE Headline"
- (let ((org-quote-string "QUOTE")
- (org-todo-keywords '((sequence "TODO" "DONE"))))
- (should (org-element-property :quotedp (org-element-at-point))))))
-
-(ert-deftest test-org-element/headline-comment-keyword ()
- "Test COMMENT keyword recognition."
- ;; Reference test.
- (org-test-with-temp-text "* Headline"
- (let ((org-comment-string "COMMENT"))
- (should-not (org-element-property :commentedp (org-element-at-point)))))
- ;; Standard position.
- (org-test-with-temp-text "* COMMENT Headline"
- (let ((org-comment-string "COMMENT"))
- (let ((headline (org-element-at-point)))
- (should (org-element-property :commentedp headline))
- ;; Test removal from raw value.
- (should (equal (org-element-property :raw-value headline) "Headline"))))
- ;; Case sensitivity.
- (let ((org-comment-string "Comment"))
- (should-not (org-element-property :commentedp (org-element-at-point)))))
- ;; With another keyword.
- (org-test-with-temp-text "* TODO COMMENT Headline"
- (let ((org-comment-string "COMMENT")
- (org-todo-keywords '((sequence "TODO" "DONE"))))
- (should (org-element-property :commentedp (org-element-at-point))))))
-
-(ert-deftest test-org-element/headline-archive-tag ()
- "Test ARCHIVE tag recognition."
- ;; Reference test.
- (org-test-with-temp-text "* Headline"
- (let ((org-archive-tag "ARCHIVE"))
- (should-not (org-element-property :archivedp (org-element-at-point)))))
- ;; Single tag.
- (org-test-with-temp-text "* Headline :ARCHIVE:"
- (let ((org-archive-tag "ARCHIVE"))
- (let ((headline (org-element-at-point)))
- (should (org-element-property :archivedp headline))
- ;; Test tag removal.
- (should-not (org-element-property :tags headline))))
- (let ((org-archive-tag "Archive"))
- (should-not (org-element-property :archivedp (org-element-at-point)))))
- ;; Multiple tags.
- (org-test-with-temp-text "* Headline :test:ARCHIVE:"
- (let ((org-archive-tag "ARCHIVE"))
- (let ((headline (org-element-at-point)))
- (should (org-element-property :archivedp headline))
- ;; Test tag removal.
- (should (equal (org-element-property :tags headline) ":test:"))))))
-
-
-\f
-;;;; Example-blocks and Src-blocks
-
-(ert-deftest test-org-element/block-switches ()
- "Test `example-block' and `src-block' switches parsing."
- (let ((org-coderef-label-format "(ref:%s)"))
- ;; 1. Test "-i" switch.
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should-not (org-element-property :preserve-indent element))))
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -i\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (org-element-property :preserve-indent element))))
- (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should-not (org-element-property :preserve-indent element))))
- (org-test-with-temp-text "#+BEGIN_EXAMPLE -i\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (org-element-property :preserve-indent element))))
- ;; 2. "-n -r -k" combination should number lines, retain labels but
- ;; not use them in coderefs.
- (org-test-with-temp-text "#+BEGIN_EXAMPLE -n -r -k\nText.\N#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (org-element-property :retain-labels element)
- (not (org-element-property :use-labels element))))))
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp -n -r -k\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (org-element-property :retain-labels element)
- (not (org-element-property :use-labels element))))))
- ;; 3. "-n -r" combination should number-lines remove labels and not
- ;; use them in coderefs.
- (org-test-with-temp-text "#+BEGIN_EXAMPLE -n -r\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (not (org-element-property :retain-labels element))
- (not (org-element-property :use-labels element))))))
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (not (org-element-property :retain-labels element))
- (not (org-element-property :use-labels element))))))
- ;; 4. "-n" or "+n" should number lines, retain labels and use them
- ;; in coderefs.
- (org-test-with-temp-text "#+BEGIN_EXAMPLE -n\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (org-element-property :retain-labels element)
- (org-element-property :use-labels element)))))
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -n\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (org-element-property :retain-labels element)
- (org-element-property :use-labels element)))))
- (org-test-with-temp-text "#+BEGIN_EXAMPLE +n\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (org-element-property :retain-labels element)
- (org-element-property :use-labels element)))))
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp +n\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (and (org-element-property :number-lines element)
- (org-element-property :retain-labels element)
- (org-element-property :use-labels element)))))
- ;; 5. No switch should not number lines, but retain labels and use
- ;; them in coderefs.
- (org-test-with-temp-text "#+BEGIN_EXAMPLE\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (and (not (org-element-property :number-lines element))
- (org-element-property :retain-labels element)
- (org-element-property :use-labels element)))))
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (and (not (org-element-property :number-lines element))
- (org-element-property :retain-labels element)
- (org-element-property :use-labels element)))))
- ;; 6. "-r" switch only: do not number lines, remove labels, and
- ;; don't use labels in coderefs.
- (org-test-with-temp-text "#+BEGIN_EXAMPLE -r\nText.\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should (and (not (org-element-property :number-lines element))
- (not (org-element-property :retain-labels element))
- (not (org-element-property :use-labels element))))))
- (org-test-with-temp-text "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1)\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should (and (not (org-element-property :number-lines element))
- (not (org-element-property :retain-labels element))
- (not (org-element-property :use-labels element))))))
- ;; 7. Recognize coderefs with user-defined syntax.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText [ref:text]\n#+END_EXAMPLE"
- (let ((element (org-element-current-element)))
- (should
- (equal (org-element-property :label-fmt element) "[ref:%s]"))))
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp -l \"[ref:%s]\"\n(+ 1 1) [ref:text]\n#+END_SRC"
- (let ((element (org-element-current-element)))
- (should
- (equal (org-element-property :label-fmt element) "[ref:%s]"))))))
-
-
-\f
-;;; Navigation tools.
-
-(ert-deftest test-org-element/forward-element ()
- "Test `org-element-forward' specifications."
- ;; 1. At EOB: should error.
- (org-test-with-temp-text "Some text\n"
- (goto-char (point-max))
- (should-error (org-element-forward)))
- ;; 2. Standard move: expected to ignore blank lines.
- (org-test-with-temp-text "First paragraph.\n\n\nSecond paragraph."
- (org-element-forward)
- (should (looking-at "Second paragraph.")))
- ;; 3. Headline tests.
- (org-test-with-temp-text "
-* Head 1
-** Head 1.1
-*** Head 1.1.1
-** Head 1.2"
- ;; 3.1. At an headline beginning: move to next headline at the
- ;; same level.
- (goto-line 3)
- (org-element-forward)
- (should (looking-at "** Head 1.2"))
- ;; 3.2. At an headline beginning: move to parent headline if no
- ;; headline at the same level.
- (goto-line 3)
- (org-element-forward)
- (should (looking-at "** Head 1.2")))
- ;; 4. Greater element tests.
- (org-test-with-temp-text
- "#+BEGIN_CENTER\nInside.\n#+END_CENTER\n\nOutside."
- ;; 4.1. At a greater element: expected to skip contents.
- (org-element-forward)
- (should (looking-at "Outside."))
- ;; 4.2. At the end of greater element contents: expected to skip
- ;; to the end of the greater element.
- (goto-line 2)
- (org-element-forward)
- (should (looking-at "Outside.")))
- ;; 5. List tests.
- (org-test-with-temp-text "
-- item1
-
- - sub1
-
- - sub2
-
- - sub3
-
- Inner paragraph.
-
-- item2
-
-Outside."
- ;; 5.1. At list top point: expected to move to the element after
- ;; the list.
- (goto-line 2)
- (org-element-forward)
- (should (looking-at "Outside."))
- ;; 5.2. Special case: at the first line of a sub-list, but not at
- ;; beginning of line, move to next item.
- (goto-line 2)
- (forward-char)
- (org-element-forward)
- (should (looking-at "- item2"))
- (goto-line 4)
- (forward-char)
- (org-element-forward)
- (should (looking-at " - sub2"))
- ;; 5.3 At sub-list beginning: expected to move after the sub-list.
- (goto-line 4)
- (org-element-forward)
- (should (looking-at " Inner paragraph."))
- ;; 5.4. At sub-list end: expected to move outside the sub-list.
- (goto-line 8)
- (org-element-forward)
- (should (looking-at " Inner paragraph."))
- ;; 5.5. At an item: expected to move to next item, if any.
- (goto-line 6)
- (org-element-forward)
- (should (looking-at " - sub3"))))
-
-(ert-deftest test-org-element/backward-element ()
- "Test `org-element-backward' specifications."
- ;; 1. At BOB (modulo some white spaces): should error.
- (org-test-with-temp-text " \nParagraph."
- (org-skip-whitespace)
- (should-error (org-element-backward)))
- ;; 2. Not at the beginning of an element: move at its beginning.
- (org-test-with-temp-text "Paragraph1.\n\nParagraph2."
- (goto-line 3)
- (end-of-line)
- (org-element-backward)
- (should (looking-at "Paragraph2.")))
- ;; 3. Headline tests.
- (org-test-with-temp-text "
-* Head 1
-** Head 1.1
-*** Head 1.1.1
-** Head 1.2"
- ;; 3.1. At an headline beginning: move to previous headline at the
- ;; same level.
- (goto-line 5)
- (org-element-backward)
- (should (looking-at "** Head 1.1"))
- ;; 3.2. At an headline beginning: move to parent headline if no
- ;; headline at the same level.
- (goto-line 3)
- (org-element-backward)
- (should (looking-at "* Head 1"))
- ;; 3.3. At the first top-level headline: should error.
- (goto-line 2)
- (should-error (org-element-backward)))
- ;; 4. At beginning of first element inside a greater element:
- ;; expected to move to greater element's beginning.
- (org-test-with-temp-text "Before.\n#+BEGIN_CENTER\nInside.\n#+END_CENTER."
- (goto-line 3)
- (org-element-backward)
- (should (looking-at "#\\+BEGIN_CENTER")))
- ;; 5. List tests.
- (org-test-with-temp-text "
-- item1
-
- - sub1
-
- - sub2
-
- - sub3
-
- Inner paragraph.
-
-- item2
-
-
-Outside."
- ;; 5.1. At beginning of sub-list: expected to move to the
- ;; paragraph before it.
- (goto-line 4)
- (org-element-backward)
- (should (looking-at "item1"))
- ;; 5.2. At an item in a list: expected to move at previous item.
- (goto-line 8)
- (org-element-backward)
- (should (looking-at " - sub2"))
- (goto-line 12)
- (org-element-backward)
- (should (looking-at "- item1"))
- ;; 5.3. At end of list/sub-list: expected to move to list/sub-list
- ;; beginning.
- (goto-line 10)
- (org-element-backward)
- (should (looking-at " - sub1"))
- (goto-line 15)
- (org-element-backward)
- (should (looking-at "- item1"))
- ;; 5.4. At blank-lines before list end: expected to move to top
- ;; item.
- (goto-line 14)
- (org-element-backward)
- (should (looking-at "- item1"))))
-
-(ert-deftest test-org-element/up-element ()
- "Test `org-element-up' specifications."
- ;; 1. At BOB or with no surrounding element: should error.
- (org-test-with-temp-text "Paragraph."
- (should-error (org-element-up)))
- (org-test-with-temp-text "* Head1\n* Head2"
- (goto-line 2)
- (should-error (org-element-up)))
- (org-test-with-temp-text "Paragraph1.\n\nParagraph2."
- (goto-line 3)
- (should-error (org-element-up)))
- ;; 2. At an headline: move to parent headline.
- (org-test-with-temp-text "* Head1\n** Sub-Head1\n** Sub-Head2"
- (goto-line 3)
- (org-element-up)
- (should (looking-at "\\* Head1")))
- ;; 3. Inside a greater element: move to greater element beginning.
- (org-test-with-temp-text
- "Before.\n#+BEGIN_CENTER\nParagraph1\nParagraph2\n#+END_CENTER\n"
- (goto-line 3)
- (org-element-up)
- (should (looking-at "#\\+BEGIN_CENTER")))
- ;; 4. List tests.
- (org-test-with-temp-text "* Top
-- item1
-
- - sub1
-
- - sub2
-
- Paragraph within sub2.
-
-- item2"
- ;; 4.1. Within an item: move to the item beginning.
- (goto-line 8)
- (org-element-up)
- (should (looking-at " - sub2"))
- ;; 4.2. At an item in a sub-list: move to parent item.
- (goto-line 4)
- (org-element-up)
- (should (looking-at "- item1"))
- ;; 4.3. At an item in top list: move to beginning of whole list.
- (goto-line 10)
- (org-element-up)
- (should (looking-at "- item1"))
- ;; 4.4. Special case. At very top point: should move to parent of
- ;; list.
- (goto-line 2)
- (org-element-up)
- (should (looking-at "\\* Top"))))
-
-(ert-deftest test-org-element/down-element ()
- "Test `org-element-down' specifications."
- ;; 1. Error when the element hasn't got a recursive type.
- (org-test-with-temp-text "Paragraph."
- (should-error (org-element-down)))
- ;; 2. When at a plain-list, move to first item.
- (org-test-with-temp-text "- Item 1\n - Item 1.1\n - Item 2.2"
- (goto-line 2)
- (org-element-down)
- (should (looking-at " - Item 1.1")))
- ;; 3. Otherwise, move inside the greater element.
- (org-test-with-temp-text "#+BEGIN_CENTER\nParagraph.\n#+END_CENTER"
- (org-element-down)
- (should (looking-at "Paragraph"))))
-
-
-(provide 'test-org-element)
-;;; test-org-element.el ends here
diff --git a/testing/lisp/test-org-export.el b/testing/lisp/test-org-export.el
deleted file mode 100644
index f34cc7b..0000000
--- a/testing/lisp/test-org-export.el
+++ /dev/null
@@ -1,625 +0,0 @@
-;;; test-org-export.el --- Tests for org-export.el
-
-;; Copyright (C) 2012 Nicolas Goaziou
-
-;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
-
-;; Released under the GNU General Public License version 3
-;; see: http://www.gnu.org/licenses/gpl-3.0.html
-
-;;;; Comments
-
-
-\f
-;;; Code:
-
-(unless (featurep 'org-export)
- (signal 'missing-test-dependency "org-export"))
-
-
-\f
-;;; Tests
-
-(defmacro org-test-with-backend (backend &rest body)
- "Execute body with an export back-end defined.
-
-BACKEND is the name, as a string, of the back-end. BODY is the
-body to execute. The defined back-end simply returns parsed data
-as Org syntax."
- (declare (debug (form body)) (indent 1))
- `(flet ,(let (transcoders)
- (dolist (type (append org-element-all-elements
- org-element-all-objects)
- transcoders)
- (push `(,(intern (format "org-%s-%s" backend type))
- (obj contents info)
- (,(intern (format "org-element-%s-interpreter" type))
- obj contents))
- transcoders)))
- ,@body))
-
-(ert-deftest test-org-export/parse-option-keyword ()
- "Test reading all standard #+OPTIONS: items."
- (should
- (equal
- (org-export-parse-option-keyword
- "H:1 num:t \\n:t timestamp:t arch:t author:t creator:t d:t email:t
- *:t e:t ::t f:t pri:t -:t ^:t toc:t |:t tags:t tasks:t <:t todo:t")
- '(:headline-levels
- 1 :preserve-breaks t :section-numbers t :time-stamp-file t
- :with-archived-trees t :with-author t :with-creator t :with-drawers t
- :with-email t :with-emphasize t :with-entities t :with-fixed-width t
- :with-footnotes t :with-priority t :with-special-strings t
- :with-sub-superscript t :with-toc t :with-tables t :with-tags t
- :with-tasks t :with-timestamps t :with-todo-keywords t)))
- ;; Test some special values.
- (should
- (equal
- (org-export-parse-option-keyword
- "arch:headline creator:comment d:(\"TEST\")
- ^:{} toc:1 tags:not-in-toc tasks:todo num:2")
- '( :section-numbers
- 2
- :with-archived-trees headline :with-creator comment
- :with-drawers ("TEST") :with-sub-superscript {} :with-toc 1
- :with-tags not-in-toc :with-tasks todo))))
-
-(ert-deftest test-org-export/get-inbuffer-options ()
- "Test reading all standard export keywords."
- (should
- (equal
- (org-test-with-temp-text "#+AUTHOR: Me, Myself and I
-#+CREATOR: Idem
-#+DATE: Today
-#+DESCRIPTION: Testing
-#+DESCRIPTION: with two lines
-#+EMAIL: some@email.org
-#+EXPORT_EXCLUDE_TAGS: noexport invisible
-#+KEYWORDS: test
-#+LANGUAGE: en
-#+EXPORT_SELECT_TAGS: export
-#+TITLE: Some title
-#+TITLE: with spaces"
- (org-export-get-inbuffer-options))
- '(:author
- "Me, Myself and I" :creator "Idem" :date "Today"
- :description "Testing\nwith two lines" :email "some@email.org"
- :exclude-tags ("noexport" "invisible") :keywords "test" :language "en"
- :select-tags ("export") :title "Some title with spaces"))))
-
-(ert-deftest test-org-export/define-macro ()
- "Try defining various Org macro using in-buffer #+MACRO: keyword."
- ;; Parsed macro.
- (should (equal (org-test-with-temp-text "#+MACRO: one 1"
- (org-export-get-inbuffer-options))
- '(:macro-one ("1"))))
- ;; Evaled macro.
- (should (equal (org-test-with-temp-text "#+MACRO: two (eval (+ 1 1))"
- (org-export-get-inbuffer-options))
- '(:macro-two "(eval (+ 1 1))")))
- ;; Incomplete macro.
- (should-not (org-test-with-temp-text "#+MACRO: three"
- (org-export-get-inbuffer-options)))
- ;; Macro with newline character.
- (should (equal (org-test-with-temp-text "#+MACRO: four a\\nb"
- (org-export-get-inbuffer-options))
- '(:macro-four ("a\nb"))))
- ;; Macro with protected newline character.
- (should (equal (org-test-with-temp-text "#+MACRO: five a\\\\nb"
- (org-export-get-inbuffer-options))
- '(:macro-five ("a\\nb"))))
- ;; Recursive macro.
- (org-test-with-temp-text "#+MACRO: six 6\n#+MACRO: seven 1 + {{{six}}}"
- (should
- (equal
- (org-export-get-inbuffer-options)
- '(:macro-six
- ("6")
- :macro-seven
- ("1 + " (macro (:key "six" :value "{{{six}}}" :args nil :begin 5 :end 14
- :post-blank 0))))))))
-
-(ert-deftest test-org-export/handle-options ()
- "Test if export options have an impact on output."
- ;; Test exclude tags.
- (org-test-with-temp-text "* Head1 :noexport:"
- (org-test-with-backend "test"
- (should
- (equal (org-export-as 'test nil nil nil '(:exclude-tags ("noexport")))
- ""))))
- ;; Test include tags.
- (org-test-with-temp-text "
-* Head1
-** Sub-Head1.1 :export:
-*** Sub-Head1.1.1
-* Head2"
- (org-test-with-backend "test"
- (should
- (string-match
- "\\* Head1\n\\*\\* Sub-Head1.1[ \t]+:export:\n\\*\\*\\* Sub-Head1.1.1\n"
- (org-export-as 'test nil nil nil '(:select-tags ("export")))))))
- ;; Test mixing include tags and exclude tags.
- (org-test-with-temp-text "
-* Head1 :export:
-** Sub-Head1 :noexport:
-** Sub-Head2
-* Head2 :noexport:
-** Sub-Head1 :export:"
- (org-test-with-backend "test"
- (should
- (string-match
- "\\* Head1[ \t]+:export:\n\\*\\* Sub-Head2\n"
- (org-export-as
- 'test nil nil nil
- '(:select-tags ("export") :exclude-tags ("noexport")))))))
- ;; Ignore tasks.
- (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
- (org-test-with-temp-text "* TODO Head1"
- (org-test-with-backend "test"
- (should (equal (org-export-as 'test nil nil nil '(:with-tasks nil))
- "")))))
- (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
- (org-test-with-temp-text "* TODO Head1"
- (org-test-with-backend "test"
- (should (equal (org-export-as 'test nil nil nil '(:with-tasks t))
- "* TODO Head1\n")))))
- ;; Archived tree.
- (org-test-with-temp-text "* Head1 :archive:"
- (let ((org-archive-tag "archive"))
- (org-test-with-backend "test"
- (should
- (equal (org-export-as 'test nil nil nil '(:with-archived-trees nil))
- "")))))
- (org-test-with-temp-text "* Head1 :archive:\nbody\n** Sub-head 2"
- (let ((org-archive-tag "archive"))
- (org-test-with-backend "test"
- (should
- (string-match
- "\\* Head1[ \t]+:archive:"
- (org-export-as 'test nil nil nil
- '(:with-archived-trees headline)))))))
- (org-test-with-temp-text "* Head1 :archive:"
- (let ((org-archive-tag "archive"))
- (org-test-with-backend "test"
- (should
- (string-match
- "\\`\\* Head1[ \t]+:archive:\n\\'"
- (org-export-as 'test nil nil nil '(:with-archived-trees t)))))))
- ;; Drawers.
- (let ((org-drawers '("TEST")))
- (org-test-with-temp-text ":TEST:\ncontents\n:END:"
- (org-test-with-backend "test"
- (should (equal (org-export-as 'test nil nil nil '(:with-drawers nil))
- "")))))
- (let ((org-drawers '("TEST")))
- (org-test-with-temp-text ":TEST:\ncontents\n:END:"
- (org-test-with-backend "test"
- (should (equal (org-export-as 'test nil nil nil '(:with-drawers t))
- ":TEST:\ncontents\n:END:\n"))))))
-
-(ert-deftest test-org-export/comment-tree ()
- "Test if export process ignores commented trees."
- (let ((org-comment-string "COMMENT"))
- (org-test-with-temp-text "* COMMENT Head1"
- (org-test-with-backend "test"
- (should (equal (org-export-as 'test) ""))))))
-
-(ert-deftest test-org-export/export-scope ()
- "Test all export scopes."
- (org-test-with-temp-text "
-* Head1
-** Head2
-text
-*** Head3"
- (org-test-with-backend "test"
- ;; Subtree.
- (forward-line 3)
- (should (equal (org-export-as 'test 'subtree) "text\n*** Head3\n"))
- ;; Visible.
- (goto-char (point-min))
- (forward-line)
- (org-cycle)
- (should (equal (org-export-as 'test nil 'visible) "* Head1\n"))
- ;; Body only.
- (flet ((org-test-template (body info) (format "BEGIN\n%sEND" body)))
- (should (equal (org-export-as 'test nil nil 'body-only)
- "* Head1\n** Head2\ntext\n*** Head3\n"))
- (should (equal (org-export-as 'test)
- "BEGIN\n* Head1\n** Head2\ntext\n*** Head3\nEND")))
- ;; Region.
- (goto-char (point-min))
- (forward-line 3)
- (transient-mark-mode 1)
- (push-mark (point) t t)
- (goto-char (point-at-eol))
- (should (equal (org-export-as 'test) "text\n")))))
-
-(ert-deftest test-org-export/export-snippet ()
- "Test export snippets transcoding."
- (org-test-with-temp-text "@test{A}@t{B}"
- (org-test-with-backend "test"
- (flet ((org-test-export-snippet
- (snippet contents info)
- (when (eq (org-export-snippet-backend snippet) 'test)
- (org-element-property :value snippet))))
- (let ((org-export-snippet-translation-alist nil))
- (should (equal (org-export-as 'test) "A\n")))
- (let ((org-export-snippet-translation-alist '(("t" . "test"))))
- (should (equal (org-export-as 'test) "AB\n")))))))
-
-(ert-deftest test-org-export/expand-include ()
- "Test file inclusion in an Org buffer."
- ;; Full insertion with recursive inclusion.
- (org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org\"" org-test-dir)
- (org-export-expand-include-keyword)
- (should (equal (buffer-string)
- "Small Org file with an include keyword.
-
-#+BEGIN_SRC emacs-lisp :exports results\n(+ 2 1)\n#+END_SRC
-
-Success!
-
-* Heading
-body\n")))
- ;; Localized insertion.
- (org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org\" :lines \"1-2\""
- org-test-dir)
- (org-export-expand-include-keyword)
- (should (equal (buffer-string)
- "Small Org file with an include keyword.\n")))
- ;; Insertion with constraints on headlines level.
- (org-test-with-temp-text
- (format
- "* Top heading\n#+INCLUDE: \"%s/examples/include.org\" :lines \"9-\""
- org-test-dir)
- (org-export-expand-include-keyword)
- (should (equal (buffer-string) "* Top heading\n** Heading\nbody\n")))
- ;; Inclusion within an example block.
- (org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org\" :lines \"1-2\" example"
- org-test-dir)
- (org-export-expand-include-keyword)
- (should
- (equal
- (buffer-string)
- "#+BEGIN_EXAMPLE\nSmall Org file with an include keyword.\n#+END_EXAMPLE\n")))
- ;; Inclusion within a src-block.
- (org-test-with-temp-text
- (format
- "#+INCLUDE: \"%s/examples/include.org\" :lines \"4-5\" src emacs-lisp"
- org-test-dir)
- (org-export-expand-include-keyword)
- (should (equal (buffer-string)
- "#+BEGIN_SRC emacs-lisp\n(+ 2 1)\n#+END_SRC\n"))))
-
-(ert-deftest test-org-export/user-ignore-list ()
- "Test if `:ignore-list' accepts user input."
- (org-test-with-backend "test"
- (flet ((skip-note-head
- (data backend info)
- ;; Ignore headlines with the word "note" in their title.
- (org-element-map
- data 'headline
- (lambda (headline)
- (when (string-match "\\<note\\>"
- (org-element-property :raw-value headline))
- (org-export-ignore-element headline info)))
- info)
- data))
- ;; Install function in parse tree filters.
- (let ((org-export-filter-parse-tree-functions '(skip-note-head)))
- (org-test-with-temp-text "* Head1\n* Head2 (note)\n"
- (should (equal (org-export-as 'test) "* Head1\n")))))))
-
-
-\f
-;; Footnotes
-
-(ert-deftest test-org-export/footnotes ()
- "Test footnotes specifications."
- (let ((org-footnote-section nil))
- ;; 1. Read every type of footnote.
- (org-test-with-temp-text
- "Text[fn:1] [1] [fn:label:C] [fn::D]\n\n[fn:1] A\n\n[1] B"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists
- (org-export-initial-options) '(:with-footnotes t))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- (equal
- '((1 . "A") (2 . "B") (3 . "C") (4 . "D"))
- (org-element-map
- tree 'footnote-reference
- (lambda (ref)
- (let ((def (org-export-get-footnote-definition ref info)))
- (cons (org-export-get-footnote-number ref info)
- (if (eq (org-element-property :type ref) 'inline) (car def)
- (car (org-element-contents
- (car (org-element-contents def))))))))
- info)))))
- ;; 2. Test nested footnotes order.
- (org-test-with-temp-text
- "Text[fn:1:A[fn:2]] [fn:3].\n\n[fn:2] B [fn:3] [fn::D].\n\n[fn:3] C."
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists
- (org-export-initial-options) '(:with-footnotes t))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- (equal
- '((1 . "fn:1") (2 . "fn:2") (3 . "fn:3") (4))
- (org-element-map
- tree 'footnote-reference
- (lambda (ref)
- (when (org-export-footnote-first-reference-p ref info)
- (cons (org-export-get-footnote-number ref info)
- (org-element-property :label ref))))
- info)))))
- ;; 3. Test nested footnote in invisible definitions.
- (org-test-with-temp-text "Text[1]\n\n[1] B [2]\n\n[2] C."
- ;; Hide definitions.
- (narrow-to-region (point) (point-at-eol))
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists
- (org-export-initial-options) '(:with-footnotes t))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- ;; Both footnotes should be seen.
- (should
- (= (length (org-export-collect-footnote-definitions tree info)) 2))))
- ;; 4. Test footnotes definitions collection.
- (org-test-with-temp-text "Text[fn:1:A[fn:2]] [fn:3].
-
-\[fn:2] B [fn:3] [fn::D].
-
-\[fn:3] C."
- (let ((tree (org-element-parse-buffer))
- (info (org-combine-plists
- (org-export-initial-options) '(:with-footnotes t))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should (= (length (org-export-collect-footnote-definitions tree info))
- 4))))))
-
-
-\f
-;;; Links
-
-(ert-deftest test-org-export/fuzzy-links ()
- "Test fuzz link export specifications."
- ;; 1. Links to invisible (keyword) targets should be ignored.
- (org-test-with-temp-text
- "Paragraph.\n#+TARGET: Test\n[[Test]]"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists (org-export-initial-options))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should-not
- (org-element-map
- tree 'link
- (lambda (link)
- (org-export-get-ordinal
- (org-export-resolve-fuzzy-link link info) info)) info))))
- ;; 2. Link to an headline should return headline's number.
- (org-test-with-temp-text
- "Paragraph.\n* Head1\n* Head2\n* Head3\n[[Head2]]"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists (org-export-initial-options))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- ;; Note: Headline's number is in fact a list of numbers.
- (equal '(2)
- (org-element-map
- tree 'link
- (lambda (link)
- (org-export-get-ordinal
- (org-export-resolve-fuzzy-link link info) info)) info t)))))
- ;; 3. Link to a target in an item should return item's number.
- (org-test-with-temp-text
- "- Item1\n - Item11\n - <<test>>Item12\n- Item2\n\n\n[[test]]"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists (org-export-initial-options))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- ;; Note: Item's number is in fact a list of numbers.
- (equal '(1 2)
- (org-element-map
- tree 'link
- (lambda (link)
- (org-export-get-ordinal
- (org-export-resolve-fuzzy-link link info) info)) info t)))))
- ;; 4. Link to a target in a footnote should return footnote's
- ;; number.
- (org-test-with-temp-text
- "Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists (org-export-initial-options))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- (equal '(2 3)
- (org-element-map
- tree 'link
- (lambda (link)
- (org-export-get-ordinal
- (org-export-resolve-fuzzy-link link info) info)) info)))))
- ;; 5. Link to a named element should return sequence number of that
- ;; element.
- (org-test-with-temp-text
- "#+NAME: tbl1\n|1|2|\n#+NAME: tbl2\n|3|4|\n#+NAME: tbl3\n|5|6|\n[[tbl2]]"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists (org-export-initial-options))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- (= 2
- (org-element-map
- tree 'link
- (lambda (link)
- (org-export-get-ordinal
- (org-export-resolve-fuzzy-link link info) info)) info t)))))
- ;; 6. Link to a target not within an item, a table, a footnote
- ;; reference or definition should return section number.
- (org-test-with-temp-text
- "* Head1\n* Head2\nParagraph<<target>>\n* Head3\n[[target]]"
- (let* ((tree (org-element-parse-buffer))
- (info (org-combine-plists (org-export-initial-options))))
- (setq info (org-combine-plists
- info (org-export-collect-tree-properties tree info 'test)))
- (should
- (equal '(2)
- (org-element-map
- tree 'link
- (lambda (link)
- (org-export-get-ordinal
- (org-export-resolve-fuzzy-link link info) info)) info t))))))
-
-(defun test-org-export/resolve-coderef ()
- "Test `org-export-resolve-coderef' specifications."
- (let ((org-coderef-label-format "(ref:%s)"))
- ;; 1. A link to a "-n -k -r" block returns line number.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -n -k -r\nText (ref:coderef)\n#+END_EXAMPLE"
- (let ((tree (org-element-parse-buffer)))
- (should
- (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp -n -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
- (let ((tree (org-element-parse-buffer)))
- (should
- (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
- ;; 2. A link to a "-n -r" block returns line number.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -n -r\nText (ref:coderef)\n#+END_EXAMPLE"
- (let ((tree (org-element-parse-buffer)))
- (should
- (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
- (let ((tree (org-element-parse-buffer)))
- (should
- (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
- ;; 3. A link to a "-n" block returns coderef.
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp -n\n(+ 1 1) (ref:coderef)\n#+END_SRC"
- (let ((tree (org-element-parse-buffer)))
- (should
- (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
- "coderef"))))
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -n\nText (ref:coderef)\n#+END_EXAMPLE"
- (let ((tree (org-element-parse-buffer)))
- (should
- (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
- "coderef"))))
- ;; 4. A link to a "-r" block returns line number.
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
- (let ((tree (org-element-parse-buffer)))
- (should
- (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -r\nText (ref:coderef)\n#+END_EXAMPLE"
- (let ((tree (org-element-parse-buffer)))
- (should
- (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
- ;; 5. A link to a block without a switch returns coderef.
- (org-test-with-temp-text
- "#+BEGIN_SRC emacs-lisp\n(+ 1 1) (ref:coderef)\n#+END_SRC"
- (let ((tree (org-element-parse-buffer)))
- (should
- (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
- "coderef"))))
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE\nText (ref:coderef)\n#+END_EXAMPLE"
- (let ((tree (org-element-parse-buffer)))
- (should
- (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
- "coderef"))))
- ;; 6. Correctly handle continued line numbers. A "+n" switch
- ;; should resume numbering from previous block with numbered
- ;; lines, ignoring blocks not numbering lines in the process.
- ;; A "-n" switch resets count.
- (org-test-with-temp-text "
-#+BEGIN_EXAMPLE -n
-Text.
-#+END_EXAMPLE
-
-#+BEGIN_SRC emacs-lisp
-\(- 1 1)
-#+END_SRC
-
-#+BEGIN_SRC emacs-lisp +n -r
-\(+ 1 1) (ref:addition)
-#+END_SRC
-
-#+BEGIN_EXAMPLE -n -r
-Another text. (ref:text)
-#+END_EXAMPLE"
- (let* ((tree (org-element-parse-buffer))
- (info `(:parse-tree ,tree)))
- (should (= (org-export-resolve-coderef "addition" info) 2))
- (should (= (org-export-resolve-coderef "text" info) 1))))
- ;; 7. Recognize coderef with user-specified syntax.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText. [ref:text]\n#+END_EXAMPLE"
- (let ((tree (org-element-parse-buffer)))
- (should (equal (org-export-resolve-coderef "text" `(:parse-tree ,tree))
- "text"))))))
-
-
-\f
-;;; Src-block and example-block
-
-(ert-deftest test-org-export/unravel-code ()
- "Test `org-export-unravel-code' function."
- (let ((org-coderef-label-format "(ref:%s)"))
- ;; 1. Code without reference.
- (org-test-with-temp-text "#+BEGIN_EXAMPLE\n(+ 1 1)\n#+END_EXAMPLE"
- (should (equal (org-export-unravel-code (org-element-current-element))
- '("(+ 1 1)\n"))))
- ;; 2. Code with reference.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE\n(+ 1 1) (ref:test)\n#+END_EXAMPLE"
- (should (equal (org-export-unravel-code (org-element-current-element))
- '("(+ 1 1)\n" (1 . "test")))))
- ;; 3. Code with user-defined reference.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\n(+ 1 1) [ref:test]\n#+END_EXAMPLE"
- (should (equal (org-export-unravel-code (org-element-current-element))
- '("(+ 1 1)\n" (1 . "test")))))
- ;; 4. Code references keys are relative to the current block.
- (org-test-with-temp-text "
-#+BEGIN_EXAMPLE -n
-\(+ 1 1)
-#+END_EXAMPLE
-#+BEGIN_EXAMPLE +n
-\(+ 2 2)
-\(+ 3 3) (ref:one)
-#+END_EXAMPLE"
- (goto-line 5)
- (should (equal (org-export-unravel-code (org-element-current-element))
- '("(+ 2 2)\n(+ 3 3)\n" (2 . "one")))))
- ;; 5. Free up comma-protected lines.
- ;;
- ;; 5.1. In an Org source block, every line is protected.
- (org-test-with-temp-text
- "#+BEGIN_SRC org\n,* Test\n,# comment\n,Text\n#+END_SRC"
- (should (equal (org-export-unravel-code (org-element-current-element))
- '("* Test\n# comment\nText\n"))))
- ;; 5.2. In other blocks, only headlines, comments and keywords are
- ;; protected.
- (org-test-with-temp-text
- "#+BEGIN_EXAMPLE\n,* Headline\n, * Not headline\n,Keep\n#+END_EXAMPLE"
- (should (equal (org-export-unravel-code (org-element-current-element))
- '("* Headline\n, * Not headline\n,Keep\n"))))))
-
-
-
-(provide 'test-org-export)
-;;; test-org-export.el end here
--
1.7.9.2
[-- Attachment #4: Type: text/plain, Size: 187 bytes --]
Regards,
Achim.
--
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+
Wavetables for the Terratec KOMPLEXER:
http://Synth.Stromeko.net/Downloads.html#KomplexerWaves
next prev parent reply other threads:[~2012-03-18 21:19 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-16 19:29 Org release 7.8.04 (BUGFIX-only release) Bastien
2012-03-17 16:27 ` Bastien
2012-03-17 18:14 ` Achim Gratz
2012-03-18 11:14 ` Bastien
2012-03-18 19:32 ` Achim Gratz
2012-03-18 21:08 ` Achim Gratz
2012-03-18 21:14 ` Achim Gratz [this message]
2012-03-19 7:11 ` Bastien
2012-03-19 7:41 ` Achim Gratz
2012-03-18 21:46 ` Achim Gratz
2012-03-18 21:49 ` Martyn Jago
2012-03-18 21:59 ` Achim Gratz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pqc9harc.fsf@Rainer.invalid \
--to=stromeko@nexgo.de \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).