emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Export to Texinfo
@ 2012-07-20  0:29 Jonathan Leech-Pepin
  2012-07-20  9:32 ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-07-20  0:29 UTC (permalink / raw)
  To: Org Mode Mailing List

[-- Attachment #1: Type: text/plain, Size: 3558 bytes --]

Hello all,

Over the last few days I've been working on implementing an Org ->
Texinfo exporter based on the new e-latex exporter.

It is not yet able to generate all the expected contents for export
towards an Info file, however it does create enough to successfully
export and read through Info.

Current it can do the following:
- Create the initial preamble.
- Create the menu and detailed menus in the =@top= node.
- Create the menus within each node for child menus.
- Descriptions for menus are pulled from the :DESCRIPTION: property of
  the headline.
- Convert *bold*, /italic/, ~verbatim~ and =code= markup to @strong{},
  @emph{}, @verb{} and @code{} respectively.
- Convert lisp code blocks to @lisp and other code blocks to @example.
- Create ordered and unordered lists.
- Turn descriptive lists into @table.
- Export verbatim tables to @verbatim blocks.
- Export standard tables as @multitable, using the largest cell in
  each column to define the output (outputs a string of a's equal to
  the lengths).
- Exports comments and comment blocks
- Exports Quote and example blocks, including labels for quotes.
- Footnotes are generated inline using @footnote{}.
- The copyright (@copying) section can be created by generating a
  headline with the property :copying: set to t (or any non-nil
  value).  It will be exported at the correct place in the .texi file
  and will not be duplicated in the tree.  Children of this headline
  will export within the block, so I would recommend not including any
  (it will likely result in a very odd section and errors in
  makeinfo).
- Export to .texi (org-e-texinfo-export-to-texinfo) and compile to
  info (org-e-texinfo-export-to-info).  It will not however provide an
  error buffer if it fails. That is also on the list of additions.


It will not do the following:
- Export table.el tables, they are currently being exported using the
  e-latex code, so they will cause issues with makeinfo.  I do plan to
  look at that in the future
- There is no provision for indices, limiting usefulness in
  cross-referencing.
- Additionally descriptive lists cannot be exported to @ftable or
  @vtable
- Sub and super-scripts are still being exported via latex processing.
  This likely will also fail in makeinfo.
- There is no #+attr_texinfo or #+TEXINFO: for arbitrary snippets or
  for passing features to tables/blocks.  I'm not sure exactly how to
  hook these in and would need a pointer in the right direction to do
  so.
- While looking over the reference document for the new exporter I
  realized I could likely use pre- and post- processing hooks to
  simplify some of the export process.  I have to look into this as
  well.
- The largest issue perhaps: There is no method to create @kbd{} and
  @key{} commands on export.  If anyone has any suggestions how these
  might be achieved (perhaps looking for a prefix in =code=?) I would
  greatly appreciate it.

There are a few limitations to what will successfully be exported:
- Headlines cannot contain any of the following symbols: periods,
  commas, colons or parentheses.  This is a limitation of texinfo and
  will result in errors when running makeinfo.  Semi-colons will
  export however.
- Headlines cannot contain markup or links.  Once again these are
  forbidden in texinfo and will cause failures.
- I've currently only been looking at creating valid info output,
  output to PDF or HTML via makeinfo may fail.

It can also be found at
https://github.com/jleechpe/org-mode/blob/texinfo/contrib/lisp/org-e-texinfo.el

Regards,

Jon

[-- Attachment #2: org-e-texinfo.el --]
[-- Type: application/octet-stream, Size: 61103 bytes --]

;;; org-e-texinfo.el --- Texinfo Back-End For Org Export Engine

;; Author: Jonathan Leech-Pepin <jonathan.leechpepin 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 Texinfo back-end for Org generic exporter.
;;
;; To test it, run
;;
;;   M-: (org-export-to-buffer 'e-texinfo "*Test e-texinfo*") RET
;;
;; in an org-mode buffer then switch to the buffer to see the Texinfo
;; export.  See contrib/lisp/org-export.el for more details on how
;; this exporter works.
;;
;; It introduces five new buffer keywords: "TEXINFO_CLASS",
;; "TEXINFO_FILENAME", "TEXINFO_HEADER", "SUBTITLE" and "SUBAUTHOR".

;;; Code:

(eval-when-compile (require 'cl))
(require 'org-export)

(defvar orgtbl-exp-regexp)

\f
;;; Define Back-End

(defvar org-e-texinfo-translate-alist
  '((babel-call . org-e-texinfo-babel-call)
    (bold . org-e-texinfo-bold)
    (center-block . org-e-texinfo-center-block)
    (clock . org-e-texinfo-clock)
    (code . org-e-texinfo-code)
    (comment . org-e-texinfo-comment)
    (comment-block . org-e-texinfo-comment-block)
    (drawer . org-e-texinfo-drawer)
    (dynamic-block . org-e-texinfo-dynamic-block)
    (entity . org-e-texinfo-entity)
    (example-block . org-e-texinfo-example-block)
    (export-block . org-e-texinfo-export-block)
    (export-snippet . org-e-texinfo-export-snippet)
    (fixed-width . org-e-texinfo-fixed-width)
    (footnote-definition . org-e-texinfo-footnote-definition)
    (footnote-reference . org-e-texinfo-footnote-reference)
    (headline . org-e-texinfo-headline)
    (horizontal-rule . org-e-texinfo-horizontal-rule)
    (inline-babel-call . org-e-texinfo-inline-babel-call)
    (inline-src-block . org-e-texinfo-inline-src-block)
    (inlinetask . org-e-texinfo-inlinetask)
    (italic . org-e-texinfo-italic)
    (item . org-e-texinfo-item)
    (keyword . org-e-texinfo-keyword)
    (latex-environment . org-e-texinfo-latex-environment)
    (latex-fragment . org-e-texinfo-latex-fragment)
    (line-break . org-e-texinfo-line-break)
    (link . org-e-texinfo-link)
    (macro . org-e-texinfo-macro)
    (paragraph . org-e-texinfo-paragraph)
    (plain-list . org-e-texinfo-plain-list)
    (plain-text . org-e-texinfo-plain-text)
    (planning . org-e-texinfo-planning)
    (property-drawer . org-e-texinfo-property-drawer)
    (quote-block . org-e-texinfo-quote-block)
    (quote-section . org-e-texinfo-quote-section)
    (radio-target . org-e-texinfo-radio-target)
    (section . org-e-texinfo-section)
    (special-block . org-e-texinfo-special-block)
    (src-block . org-e-texinfo-src-block)
    (statistics-cookie . org-e-texinfo-statistics-cookie)
    (strike-through . org-e-texinfo-strike-through)
    (subscript . org-e-texinfo-subscript)
    (superscript . org-e-texinfo-superscript)
    (table . org-e-texinfo-table)
    (table-cell . org-e-texinfo-table-cell)
    (table-row . org-e-texinfo-table-row)
    (target . org-e-texinfo-target)
    (template . org-e-texinfo-template)
    (timestamp . org-e-texinfo-timestamp)
    (underline . org-e-texinfo-underline)
    (verbatim . org-e-texinfo-verbatim)
    (verse-block . org-e-texinfo-verse-block))
  "Alist between element or object types and translators.")

(defconst org-e-texinfo-options-alist
  '((:texinfo-filename "TEXINFO_FILENAME" nil org-e-texinfo-filename t)
    (:texinfo-class "TEXINFO_CLASS" nil org-e-texinfo-default-class t)
    (:texinfo-header "TEXINFO_HEADER" nil nil newline)
    (:subtitle "SUBTITLE" nil nil newline)
    (:subauthor "SUBAUTHOR" nil nil newline))
  "Alist between Texinfo export properties and ways to set them.
See `org-export-options-alist' for more information on the
structure of the values.

SUBAUTHOR and SUBTITLE are for the inclusion of additional author
and title information beyond the initial variable.")


\f
;;; Internal Variables

\f
;;; User Configurable Variables

(defgroup org-export-e-texinfo nil
  "Options for exporting Org mode files to Texinfo."
  :tag "Org Export Texinfo"
  :group 'org-export)


;;;; Preamble

(defcustom org-e-texinfo-filename nil
  "Default filename for texinfo output."
  :group 'org-export-e-texinfo
  :type '(string :tag "Export Filename"))

(defcustom org-e-texinfo-default-class "info"
  "The default Texinfo class."
  :group 'org-export-e-texinfo
  :type '(string :tag "Texinfo class"))

(defcustom org-e-texinfo-classes
  '(("info"
     "\\input texinfo    @c -*- texinfo -*-"
     ("@chapter %s" . "@unnumbered %s")
     ("@section %s" . "@unnumberedsec %s")
     ("@subsection %s" . "@unnumberedsubsec %s")
     ("@subsubsection %s" . "@unnumberedsubsubsec %s")))
  "Alist of Texinfo classes and associated header and structure.
If #+Texinfo_CLASS is set in the buffer, use its value and the
associated information.  Here is the structure of each cell:

  \(class-name
    header-string
    \(numbered-section . unnumbered-section\)
    ...\)

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.

Instead of a cons cell \(numbered . unnumbered\), you can also
provide a list of 2 or 4 elements,

  \(numbered-open numbered-close\)

or

  \(numbered-open numbered-close unnumbered-open unnumbered-close\)

providing opening and closing strings for a Texinfo 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-e-texinfo
  :type '(repeat
	  (list (string :tag "Texinfo class")
		(string :tag "Texinfo header")
		(repeat :tag "Levels" :inline t
			(choice
			 (cons :tag "Heading"
			       (string :tag "  numbered")
			       (string :tag "unnumbered"))
			 (list :tag "Environment"
			       (string :tag "Opening   (numbered)")
			       (string :tag "Closing   (numbered)")
			       (string :tag "Opening (unnumbered)")
			       (string :tag "Closing (unnumbered)"))
			 (function :tag "Hook computing sectioning"))))))


;;;; Headline

(defcustom org-e-texinfo-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 as a list of strings (list of strings 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-texinfo-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}\"
              \(mapconcat 'identity tags \":\"))))"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Footnotes
;;
;; Footnotes are inserted directly

;;;; Timestamps

(defcustom org-e-texinfo-active-timestamp-format "@emph{%s}"
  "A printf format string to be applied to active timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

(defcustom org-e-texinfo-inactive-timestamp-format "@emph{%s}"
  "A printf format string to be applied to inactive timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

(defcustom org-e-texinfo-diary-timestamp-format "@emph{%s}"
  "A printf format string to be applied to diary timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

;;;; Links

(defcustom org-e-texinfo-link-with-unknown-path-format "@indicateurl{%s}"
  "Format string for links with unknown path type."
  :group 'org-export-e-texinfo
  :type 'string)


;;;; Tables

(defcustom org-e-texinfo-tables-verbatim nil
  "When non-nil, tables are exported verbatim."
  :group 'org-export-e-texinfo
  :type 'boolean)

(defcustom org-e-texinfo-table-scientific-notation "%s\\,(%s)"
  "Format string to display numbers in scientific notation.
The format should have \"%s\" twice, for mantissa and exponent
\(i.e. \"%s\\\\times10^{%s}\").

When nil, no transformation is made."
  :group 'org-export-e-texinfo
  :type '(choice
	  (string :tag "Format string")
	  (const :tag "No formatting")))

(defcustom org-e-texinfo-def-table-markup "@samp"
  "Default setting for @table environments.")

;;;; Text markup

(defcustom org-e-texinfo-text-markup-alist '((bold . "@strong{%s}")
					   (code . code)
					   (italic . "@emph{%s}")
					   (verbatim . verb)
					   (comment . "@c %s"))
  "Alist of Texinfo expressions to convert text markup.

The key must be a symbol among `bold', `code', `italic',
`strike-through', `underline' and `verbatim'.  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.

If no association can be found for a given markup, text will be
returned as-is."
  :group 'org-export-e-texinfo
  :type 'alist
  :options '(bold code italic verbatim comment))


;;;; Drawers

(defcustom org-e-texinfo-format-drawer-function nil
  "Function called to format a drawer in Texinfo 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-texinfo-format-drawer-default \(name contents\)
  \"Format a drawer element for Texinfo export.\"
  contents\)"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Inlinetasks

(defcustom org-e-texinfo-format-inlinetask-function nil
  "Function called to format an inlinetask in Texinfo 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 list of strings.
  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-texinfo-format-inlinetask \(todo type priority name tags contents\)
\"Format an inline task element for Texinfo 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:}\"
                    \(mapconcat 'identity 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-texinfo
  :type 'function)


;;;; Src blocks
;;
;; Src Blocks are example blocks, except for LISP

;;;; Plain text

(defcustom org-e-texinfo-quotes
  '(("quotes"
     ("\\(\\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-texinfo
  :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

(defcustom org-e-texinfo-info-process
  '("makeinfo %f")
  "Commands to process a texinfo file to an INFO file.
This is 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."
  :group 'org-export-texinfo
  :type '(repeat :tag "Shell command sequence"
		 (string :tag "Shell command")))

\f
;;; Internal Functions

(defun org-e-texinfo--find-copying (info)
  ""
  (let (copying)
    (org-element-map (plist-get info :parse-tree) 'headline
		     (lambda (ref)
		       (when (org-element-property :copying ref)
			 (push ref copying))) info 't)
    ;; Retrieve the single entry
    (car copying)))

(defun org-e-texinfo--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-texinfo--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-texinfo--quotation-marks (text info)
  "Export quotation marks using ` and ' as the markers.
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 org-e-texinfo-quotes))
  text)

(defun org-e-texinfo--text-markup (text markup)
  "Format TEXT depending on MARKUP text markup.
See `org-e-texinfo-text-markup-alist' for details."
  (let ((fmt (cdr (assq markup org-e-texinfo-text-markup-alist))))
    (cond
     ;; No format string: Return raw text.
     ((not fmt) text)
     ((eq 'verb fmt)
      (let ((separator (org-e-texinfo--find-verb-separator text)))
	(concat "@verb{" separator text separator "}")))
     ((eq 'code fmt)
      (let ((start 0)
	    (rtn "")
	    char)
	(while (string-match "[@{}]" text)
	  (setq char (match-string 0 text))
	  (if (> (match-beginning 0) 0)
	      (setq rtn (concat rtn (substring text 0 (match-beginning 0)))))
	  (setq text (substring text (1+ (match-beginning 0))))
	  (setq char (concat "@" char)
		rtn (concat rtn char)))
	(setq text (concat rtn text)
	      fmt "@code{%s}")
	(format fmt text)))
     ;; Else use format string.
     (t (format fmt text)))))

;;;; Menu creation

(defun org-e-texinfo--build-menu (tree level info &optional detailed)
  ""
  (let ((menu (org-e-texinfo--generate-menu-list tree level info)))
    (cond
     (detailed
      ;; Looping is done separately
      (setq text-menu (org-e-texinfo--generate-detailed menu level info)))
     (t
      (setq text-menu (org-e-texinfo--generate-menu-items menu info))))
    (when text-menu
      (setq output (org-e-texinfo--format-menu text-menu))
      (mapconcat 'identity output "\n"))))

(defun org-e-texinfo--generate-detailed (menu level info)
  ""
  ;; Export class definition has 2 descriptive lines, this omits them
  ;; then calculates how many levels of headlines are used for TOC/Menu.
  (setq max-depth (plist-get info :headline-levels))
  (when (> max-depth level)
    (loop for headline in menu append
	  (let* ((title (org-e-texinfo--menu-headlines headline info))
		 (sublist (org-e-texinfo--generate-menu-list
			   headline (1+ level) info))
		 (submenu (if (org-e-texinfo--generate-menu-items sublist info)
			      (append (list title)
				      (org-e-texinfo--generate-menu-items sublist info))
			    'nil))
		 ;; Recursion
		 (recursion (org-e-texinfo--generate-detailed sublist (1+ level) info))
		 )
	    (setq recursion (append submenu recursion))
	    recursion))))

(defun org-e-texinfo--generate-menu-list (tree level info)
  "Generate the list of headlines that are within a given level
of the tree for further formatting.

TREE is the parse-tree containing the headlines.  LEVEL is the
headline level to generate a list of.  INFO is a plist holding
contextual information."
  (let (seq)
    (org-element-map
     tree 'headline
     (lambda (ref)
       (when (org-element-property :level ref)
	 (if (and (eq level (org-element-property :level ref))
		  ;; Do not take note of footnotes or copying headlines
		  (not (org-element-property :copying ref))
		  (not (org-element-property :footnote-section-p ref)))
	     (push ref seq)))))
    ;; Return the list of headlines (reverse to have in actual order)
    (reverse seq)))

(defun org-e-texinfo--generate-menu-items (menu info)
  ""
  
  (loop for headline in menu collect
	(let* ((title (org-export-data
		       (org-element-property :title headline) info))
	       (descr (org-export-data
		       (org-element-property :description headline) info))
	       (len (length title))
	       (output (list len title descr)))
	  output)))

(defun org-e-texinfo--menu-headlines (menu info)
  ""
  (setq title (org-export-data
               (org-element-property :title headline) info))
  (list 0 title 'nil))

(defun org-e-texinfo--format-menu (text-menu)
  ""
  ;; Format should be a list of menu entries
  ;; (length title description).  For headlines they should be
  ;; (nil title nil).  This permits proper spacing settings
  (let* ((lengths (mapcar 'car text-menu))
         (max-length (apply 'max lengths)))
    (setq output
          (mapcar (lambda (name)
                    (let* ((title (nth 1 name))
                           (desc (nth 2 name))
                           (length (nth 0 name)))
                      (if (> length 0)
                          (concat "* " title ":: "
                                  (make-string (- (+ 3 max-length) length)
                                               ?\s)
                                  (if desc
                                      (concat desc)))
                        (concat "\n" title "\n"))))
		  text-menu))
    output))



;;; Template

(defun org-e-texinfo-template (contents info)
  "Return complete document string after Texinfo conversion.
CONTENTS is the transcoded contents string.  INFO is a plist
holding export options."
  (let* ((title (org-export-data (plist-get info :title) info))
	 (info-filename (or (plist-get info :texinfo-filename)
			    (file-name-nondirectory
			     (org-export-output-file-name ".info"))))
	 (author (org-export-data (plist-get info :author) info))
	 (texinfo-header (plist-get info :texinfo-header))
	 (subtitle (plist-get info :subtitle))
	 (subauthor (plist-get info :subauthor))
	 (class (plist-get info :texinfo-class))
	 (header (nth 1 (assoc class org-e-texinfo-classes)))
	 (copying (org-e-texinfo--find-copying info)))
    (concat
     ;; Header
     header "\n"
     "@c %**start of header\n"
     ;; Filename and Title
     "@setfilename " info-filename "\n"
     "@settitle " title "\n"
     "\n\n"
     "@c Version and Contact Info\n"
     "@set AUTHOR " author "\n"

     ;; Additional Header Options set by `#+TEXINFO_HEADER
     (if texinfo-header
	 (concat "\n"
		 texinfo-header
		 "\n"))
     
     "@c %**end of header\n"
     "@finalout\n"
     "\n\n"

     ;; Copying
     "@copying\n"
     ;; Only export the content of the headline, do not need the
     ;; initial headline.
     (org-export-data (nth 2 copying) info)
     "@end copying\n"
     "\n\n"

     ;; Title
     "@titlepage\n"
     "@title " title "\n\n"
     (if subtitle
	 (concat "@subtitle " subtitle "\n"))
     "@author " author "\n"
     (if subauthor
	 (concat subauthor "\n"))
     "\n"
     "@c The following two commands start the copyright page.\n"
     "@page\n"
     "@vskip 0pt plus 1filll\n"
     "@insertcopying\n"
     "@end titlepage\n\n"
     "@c Output the table of contents at the beginning.\n"
     "@contents\n\n"

     ;; Configure Top Node when not for Tex
     "@ifnottex\n"
     "@node Top\n"
     "@top " title " Manual\n"
     "@insertcopying\n"
     "@end ifnottex\n\n"
     
     ;; Menu
     "@menu\n"
     (org-e-texinfo-make-menu info 'main)
     "\n\n"
     ;; Detailed Menu
     "@detailmenu\n"
     " --- The Detailed Node Listing ---\n"
     (org-e-texinfo-make-menu info 'detailed)
     "\n\n"
     "@end detailmenu\n"
     "@end menu\n"
     "\n\n"
     
     ;; Document's body.
     contents
     "\n"
     ;; Creator.
     (let ((creator-info (plist-get info :with-creator)))
       (cond
	((not creator-info) "")
	((eq creator-info 'comment)
	 (format "@c %s\n" (plist-get info :creator)))
	(t (concat (plist-get info :creator) "\n"))))
     ;; Document end.
     "\n@bye")))


\f
;;; Transcode Functions

;;;; Babel Call
;;
;; Babel Calls are ignored.


;;;; Bold

(defun org-e-texinfo-bold (bold contents info)
  "Transcode BOLD from Org to Texinfo.
CONTENTS is the text with bold markup.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup contents 'bold))


;;;; Center Block
;;
;; Center blocks are ignored


;;;; Clock

(defun org-e-texinfo-clock (clock contents info)
  "Transcode a CLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (concat
   "@noindent"
   (format "@strong{%s} " org-clock-string)
   (format org-e-texinfo-inactive-timestamp-format
	   (concat (org-translate-time (org-element-property :value clock))
		   (let ((time (org-element-property :time clock)))
		     (and time (format " (%s)" time)))))
   "@*"))


;;;; Code

(defun org-e-texinfo-code (code contents info)
  "Transcode a CODE object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist used as a communication
channel."
  (org-e-texinfo--text-markup (org-element-property :value code) 'code))

;;;; Comment

(defun org-e-texinfo-comment (comment contents info)
  "Transcode a COMMENT object from Org to Texinfo.
CONTENTS is the text in the comment.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup (org-element-property :value comment) 'comment))

;;;; Comment Block

(defun org-e-texinfo-comment-block (comment-block contents info)
  "Transcode a COMMENT-BLOCK object from Org to Texinfo.
CONTENTS is the text within the block.  INFO is a plist holding
contextual information."
  (format "@ignore\n%s@end ignore" (org-element-property :value comment-block)))

;;;; Drawer

(defun org-e-texinfo-drawer (drawer contents info)
  "Transcode a DRAWER element from Org to Texinfo.
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-texinfo-format-drawer-function)
		     (funcall org-e-texinfo-format-drawer-function
			      name contents)
		   ;; If there's no user defined function: simply
		   ;; display contents of the drawer.
		   contents)))
    output))


;;;; Dynamic Block

(defun org-e-texinfo-dynamic-block (dynamic-block contents info)
  "Transcode a DYNAMIC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information.  See `org-export-data'."
  contents)


;;;; Entity

(defun org-e-texinfo-entity (entity contents info)
  "Transcode an ENTITY object from Org to Texinfo.
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 "@math{%s}" ent) ent)))


;;;; Example Block

(defun org-e-texinfo-example-block (example-block contents info)
  "Transcode an EXAMPLE-BLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (format "@verbatim\n%s@end verbatim"
	  (org-export-format-code-default example-block info)))


;;;; Export Block

(defun org-e-texinfo-export-block (export-block contents info)
  "Transcode a EXPORT-BLOCK element from Org to Texinfo.
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))))


;;;; Export Snippet

(defun org-e-texinfo-export-snippet (export-snippet contents info)
  "Transcode a EXPORT-SNIPPET object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (when (eq (org-export-snippet-backend export-snippet) 'e-texinfo)
    (org-element-property :value export-snippet)))


;;;; Fixed Width

(defun org-e-texinfo-fixed-width (fixed-width contents info)
  "Transcode a FIXED-WIDTH element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (format "@example\n%s\n@end example"
	  (org-remove-indentation
	   (org-element-property :value fixed-width))))


;;;; Footnote Definition
;;
;; Footnote Definitions are ignored.


;;;; Footnote Reference
;;

(defun org-e-texinfo-footnote-reference (footnote contents info)
  ""
  (let ((def (org-export-get-footnote-definition footnote info)))
    (format "@footnote{%s}"
	    (org-trim (org-export-data def info)))))

;;;; Headline

(defun org-e-texinfo-headline (headline contents info)
  "Transcode an HEADLINE element from Org to Texinfo.
CONTENTS holds the contents of the headline.  INFO is a plist
holding contextual information."
  (let* ((class (plist-get info :texinfo-class))
	 (level (org-export-get-relative-level headline info))
	 (numberedp (org-export-numbered-headline-p headline info))
	 (class-sectionning (assoc class org-e-texinfo-classes))
	 ;; Create node info, to insert it before section formatting.
	 (node (format "@node %s\n"
		       (org-export-data (org-element-property :title headline) info)))
	 ;; Menus must be generated with first child, otherwise they
	 ;; will not nest properly
	 (menu (let* ((first (org-export-first-sibling-p headline))
		      (parent (org-export-get-parent-headline headline))
		      (title (org-export-data (org-element-property :title parent) info))
		      heading
		      (tree (plist-get info :parse-tree)))
		 (if first
		     (org-element-map
		      (plist-get info :parse-tree) 'headline
		      (lambda (ref)
			(if (member title (org-element-property :title ref))
			    (push ref heading)))
		      info 't))
		 (setq listing (org-e-texinfo--build-menu (car heading) level info))
	 	 (if listing
	 	     (setq listing (format "\n@menu\n%s\n@end menu\n\n" listing))
	 	   'nil)
		 ))
	 ;; 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 menu node (funcall (if numberedp #'car #'cdr) sec) "\n%s"))
	     ;; (numbered-open numbered-close)
	     ((= (length sec) 2)
	      (when numberedp (concat menu node (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 menu node (nth 2 sec) "\n%s" (nth 3 sec)))))))
	 (text (org-export-data (org-element-property :title headline) info))
	 (todo
	  (and (plist-get info :with-todo-keywords)
	       (let ((todo (org-element-property :todo-keyword headline)))
		 (and todo (org-export-data todo info)))))
	 (todo-type (and todo (org-element-property :todo-type headline)))
	 (tags (and (plist-get info :with-tags)
		    (org-export-get-tags headline info)))
	 (priority (and (plist-get info :with-priority)
			(org-element-property :priority headline)))
	 ;; Create the headline text along with a no-tag version.  The
	 ;; latter is required to remove tags from table of contents.
	 (full-text (if (functionp org-e-texinfo-format-headline-function)
			;; User-defined formatting function.
			(funcall org-e-texinfo-format-headline-function
				 todo todo-type priority text tags)
		      ;; Default formatting.
		      (concat
		       (when todo
			 (format "@strong{%s} " todo))
		       (when priority (format "@emph{#%s} " priority))
		       text
		       (when tags
			 (format ":%s:"
				 (mapconcat 'identity tags ":"))))))
	 (full-text-no-tag
	  (if (functionp org-e-texinfo-format-headline-function)
	      ;; User-defined formatting function.
	      (funcall org-e-texinfo-format-headline-function
		       todo todo-type priority text nil)
	    ;; Default formatting.
	    (concat
	     (when todo (format "@strong{%s} " todo))
	     (when priority (format "@emph{#%c} " priority))
	     text)))
	 (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 the `copying' section: ignore it
     ;;         This is used elsewhere.
     ((org-element-property :copying headline) nil)
     ;; Case 3: 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) (org-export-low-level-p headline info))
      ;; Build the real contents of the sub-tree.
      (let ((low-level-body
	     (concat
	      ;; If the headline is the first sibling, start a list.
	      (when (org-export-first-sibling-p headline)
		(format "@%s\n" (if numberedp 'enumerate 'itemize)))
	      ;; Itemize headline
	      "@item\n" full-text "\n" 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)) low-level-body
	  (replace-regexp-in-string
	   "[ \t\n]*\\'"
	   (format "\n@end %s" (if numberedp 'enumerate 'itemize))
	   low-level-body))))
     ;; Case 4: Standard headline.  Export it as a section.
     (t
      (cond
       ((not (and tags (eq (plist-get info :with-tags) 'not-in-toc)))
	;; Regular section.  Use specified format string.
	(format (replace-regexp-in-string "%]" "%%]" section-fmt) full-text
		(concat pre-blanks contents "\n")))
       ((string-match "\\`@\\(.*?\\){" section-fmt)
	;; If tags should be removed from table of contents, insert
	;; title without tags as an alternative heading in sectioning
	;; command.
	(format (replace-match (concat (match-string 1 section-fmt) "[%s]")
			       nil nil section-fmt 1)
		;; Replace square brackets with parenthesis since
		;; square brackets are not supported in optional
		;; arguments.
		(replace-regexp-in-string
		 "\\[" "("
		 (replace-regexp-in-string
		  "\\]" ")"
		  full-text-no-tag))
		full-text
		(concat pre-blanks contents "\n")))
       (t
	;; Impossible to add an alternative heading.  Fallback to
	;; regular sectioning format string.
	(format (replace-regexp-in-string "%]" "%%]" section-fmt) full-text
		(concat pre-blanks contents "\n"))))))))


;;;; Horizontal Rule
;;
;; Horizontal rules are ignored

;;;; Inline Babel Call
;;
;; Inline Babel Calls are ignored.


;;;; Inline Src Block

(defun org-e-texinfo-inline-src-block (inline-src-block contents info)
  "Transcode an INLINE-SRC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((code (org-element-property :value inline-src-block))
	 (separator (org-e-texinfo--find-verb-separator code)))
    (cond
     ;; Do not use a special package: transcode it verbatim.
     ((not org-e-texinfo-listings)
      (concat "\\verb" separator code separator))
     ;; Use minted package.
     ((eq org-e-texinfo-listings 'minted)
      (let* ((org-lang (org-element-property :language inline-src-block))
	     (mint-lang (or (cadr (assq (intern org-lang)
					org-e-texinfo-minted-langs))
			    org-lang))
	     (options (org-e-texinfo--make-option-string
		       org-e-texinfo-minted-options)))
	(concat (format "\\mint%s{%s}"
			(if (string= options "") "" (format "[%s]" options))
			mint-lang)
		separator code separator)))
     ;; Use listings package.
     (t
      ;; Maybe translate language's name.
      (let* ((org-lang (org-element-property :language inline-src-block))
	     (lst-lang (or (cadr (assq (intern org-lang)
				       org-e-texinfo-listings-langs))
			   org-lang))
	     (options (org-e-texinfo--make-option-string
		       (append org-e-texinfo-listings-options
			       `(("language" ,lst-lang))))))
	(concat (format "\\lstinline[%s]" options)
		separator code separator))))))


;;;; Inlinetask

(defun org-e-texinfo-inlinetask (inlinetask contents info)
  "Transcode an INLINETASK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  (let ((title (org-export-data (org-element-property :title inlinetask) info))
	(todo (and (plist-get info :with-todo-keywords)
		   (let ((todo (org-element-property :todo-keyword inlinetask)))
		     (and todo (org-export-data todo info)))))
	(todo-type (org-element-property :todo-type inlinetask))
	(tags (and (plist-get info :with-tags)
		   (org-export-get-tags inlinetask info)))
	(priority (and (plist-get info :with-priority)
		       (org-element-property :priority inlinetask))))
    ;; If `org-e-texinfo-format-inlinetask-function' is provided, call it
    ;; with appropriate arguments.
    (if (functionp org-e-texinfo-format-inlinetask-function)
	(funcall org-e-texinfo-format-inlinetask-function
		 todo todo-type priority title tags contents)
      ;; Otherwise, use a default template.
      (let ((full-title
	     (concat
	      (when todo (format "@strong{%s} " todo))
	      (when priority (format "%c " priority))
	      title
	      (when tags (format ":%s:"
				 (mapconcat 'identity tags ":"))))))
	(format (concat "@center %s\n\n"
			"%s"
			"\n")
		full-title contents)))))


;;;; Italic

(defun org-e-texinfo-italic (italic contents info)
  "Transcode ITALIC from Org to Texinfo.
CONTENTS is the text with italic markup.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup contents 'italic))

;;;; Item

(defun org-e-texinfo-item (item contents info)
  "Transcode an ITEM element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (concat "\n@item\n"
	    (org-trim contents) "\n"))


;;;; Keyword

(defun org-e-texinfo-keyword (keyword contents info)
  "Transcode a KEYWORD element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((key (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)
     ((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))))
	    (concat
	     (when (wholenump depth)
	       (format "\\setcounter{tocdepth}{%s}\n" depth))
	     "\\tableofcontents")))
	 ((string= "tables" value) "\\listoftables")
	 ((string= "figures" value) "\\listoffigures")
	 ((string= "listings" value)
	  (cond
	   ((eq org-e-texinfo-listings 'minted) "\\listoflistings")
	   (org-e-texinfo-listings "\\lstlistoflistings")
	   ;; At the moment, src blocks with a caption are wrapped
	   ;; into a figure environment.
	   (t "\\listoffigures")))))))))


;;;; Latex Environment

(defun org-e-texinfo-latex-environment (latex-environment contents info)
  "Transcode a LATEX-ENVIRONMENT element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (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

(defun org-e-texinfo-latex-fragment (latex-fragment contents info)
  "Transcode a LATEX-FRAGMENT object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (org-element-property :value latex-fragment))


;;;; Line Break

(defun org-e-texinfo-line-break (line-break contents info)
  "Transcode a LINE-BREAK object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  "@*")


;;;; Link

(defun org-e-texinfo-link (link desc info)
  "Transcode a LINK object from Org to Texinfo.

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"))
		 (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))
		   (concat "file://" raw-path)))
		(t raw-path)))
	 (email (if (string= type "mailto")
		    (let ((text (replace-regexp-in-string
				 "@" "@@" raw-path)))
		     (concat text (if desc (concat "," desc))))))
	 protocol)
    (cond
     ;; Links pointing to an headline: Find destination and build
     ;; appropriate referencing command.
     ((member type '("custom-id" "fuzzy" "id"))
      (let ((destination (org-export-resolve-id-link link info)))
	(case (org-element-type destination)
	  ;; Id link points to an external file.
	  (plain-text
	   (if desc (format "@uref{file://%s,%s}" destination desc)
	     (format "@uref{file://%s}" destination)))
	  ;; LINK points to an headline.  Use the headline as the NODE target
	  (headline
	   (format "@ref{%s}"
		   (org-export-data
		    (org-element-property :title destination) info)))
	  (t))))
     ;; Special case for email addresses
     (email
      (format "@email{%s}" email))
     ;; External link with a description part.
     ((and path desc) (format "@uref{%s,%s}" path desc))
     ;; External link without a description part.
     (path (format "@uref{%s}" path))
     ;; No path, only description.  Try to do something useful.
     (t (format org-e-texinfo-link-with-unknown-path-format desc)))))


;;;; Macro

(defun org-e-texinfo-macro (macro contents info)
  "Transcode a MACRO element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  ;; Use available tools.
  (org-export-expand-macro macro info))


;;;; Menu

(defun org-e-texinfo-make-menu (tree level &optional info)
  "Create the menu for inclusion in the texifo document.
INFO is the parsed buffer that contains the headlines.  LEVEL
determines whether to make the main menu, or the detailed menu."
  (let* ((info (if info
		   info
		 tree))
	 (parse (plist-get tree :parse-tree))
	 ;; Top determines level to build menu from, it finds the
	 ;; level of the first headline in the export.
	 (top (org-element-map
	       parse 'headline
	       (lambda (headline)
		 (org-element-property :level headline)) info 't))
	 menu menu-title)
    (cond
     ;; Generate the main menu
     ((eq level 'main)
      (org-e-texinfo--build-menu parse top info))
     ;; Generate the detailed (recursive) menu
     ((eq level 'detailed)
      ;; Requires recursion
      ;;(org-e-texinfo--build-detailed-menu parse top info)
      (or (org-e-texinfo--build-menu parse top info 'detailed)
	  "detailed")
      )
     ;; If an integer, create specific menu for that level
     ((integerp level)
      (org-e-texinfo--build-menu parse level info))
     ;; Otherwise do nothing
     (t
      ))))


;;;; Paragraph

(defun org-e-texinfo-paragraph (paragraph contents info)
  "Transcode a PARAGRAPH element from Org to Texinfo.
CONTENTS is the contents of the paragraph, as a string.  INFO is
the plist used as a communication channel."
  contents)


;;;; Plain List

(defun org-e-texinfo-plain-list (plain-list contents info)
  "Transcode a PLAIN-LIST element from Org to Texinfo.
CONTENTS is the contents of the list.  INFO is a plist holding
contextual information."
  (let* ((type (org-element-property :type plain-list))
	 (list-type (cond
		     ((eq type 'ordered) "enumerate")
		     ((eq type 'unordered) "itemize")
		     ((eq type 'descriptive) "table"))))
    (format "@%s%s\n@end %s"
	    (if (eq type 'descriptive)
		(concat list-type " " org-e-texinfo-def-table-markup)
	     list-type)
	    contents
	    list-type)))


;;;; Plain Text

(defun org-e-texinfo-plain-text (text info)
  "Transcode a TEXT string from Org to Texinfo.
TEXT is the string to transcode.  INFO is a plist holding
contextual information."
  ;; Protect @ { and }.
  (while (string-match "\\([^\\]\\|^\\)\\([@{}]\\)" text)
    (setq text
	  (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
  ;; Handle quotation marks
  (setq text (org-e-texinfo--quotation-marks text info))
  ;; Convert special strings.
  (when (plist-get info :with-special-strings)
    (while (string-match (regexp-quote "...") text)
      (setq text (replace-match "@dots{}" nil t 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)


;;;; Planning

(defun org-e-texinfo-planning (planning contents info)
  "Transcode a PLANNING element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (concat
   "@noindent"
   (mapconcat
    'identity
    (delq nil
	  (list
	   (let ((closed (org-element-property :closed planning)))
	     (when closed
	       (concat
		(format "@strong%s} " org-closed-string)
		(format org-e-texinfo-inactive-timestamp-format
			(org-translate-time closed)))))
	   (let ((deadline (org-element-property :deadline planning)))
	     (when deadline
	       (concat
		(format "@strong{%s} " org-deadline-string)
		(format org-e-texinfo-active-timestamp-format
			(org-translate-time deadline)))))
	   (let ((scheduled (org-element-property :scheduled planning)))
	     (when scheduled
	       (concat
		(format "@strong{%s} " org-scheduled-string)
		(format org-e-texinfo-active-timestamp-format
			(org-translate-time scheduled)))))))
    " ")
   "@*"))


;;;; Property Drawer

(defun org-e-texinfo-property-drawer (property-drawer contents info)
  "Transcode a PROPERTY-DRAWER element from Org to Texinfo.
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-texinfo-quote-block (quote-block contents info)
  "Transcode a QUOTE-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  
  (let* ((title (org-element-property :name quote-block))
	 (start-quote (concat "@quotation"

			      (if title
				 (format " %s" title)))))
    
    (format "%s\n%s@end quotation" start-quote contents)))



;;;; Quote Section

(defun org-e-texinfo-quote-section (quote-section contents info)
  "Transcode a QUOTE-SECTION element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((value (org-remove-indentation
		(org-element-property :value quote-section))))
    (when value (format "@verbatim\n%s@end verbatim" value))))


;;;; Radio Target
;;
;; Radio targets are not exported at the moment


;;;; Section

(defun org-e-texinfo-section (section contents info)
  "Transcode a SECTION element from Org to Texinfo.
CONTENTS holds the contents of the section.  INFO is a plist
holding contextual information."
  contents)


;;;; Special Block
;;
;; Are ignored at the moment

;;;; Src Block

(defun org-e-texinfo-src-block (src-block contents info)
  "Transcode a SRC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((lang (org-element-property :language src-block))
	 (lisp-p (string-match-p "lisp" lang)))
    (cond
     ;; Case 1.  Lisp Block
     (lisp-p
      (format "@lisp\n%s\n@end lisp" contents))
     ;; Case 2.  Other blocks
     (t
      (format "@example\n%s\n@end example" contents)))))


;;;; Statistics Cookie

(defun org-e-texinfo-statistics-cookie (statistics-cookie contents info)
  "Transcode a STATISTICS-COOKIE object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (org-element-property :value statistics-cookie))


;;;; Strike-Through
;;
;; Strikethrough is ignored


;;;; Subscript

(defun org-e-texinfo-subscript (subscript contents info)
  "Transcode a SUBSCRIPT object from Org to Texinfo.
CONTENTS is the contents of the object.  INFO is a plist holding
contextual information."
  (format (if (= (length contents) 1) "$_%s$" "$_{\\mathrm{%s}}$") contents))


;;;; Superscript

(defun org-e-texinfo-superscript (superscript contents info)
  "Transcode a SUPERSCRIPT object from Org to Texinfo.
CONTENTS is the contents of the object.  INFO is a plist holding
contextual information."
  (format (if (= (length contents) 1) "$^%s$" "$^{\\mathrm{%s}}$") contents))


;;;; Table
;;
;; `org-e-texinfo-table' is the entry point for table transcoding.  It
;; takes care of tables with a "verbatim" attribute.  Otherwise, it
;; delegates the job to either `org-e-texinfo-table--table.el-table' or
;; `org-e-texinfo-table--org-table' functions, depending of the type of
;; the table.
;;
;; `org-e-texinfo-table--align-string' is a subroutine used to build
;; alignment string for Org tables.

(defun org-e-texinfo-table (table contents info)
  "Transcode a TABLE element from Org to Texinfo.
CONTENTS is the contents of the table.  INFO is a plist holding
contextual information."
  (cond
   ;; Case 1: verbatim table.
   ((or org-e-texinfo-tables-verbatim
	(let ((attr (mapconcat 'identity
			       (org-element-property :attr_latex table)
			       " ")))
	  (and attr (string-match "\\<verbatim\\>" attr))))
    (format "@verbatim \n%s\n@end verbatim"
	    ;; Re-create table, without affiliated keywords.
	    (org-trim
	     (org-element-interpret-data
	      `(table nil ,@(org-element-contents table))))))
   ;; Case 2: table.el table.  Convert it using appropriate tools.
   ((eq (org-element-property :type table) 'table.el)
    (org-e-texinfo-table--table.el-table table contents info))
   ;; Case 3: Standard table.
   (t (org-e-texinfo-table--org-table table contents info))))

(defun org-e-texinfo-table-column-widths (table info)
  "Determine the largest table cell in each column to process alignment.

TABLE is the table element to transcode.  INFO is a plist used as
a communication channel."
  (let* ((rows (org-element-map table 'table-row 'identity info))
	 (collected (loop for row in rows collect
			  (org-element-map
			   row 'table-cell 'identity info)))
	 (number-cells (length (car collected)))
	 cells counts)
    (loop for row in collected do
	  (push (mapcar (lambda (ref)
		     (let* ((start (org-element-property :contents-begin ref))
			    (end (org-element-property :contents-end ref))
			    (length (- end start)))
		       length)) row) cells))
    (setq cells (remove-if #'null cells))
    (push (loop for count from 0 to (- number-cells 1) collect
		   (loop for item in cells collect
			 (nth count item))) counts)
    (mapconcat '(lambda (size)
		  (make-string size ?a)) (mapcar (lambda (ref)
				   (apply 'max `,@ref)) (car counts))
	       "} {")
  ))

(defun org-e-texinfo-table--org-table (table contents info)
  "Return appropriate Texinfo code for an Org table.

TABLE is the table type element to transcode.  CONTENTS is its
contents, as a string.  INFO is a plist used as a communication
channel.

This function assumes TABLE has `org' as its `:type' attribute."
  (let* (
	 (columns (org-e-texinfo-table-column-widths table info))
	 )
    ;; Prepare the final format string for the table.
    (cond
     ;; Longtable.
     ;; Others.
     (t (concat
	 (format "@multitable {%s}\n%s@end multitable"
		 columns
		 contents))))))

(defun org-e-texinfo-table--table.el-table (table contents info)
  "Return appropriate Texinfo code for a table.el table.

TABLE is the table type element to transcode.  CONTENTS is its
contents, as a string.  INFO is a plist used as a communication
channel.

This function assumes TABLE has `table.el' as its `:type'
attribute."
  (require 'table)
  ;; Ensure "*org-export-table*" buffer is empty.
  (with-current-buffer (get-buffer-create "*org-export-table*")
    (erase-buffer))
  (let ((output (with-temp-buffer
		  (insert (org-element-property :value table))
		  (goto-char 1)
		  (re-search-forward "^[ \t]*|[^|]" nil t)
		  (table-generate-source 'latex "*org-export-table*")
		  (with-current-buffer "*org-export-table*"
		    (org-trim (buffer-string))))))
    (kill-buffer (get-buffer "*org-export-table*"))
    ;; Remove left out comments.
    (while (string-match "^%.*\n" output)
      (setq output (replace-match "" t t output)))
    ;; When the "rmlines" attribute is provided, remove all hlines but
    ;; the the one separating heading from the table body.
    (let ((attr (mapconcat 'identity
			   (org-element-property :attr_latex table)
			   " ")))
      (when (and attr (string-match "\\<rmlines\\>" attr))
	(let ((n 0) (pos 0))
	  (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 (not org-e-texinfo-tables-centered) output
      (format "\\begin{center}\n%s\n\\end{center}" output))))


;;;; Table Cell

(defun org-e-texinfo-table-cell (table-cell contents info)
  "Transcode a TABLE-CELL element from Org to Texinfo.
CONTENTS is the cell contents.  INFO is a plist used as
a communication channel."
  (concat (if (and contents
		   org-e-texinfo-table-scientific-notation
		   (string-match orgtbl-exp-regexp contents))
	      ;; Use appropriate format string for scientific
	      ;; notation.
	      (format org-e-texinfo-table-scientific-notation
		      (match-string 1 contents)
		      (match-string 2 contents))
	    contents)
	  (when (org-export-get-next-element table-cell) "\n@tab ")))


;;;; Table Row

(defun org-e-texinfo-table-row (table-row contents info)
  "Transcode a TABLE-ROW element from Org to Texinfo.
CONTENTS is the contents of the row.  INFO is a plist used as
a communication channel."
  ;; Rules are ignored since table separators are deduced from
  ;; borders of the current row.
  (when (eq (org-element-property :type table-row) 'standard) 
    (concat "@item " contents "\n")))


;;;; Target

(defun org-e-texinfo-target (target contents info)
  "Transcode a TARGET object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (format "\\label{%s}"
	  (org-export-solidify-link-text (org-element-property :value target))))


;;;; Timestamp

(defun org-e-texinfo-timestamp (timestamp contents info)
  "Transcode a TIMESTAMP object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (let ((value (org-translate-time (org-element-property :value timestamp)))
	(type (org-element-property :type timestamp)))
    (cond ((memq type '(active active-range))
	   (format org-e-texinfo-active-timestamp-format value))
	  ((memq type '(inactive inactive-range))
	   (format org-e-texinfo-inactive-timestamp-format value))
	  (t (format org-e-texinfo-diary-timestamp-format value)))))


;;;; Underline
;;
;; Underline is ignored


;;;; Verbatim

(defun org-e-texinfo-verbatim (verbatim contents info)
  "Transcode a VERBATIM object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist used as a communication
channel."
  (org-e-texinfo--text-markup (org-element-property :value verbatim) 'verbatim))


;;;; Verse Block

(defun org-e-texinfo-verse-block (verse-block contents info)
  "Transcode a VERSE-BLOCK element from Org to Texinfo.
CONTENTS is verse block contents. INFO is a plist holding
contextual information."
  ;; In a verse environment, add a line break to each newline
  ;; character and change each white space at beginning of a line
  ;; into a space of 1 em.  Also change each blank line with
  ;; a vertical space of 1 em.
  (progn
    (setq contents (replace-regexp-in-string
		    "^ *\\\\\\\\$" "\\\\vspace*{1em}"
		    (replace-regexp-in-string
		     "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n" contents)))
    (while (string-match "^[ \t]+" contents)
      (let ((new-str (format "\\hspace*{%dem}"
			     (length (match-string 0 contents)))))
	(setq contents (replace-match new-str nil t contents))))
    (format "\\begin{verse}\n%s\\end{verse}" contents)))


\f
;;; Interactive functions

(defun org-e-texinfo-export-to-texinfo
  (&optional subtreep visible-only body-only ext-plist pub-dir)
  "Export current buffer to a Texinfo 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 ".texi" subtreep pub-dir)))
    (org-export-to-file
     'e-texinfo outfile subtreep visible-only body-only ext-plist)))

(defun org-e-texinfo-export-to-info
  (&optional subtreep visible-only body-only ext-plist pub-dir)
  "Export current buffer to Texinfo then process through to INFO.

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 INFO file's name."
  (interactive)
  (org-e-texinfo-compile
   (org-e-texinfo-export-to-texinfo
    subtreep visible-only body-only ext-plist pub-dir)))

(defun org-e-texinfo-compile (texifile)
  "Compile a texinfo file.

TEXIFILE is the name of the file being compiled.  Processing is
done through the command specified in `org-e-texinfo-info-process'.

Return INFO file name or an error if it couldn't be produced."
  (let* ((wconfig (current-window-configuration))
	 (texifile (file-truename texifile))
	 (base (file-name-sans-extension texifile))
	 errors)
    (message (format "Processing Texinfo file %s ..." texifile))
    (unwind-protect
	(progn
	  (cond
	   ;; A function is provided: Apply it.
	   ((functionp org-e-texinfo-info-process)
	    (funcall org-e-texinfo-info-process (shell-quote-argument texifile)))
	   ;; A list is provided: Replace %b, %f and %o with appropriate
	   ;; values in each command before applying it.  Output is
	   ;; redirected to "*Org INFO Texinfo Output*" buffer.
	   ((consp org-e-texinfo-info-process)
	    (let* ((out-dir (or (file-name-directory texifile) "./"))
		   (outbuf (get-buffer-create "*Org Info Texinfo Output*")))
	      (mapc
	       (lambda (command)
		 (shell-command
		  (replace-regexp-in-string
		   "%b" (shell-quote-argument base)
		   (replace-regexp-in-string
		    "%f" (shell-quote-argument texifile)
		    (replace-regexp-in-string
		     "%o" (shell-quote-argument out-dir) command t t) t t) t t)
		  outbuf))
	       org-e-texinfo-info-process)
	      ;; Collect standard errors from output buffer.
	      (setq errors (org-e-texinfo-collect-errors outbuf))))
	   (t (error "No valid command to process to Info")))
	  (let ((infofile (concat base ".info")))
	    ;; Check for process failure.  Provide collected errors if
	    ;; possible.
	    (if (not (file-exists-p infofile))
		(error (concat (format "INFO file %s wasn't produced" infofile)
			       (when errors (concat ": " errors))))
	      ;; Else remove log files, when specified, and signal end of
	      ;; process to user, along with any error encountered.
	      (message (concat "Process completed"
			       (if (not errors) "."
				 (concat " with errors: " errors)))))
	    ;; Return output file name.
	    infofile))
      (set-window-configuration wconfig))))

(defun org-e-texinfo-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 "makeinfo" 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-texinfo)
;;; org-e-texinfo.el ends here

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-20  0:29 Export to Texinfo Jonathan Leech-Pepin
@ 2012-07-20  9:32 ` Nicolas Goaziou
  2012-07-20 13:34   ` Jonathan Leech-Pepin
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2012-07-20  9:32 UTC (permalink / raw)
  To: Jonathan Leech-Pepin; +Cc: François Pinard, Org Mode Mailing List

Hello,

Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:

> Over the last few days I've been working on implementing an Org ->
> Texinfo exporter based on the new e-latex exporter.

Argh. While your idea is nice, starting from `e-latex' exporter is
almost certainly a bad move. Indeed, it is a quite convoluted back-end
which may not help to understand how the generic exporter can be used.

At some point I will have to write a tutorial on how to start a back-end
from scratch...

> It is not yet able to generate all the expected contents for export
> towards an Info file, however it does create enough to successfully
> export and read through Info.

You may want to get in touch with François Pinard (CC'ed), who had
started a similar project a few weeks ago.

> - There is no provision for indices, limiting usefulness in
>   cross-referencing.

Org export has some tools to handle cross-referencing even when the
back-end doesn't (ASCII exporter has it).

> - There is no #+attr_texinfo or #+TEXINFO: for arbitrary snippets or
>   for passing features to tables/blocks.  I'm not sure exactly how to
>   hook these in and would need a pointer in the right direction to do
>   so.

If you add #+ATTR_TEXINFO above an element, you can access its contents
with (org-element-property :attr_texinfo element).

Ideally parameters should be passed as a plist. I.e.

--8<---------------cut here---------------start------------->8---
#+ATTR_TEXINFO: :width 5 :key "some value"
Some element
--8<---------------cut here---------------end--------------->8---

In that case, you can use `org-export-read-attribute' to
parse :attr_texinfo. I.e.

  (org-export-read-attribute :attr_texinfo element)

 will return

  '(:width 5 :key "some value")

You can then pick the property you want with `plist-get'... Seeing this,
I think I should add an optional argument to directly access a given
property. I.e.

  (org-export-read-attribute :attr_texinfo element :width) => 5

#+TEXINFO: keywords are automatically recognized as keywords. There is
nothing special to do. I.e.

  (defun org-e-texinfo-keyword (keyword contents info)
    (let ((key (org-element-property :key keyword))
          (value (org-element-property :value keyword)))
      (cond
       ...
       ((equal key "TEXINFO") value)      ; Return value as-is
       ...)))

Though, if you want to add support for #+BEGIN_TEXINFO/#+END_TEXINFO
blocks, you will have to add:

  (add-to-list 'org-element-block-name-alist
               '("TEXINFO" . org-element-export-block-parser))

> - The largest issue perhaps: There is no method to create @kbd{} and
>   @key{} commands on export.  If anyone has any suggestions how these
>   might be achieved (perhaps looking for a prefix in =code=?) I would
>   greatly appreciate it.

You can probably use export-snippets:

  An important key: @@e-info:@kbd{C-c C-c}@@.

> There are a few limitations to what will successfully be exported:
> - Headlines cannot contain any of the following symbols: periods,
>   commas, colons or parentheses.  This is a limitation of texinfo and
>   will result in errors when running makeinfo.  Semi-colons will
>   export however.

Can't you protect these chars?


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-20  9:32 ` Nicolas Goaziou
@ 2012-07-20 13:34   ` Jonathan Leech-Pepin
  2012-07-20 13:42     ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-07-20 13:34 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: François Pinard, Org Mode Mailing List

>
>> - The largest issue perhaps: There is no method to create @kbd{} and
>>   @key{} commands on export.  If anyone has any suggestions how these
>>   might be achieved (perhaps looking for a prefix in =code=?) I would
>>   greatly appreciate it.
>
> You can probably use export-snippets:
>
>   An important key: @@e-info:@kbd{C-c C-c}@@.

Can I define the export-snippet using:

    (add-to-list 'org-export-snippet-translation-alist
                 '("e-info" . "e-texinfo"))

Or should that be left up to the discretion of the user?

>> There are a few limitations to what will successfully be exported:
>> - Headlines cannot contain any of the following symbols: periods,
>>   commas, colons or parentheses.  This is a limitation of texinfo and
>>   will result in errors when running makeinfo.  Semi-colons will
>>   export however.
>
> Can't you protect these chars?

Unfortunately you can't currently.  I'm using the Headlines both as
section heading and Node heading.  The Nodes cannot contain those
characters.  This also means that you cannot have duplicate headline
names in the document.

See http://www.gnu.org/software/texinfo/manual/texinfo/html_node/Node-Line-Requirements.html

I should be able to get around this by allowing for a :NODE: property
for use in the menus however, if there is some benefit in doing so.

>
>
> Regards,
>
> --
> Nicolas Goaziou

Regards,

Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-20 13:34   ` Jonathan Leech-Pepin
@ 2012-07-20 13:42     ` Nicolas Goaziou
  2012-07-31 21:03       ` Jonathan Leech-Pepin
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2012-07-20 13:42 UTC (permalink / raw)
  To: Jonathan Leech-Pepin; +Cc: François Pinard, Org Mode Mailing List

Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:

> Can I define the export-snippet using:
>
>     (add-to-list 'org-export-snippet-translation-alist
>                  '("e-info" . "e-texinfo"))
>
> Or should that be left up to the discretion of the user?

This is an user-oriented variable (customizable).

Though, you have full control over which export snippets you accept. In
the following example, you accept both @@info:...@@ and @@texinfo:...@@
snippets:

  (defun org-e-latex-export-snippet (export-snippet contents info)
    "Blah..."
    (when (memq (org-export-snippet-backend export-snippet) '(info texinfo))
      (org-element-property :value export-snippet)))

Just specify it in package's documentation.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-20 13:42     ` Nicolas Goaziou
@ 2012-07-31 21:03       ` Jonathan Leech-Pepin
  2012-07-31 21:18         ` Nicolas Goaziou
  2012-08-02 15:34         ` Bastien
  0 siblings, 2 replies; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-07-31 21:03 UTC (permalink / raw)
  To: Org Mode Mailing List; +Cc: François Pinard, Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 4088 bytes --]

Hello,

I've done some further work on the org-e-texinfo exporter and have
gotten it to a point where it should be usable with only a few
shortcomings.

Features:
- The copying section is created from the first headline containing
  the property :copying:.  Headlines with this property will not be
  exported except in the @copying block.
- Indexes will be created using unnumbered headings from headlines
  containing an :index: property.  If the property has a value
  corresponding to a texinfo index ("cp" "fn" "ky" "pg" "tp" "vr") it
  will be generated using @printindex.  Otherwise only the text will
  be exported and index printing will only be done if explicitly
  indicated.
- The following export-snippets are recognized by the exporter:
  info, e-info and e-texinfo.
- Header arguments can be added using ~#+TEXINFO_HEADER~
- Info directory information is provided by:
  #+TEXINFO_DIR_CATEGORY (e.g: "Emacs")
  #+TEXINFO_DIR_TITLE (e.g: "Org Mode Guide: (orgguide)")
  #+TEXINFO_DIR_DESC (e.g: "Abbreviated Org-mode Manual")
- The info filename is determined by ~#+TEXINFO_FILENAME~, or by
  appending .info to the .org filename.
- Additional title and author information (beyond a single line) can
  be included using #+SUBTITLE and #+SUBAUTHOR respectively.
- The menu and detailed menu in the TOP node, as well as the in-node
  menus of child nodes are generated on export.  Descriptions of the
  nodes are defined in the :DESCRIPTION: property of the headlines.
- Tables are exported to @multitable.  Column widths are either
  defined by the widest cell in each column (a string of ~a~ is
  generated equal to that length), or by a string of fractions in
  #+attr_texinfo (e.g: ~#+attr_texinfo :columns "0.33 0.33 0.33"~)


I have left in an option for #+TEXINFO_CLASS even though only a single
one is defined by default.  Removing it would require reworking
certain portions of the code at the moment, leaving it in allows for
changes if an alternate structure is desired.

It still has issues with the following:
- Table.el tables will not be exported.
- Only a single type of two-column table can currently be created, ~@table~.
- Two-column tables are restricted to a single "indicating" command,
  defined by ~org-e-texinfo-def-table-markup~.  I'm not sure how to
  get around these limitations since they are created from description
  lists (which do not recognize #+attr lines).
- Links will export either as @ref{} or @uref{}.  Manually creating
  @pxref{} and @xref{} links is possible within export snippets.  I'm
  not certain where I would need to check to determine the context to
  select between the three choices.  @xref and @pxref are preferred in
  some cases, however @ref does provide the necessary features in Info
  output.


Also attached is a transcription of orgguide.texi to orgguide.org for
use with the e-texinfo exporter.  It is not exactly identical and
likely has a few places that could be better transcribed into org from
.texi, however it does demonstrate the resultant output when
exporting.

Prior to exporting the following must be evaluated:

  (add-to-list 'org-export-snippet-translation-alist
               '("info" . "e-texinfo"))
  (setq org-e-texinfo-def-table-markup "@kbd")

Regards,

Jon

On 20 July 2012 09:42, Nicolas Goaziou <n.goaziou@gmail.com> wrote:
> Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:
>
>> Can I define the export-snippet using:
>>
>>     (add-to-list 'org-export-snippet-translation-alist
>>                  '("e-info" . "e-texinfo"))
>>
>> Or should that be left up to the discretion of the user?
>
> This is an user-oriented variable (customizable).
>
> Though, you have full control over which export snippets you accept. In
> the following example, you accept both @@info:...@@ and @@texinfo:...@@
> snippets:
>
>   (defun org-e-latex-export-snippet (export-snippet contents info)
>     "Blah..."
>     (when (memq (org-export-snippet-backend export-snippet) '(info texinfo))
>       (org-element-property :value export-snippet)))
>
> Just specify it in package's documentation.

[-- Attachment #2: org-e-texinfo.el --]
[-- Type: application/octet-stream, Size: 62533 bytes --]

;;; org-e-texinfo.el --- Texinfo Back-End For Org Export Engine

;; Author: Jonathan Leech-Pepin <jonathan.leechpepin 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 Texinfo back-end for Org generic
;; exporter.
;;
;; To test it, run
;;
;;   M-: (org-export-to-buffer 'e-texinfo "*Test e-texinfo*") RET
;;
;; in an org-mode buffer then switch to the buffer to see the Texinfo
;; export.  See contrib/lisp/org-export.el for more details on how
;; this exporter works.
;;
;; It introduces eight new buffer keywords: "TEXINFO_CLASS",
;; "TEXINFO_FILENAME", "TEXINFO_HEADER", "TEXINFO_DIR_CATEGORY",
;; "TEXINFO_DIR_TITLE", "TEXINFO_DIR_DESC" "SUBTITLE" and "SUBAUTHOR".
;;
;; To include inline code snippets (for example for generating @kbd{}
;; and @key{} commands), the following export-snippet keys are
;; accepted:
;; 
;;     info
;;     e-info
;;     e-texinfo
;;
;; You can add them for export snippets via any of the below:
;;
;;    (add-to-list 'org-export-snippet-translation-alist
;;                 '("e-info" . "e-texinfo"))
;;    (add-to-list 'org-export-snippet-translation-alist
;;                 '("e-texinfo" . "e-texinfo"))
;;    (add-to-list 'org-export-snippet-translation-alist
;;                 '("info" . "e-texinfo"))
;; 


;;; Code:

(eval-when-compile (require 'cl))
(require 'org-export)

(defvar orgtbl-exp-regexp)

\f
;;; Define Back-End

(defvar org-e-texinfo-translate-alist
  '((babel-call . org-e-texinfo-babel-call)
    (bold . org-e-texinfo-bold)
    (center-block . org-e-texinfo-center-block)
    (clock . org-e-texinfo-clock)
    (code . org-e-texinfo-code)
    (comment . org-e-texinfo-comment)
    (comment-block . org-e-texinfo-comment-block)
    (drawer . org-e-texinfo-drawer)
    (dynamic-block . org-e-texinfo-dynamic-block)
    (entity . org-e-texinfo-entity)
    (example-block . org-e-texinfo-example-block)
    (export-block . org-e-texinfo-export-block)
    (export-snippet . org-e-texinfo-export-snippet)
    (fixed-width . org-e-texinfo-fixed-width)
    (footnote-definition . org-e-texinfo-footnote-definition)
    (footnote-reference . org-e-texinfo-footnote-reference)
    (headline . org-e-texinfo-headline)
    (horizontal-rule . org-e-texinfo-horizontal-rule)
    (inline-babel-call . org-e-texinfo-inline-babel-call)
    (inline-src-block . org-e-texinfo-inline-src-block)
    (inlinetask . org-e-texinfo-inlinetask)
    (italic . org-e-texinfo-italic)
    (item . org-e-texinfo-item)
    (keyword . org-e-texinfo-keyword)
    (latex-environment . org-e-texinfo-latex-environment)
    (latex-fragment . org-e-texinfo-latex-fragment)
    (line-break . org-e-texinfo-line-break)
    (link . org-e-texinfo-link)
    (macro . org-e-texinfo-macro)
    (paragraph . org-e-texinfo-paragraph)
    (plain-list . org-e-texinfo-plain-list)
    (plain-text . org-e-texinfo-plain-text)
    (planning . org-e-texinfo-planning)
    (property-drawer . org-e-texinfo-property-drawer)
    (quote-block . org-e-texinfo-quote-block)
    (quote-section . org-e-texinfo-quote-section)
    (radio-target . org-e-texinfo-radio-target)
    (section . org-e-texinfo-section)
    (special-block . org-e-texinfo-special-block)
    (src-block . org-e-texinfo-src-block)
    (statistics-cookie . org-e-texinfo-statistics-cookie)
    (strike-through . org-e-texinfo-strike-through)
    (subscript . org-e-texinfo-subscript)
    (superscript . org-e-texinfo-superscript)
    (table . org-e-texinfo-table)
    (table-cell . org-e-texinfo-table-cell)
    (table-row . org-e-texinfo-table-row)
    (target . org-e-texinfo-target)
    (template . org-e-texinfo-template)
    (timestamp . org-e-texinfo-timestamp)
    (underline . org-e-texinfo-underline)
    (verbatim . org-e-texinfo-verbatim)
    (verse-block . org-e-texinfo-verse-block))
  "Alist between element or object types and translators.")

(defconst org-e-texinfo-options-alist
  '((:texinfo-filename "TEXINFO_FILENAME" nil org-e-texinfo-filename t)
    (:texinfo-class "TEXINFO_CLASS" nil org-e-texinfo-default-class t)
    (:texinfo-header "TEXINFO_HEADER" nil nil newline)
    (:subtitle "SUBTITLE" nil nil newline)
    (:subauthor "SUBAUTHOR" nil nil newline)
    (:texinfo-dircat "TEXINFO_DIR_CATEGORY" nil nil t)
    (:texinfo-dirtitle "TEXINFO_DIR_TITLE" nil nil t)
    (:texinfo-dirdesc "TEXINFO_DIR_DESC" nil nil t))
  "Alist between Texinfo export properties and ways to set them.
See `org-export-options-alist' for more information on the
structure of the values.

SUBAUTHOR and SUBTITLE are for the inclusion of additional author
and title information beyond the initial variable.")

(defconst org-e-texinfo-filters-alist
  '((:filter-headline . org-e-texinfo-filter-section-blank-lines)
    (:filter-section . org-e-texinfo-filter-section-blank-lines))
  "Alist between filters keywords and back-end specific filters.
  See `org-export-filters-alist' for more information")


\f
;;; Internal Variables

;; Add TEXINFO to the list of available of available export blocks.
(add-to-list 'org-element-block-name-alist
	     '("TEXINFO" . org-element-export-block-parser))
\f
;;; User Configurable Variables

(defgroup org-export-e-texinfo nil
  "Options for exporting Org mode files to Texinfo."
  :tag "Org Export Texinfo"
  :group 'org-export)


;;;; Preamble

(defcustom org-e-texinfo-filename nil
  "Default filename for texinfo output."
  :group 'org-export-e-texinfo
  :type '(string :tag "Export Filename"))

(defcustom org-e-texinfo-default-class "info"
  "The default Texinfo class."
  :group 'org-export-e-texinfo
  :type '(string :tag "Texinfo class"))

(defcustom org-e-texinfo-classes
  '(("info"
     "\\input texinfo    @c -*- texinfo -*-"
     ("@chapter %s" . "@unnumbered %s")
     ("@section %s" . "@unnumberedsec %s")
     ("@subsection %s" . "@unnumberedsubsec %s")
     ("@subsubsection %s" . "@unnumberedsubsubsec %s")))
  "Alist of Texinfo classes and associated header and structure.
If #+Texinfo_CLASS is set in the buffer, use its value and the
associated information.  Here is the structure of each cell:

  \(class-name
    header-string
    \(numbered-section . unnumbered-section\)
    ...\)

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.

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-texinfo
  :type '(repeat
	  (list (string :tag "Texinfo class")
		(string :tag "Texinfo header")
		(repeat :tag "Levels" :inline t
			(choice
			 (cons :tag "Heading"
			       (string :tag "  numbered")
			       (string :tag "unnumbered"))
			 (function :tag "Hook computing sectioning"))))))


;;;; Headline

(defcustom org-e-texinfo-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 as a list of strings (list of strings 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-texinfo-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}\"
              \(mapconcat 'identity tags \":\"))))"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Footnotes
;;
;; Footnotes are inserted directly

;;;; Timestamps

(defcustom org-e-texinfo-active-timestamp-format "@emph{%s}"
  "A printf format string to be applied to active timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

(defcustom org-e-texinfo-inactive-timestamp-format "@emph{%s}"
  "A printf format string to be applied to inactive timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

(defcustom org-e-texinfo-diary-timestamp-format "@emph{%s}"
  "A printf format string to be applied to diary timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

;;;; Links

(defcustom org-e-texinfo-link-with-unknown-path-format "@indicateurl{%s}"
  "Format string for links with unknown path type."
  :group 'org-export-e-texinfo
  :type 'string)


;;;; Tables

(defcustom org-e-texinfo-tables-verbatim nil
  "When non-nil, tables are exported verbatim."
  :group 'org-export-e-texinfo
  :type 'boolean)

(defcustom org-e-texinfo-table-scientific-notation "%s\\,(%s)"
  "Format string to display numbers in scientific notation.
The format should have \"%s\" twice, for mantissa and exponent
\(i.e. \"%s\\\\times10^{%s}\").

When nil, no transformation is made."
  :group 'org-export-e-texinfo
  :type '(choice
	  (string :tag "Format string")
	  (const :tag "No formatting")))

(defcustom org-e-texinfo-def-table-markup "@samp"
  "Default setting for @table environments.")

;;;; Text markup

(defcustom org-e-texinfo-text-markup-alist '((bold . "@strong{%s}")
					   (code . code)
					   (italic . "@emph{%s}")
					   (verbatim . verb)
					   (comment . "@c %s"))
  "Alist of Texinfo expressions to convert text markup.

The key must be a symbol among `bold', `italic' and `comment'.
The value is a formatting string to wrap fontified text with.

Value can also be set to the following symbols: `verb' and
`code'.  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 \"@code\"
to typeset and try to protect special characters.

If no association can be found for a given markup, text will be
returned as-is."
  :group 'org-export-e-texinfo
  :type 'alist
  :options '(bold code italic verbatim comment))


;;;; Drawers

(defcustom org-e-texinfo-format-drawer-function nil
  "Function called to format a drawer in Texinfo 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-texinfo-format-drawer-default \(name contents\)
  \"Format a drawer element for Texinfo export.\"
  contents\)"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Inlinetasks

(defcustom org-e-texinfo-format-inlinetask-function nil
  "Function called to format an inlinetask in Texinfo 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 list of strings.
  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-texinfo-format-inlinetask \(todo type priority name tags contents\)
\"Format an inline task element for Texinfo export.\"
  \(let ((full-title
	 \(concat
	  \(when todo
            \(format \"@strong{%s} \" todo))
	  \(when priority (format \"#%c \" priority))
	  title
	  \(when tags
            \(format \":%s:\"
                    \(mapconcat 'identity tags \":\")))))
    \(format (concat \"@center %s\n\n\"
		    \"%s\"
                    \"\n\"))
	    full-title contents))"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Src blocks
;;
;; Src Blocks are example blocks, except for LISP

;;;; Plain text

(defcustom org-e-texinfo-quotes
  '(("quotes"
     ("\\(\\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-texinfo
  :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

(defcustom org-e-texinfo-info-process
  '("makeinfo %f")
  "Commands to process a texinfo file to an INFO file.
This is 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."
  :group 'org-export-texinfo
  :type '(repeat :tag "Shell command sequence"
		 (string :tag "Shell command")))

\f
;;; Internal Functions

(defun org-e-texinfo-filter-section-blank-lines (headline back-end info)
  "Filter controlling number of blank lines after a section."
  (if (not (eq back-end 'e-texinfo)) headline
    (let ((blanks (make-string 2 ?\n)))
      (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline))))

(defun org-e-texinfo--find-copying (info)
  "Retrieve the headline identified by the property :copying:.

INFO is the plist containing the export options and tree.  It is
used to find and extract the single desired headline.  This
cannot be treated as a standard headline since it must be
inserted in a specific location."
  (let (copying)
    (org-element-map (plist-get info :parse-tree) 'headline
		     (lambda (copy)
		       (when (org-element-property :copying copy)
			 (push copy copying))) info 't)
    ;; Retrieve the single entry
    (car copying)))

(defun org-e-texinfo--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-texinfo--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-texinfo--quotation-marks (text info)
  "Export quotation marks using ` and ' as the markers.
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 org-e-texinfo-quotes))
  text)

(defun org-e-texinfo--text-markup (text markup)
  "Format TEXT depending on MARKUP text markup.
See `org-e-texinfo-text-markup-alist' for details."
  (let ((fmt (cdr (assq markup org-e-texinfo-text-markup-alist))))
    (cond
     ;; No format string: Return raw text.
     ((not fmt) text)
     ((eq 'verb fmt)
      (let ((separator (org-e-texinfo--find-verb-separator text)))
	(concat "@verb{" separator text separator "}")))
     ((eq 'code fmt)
      (let ((start 0)
	    (rtn "")
	    char)
	(while (string-match "[@{}]" text)
	  (setq char (match-string 0 text))
	  (if (> (match-beginning 0) 0)
	      (setq rtn (concat rtn (substring text 0 (match-beginning 0)))))
	  (setq text (substring text (1+ (match-beginning 0))))
	  (setq char (concat "@" char)
		rtn (concat rtn char)))
	(setq text (concat rtn text)
	      fmt "@code{%s}")
	(format fmt text)))
     ;; Else use format string.
     (t (format fmt text)))))

;;;; Menu creation

(defun org-e-texinfo--build-menu (tree level info &optional detailed)
  "Create the @menu/@end menu information from TREE at headline
level LEVEL.

TREE contains the parse-tree to work with, either of the entire
document or of a specific parent headline.  LEVEL indicates what
level of headlines to look at when generating the menu.  INFO is
a plist containing contextual information.

Detailed determines whether to build a single level of menu, or
recurse into all children as well."
  (let ((menu (org-e-texinfo--generate-menu-list tree level info))
	output text-menu)
    (cond
     (detailed
      ;; Looping is done within the menu generation.
      (setq text-menu (org-e-texinfo--generate-detailed menu level info)))
     (t
      (setq text-menu (org-e-texinfo--generate-menu-items menu info))))
    (when text-menu
      (setq output (org-e-texinfo--format-menu text-menu))
      (mapconcat 'identity output "\n"))))

(defun org-e-texinfo--generate-detailed (menu level info)
  "Generate a detailed listing of all subheadings within MENU starting at LEVEL.

MENU is the parse-tree to work with.  LEVEL is the starting level
for the menu headlines and from which recursion occurs.  INFO is
a plist containing contextual information."
  (let ((max-depth (plist-get info :headline-levels)))
    (when (> max-depth level)
      (loop for headline in menu append
	    (let* ((title (org-e-texinfo--menu-headlines headline info))
		   ;; Create list of menu entries for the next level
		   (sublist (org-e-texinfo--generate-menu-list
			     headline (1+ level) info))
		   ;; Generate the menu items for that level.  If
		   ;; there are none omit that heading completely,
		   ;; otherwise join the title to it's related entries.
		   (submenu (if (org-e-texinfo--generate-menu-items sublist info)
				(append (list title)
					(org-e-texinfo--generate-menu-items sublist info))
			      'nil))
		   ;; Start the process over the next level down.
		   (recursion (org-e-texinfo--generate-detailed sublist (1+ level) info)))
	      (setq recursion (append submenu recursion))
	      recursion)))))

(defun org-e-texinfo--generate-menu-list (tree level info)
  "Generate the list of headlines that are within a given level
of the tree for further formatting.

TREE is the parse-tree containing the headlines.  LEVEL is the
headline level to generate a list of.  INFO is a plist holding
contextual information."
  (let (seq)
    (org-element-map
     tree 'headline
     (lambda (head)
       (when (org-element-property :level head)
	 (if (and (eq level (org-element-property :level head))
		  ;; Do not take note of footnotes or copying headlines
		  (not (org-element-property :copying head))
		  (not (org-element-property :footnote-section-p head)))
	     (push head seq)))))
    ;; Return the list of headlines (reverse to have in actual order)
    (reverse seq)))

(defun org-e-texinfo--generate-menu-items (items info)
  "Generate a list of headline information from the listing ITEMS.

ITEMS is a list of the headlines to be converted into entries.
INFO is a plist containing contextual information.

Returns a list containing the following information from each
headline: length, title, description.  This is used to format the
menu using `org-e-texinfo--format-menu'."
  (loop for headline in items collect
	(let* ((title (org-export-data
		       (org-element-property :title headline) info))
	       (descr (org-export-data
		       (org-element-property :description headline) info))
	       (len (length title))
	       (output (list len title descr)))
	  output)))

(defun org-e-texinfo--menu-headlines (headline info)
  "Retrieve the title from HEADLINE.

INFO is a plist holding contextual information.

Return the headline as a list of (length title description) with
length of -1 and nil description.  This is used in
`org-e-texinfo--format-menu' to identify headlines as opposed to
entries."
  (let ((title (org-export-data
		(org-element-property :title headline) info)))
    (list -1 title 'nil)))

(defun org-e-texinfo--format-menu (text-menu)
  "Format the TEXT-MENU items to be properly printed in the menu.

Each entry in the menu should be provided as (length title
description).

Headlines in the detailed menu are given length -1 to ensure they
are never confused with other entries.  They also have no
description.

Other menu items are output as:
    Title::     description

With the spacing between :: and description based on the length
of the longest menu entry."

  (let* ((lengths (mapcar 'car text-menu))
         (max-length (apply 'max lengths))
	 output)
    (setq output
          (mapcar (lambda (name)
                    (let* ((title (nth 1 name))
                           (desc (nth 2 name))
                           (length (nth 0 name)))
                      (if (> length -1)
                          (concat "* " title ":: "
                                  (make-string
				   (- (+ 3 max-length) length)
                                               ?\s)
                                  (if desc
                                      (concat desc)))
                        (concat "\n" title "\n"))))
		  text-menu))
    output))



;;; Template

(defun org-e-texinfo-template (contents info)
  "Return complete document string after Texinfo conversion.
CONTENTS is the transcoded contents string.  INFO is a plist
holding export options."
  (let* ((title (org-export-data (plist-get info :title) info))
	 (info-filename (or (plist-get info :texinfo-filename)
			    (file-name-nondirectory
			     (org-export-output-file-name ".info"))))
	 (author (org-export-data (plist-get info :author) info))
	 (texinfo-header (plist-get info :texinfo-header))
	 (subtitle (plist-get info :subtitle))
	 (subauthor (plist-get info :subauthor))
	 (class (plist-get info :texinfo-class))
	 (header (nth 1 (assoc class org-e-texinfo-classes)))
	 (copying (org-e-texinfo--find-copying info))
	 (dircat (plist-get info :texinfo-dircat))
	 (dirtitle (plist-get info :texinfo-dirtitle))
	 (dirdesc (plist-get info :texinfo-dirdesc))
	 ;; Spacing to align description (column 32 - 3 for `* ' and
	 ;; `.' in text.
	 (dirspacing (- 29 (length dirtitle))))
    (concat
     ;; Header
     header "\n"
     "@c %**start of header\n"
     ;; Filename and Title
     "@setfilename " info-filename "\n"
     "@settitle " title "\n"
     "\n\n"
     "@c Version and Contact Info\n"
     "@set AUTHOR " author "\n"

     ;; Additional Header Options set by `#+TEXINFO_HEADER
     (if texinfo-header
	 (concat "\n"
		 texinfo-header
		 "\n"))
     
     "@c %**end of header\n"
     "@finalout\n"
     "\n\n"

     ;; Copying
     "@copying\n"
     ;; Only export the content of the headline, do not need the
     ;; initial headline.
     (org-export-data (nth 2 copying) info)
     "@end copying\n"
     "\n\n"

     ;; Info directory information
     ;; Only supply if both title and category are provided
     (if (and dircat dirtitle)
	 (concat "@dircategory " dircat "\n"
		 "@direntry\n"
		 "* " dirtitle "."
		 (make-string dirspacing ?\s)
		 dirdesc "\n"
		 "@end direntry\n"))
     "\n\n"

     ;; Title
     "@titlepage\n"
     "@title " title "\n\n"
     (if subtitle
	 (concat "@subtitle " subtitle "\n"))
     "@author " author "\n"
     (if subauthor
	 (concat subauthor "\n"))
     "\n"
     "@c The following two commands start the copyright page.\n"
     "@page\n"
     "@vskip 0pt plus 1filll\n"
     "@insertcopying\n"
     "@end titlepage\n\n"
     "@c Output the table of contents at the beginning.\n"
     "@contents\n\n"

     ;; Configure Top Node when not for Tex
     "@ifnottex\n"
     "@node Top\n"
     "@top " title " Manual\n"
     "@insertcopying\n"
     "@end ifnottex\n\n"
     
     ;; Menu
     "@menu\n"
     (org-e-texinfo-make-menu info 'main)
     "\n\n"
     ;; Detailed Menu
     "@detailmenu\n"
     " --- The Detailed Node Listing ---\n"
     (org-e-texinfo-make-menu info 'detailed)
     "\n\n"
     "@end detailmenu\n"
     "@end menu\n"
     "\n\n"
     
     ;; Document's body.
     contents
     "\n"
     ;; Creator.
     (let ((creator-info (plist-get info :with-creator)))
       (cond
	((not creator-info) "")
	((eq creator-info 'comment)
	 (format "@c %s\n" (plist-get info :creator)))
	(t (concat (plist-get info :creator) "\n"))))
     ;; Document end.
     "\n@bye")))


\f
;;; Transcode Functions

;;;; Babel Call
;;
;; Babel Calls are ignored.


;;;; Bold

(defun org-e-texinfo-bold (bold contents info)
  "Transcode BOLD from Org to Texinfo.
CONTENTS is the text with bold markup.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup contents 'bold))


;;;; Center Block
;;
;; Center blocks are ignored


;;;; Clock

(defun org-e-texinfo-clock (clock contents info)
  "Transcode a CLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (concat
   "@noindent"
   (format "@strong{%s} " org-clock-string)
   (format org-e-texinfo-inactive-timestamp-format
	   (concat (org-translate-time (org-element-property :value clock))
		   (let ((time (org-element-property :time clock)))
		     (and time (format " (%s)" time)))))
   "@*"))


;;;; Code

(defun org-e-texinfo-code (code contents info)
  "Transcode a CODE object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist used as a communication
channel."
  (org-e-texinfo--text-markup (org-element-property :value code) 'code))

;;;; Comment

(defun org-e-texinfo-comment (comment contents info)
  "Transcode a COMMENT object from Org to Texinfo.
CONTENTS is the text in the comment.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup (org-element-property :value comment) 'comment))

;;;; Comment Block

(defun org-e-texinfo-comment-block (comment-block contents info)
  "Transcode a COMMENT-BLOCK object from Org to Texinfo.
CONTENTS is the text within the block.  INFO is a plist holding
contextual information."
  (format "@ignore\n%s@end ignore" (org-element-property :value comment-block)))

;;;; Drawer

(defun org-e-texinfo-drawer (drawer contents info)
  "Transcode a DRAWER element from Org to Texinfo.
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-texinfo-format-drawer-function)
		     (funcall org-e-texinfo-format-drawer-function
			      name contents)
		   ;; If there's no user defined function: simply
		   ;; display contents of the drawer.
		   contents)))
    output))


;;;; Dynamic Block

(defun org-e-texinfo-dynamic-block (dynamic-block contents info)
  "Transcode a DYNAMIC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information.  See `org-export-data'."
  contents)


;;;; Entity

(defun org-e-texinfo-entity (entity contents info)
  "Transcode an ENTITY object from Org to Texinfo.
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 "@math{%s}" ent) ent)))


;;;; Example Block

(defun org-e-texinfo-example-block (example-block contents info)
  "Transcode an EXAMPLE-BLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (format "@verbatim\n%s@end verbatim"
	  (org-export-format-code-default example-block info)))


;;;; Export Block

(defun org-e-texinfo-export-block (export-block contents info)
  "Transcode a EXPORT-BLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (when (string= (org-element-property :type export-block) "TEXINFO")
    (org-remove-indentation (org-element-property :value export-block))))


;;;; Export Snippet

(defun org-e-texinfo-export-snippet (export-snippet contents info)
  "Transcode a EXPORT-SNIPPET object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (when (eq (org-export-snippet-backend export-snippet) 'e-texinfo)
    (org-element-property :value export-snippet)))


;;;; Fixed Width

(defun org-e-texinfo-fixed-width (fixed-width contents info)
  "Transcode a FIXED-WIDTH element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (format "@example\n%s\n@end example"
	  (org-remove-indentation
	   (org-element-property :value fixed-width))))


;;;; Footnote Definition
;;
;; Footnote Definitions are ignored.


;;;; Footnote Reference
;;

(defun org-e-texinfo-footnote-reference (footnote contents info)
  "Create a footnote reference for FOOTNOTE.

FOOTNOTE is the footnote to define.  CONTENTS is nil.  INFO is a
plist holding contextual information."
  (let ((def (org-export-get-footnote-definition footnote info)))
    (format "@footnote{%s}"
	    (org-trim (org-export-data def info)))))

;;;; Headline

(defun org-e-texinfo-headline (headline contents info)
  "Transcode an HEADLINE element from Org to Texinfo.
CONTENTS holds the contents of the headline.  INFO is a plist
holding contextual information."
  (let* ((class (plist-get info :texinfo-class))
	 (level (org-export-get-relative-level headline info))
	 (numberedp (org-export-numbered-headline-p headline info))
	 (class-sectionning (assoc class org-e-texinfo-classes))
	 ;; Find the index type, if any
	 (index (org-element-property :index headline))
	 ;; Create node info, to insert it before section formatting.
	 (node (format "@node %s\n"
		       (org-export-data
			(org-element-property :title headline) info)))
	 ;; Menus must be generated with first child, otherwise they
	 ;; will not nest properly
	 (menu (let* ((first (org-export-first-sibling-p headline info))
		      (parent (org-export-get-parent-headline headline))
		      (title (org-export-data
			      (org-element-property :title parent) info))
		      heading listing
		      (tree (plist-get info :parse-tree)))
		 (if first
		     (org-element-map
		      (plist-get info :parse-tree) 'headline
		      (lambda (ref)
			(if (member title (org-element-property :title ref))
			    (push ref heading)))
		      info 't))
		 (setq listing (org-e-texinfo--build-menu
				(car heading) level info))
	 	 (if listing
	 	     (setq listing (format
				    "\n@menu\n%s\n@end menu\n\n" listing))
	 	   'nil)))
	 ;; 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)))
	      ;; If an index, always unnumbered
	      (if index
		  (concat menu node (cdr sec) "\n%s")
		;; Otherwise number as needed.
		(concat menu node
			(funcall
			 (if numberedp #'car #'cdr) sec) "\n%s"))))))
	 (text (org-export-data
		(org-element-property :title headline) info))
	 (todo
	  (and (plist-get info :with-todo-keywords)
	       (let ((todo (org-element-property :todo-keyword headline)))
		 (and todo (org-export-data todo info)))))
	 (todo-type (and todo (org-element-property :todo-type headline)))
	 (tags (and (plist-get info :with-tags)
		    (org-export-get-tags headline info)))
	 (priority (and (plist-get info :with-priority)
			(org-element-property :priority headline)))
	 ;; Create the headline text along with a no-tag version.  The
	 ;; latter is required to remove tags from table of contents.
	 (full-text (if (functionp org-e-texinfo-format-headline-function)
			;; User-defined formatting function.
			(funcall org-e-texinfo-format-headline-function
				 todo todo-type priority text tags)
		      ;; Default formatting.
		      (concat
		       (when todo
			 (format "@strong{%s} " todo))
		       (when priority (format "@emph{#%s} " priority))
		       text
		       (when tags
			 (format ":%s:"
				 (mapconcat 'identity tags ":"))))))
	 (full-text-no-tag
	  (if (functionp org-e-texinfo-format-headline-function)
	      ;; User-defined formatting function.
	      (funcall org-e-texinfo-format-headline-function
		       todo todo-type priority text nil)
	    ;; Default formatting.
	    (concat
	     (when todo (format "@strong{%s} " todo))
	     (when priority (format "@emph{#%c} " priority))
	     text)))
	 (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 the `copying' section: ignore it
     ;;         This is used elsewhere.
     ((org-element-property :copying headline) nil)
     ;; Case 3: An index.  If it matches one of the known indexes,
     ;;         print it as such following the contents, otherwise
     ;;         print the contents and leave the index up to the user.
     (index
      (format
       section-fmt full-text
       (concat pre-blanks contents "\n" 
	       (if (member index '("cp" "fn" "ky" "pg" "tp" "vr"))
		   (concat "@printindex " index)))))
     ;; Case 4: 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) (org-export-low-level-p headline info))
      ;; Build the real contents of the sub-tree.
      (let ((low-level-body
	     (concat
	      ;; If the headline is the first sibling, start a list.
	      (when (org-export-first-sibling-p headline)
		(format "@%s\n" (if numberedp 'enumerate 'itemize)))
	      ;; Itemize headline
	      "@item\n" full-text "\n" 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)) low-level-body
	  (replace-regexp-in-string
	   "[ \t\n]*\\'"
	   (format "\n@end %s" (if numberedp 'enumerate 'itemize))
	   low-level-body))))
     ;; Case 5: Standard headline.  Export it as a section.
     (t
      (cond
       ((not (and tags (eq (plist-get info :with-tags) 'not-in-toc)))
	;; Regular section.  Use specified format string.
	(format (replace-regexp-in-string "%]" "%%]" section-fmt) full-text
		(concat pre-blanks contents)))
       ((string-match "\\`@\\(.*?\\){" section-fmt)
	;; If tags should be removed from table of contents, insert
	;; title without tags as an alternative heading in sectioning
	;; command.
	(format (replace-match (concat (match-string 1 section-fmt) "[%s]")
			       nil nil section-fmt 1)
		;; Replace square brackets with parenthesis since
		;; square brackets are not supported in optional
		;; arguments.
		(replace-regexp-in-string
		 "\\[" "("
		 (replace-regexp-in-string
		  "\\]" ")"
		  full-text-no-tag))
		full-text
		(concat pre-blanks contents)))
       (t
	;; Impossible to add an alternative heading.  Fallback to
	;; regular sectioning format string.
	(format (replace-regexp-in-string "%]" "%%]" section-fmt) full-text
		(concat pre-blanks contents))))))))


;;;; Horizontal Rule
;;
;; Horizontal rules are ignored

;;;; Inline Babel Call
;;
;; Inline Babel Calls are ignored.


;;;; Inline Src Block

(defun org-e-texinfo-inline-src-block (inline-src-block contents info)
  "Transcode an INLINE-SRC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((code (org-element-property :value inline-src-block))
	 (separator (org-e-texinfo--find-verb-separator code)))
    (concat "@verb{" separator code separator "}")))


;;;; Inlinetask

(defun org-e-texinfo-inlinetask (inlinetask contents info)
  "Transcode an INLINETASK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  (let ((title (org-export-data (org-element-property :title inlinetask) info))
	(todo (and (plist-get info :with-todo-keywords)
		   (let ((todo (org-element-property :todo-keyword inlinetask)))
		     (and todo (org-export-data todo info)))))
	(todo-type (org-element-property :todo-type inlinetask))
	(tags (and (plist-get info :with-tags)
		   (org-export-get-tags inlinetask info)))
	(priority (and (plist-get info :with-priority)
		       (org-element-property :priority inlinetask))))
    ;; If `org-e-texinfo-format-inlinetask-function' is provided, call it
    ;; with appropriate arguments.
    (if (functionp org-e-texinfo-format-inlinetask-function)
	(funcall org-e-texinfo-format-inlinetask-function
		 todo todo-type priority title tags contents)
      ;; Otherwise, use a default template.
      (let ((full-title
	     (concat
	      (when todo (format "@strong{%s} " todo))
	      (when priority (format "#%c " priority))
	      title
	      (when tags (format ":%s:"
				 (mapconcat 'identity tags ":"))))))
	(format (concat "@center %s\n\n"
			"%s"
			"\n")
		full-title contents)))))


;;;; Italic

(defun org-e-texinfo-italic (italic contents info)
  "Transcode ITALIC from Org to Texinfo.
CONTENTS is the text with italic markup.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup contents 'italic))

;;;; Item

(defun org-e-texinfo-item (item contents info)
  "Transcode an ITEM element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((tag (org-element-property :tag item))
	 (desc (org-export-data tag info)))
   (concat "\n@item " (if tag desc) "\n"
	   (org-trim contents) "\n")))


;;;; Keyword

(defun org-e-texinfo-keyword (keyword contents info)
  "Transcode a KEYWORD element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((key (org-element-property :key keyword))
	(value (org-element-property :value keyword)))
    (cond
     ((string= key "TEXINFO") value)
     ((string= key "CINDEX") (format "@cindex %s" value))
     ((string= key "FINDEX") (format "@findex %s" value))
     ((string= key "KINDEX") (format "@kindex %s" value))
     ((string= key "PINDEX") (format "@pindex %s" value))
     ((string= key "TINDEX") (format "@tindex %s" value))
     ((string= key "VINDEX") (format "@vindex %s" value))
     )))


;;;; Latex Environment
;;
;; Latex environments are ignored


;;;; Latex Fragment
;;
;; Latex fragments are ignored.


;;;; Line Break

(defun org-e-texinfo-line-break (line-break contents info)
  "Transcode a LINE-BREAK object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  "@*")


;;;; Link

(defun org-e-texinfo-link (link desc info)
  "Transcode a LINK object from Org to Texinfo.

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"))
		 (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))
		   (concat "file://" raw-path)))
		(t raw-path)))
	 (email (if (string= type "mailto")
		    (let ((text (replace-regexp-in-string
				 "@" "@@" raw-path)))
		     (concat text (if desc (concat "," desc))))))
	 protocol)
    (cond
     ;; Links pointing to an headline: Find destination and build
     ;; appropriate referencing command.
     ((member type '("custom-id" "id"))
      (let ((destination (org-export-resolve-id-link link info)))
	(case (org-element-type destination)
	  ;; Id link points to an external file.
	  (plain-text
	   (if desc (format "@uref{file://%s,%s}" destination desc)
	     (format "@uref{file://%s}" destination)))
	  ;; LINK points to an headline.  Use the headline as the NODE target
	  (headline
	   (format "@ref{%s}"
		   (org-export-data
		    (org-element-property :title destination) info)))
	  (otherwise
	   (let ((path (org-export-solidify-link-text path)))
	     (if (not desc) (format "@ref{%s}" path)
	       (format "@ref{%s,,%s}" path desc)))))))
     ((member type '("fuzzy"))
      (let ((destination (org-export-resolve-fuzzy-link link info)))
	(case (org-element-type destination)
	  ;; Id link points to an external file.
	  (plain-text
	   (if desc (format "@uref{file://%s,%s}" destination desc)
	     (format "@uref{file://%s}" destination)))
	  ;; LINK points to an headline.  Use the headline as the NODE target
	  (headline
	   (format "@ref{%s}"
		   (org-export-data
		    (org-element-property :title destination) info)))
	  (otherwise
	   (let ((path (org-export-solidify-link-text path)))
	     (if (not desc) (format "@ref{%s}" path)
	       (format "@ref{%s,,%s}" path desc)))))))
     ;; Special case for email addresses
     (email
      (format "@email{%s}" email))
     ;; External link with a description part.
     ((and path desc) (format "@uref{%s,%s}" path desc))
     ;; External link without a description part.
     (path (format "@uref{%s}" path))
     ;; No path, only description.  Try to do something useful.
     (t (format org-e-texinfo-link-with-unknown-path-format desc)))))


;;;; Macro

(defun org-e-texinfo-macro (macro contents info)
  "Transcode a MACRO element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  ;; Use available tools.
  (org-export-expand-macro macro info))


;;;; Menu

(defun org-e-texinfo-make-menu (info level)
  "Create the menu for inclusion in the texifo document.

INFO is the parsed buffer that contains the headlines.  LEVEL
determines whether to make the main menu, or the detailed menu.

This is only used for generating the primary menu.  In-Node menus
are generated directly."
  (let* ((parse (plist-get info :parse-tree))
	 ;; Top determines level to build menu from, it finds the
	 ;; level of the first headline in the export.
	 (top (org-element-map
	       parse 'headline
	       (lambda (headline)
		 (org-element-property :level headline)) info 't)))
    (cond
     ;; Generate the main menu
     ((eq level 'main)
      (org-e-texinfo--build-menu parse top info))
     ;; Generate the detailed (recursive) menu
     ((eq level 'detailed)
      ;; Requires recursion
      ;;(org-e-texinfo--build-detailed-menu parse top info)
      (or (org-e-texinfo--build-menu parse top info 'detailed)
	  "detailed"))
     ;; Otherwise do nothing
     (t))))


;;;; Paragraph

(defun org-e-texinfo-paragraph (paragraph contents info)
  "Transcode a PARAGRAPH element from Org to Texinfo.
CONTENTS is the contents of the paragraph, as a string.  INFO is
the plist used as a communication channel."
  contents)


;;;; Plain List

(defun org-e-texinfo-plain-list (plain-list contents info)
  "Transcode a PLAIN-LIST element from Org to Texinfo.
CONTENTS is the contents of the list.  INFO is a plist holding
contextual information."
  (let* ((type (org-element-property :type plain-list))
	 (list-type (cond
		     ((eq type 'ordered) "enumerate")
		     ((eq type 'unordered) "itemize")
		     ((eq type 'descriptive) "table"))))
    (format "@%s%s\n@end %s"
	    (if (eq type 'descriptive)
		(concat list-type " " org-e-texinfo-def-table-markup)
	     list-type)
	    contents
	    list-type)))


;;;; Plain Text

(defun org-e-texinfo-plain-text (text info)
  "Transcode a TEXT string from Org to Texinfo.
TEXT is the string to transcode.  INFO is a plist holding
contextual information."
  ;; Protect @ { and }.
  (while (string-match "\\([^\\]\\|^\\)\\([@{}]\\)" text)
    (setq text
	  (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
  ;; LaTeX into @LaTeX{} 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-texinfo--quotation-marks text info))
  ;; Convert special strings.
  (when (plist-get info :with-special-strings)
    (while (string-match (regexp-quote "...") text)
      (setq text (replace-match "@dots{}" nil t 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)


;;;; Planning

(defun org-e-texinfo-planning (planning contents info)
  "Transcode a PLANNING element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (concat
   "@noindent"
   (mapconcat
    'identity
    (delq nil
	  (list
	   (let ((closed (org-element-property :closed planning)))
	     (when closed
	       (concat
		(format "@strong%s} " org-closed-string)
		(format org-e-texinfo-inactive-timestamp-format
			(org-translate-time closed)))))
	   (let ((deadline (org-element-property :deadline planning)))
	     (when deadline
	       (concat
		(format "@strong{%s} " org-deadline-string)
		(format org-e-texinfo-active-timestamp-format
			(org-translate-time deadline)))))
	   (let ((scheduled (org-element-property :scheduled planning)))
	     (when scheduled
	       (concat
		(format "@strong{%s} " org-scheduled-string)
		(format org-e-texinfo-active-timestamp-format
			(org-translate-time scheduled)))))))
    " ")
   "@*"))


;;;; Property Drawer

(defun org-e-texinfo-property-drawer (property-drawer contents info)
  "Transcode a PROPERTY-DRAWER element from Org to Texinfo.
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-texinfo-quote-block (quote-block contents info)
  "Transcode a QUOTE-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  
  (let* ((title (org-element-property :name quote-block))
	 (start-quote (concat "@quotation"

			      (if title
				 (format " %s" title)))))
    
    (format "%s\n%s@end quotation" start-quote contents)))


;;;; Quote Section

(defun org-e-texinfo-quote-section (quote-section contents info)
  "Transcode a QUOTE-SECTION element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((value (org-remove-indentation
		(org-element-property :value quote-section))))
    (when value (format "@verbatim\n%s@end verbatim" value))))


;;;; Radio Target

(defun org-e-texinfo-radio-target (radio-target text info)
  "Transcode a RADIO-TARGET object from Org to Texinfo.
TEXT is the text of the target.  INFO is a plist holding
contextual information."
  (format "@anchor{%s}%s"
	  (org-export-solidify-link-text
	   (org-element-property :value radio-target))
	  text))


;;;; Section

(defun org-e-texinfo-section (section contents info)
  "Transcode a SECTION element from Org to Texinfo.
CONTENTS holds the contents of the section.  INFO is a plist
holding contextual information."
  contents)


;;;; Special Block
;;
;; Are ignored at the moment

;;;; Src Block

(defun org-e-texinfo-src-block (src-block contents info)
  "Transcode a SRC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((lang (org-element-property :language src-block))
	 (lisp-p (string-match-p "lisp" lang)))
    (cond
     ;; Case 1.  Lisp Block
     (lisp-p
      (format "@lisp\n%s\n@end lisp"
	      (org-export-format-code-default src-block info)))
     ;; Case 2.  Other blocks
     (t
      (format "@example\n%s\n@end example"
	      (org-export-format-code-default src-block info))))))


;;;; Statistics Cookie

(defun org-e-texinfo-statistics-cookie (statistics-cookie contents info)
  "Transcode a STATISTICS-COOKIE object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (org-element-property :value statistics-cookie))


;;;; Strike-Through
;;
;; Strikethrough is ignored


;;;; Subscript

(defun org-e-texinfo-subscript (subscript contents info)
  "Transcode a SUBSCRIPT object from Org to Texinfo.
CONTENTS is the contents of the object.  INFO is a plist holding
contextual information."
  (format "@math{_%s}" contents))


;;;; Superscript

(defun org-e-texinfo-superscript (superscript contents info)
  "Transcode a SUPERSCRIPT object from Org to Texinfo.
CONTENTS is the contents of the object.  INFO is a plist holding
contextual information."
  (format "@math{^%s}" contents))


;;;; Table
;;
;; `org-e-texinfo-table' is the entry point for table transcoding.  It
;; takes care of tables with a "verbatim" attribute.  Otherwise, it
;; delegates the job to either `org-e-texinfo-table--table.el-table' or
;; `org-e-texinfo-table--org-table' functions, depending of the type of
;; the table.
;;
;; `org-e-texinfo-table--align-string' is a subroutine used to build
;; alignment string for Org tables.

(defun org-e-texinfo-table (table contents info)
  "Transcode a TABLE element from Org to Texinfo.
CONTENTS is the contents of the table.  INFO is a plist holding
contextual information."
  (cond
   ;; Case 1: verbatim table.
   ((or org-e-texinfo-tables-verbatim
	(let ((attr (mapconcat 'identity
			       (org-element-property :attr_latex table)
			       " ")))
	  (and attr (string-match "\\<verbatim\\>" attr))))
    (format "@verbatim \n%s\n@end verbatim"
	    ;; Re-create table, without affiliated keywords.
	    (org-trim
	     (org-element-interpret-data
	      `(table nil ,@(org-element-contents table))))))
   ;; Case 2: table.el table.  Convert it using appropriate tools.
   ((eq (org-element-property :type table) 'table.el)
    (org-e-texinfo-table--table.el-table table contents info))
   ;; Case 3: Standard table.
   (t (org-e-texinfo-table--org-table table contents info))))

(defun org-e-texinfo-table-column-widths (table info)
  "Determine the largest table cell in each column to process alignment.

TABLE is the table element to transcode.  INFO is a plist used as
a communication channel."
  (let* ((rows (org-element-map table 'table-row 'identity info))
	 (collected (loop for row in rows collect
			  (org-element-map
			   row 'table-cell 'identity info)))
	 (number-cells (length (car collected)))
	 cells counts)
    (loop for row in collected do
	  (push (mapcar (lambda (ref)
		     (let* ((start (org-element-property :contents-begin ref))
			    (end (org-element-property :contents-end ref))
			    (length (- end start)))
		       length)) row) cells))
    (setq cells (remove-if #'null cells))
    (push (loop for count from 0 to (- number-cells 1) collect
		   (loop for item in cells collect
			 (nth count item))) counts)
    (mapconcat '(lambda (size)
		  (make-string size ?a)) (mapcar (lambda (ref)
				   (apply 'max `,@ref)) (car counts))
	       "} {")
  ))

(defun org-e-texinfo-table--org-table (table contents info)
  "Return appropriate Texinfo code for an Org table.

TABLE is the table type element to transcode.  CONTENTS is its
contents, as a string.  INFO is a plist used as a communication
channel.

This function assumes TABLE has `org' as its `:type' attribute."
  (let* ((attr (org-export-read-attribute :attr_texinfo table))
	 (col-width (plist-get attr :columns))
	 (columns (if col-width
		      (format "@columnfractions %s"
			      col-width)
		    (format "{%s}"
			    (org-e-texinfo-table-column-widths
			     table info)))))
    ;; Prepare the final format string for the table.
    (cond
     ;; Longtable.
     ;; Others.
     (t (concat
	 (format "@multitable %s\n%s@end multitable"
		 columns
		 contents))))))

(defun org-e-texinfo-table--table.el-table (table contents info)
  "Returns nothing.

Rather than return an invalid table, nothing is returned."
  'nil)


;;;; Table Cell

(defun org-e-texinfo-table-cell (table-cell contents info)
  "Transcode a TABLE-CELL element from Org to Texinfo.
CONTENTS is the cell contents.  INFO is a plist used as
a communication channel."
  (concat (if (and contents
		   org-e-texinfo-table-scientific-notation
		   (string-match orgtbl-exp-regexp contents))
	      ;; Use appropriate format string for scientific
	      ;; notation.
	      (format org-e-texinfo-table-scientific-notation
		      (match-string 1 contents)
		      (match-string 2 contents))
	    contents)
	  (when (org-export-get-next-element table-cell) "\n@tab ")))


;;;; Table Row

(defun org-e-texinfo-table-row (table-row contents info)
  "Transcode a TABLE-ROW element from Org to Texinfo.
CONTENTS is the contents of the row.  INFO is a plist used as
a communication channel."
  ;; Rules are ignored since table separators are deduced from
  ;; borders of the current row.
  (when (eq (org-element-property :type table-row) 'standard) 
    (concat "@item " contents "\n")))


;;;; Target

(defun org-e-texinfo-target (target contents info)
  "Transcode a TARGET object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (format "@anchor{%s}"
	  (org-export-solidify-link-text (org-element-property :value target))))


;;;; Timestamp

(defun org-e-texinfo-timestamp (timestamp contents info)
  "Transcode a TIMESTAMP object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (let ((value (org-translate-time (org-element-property :value timestamp)))
	(type (org-element-property :type timestamp)))
    (cond ((memq type '(active active-range))
	   (format org-e-texinfo-active-timestamp-format value))
	  ((memq type '(inactive inactive-range))
	   (format org-e-texinfo-inactive-timestamp-format value))
	  (t (format org-e-texinfo-diary-timestamp-format value)))))


;;;; Underline
;;
;; Underline is ignored


;;;; Verbatim

(defun org-e-texinfo-verbatim (verbatim contents info)
  "Transcode a VERBATIM object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist used as a communication
channel."
  (org-e-texinfo--text-markup (org-element-property :value verbatim) 'verbatim))


;;;; Verse Block

(defun org-e-texinfo-verse-block (verse-block contents info)
  "Transcode a VERSE-BLOCK element from Org to Texinfo.
CONTENTS is verse block contents. INFO is a plist holding
contextual information."
  ;; In a verse environment, add a line break to each newline
  ;; character and change each white space at beginning of a line
  ;; into a space of 1 em.  Also change each blank line with
  ;; a vertical space of 1 em.
  (progn
    (setq contents (replace-regexp-in-string
		    "^ *\\\\\\\\$" "\\\\vspace*{1em}"
		    (replace-regexp-in-string
		     "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n" contents)))
    (while (string-match "^[ \t]+" contents)
      (let ((new-str (format "\\hspace*{%dem}"
			     (length (match-string 0 contents)))))
	(setq contents (replace-match new-str nil t contents))))
    (format "\\begin{verse}\n%s\\end{verse}" contents)))


\f
;;; Interactive functions

(defun org-e-texinfo-export-to-texinfo
  (&optional subtreep visible-only body-only ext-plist pub-dir)
  "Export current buffer to a Texinfo 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 ".texi" subtreep pub-dir)))
    (org-export-to-file
     'e-texinfo outfile subtreep visible-only body-only ext-plist)))

(defun org-e-texinfo-export-to-info
  (&optional subtreep visible-only body-only ext-plist pub-dir)
  "Export current buffer to Texinfo then process through to INFO.

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 INFO file's name."
  (interactive)
  (org-e-texinfo-compile
   (org-e-texinfo-export-to-texinfo
    subtreep visible-only body-only ext-plist pub-dir)))

(defun org-e-texinfo-compile (texifile)
  "Compile a texinfo file.

TEXIFILE is the name of the file being compiled.  Processing is
done through the command specified in `org-e-texinfo-info-process'.

Return INFO file name or an error if it couldn't be produced."
  (let* ((wconfig (current-window-configuration))
	 (texifile (file-truename texifile))
	 (base (file-name-sans-extension texifile))
	 errors)
    (message (format "Processing Texinfo file %s ..." texifile))
    (unwind-protect
	(progn
	  (cond
	   ;; A function is provided: Apply it.
	   ((functionp org-e-texinfo-info-process)
	    (funcall org-e-texinfo-info-process (shell-quote-argument texifile)))
	   ;; A list is provided: Replace %b, %f and %o with appropriate
	   ;; values in each command before applying it.  Output is
	   ;; redirected to "*Org INFO Texinfo Output*" buffer.
	   ((consp org-e-texinfo-info-process)
	    (let* ((out-dir (or (file-name-directory texifile) "./"))
		   (outbuf (get-buffer-create "*Org Info Texinfo Output*")))
	      (mapc
	       (lambda (command)
		 (shell-command
		  (replace-regexp-in-string
		   "%b" (shell-quote-argument base)
		   (replace-regexp-in-string
		    "%f" (shell-quote-argument texifile)
		    (replace-regexp-in-string
		     "%o" (shell-quote-argument out-dir) command t t) t t) t t)
		  outbuf))
	       org-e-texinfo-info-process)
	      ;; Collect standard errors from output buffer.
	      (setq errors (org-e-texinfo-collect-errors outbuf))))
	   (t (error "No valid command to process to Info")))
	  (let ((infofile (concat base ".info")))
	    ;; Check for process failure.  Provide collected errors if
	    ;; possible.
	    (if (not (file-exists-p infofile))
		(error (concat (format "INFO file %s wasn't produced" infofile)
			       (when errors (concat ": " errors))))
	      ;; Else remove log files, when specified, and signal end of
	      ;; process to user, along with any error encountered.
	      (message (concat "Process completed"
			       (if (not errors) "."
				 (concat " with errors: " errors)))))
	    ;; Return output file name.
	    infofile))
      (set-window-configuration wconfig))))

(defun org-e-texinfo-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 "makeinfo" run.
      (when (re-search-backward "^makeinfo (GNU texinfo)" nil t)
	(let ((case-fold-search t)
	      (errors ""))
	  (when (save-excursion
		  (re-search-forward "perhaps incorrect sectioning?" nil t))
	    (setq errors (concat errors " [incorrect sectionnng]")))
	  (when (save-excursion
		  (re-search-forward "missing close brace" nil t))
	    (setq errors (concat errors " [syntax error]")))
	  (when (save-excursion
		  (re-search-forward "Unknown command" nil t))
	    (setq errors (concat errors " [undefined @command]")))
	  (when (save-excursion
		  (re-search-forward "No matching @end" nil t))
	    (setq errors (concat errors " [block incomplete]")))
	  (when (save-excursion
		  (re-search-forward "requires a sectioning" nil t))
	    (setq errors (concat errors " [invalid section command]")))
	  (when (save-excursion
		  (re-search-forward "[unexpected]" nil t))
	    (setq errors (concat errors " [unexpected error]")))
	  (and (org-string-nw-p errors) (org-trim errors)))))))


(provide 'org-e-texinfo)
;;; org-e-texinfo.el ends here

[-- Attachment #3: orgguide.org --]
[-- Type: application/octet-stream, Size: 93762 bytes --]

#+TITLE: The compact Org-Mode Guide
#+AUTHOR: Carsten Dominic

## Change TODO list to allow for TODO in headline
#+TODO: FIXME(f)

#+TEXINFO_FILENAME: orgguide.info

# #+TEXINFO_HEADER: @include org-version.inc
#+TEXINFO_HEADER: @c Use proper quote and backtick for code sections in PDF output
#+TEXINFO_HEADER: @c Cf. Texinfo manual 14.2
#+TEXINFO_HEADER: @set txicodequoteundirected
#+TEXINFO_HEADER: @set txicodequotebacktick
#+TEXINFO_HEADER: @c Version and Contact Info
#+TEXINFO_HEADER: @set MAINTAINERSITE @uref{http://orgmode.org,maintainers webpage}
#+TEXINFO_HEADER: @set MAINTAINER Carsten Dominik
#+TEXINFO_HEADER: @set MAINTAINEREMAIL @email{carsten at orgmode dot org}
#+TEXINFO_HEADER: @set MAINTAINERCONTACT @uref{mailto:carsten at orgmode dot org,contact the maintainer}

#+TEXINFO_DIR_CATEGORY: Emacs
#+TEXINFO_DIR_TITLE: Org Mode Guide: (orgguide)
#+TEXINFO_DIR_DESC: Abbreviated Org-mode Manual


* Copying
:PROPERTIES:
:copying: t
:END:

Copyright @@info:@copyright{}@@ 2010-2012 Free Software Foundation

#+BEGIN_QUOTE
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover texts being "A GNU Manual,"
and with the Back-Cover Texts as in (a) below.  A copy of the license
is included in the section entitled "GNU Free Documentation License."

(a) The FSF's Back-Cover Text is: "You have the freedom to copy and
modify this GNU manual.  Buying copies from the FSF supports it in
developing GNU and promoting software freedom."

This document is part of a collection distributed under the GNU Free
Documentation License.  If you want to distribute this document
separately from the collection, you can do so by adding a copy of the
license to the document, as described in section 6 of the license.
#+END_QUOTE

* Introduction
:PROPERTIES:
:DESCRIPTION: Getting started
:END:

** Preface
:PROPERTIES:
:DESCRIPTION: Welcome
:END:

Org is a mode for keeping notes, maintaining TODO lists, and doing
project planning with a fast and effective plain-text system.  It is
also an authoring and publishing system.

This document is a much compressed derivative of the [[http://orgmode.org/index.html#sec-4_1][comprehensive
Org-mode manual]].  It contains all basic features and commands, along
with important hints for customization.  It is intended for beginners
who would shy back from a 200 page manual because of sheer size.

** Installation
:PROPERTIES:
:DESCRIPTION: How to install a downloaded version of Org
:END:

*Important*: If you are using a version of Org that is part of the
Emacs distribution or an XEmacs package, please skip this section and
go directly to [[Activation]].

If you have downloaded Org from the Web, either as a distribution
@@info:@file{.zip}@@ or @@info:@file{.tar}@@ file, or as a Git archive,
it is best to run it directly from the distribution directory.  You
need to add the @@info:@file{lisp}@@ subdirectories to the Emacs load
path.  To do this, add the following line to @@info:@file{.emacs}@@:

#+begin_src emacs-lisp
  (setq load-path (cons "~/path/to/orgdir/lisp" load-path))
  (setq load-path (cons "~/path/to/orgdir/contrib/lisp" load-path))
#+end_src

@@info:@noindent@@ For speed you should byte-compile the Lisp files
with the shell command:

#+begin_src shell
make
#+end_src

Then add the following line to @@info:@file{.emacs}@@.  It is needed so that
Emacs can autoload functions that are located in files not immediately
loaded when Org-mode starts.
#+begin_src emacs-lisp
(require 'org-install)
#+end_src

** Activation
:PROPERTIES:
:DESCRIPTION: How to activate Org for certain buffers
:END:

Add the following lines to your @@info:@file{.emacs}@@ file.  The last
three lines define /global/ keys for some commands --- please choose
suitable keys yourself.

#+begin_src emacs-lisp
;; The following lines are always needed.  Choose your own keys.
(add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
(add-hook 'org-mode-hook 'turn-on-font-lock) ; not needed when global-font-lock-mode is on
(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cb" 'org-iswitchb)
#+end_src

With this setup, all files with extension @@info:@samp{.org}@@ will be
put into Org mode.
** Feedback
:PROPERTIES:
:DESCRIPTION: Bug reports, ideas, patches etc.
:END:

If you find problems with Org, or if you have questions, remarks, or
ideas about it, please mail to the Org mailing list
[[mailto:emacs-orgmode@gnu.org]].  For information on how to submit bug reports,
see the main manual.
* Document Structure
:PROPERTIES:
:DESCRIPTION: A tree works like your brain
:END:

Org is based on Outline mode and provides flexible commands to
edit the structure of the document.

** Outlines
:PROPERTIES:
:DESCRIPTION: Org is based on Outline mode
:END:

Org is implemented on top of Outline mode.  Outlines allow a document
to be organized in a hierarchical structure, which (at least for me)
is the best representation of notes and thoughts.  An overview of this
structure is achieved by folding (hiding) large parts of the document
to show only the general document structure and the parts currently
being worked on.  Org greatly simplifies the use of outlines by
compressing the entire show/hide functionality into a single command,
@@info:@command{org-cycle}@@, which is bound to the @@info:@key{TAB}@@
key.

** Headlines
:PROPERTIES:
:DESCRIPTION: How to typeset Org tree headlines
:END:

Headlines define the structure of an outline tree.  The headlines in
Org start with one or more stars, on the left margin[fn:1].  For
example:

#+begin_src org
  ,* Top level headline
  ,** Second level
  ,*** 3rd level
  ,    some text
  ,*** 3rd level
  ,    more text
  
  ,* Another top level headline
#+end_src

@@info:@noindent@@ Some people find the many stars too noisy and would
prefer an outline that has whitespace followed by a single star as
headline starters.  [[Clean view]], describes a setup to realize this.

** Visibility cycling
:PROPERTIES:
:DESCRIPTION: Show and hide, much simplified
:END:

Outlines make it possible to hide parts of the text in the buffer.
Org uses just two commands, bound to @@info:@key{TAB}@@ and
@@info:@kbd{S-@key{TAB}@@} to change the visibility in the buffer.


- @@info:@key{TAB}@@ :: /Subtree cycling/: Rotate current subtree among the states

     #+begin_example
       ,-> FOLDED -> CHILDREN -> SUBTREE --.
       '-----------------------------------'
     #+end_example

     When called with a prefix argument (@@info:@kbd{C-u @key{TAB}}@@) or with
     the shift key, global cycling is invoked.

- S-@@info:@key{TAB}@@ @@info:@r{and}@@ C-u @@info:@key{TAB}@@ :: /Global
     cycling/: Rotate the entire buffer among the states

     #+begin_example
       ,-> OVERVIEW -> CONTENTS -> SHOW ALL --.
       '--------------------------------------'
     #+end_example

- C-u C-u C-u @@info:@key{TAB}@@ :: Show all, including drawers.

When Emacs first visits an Org file, the global state is set to
OVERVIEW, i.e.: only the top level headlines are visible.  This can be
configured through the variable ~org-startup-folded~, or on a
per-file basis by adding a startup keyword ~overview~, ~content~,
~showall~, like this:

#+begin_src org
  ,#+STARTUP: content
#+end_src

** Motion
:PROPERTIES:
:DESCRIPTION: Jumping to other headlines
:END:
The following commands jump to other headlines in the buffer.

- C-c C-n :: Next heading.
- C-c C-p :: Previous heading.
- C-c C-f :: Next heading same level.
- C-c C-b :: Previous heading same level.
- C-c C-u :: Backward to higher level heading.

** Structure editing
:PROPERTIES:
:DESCRIPTION: Changing sequence and level of headlines
:END:

- M-@@info:@key{RET}@@
Insert new heading with same level as current.  If the cursor is in a plain
list item, a new item is created ([[Plain lists]]).  When this command is
used in the middle of a line, the line is split and the rest of the line
becomes the new headline[fn:2].
- M-S-@@info:@key{RET}@@ :: Insert new TODO entry with same level as
     current heading.
- @@info:@key{TAB}@@ in new, empty entry :: In a new entry with no text
     yet, @@info:@key{TAB}@@ will cycle through reasonable levels.
- M-@@info:@key{left}@r{/}@key{right}@@ :: Promote/demote current
     heading by one level.
- M-S-@@info:@key{left}@r{/}@key{right}@@ :: Promote/demote the
     current subtree by one level.
- M-S-@@info:@key{up}@r{/}@key{down}@@ :: Move subtree up/down
     (swap with previous/next subtree of same level).
- C-c C-w :: Refile entry or region to a different location.  [[Refiling%20notes][Refiling notes]].
- C-x n s/w :: Narrow buffer to current subtree / widen it again

When there is an active region (Transient Mark mode), promotion and
demotion work on all headlines in the region.

** Sparse trees
:PROPERTIES:
:DESCRIPTION: Matches embedded in context
:END:

An important feature of Org mode is the ability to construct /sparse
trees/ for selected information in an outline tree, so that the entire
document is folded as much as possible, but the selected information
is made visible along with the headline structure above
it[fn:12].  Just try it out and you will see
immediately how it works.

Org mode contains several commands creating such trees, all these
commands can be accessed through a dispatcher:

- C-c / :: This prompts for an extra key to select a sparse-tree
           creating command.
- C-c / r :: Occur.  Prompts for a regexp and shows a sparse tree with
             all matches.  Each match is also highlighted; the
             highlights disappear by pressing @@info:@kbd{C-c C-c}@@.

The other sparse tree commands select headings based on TODO keywords,
tags, or properties and will be discussed later in this manual.

** Plain lists
:PROPERTIES:
:DESCRIPTION: Additional structure within an entry
:END:

Within an entry of the outline tree, hand-formatted lists can provide
additional structure.  They also provide a way to create lists of
checkboxes ([[Checkboxes]]).  Org supports editing such lists,
and the HTML exporter ([[Exporting]]) parses and formats them.

Org knows ordered lists, unordered lists, and description lists.
- /Unordered/ list items start with @@info:@samp{-}@@,
  @@info:@samp{+}@@, or @@info:@samp{*}@@ as bullets.
- /Ordered/ list items start with @@info:@samp{1.}@@ or
  @@info:@samp{1)}@@.
- /Description/ list use '::' to separate the
     /term/ from the description.

Items belonging to the same list must have the same indentation on the first
line.  An item ends before the next line that is indented like its
bullet/number, or less.  A list ends when all items are closed, or before two
blank lines.  An example:

#+begin_src org
  ,** Lord of the Rings
  ,   My favorite scenes are (in this order)
  ,   1. The attack of the Rohirrim
  ,   2. Eowyn's fight with the witch king
  ,      + this was already my favorite scene in the book
  ,      + I really like Miranda Otto.
  ,   Important actors in this film are:
  ,   - Elijah Wood :: He plays Frodo
  ,   - Sean Austin :: He plays Sam, Frodo's friend.
#+end_src


The following commands act on items when the cursor is in the first line of
an item (the line with the bullet or number).

- @@info:@key{TAB}@@ :: Items can be folded just like headline levels.
- M-@@info:@key{RET}@@ :: Insert new item at current level.  With a
     prefix argument, force a new heading ([[Structure editing]]).
- M-S-@@info:@key{RET}@@ :: Insert a new item with a checkbox
     ([[Checkboxes]]).
- M-S-@@info:@key{up}@r{/}@key{down}@@ :: Move the item including
     subitems up/down (swap with previous/next item of same
     indentation).  If the list is ordered, renumbering is automatic.
- M-@@info:@key{left}@r{/}M-@key{right}@@ :: Decrease/increase the
     indentation of an item, leaving children alone.
- M-S-@@info:@key{left}@r{/}@key{right}@@ :: Decrease/increase the
     indentation of the item, including subitems.
- C-c C-c :: If there is a checkbox ([[Checkboxes]]) in the item
             line, toggle the state of the checkbox.  Also verify
             bullets and indentation consistency in the whole list.
- C-c - :: Cycle the entire list level through the different
           itemize/enumerate bullets (@@info:@samp{-}@@,
           @@info:@samp{+}@@, @@info:@samp{*}@@, @@info:@samp{1.}@@,
           @@info:@samp{1)}@@).

** Footnote
:PROPERTIES:
:DESCRIPTION: How footnotes are defined in Org's syntax
:END:

A footnote is defined in a paragraph that is started by a footnote marker in
square brackets in column 0, no indentation allowed.  The footnote reference
is simply the marker in square brackets, inside text.  For example:

#+begin_src org
  ,The Org homepage[fn:1] now looks a lot better than it used to.
  ,...
  ,[fn:1] The link is: http://orgmode.org
#+end_src

@@info:@noindent@@ The following commands handle footnotes:

- C-c C-x f :: The footnote action command.  When the cursor is on a
               footnote reference, jump to the definition.  When it is
               at a definition, jump to the (first) reference.
               Otherwise, create a new footnote.  When this command is
               called with a prefix argument, a menu of additional
               options including renumbering is offered.

- C-c C-c :: Jump between definition and reference.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Document-Structure.html#Document-Structure][Chapter 2 of the manual]]\\
[[http://sachachua.com/wp/2008/01/outlining-your-notes-with-org/][Sacha Chua's tutorial]]

* Tables
:PROPERTIES:
:DESCRIPTION: Pure magic for quick formatting
:END:


Org comes with a fast and intuitive table editor.  Spreadsheet-like
calculations are supported in connection with the Emacs
@@info:@file{calc}@@ package
#+BEGIN_TEXINFO
@ifinfo
(@pxref{Top,Calc,,Calc,Gnu Emacs Calculator Manual}).
@end ifinfo
@ifnotinfo
(see the Emacs Calculator manual for more information about the Emacs
calculator).
@end ifnotinfo
#+END_TEXINFO

Org makes it easy to format tables in plain ASCII.  Any line with
@@info:@samp{|}@@ as the first non-whitespace character is considered
part of a table.  @@info:@samp{|}@@ is also the column separator.  A
table might look like this:

#+begin_src org
  ,| Name  | Phone | Age |
  ,|-------+-------+-----|
  ,| Peter |  1234 |  17 |
  ,| Anna  |  4321 |  25 |
#+end_src

A table is re-aligned automatically each time you press
@@info:@key{TAB}@@ or @@info:@key{RET}@@ or @@info:@kbd{C-c C-c}@@
inside the table.  @@info:@key{TAB}@@ also moves to the next field
(@@info:@key{RET}@@ to the next row) and creates new table rows at the
end of the table or before horizontal lines.  The indentation of the
table is set by the first line.  Any line starting with
@@info:@samp{|-}@@ is considered as a horizontal separator line and
will be expanded on the next re-align to span the whole table width.
So, to create the above table, you would only type

#+begin_src org
  ,|Name|Phone|Age|
  ,|-
#+end_src

@noindent and then press @@info:@key{TAB}@@ to align the table and start filling in
fields.  Even faster would be to type @@info:@code{|Name|Phone|Age}@@ followed by
@@info:@kbd{C-c @key{RET}@@}.

When typing text into a field, Org treats @@info:@key{DEL}@@,
@@info:@key{Backspace}@@, and all character keys in a special way, so that
inserting and deleting avoids shifting other fields.  Also, when
typing @@info:@emph{immediately after the cursor was moved into a new field
with @kbd{@key{TAB}}, @kbd{S-@key{TAB}} or @kbd{@key{RET}}}@@, the
field is automatically made blank.

@@info:@subsubheading Creation and conversion@@
- C-c | :: Convert the active region to table.  If every line contains
           at least one TAB character, the function assumes that the
           material is tab separated.  If every line contains a comma,
           comma-separated values (CSV) are assumed.  If not, lines
           are split at whitespace into fields.

           If there is no active region, this command creates an empty
           Org table.  But it's easier just to start typing, like
           @@info:@kbd{|Name|Phone|Age C-c @key{RET}}@@.

@@info:@subsubheading Re-aligning and field motion@@
- C-c C-c :: Re-align the table without moving the cursor.
- @@info:@key{TAB}@@ :: Re-align the table, move to the next field.
     Creates a new row if necessary.
- S-@@info:@key{TAB}@@ :: Re-align, move to previous field.
- @@info:@key{RET}@@ :: Re-align the table and move down to next row.
     Creates a new row if necessary.

@@info:@subsubheading Column and row editing@@
- M-@@info:@key{left}@@ :: @@info:@itemx M-@key{right}@@ 
                           Move the current column left/right.
- M-S-@@info:@key{left}@@ :: Kill the current column.
- M-S-@@info:@key{right}@@ :: Insert a new column to the left of the cursor
     position.
- M-@@info:@key{up}@@ :: @@info:@itemx M-@key{down}@@
                Move the current row up/down.
- M-S-@@info:@key{up}@@ :: Kill the current row or horizontal line.
- M-S-@@info:@key{down}@@ :: Insert a new row above the current row.
     With a prefix argument, the line is created below the current
     one.
- C-c - :: Insert a horizontal line below current row.  With a prefix
           argument, the line is created above the current line.
- C-c @@info:@key{RET}@@ :: Insert a horizontal line below current
     row, and move the cursor into the row below that line.
- C-c ^ :: Sort the table lines in the region.  The position of point
           indicates the column to be used for sorting, and the range
           of lines is the range between the nearest horizontal
           separator lines, or the entire table.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Tables.html#Tables][Chapter 3 of the manual]]\\
[[http://orgmode.org/worg/org-tutorials/tables.php][Bastien's table tutorial]]\\
[[{http://orgmode.org/worg/org-tutorials/org-spreadsheet-intro.php][Bastien's spreadsheet tutorial]]\\
[[http://orgmode.org/worg/org-tutorials/org-plot.php][Eric's plotting tutorial]]

* Hyperlinks
:PROPERTIES:
:DESCRIPTION: Notes in context
:END:

Like HTML, Org provides links inside a file, external links to other
files, Usenet articles, emails, and much more.

** Link format
:PROPERTIES:
:DESCRIPTION: How links in Org are formatted
:END:

Org will recognize plain URL-like links and activate them as clickable
links.  The general link format, however, looks like this:

#+begin_src org
[[link][description]]       @r{or alternatively}           [[link]]
#+end_src

@@info:@noindent Once@@ a link in the buffer is complete (all brackets
present), Org will change the display so that
@@info:@samp{description}@@ is displayed instead of
@@info:@samp{[[link][description]]}@@ and @@info:@samp{link}@@ is displayed
instead of @@info:@samp{[[link]]}@@.  To edit the invisible
@@info:@samp{link}@@ part, use @@info:@kbd{C-c C-l}@@ with the cursor
on the link.

** Internal links
:PROPERTIES:
:DESCRIPTION: Links to other places in the current file
:END:

If the link does not look like a URL, it is considered to be internal
in the current file.  The most important case is a link like
@@info:@samp{[[#my-custom-id]]}@@ which will link to the entry with the
@@info:@code{CUSTOM_ID}@@ property @@info:@samp{my-custom-id}@@.

Links such as @@info:@samp{[[My Target]]}@@ or @@info:@samp{[[My Target][Find my
target]]}@@ lead to a text search in the current file for the
corresponding target which looks like @@info:@samp{<<My Target>>}@@.

** External links
:PROPERTIES:
:DESCRIPTION: URL-like links to the world
:END:

Org supports links to files, websites, Usenet and email messages, BBDB
database entries and links to both IRC conversations and their logs.
External links are URL-like locators.  They start with a short
identifying string followed by a colon.  There can be no space after
the colon.  Here are some examples:

: http://www.astro.uva.nl/~dominik          @r{on the web}
: file:/home/dominik/images/jupiter.jpg     @r{file, absolute path}
: /home/dominik/images/jupiter.jpg          @r{same as above}
: file:papers/last.pdf                      @r{file, relative path}
: file:projects.org                         @r{another Org file}
: docview:papers/last.pdf::NNN              @r{open file in doc-view mode at page NNN}
: id:B7423F4D-2E8A-471B-8810-C40F074717E9   @r{Link to heading by ID}
: news:comp.emacs                           @r{Usenet link}
: mailto:adent@@galaxy.net                   @r{Mail link}
: vm:folder                                 @r{VM folder link}
: vm:folder#id                              @r{VM message link}
: wl:folder#id                              @r{WANDERLUST message link}
: mhe:folder#id                             @r{MH-E message link}
: rmail:folder#id                           @r{RMAIL message link}
: gnus:group#id                             @r{Gnus article link}
: bbdb:R.*Stallman                          @r{BBDB link (with regexp)}
: irc:/irc.com/#emacs/bob                   @r{IRC link}
: info:org:External%20links                 @r{Info node link (with encoded space)}

A link should be enclosed in double brackets and may contain a
descriptive text to be displayed instead of the URL ([[Link format]]),
for example:

#+begin_src org
[[http://www.gnu.org/software/emacs/][GNU Emacs]]
#+end_src

@@info:@noindent If@@ the description is a file name or URL that
points to an image, HTML export ([[HTML export]]) will inline the
image as a clickable button.  If there is no description at all and
the link points to an image, that image will be inlined into the
exported HTML file.

** Handling links
:PROPERTIES:
:DESCRIPTION: Creating, inserting and following
:END:

Org provides methods to create a link in the correct syntax, to
insert it into an Org file, and to follow the link.

- C-c l :: Store a link to the current location.  This is a /global/
           command (you must create the key binding yourself) which
           can be used in any buffer to create a link.  The link will
           be stored for later insertion into an Org buffer (see
           below).
- C-c C-l :: Insert a link.  This prompts for a link to be inserted
             into the buffer.  You can just type a link, or use
             history keys @@info:@key{up}@@ and @@info:@key{down}@@ to
             access stored links.  You will be prompted for the
             description part of the link. When called with a
             @@info:@kbd{C-u}@@ prefix argument, file name completion
             is used to link to a file.
- C-c C-l @@info:@r{(with cursor on existing link)}@@ :: When the
     cursor is on an existing link, @@info:@kbd{C-c C-l}@@ allows you
     to edit the link and description parts of the link.
- C-c C-o @@info:@r{or}@@ mouse-1 @@info:@r{or}@@ mouse-2 :: Open link
     at point.
- C-c & :: Jump back to a recorded position.  A position is recorded
           by the commands following internal links, and by
           @@info:@kbd{C-c %}@@.  Using this command several times in
           direct succession moves through a ring of previously
           recorded positions.

** Targeted links
:PROPERTIES:
:DESCRIPTION: Point at a location in a file
:END:

File links can contain additional information to make Emacs jump to a
particular location in the file when following a link.  This can be a
line number or a search option after a double colon.

Here is the syntax of the different ways to attach a search to a file
link, together with an explanation:

: [[file:~/code/main.c::255]]                 @r{Find line 255}
: [[file:~/xx.org::My Target]]                @r{Find @samp{<<My Target>>}}
: [[file:~/xx.org::#my-custom-id]]            @r{Find entry with custom id}

@@info:@noindent@@ *Further Reading*
[[http://orgmode.org/manual/Hyperlinks.html#Hyperlinks][Chapter 4 of the manual]]

* TODO Items
:PROPERTIES:
:DESCRIPTION: Every tree branch can be a TODO item
:END:

Org mode does not maintain TODO lists as separate documents[fn:3].
Instead, TODO items are an integral part of the notes file, because
TODO items usually come up while taking notes!  With Org mode, simply
mark any entry in a tree as being a TODO item.  In this way,
information is not duplicated, and the entire context from which the
TODO item emerged is always present.

Of course, this technique for managing TODO items scatters them
throughout your notes file.  Org mode compensates for this by
providing methods to give you an overview of all the things that you
have to do.

** Using TODO states
:PROPERTIES:
:DESCRIPTION: Setting and switching states
:END:

Any headline becomes a TODO item when it starts with the word
@@info:@samp{TODO}@@, for example:

#+begin_src org
  ,*** TODO Write letter to Sam Fortune
#+end_src

@@info:@noindent
The@@ most important commands to work with TODO entries are:

- C-c C-t :: Rotate the TODO state of the current item among

             #+begin_example
               ,-> (unmarked) -> TODO -> DONE --.
               '--------------------------------'
             #+end_example

             The same rotation can also be done ``remotely'' from the
             timeline and agenda buffers with the @@info:@kbd{t}@@
             command key ([[Agenda commands]]).

- S-@@info:@key{right}@r{/}@key{left}@@ :: Select the
     following/preceding TODO state, similar to cycling.
- C-c / t :: View TODO items in a /sparse tree/ ([[Sparse trees]]).  Folds
             the buffer, but shows all TODO items and the headings
             hierarchy above them.
- C-c a t :: Show the global TODO list.  Collects the TODO items from
             all agenda files ([[Agenda Views]]) into a single buffer.
             [[Global TODO list]], for more information.
- S-M-@@info:@key{RET}@@ :: Insert a new TODO entry below the current
     one.

@@info:@noindent@@ Changing a TODO state can also trigger tag changes.
See the docstring of the option ~org-todo-state-tags-triggers~ for
details.

** Multi-state workflows
:PROPERTIES:
:DESCRIPTION: More than just on/off
:END:

You can use TODO keywords to indicate different /sequential/
states in the process of working on an item, for example:

#+begin_src emacs-lisp
  (setq org-todo-keywords
    '((sequence "TODO" "FEEDBACK" "VERIFY" "|" "DONE" "DELEGATED")))
#+end_src

The vertical bar separates the TODO keywords (states that /need
action/) from the DONE states (which need /no further action/).  If
you don't provide the separator bar, the last state is used as the
DONE state.  With this setup, the command @@info:@kbd{C-c C-t}@@ will
cycle an entry from TODO to FEEDBACK, then to VERIFY, and finally to
DONE and DELEGATED.

Sometimes you may want to use different sets of TODO keywords in
parallel.  For example, you may want to have the basic ~TODO~/~DONE~,
but also a workflow for bug fixing, and a separate state indicating
that an item has been canceled (so it is not DONE, but also does not
require action).  Your setup would then look like this:

#+begin_src emacs-lisp
  (setq org-todo-keywords
        '((sequence "TODO(t)" "|" "DONE(d)")
          (sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")
          (sequence "|" "CANCELED(c)")))
#+end_src

The keywords should all be different, this helps Org mode to keep
track of which subsequence should be used for a given entry.  The
example also shows how to define keys for fast access of a particular
state, by adding a letter in parenthesis after each keyword - you will
be prompted for the key after @@info:@kbd{C-c C-t}@@.

To define TODO keywords that are valid only in a single file, use the
following text anywhere in the file.

#+begin_src org
  ,#+TODO: TODO(t) | DONE(d)
  ,#+TODO: REPORT(r) BUG(b) KNOWNCAUSE(k) | FIXED(f)
  ,#+TODO: | CANCELED(c)
#+end_src

After changing one of these lines, use @@info:@kbd{C-c C-c}@@ with the
cursor still in the line to make the changes known to Org mode.

** Progress logging
:PROPERTIES:
:DESCRIPTION: Dates and notes for progress
:END:

Org mode can automatically record a timestamp and possibly a note when
you mark a TODO item as DONE, or even each time you change the state
of a TODO item.  This system is highly configurable, settings can be
on a per-keyword basis and can be localized to a file or even a
subtree.  For information on how to clock working time for a task, see
[[Clocking work time]].

*** Closing items
:PROPERTIES:
:DESCRIPTION: When was this entry marked DONE?
:END:

The most basic logging is to keep track of /when/ a certain TODO item
was finished.  This is achieved with[fn:4].

#+begin_src emacs-lisp
  (setq org-log-done 'time)
#+end_src

@@info:@noindent@@ Then each time you turn an entry from a TODO
(not-done) state into any of the DONE states, a line
@@info:@samp{CLOSED: [timestamp]}@@ will be inserted just after the
headline.  If you want to record a note along with the timestamp,
use[fn:5]

#+begin_src emacs-lisp
  (setq org-log-done 'note)
#+end_src

@@info:@noindent You@@ will then be prompted for a note, and that note
will be stored below the entry with a @@info:@samp{Closing Note}@@
heading.

*** Tracking TODO state changes
:PROPERTIES:
:DESCRIPTION:  When did the status change?
:END:

You might want to keep track of TODO state changes.  You can either record
just a timestamp, or a time-stamped note for a change.  These records will be
inserted after the headline as an itemized list.  When taking a lot of notes,
you might want to get the notes out of the way into a drawer.  Customize the
variable ~org-log-into-drawer~ to get this behavior.

For state logging, Org mode expects configuration on a per-keyword basis.
This is achieved by adding special markers @@info:@samp{!}@@ (for a timestamp) and
@@info:@samp{@@}@@ (for a note) in parentheses after each keyword.  For example:
#+begin_src org
  ,#+TODO: TODO(t) WAIT(w@@/!) | DONE(d!) CANCELED(c@@)
#+end_src
@@info:@noindent@@ will define TODO keywords and fast access keys, and
also request that a time is recorded when the entry is set to DONE,
and that a note is recorded when switching to WAIT or CANCELED.  The
same syntax works also when setting ~org-todo-keywords~.

** Priorities
:PROPERTIES:
:DESCRIPTION: Some things are more important than others
:END:

If you use Org mode extensively, you may end up with enough TODO items
that it starts to make sense to prioritize them.  Prioritizing can be
done by placing a /priority cookie/ into the headline of a TODO item,
like this

#+begin_src org
  ,*** TODO [#A] Write letter to Sam Fortune
#+end_src

@@info:@noindent@@ Org mode supports three priorities:
@@info:@samp{A}@@, @@info:@samp{B}@@, and @@info:@samp{C}@@.
@@info:@samp{A}@@ is the highest, @@info:@samp{B}@@ the default if
none is given.  Priorities make a difference only in the agenda.

- @@info:@kbd{C-c ,}@@ :: Set the priority of the current headline.
     Press @@info:@samp{A}@@, @@info:@samp{B}@@ or @@info:@samp{C}@@
     to select a priority, or @@info:@key{SPC}@@ to remove the cookie.
- S-@@info:@key{up}@@ :: @@info:@itemx S-@key{down}@@
     Increase/decrease priority of current headline

** Breaking down tasks
:PROPERTIES:
:DESCRIPTION: Splitting a task into manageable pieces
:END:

It is often advisable to break down large tasks into smaller, manageable
subtasks.  You can do this by creating an outline tree below a TODO item,
with detailed subtasks on the tree.  To keep the overview over the fraction
of subtasks that are already completed, insert either @@info:@samp{[/]}@@ or
@@info:@samp{[%]}@@ anywhere in the headline.  These cookies will be updated each time
the TODO status of a child changes, or when pressing @@info:@kbd{C-c C-c}@@ on the
cookie.  For example:

#+begin_src org
  ,* Organize Party [33%]
  ,** TODO Call people [1/2]
  ,*** TODO Peter
  ,*** DONE Sarah
  ,** TODO Buy food
  ,** DONE Talk to neighbor
#+end_src
** Checkboxes
:PROPERTIES:
:DESCRIPTION: Tick-off lists
:END:

Every item in a plain list ([[Plain lists]]) can be made into a checkbox
by starting it with the string @@info:@samp{[ ]}@@.  Checkboxes are
not included into the global TODO list, so they are often great to
split a task into a number of simple steps.  
Here is an example of a checkbox list.

#+begin_src org
  ,* TODO Organize party [1/3]
  ,  - [-] call people [1/2]
  ,    - [ ] Peter
  ,    - [X] Sarah
  ,  - [X] order food
  ,  - [ ] think about what music to play
#+end_src

Checkboxes work hierarchically, so if a checkbox item has children that
are checkboxes, toggling one of the children checkboxes will make the
parent checkbox reflect if none, some, or all of the children are
checked.

@@info:@noindent@@ The following commands work with checkboxes:

- C-c C-c :: Toggle checkbox status or (with prefix arg) checkbox
             presence at point.
- M-S-@@info:@key{RET}@@ :: Insert a new item with a checkbox.  This
     works only if the cursor is already in a plain list item ([[Plain lists]]).

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/TODO-Items.html#TODO-Items][Chapter 5 of the manual]]\\
[[http://orgmode.org/worg/org-tutorials/orgtutorial_dto.php][David O'Toole's introductory tutorial]]\\
[[http://members.optusnet.com.au/~charles57/GTD/gtd_workflow.html][Charles Cave's GTD setup]]

* Tags
:PROPERTIES:
:DESCRIPTION: Tagging headlines and matching sets of tags
:END:

An excellent way to implement labels and contexts for
cross-correlating information is to assign /tags/ to headlines.  Org
mode has extensive support for tags.

Every headline can contain a list of tags; they occur at the end of
the headline.  Tags are normal words containing letters, numbers,
@@info:@samp{_}@@, and @@info:@samp{@@}@@.  Tags must be preceded and
followed by a single colon, e.g., @@info:@samp{:work:}@@.  Several
tags can be specified, as in @@info:@samp{:work:urgent:}@@.  Tags will
by default be in bold face with the same color as the headline.

** Tag inheritance
:PROPERTIES:
:DESCRIPTION: Tags use the tree structure of the outline
:END:

/Tags/ make use of the hierarchical structure of outline trees.  If a
heading has a certain tag, all subheadings will inherit the tag as
well.  For example, in the list

#+begin_src org
  ,* Meeting with the French group      :work:
  ,** Summary by Frank                  :boss:notes:
  ,*** TODO Prepare slides for him      :action:
#+end_src

@@info:@noindent@@
the final heading will have the tags @@info:@samp{:work:}@@, @@info:@samp{:boss:}@@,
@@info:@samp{:notes:}@@, and @@info:@samp{:action:}@@ even though the final heading is not
explicitly marked with those tags.  You can also set tags that all entries in
a file should inherit just as if these tags were defined in a hypothetical
level zero that surrounds the entire file.  Use a line like this[fn:6]:

#+begin_src org
  ,#+FILETAGS: :Peter:Boss:Secret:
#+end_src

** Setting tags
:PROPERTIES:
:DESCRIPTION: How to assign tags to a headline
:END:

Tags can simply be typed into the buffer at the end of a headline.
After a colon, @@info:@kbd{M-@key{TAB}}@@ offers completion on tags.
There is also a special command for inserting tags:

- C-c C-q :: Enter new tags for the current headline.  Org mode will
             either offer completion or a special single-key interface
             for setting tags, see below.  After pressing
             @@info:@key{RET}@@, the tags will be inserted and aligned
             to ~org-tags-column~.  When called with a
             @@info:@kbd{C-u}@@ prefix, all tags in the current buffer
             will be aligned to that column, just to make things look
             nice.
- C-c C-c :: When the cursor is in a headline, this does the same as
             @@info:@kbd{C-c C-q}@@.

Org will support tag insertion based on a /list of tags/.  By default
this list is constructed dynamically, containing all tags currently
used in the buffer.  You may also globally specify a hard list of tags
with the variable ~org-tag-alist~.  Finally you can set the default
tags for a given file with lines like

@smallexample
#+TAGS: @@work @@home @@tennisclub
#+TAGS: laptop car pc sailboat
@end smallexample

By default Org mode uses the standard minibuffer completion facilities
for entering tags.  However, it also implements another, quicker, tag
selection method called /fast tag selection/.  This allows you to
select and deselect tags with just a single key press.  For this to
work well you should assign unique letters to most of your commonly
used tags.  You can do this globally by configuring the variable
~org-tag-alist~ in your @@info:@file{.emacs}@@ file.  For example, you
may find the need to tag many items in different files with
@@info:@samp{:@@home:}@@.  In this case you can set something like:

#+begin_src emacs-lisp
(setq org-tag-alist '(("@@work" . ?w) ("@@home" . ?h) ("laptop" . ?l)))
#+end_src

@@info:@noindent@@ If the tag is only relevant to the file you are
working on, then you can instead set the TAGS option line as:

#+begin_src org
  ,#+TAGS: @@work(w)  @@home(h)  @@tennisclub(t)  laptop(l)  pc(p)
#+end_src

** Tag searches
:PROPERTIES:
:DESCRIPTION: Searching for combinations of tags
:END:

Once a system of tags has been set up, it can be used to collect related
information into special lists.

- C-c \ :: @@info:@itemx C-c / m@@ 
           Create a sparse tree with all headlines matching a tags
           search.  With a @@info:@kbd{C-u}@@ prefix argument, ignore
           headlines that are not a TODO line.

- C-c a m :: Create a global list of tag matches from all agenda
             files. [[Matching tags and properties]].
- C-c a M :: Create a global list of tag matches from all agenda
             files, but check only TODO items and force checking
             subitems (see variable ~org-tags-match-list-sublevels~).

These commands all prompt for a match string which allows basic
Boolean logic like @@info:@samp{+boss+urgent-project1}@@, to find
entries with tags @@info:@samp{boss}@@ and @@info:@samp{urgent}@@, but
not @@info:@samp{project1}@@, or @@info:@samp{Kathy|Sally}@@ to find
entries which are tagged, like @@info:@samp{Kathy}@@ or
@@info:@samp{Sally}@@.  The full syntax of the search string is rich
and allows also matching against TODO keywords, entry levels and
properties.  For a complete description with many examples, see
[[Matching tags and properties]].

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Tags.html#Tags][Chapter 6 of the manual]]\\
[[http://sachachua.com/wp/2008/01/tagging-in-org-plus-bonus-code-for-timeclocks-and-tags/][Sacha Chua's article about tagging in Org-mode]]

* Properties
:PROPERTIES:
:DESCRIPTION: Properties
:END:

Properties are key-value pairs associates with and entry.  They live
in a special drawer with the name ~PROPERTIES~.  Each property is
specified on a single line, with the key (surrounded by colons) first,
and the value after it:

#+begin_src org
  ,* CD collection
  ,** Classic
  ,*** Goldberg Variations
  ,    :PROPERTIES:
  ,    :Title:     Goldberg Variations
  ,    :Composer:  J.S. Bach
  ,    :Publisher: Deutsche Grammophon
  ,    :NDisks:    1
  ,    :END:
#+end_src

You may define the allowed values for a particular property
@@info:@samp{:Xyz:}@@ by setting a property @@info:@samp{:Xyz_ALL:}@@.
This special property is @@info:@emph{inherited}@@, so if you set it
in a level 1 entry, it will apply to the entire tree.  When allowed
values are defined, setting the corresponding property becomes easier
and is less prone to typing errors.  For the example with the CD
collection, we can predefine publishers and the number of disks in a
box like this:

#+begin_src org
  ,* CD collection
  ,  :PROPERTIES:
  ,  :NDisks_ALL:  1 2 3 4
  ,  :Publisher_ALL: "Deutsche Grammophon" Philips EMI
  ,  :END:
#+end_src
or globally using ~org-global-properties~, or file-wide like this:
#+begin_src org
  ,#+PROPERTY: NDisks_ALL 1 2 3 4
#+end_src

- C-c C-x p :: Set a property.  This prompts for a property name and a
               value.
- C-c C-c d :: Remove a property from the current entry.

To create sparse trees and special lists with selection based on
properties, the same commands are used as for tag searches ([[Tag%20searches][Tag searches]]).
The syntax for the search string is described in [[Matching%20tags%20and%20properties][Matching tags and properties]].

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Properties-and-Columns.html#Properties-and-Columns][Chapter 7 of the manual]]\\
[[http://orgmode.org/worg/org-tutorials/org-column-view-tutorial.php][Bastien Guerry's column view tutorial]]

* Dates and Times
:PROPERTIES:
:DESCRIPTION: Making items useful for planning
:END:

To assist project planning, TODO items can be labeled with a date and/or
a time.  The specially formatted string carrying the date and time
information is called a /timestamp/ in Org mode.

** Timestamps
:PROPERTIES:
:DESCRIPTION: Assigning a time to a tree entry
:END:

A timestamp is a specification of a date (possibly with a time or a
range of times) in a special format, either @@info:@samp{<2003-09-16
Tue>}@@ or @@info:@samp{<2003-09-16 Tue 09:39>}@@ or
@@info:@samp{<2003-09-16 Tue 12:00-12:30>}@@.  A timestamp can appear
anywhere in the headline or body of an Org tree entry.  Its presence
causes entries to be shown on specific dates in the agenda
([[Weekly/daily agenda]]).  We distinguish:

@@info:@noindent@@ *Plain timestamp; Event; Appointment*\\
A simple timestamp just assigns a date/time to an item.  This is just
like writing down an appointment or event in a paper agenda.

#+begin_src org
  ,* Meet Peter at the movies
  ,  <2006-11-01 Wed 19:15>
  ,* Discussion on climate change
  ,  <2006-11-02 Thu 20:00-22:00>
#+end_src

@@info:@noindent@@ *Timestamp with repeater interval*\\
A timestamp may contain a /repeater interval/, indicating that it
applies not only on the given date, but again and again after a
certain interval of N days (d), weeks (w), months (m), or years (y).
The following will show up in the agenda every Wednesday:
#+begin_src org
  ,* Pick up Sam at school
  ,  <2007-05-16 Wed 12:30 +1w>
#+end_src

@@info:@noindent@@ *Diary-style sexp entries*\\
For more complex date specifications, Org mode supports using the
special sexp diary entries implemented in the Emacs calendar/diary
package.  For example
#+begin_src org
  ,* The nerd meeting on every 2nd Thursday of the month
  ,  <%%(diary-float t 4 2)>
#+end_src

@@info:@noindent@@ *Time/Date range*\\
Two timestamps connected by @@info:@samp{--}@@ denote a range.
#+begin_src org
  ,** Meeting in Amsterdam
  ,   <2004-08-23 Mon>--<2004-08-26 Thu>
#+end_src

@@info:@noindent@@ *Inactive timestamp*\\
Just like a plain timestamp, but with square brackets instead of
angular ones.  These timestamps are inactive in the sense that they do
/not/ trigger an entry to show up in the agenda.

#+begin_src org
  ,* Gillian comes late for the fifth time
  ,  [2006-11-01 Wed]
#+end_src

** Creating timestamps
:PROPERTIES:
:DESCRIPTION: Commands which insert timestamps
:END:

For Org mode to recognize timestamps, they need to be in the specific
format.  All commands listed below produce timestamps in the correct
format.

- C-c . :: Prompt for a date and insert a corresponding timestamp.
           When the cursor is at an existing timestamp in the buffer,
           the command is used to modify this timestamp instead of
           inserting a new one.  When this command is used twice in
           succession, a time range is inserted.  With a prefix, also
           add the current time.
- C-c ! :: Like @@info:@kbd{C-c .}@@, but insert an inactive timestamp
           that will not cause an agenda entry.
- S-@@info:@key{left}@r{/}@key{right}@@ :: Change date at cursor by
     one day.
- S-@@info:@key{up}@r{/}@key{down}@@ :: Change the item under the
     cursor in a timestamp.  The cursor can be on a year, month, day,
     hour or minute.  When the timestamp contains a time range like
     @@info:@samp{15:30-16:30}@@, modifying the first time will also
     shift the second, shifting the time block with constant length.
     To change the length, modify the second time.

When Org mode prompts for a date/time, it will accept any string containing
some date and/or time information, and intelligently interpret the string,
deriving defaults for unspecified information from the current date and time.
You can also select a date in the pop-up calendar.  See the manual for more
information on how exactly the date/time prompt works.

** Deadlines and scheduling
:PROPERTIES:
:DESCRIPTION: Planning your work
:END:

A timestamp may be preceded by special keywords to facilitate planning:

@@info:@noindent@@ *DEADLINE*\
Meaning: the task (most likely a TODO item, though not necessarily) is supposed
to be finished on that date.

- C-c C-d :: Insert @@info:@samp{DEADLINE}@@ keyword along with a
             stamp, in the line following the headline.

On the deadline date, the task will be listed in the agenda.  In
addition, the agenda for /today/ will carry a warning about the
approaching or missed deadline, starting ~org-deadline-warning-days~
before the due date, and continuing until the entry is marked DONE.
An example:

#+begin_src org
  ,*** TODO write article about the Earth for the Guide
  ,    The editor in charge is [[bbdb:Ford Prefect]]
  ,    DEADLINE: <2004-02-29 Sun>
#+end_src

@@info:@noindent@@ *SCHEDULED*\\
Meaning: you are /planning to start working/ on that task on the given
date[fn:7].

- C-c C-s :: Insert @@info:@samp{SCHEDULED}@@ keyword along with a
             stamp, in the line following the headline.

The headline will be listed under the given date[fn:8].  In addition, a reminder that
the scheduled date has passed will be present in the compilation for
/today/, until the entry is marked DONE.  I.e.: the task will
automatically be forwarded until completed.

#+begin_src org
  ,*** TODO Call Trillian for a date on New Years Eve.
  ,    SCHEDULED: <2004-12-25 Sat>
#+end_src

Some tasks need to be repeated again and again.  Org mode helps to
organize such tasks using a so-called repeater in a DEADLINE,
SCHEDULED, or plain timestamp.  In the following example
#+begin_src org
  ,** TODO Pay the rent
  ,   DEADLINE: <2005-10-01 Sat +1m>
#+end_src
@@info:@noindent@@ the ~+1m~ is a repeater; the intended
interpretation is that the task has a deadline on <2005-10-01> and
repeats itself every (one) month starting from that time.

** Clocking work time
:PROPERTIES:
:DESCRIPTION: Tracking how long you spend on a task
:END:

Org mode allows you to clock the time you spend on specific tasks in a
project.

- C-c C-x C-i :: Start the clock on the current item (clock-in).  This
                 inserts the CLOCK keyword together with a timestamp.
                 When called with a @@info:@kbd{C-u}@@ prefix
                 argument, select the task from a list of recently
                 clocked tasks.
- C-c C-x C-o :: Stop the clock (clock-out).  This inserts another
                 timestamp at the same location where the clock was
                 last started.  It also directly computes the
                 resulting time in inserts it after the time range as
                 @@info:@samp{=> HH:MM}@@.
- C-c C-x C-e :: Update the effort estimate for the current clock
                 task.
- C-c C-x C-x :: Cancel the current clock.  This is useful if a clock
                 was started by mistake, or if you ended up working on
                 something else.
- C-c C-x C-j :: Jump to the entry that contains the currently running
                 clock.  With a @@info:@kbd{C-u}@@ prefix arg, select
                 the target task from a list of recently clocked
                 tasks.
- C-c C-x C-r :: Insert a dynamic block containing a clock report as
                 an Org-mode table into the current file.  When the
                 cursor is at an existing clock table, just update it.

                 #+begin_src org
                   ,#+BEGIN: clocktable :maxlevel 2 :emphasize nil :scope file
                   ,#+END: clocktable
                 #+end_src
                 @@info:@noindent@@ For details about how to customize
                 this view, see [[http://orgmode.org/manual/Clocking-work-time.html#Clocking-work-time][the manual]].
- C-c C-c :: Update dynamic block at point.  The cursor needs to be in
             the ~#+BEGIN~ line of the dynamic block.

The @@info:@kbd{l}@@ key may be used in the timeline ([[Timeline]]) and in
the agenda ([[Weekly/daily agenda]]) to show which tasks have been worked
on or closed during a day.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Dates-and-Times.html#Dates-and-Times][Chapter 8 of the manual]]\\
[[http://members.optusnet.com.au/~charles57/GTD/org_dates/][Charles Cave's Date and Time tutorial]]\\
[[http://doc.norang.ca/org-mode.html#Clocking][Bernt Hansen's clocking workflow]]

* Capture - Refile - Archive
:PROPERTIES:
:DESCRIPTION: The ins and outs for projects
:END:

An important part of any organization system is the ability to quickly
capture new ideas and tasks, and to associate reference material with
them.  Org defines a capture process to create tasks.  It stores files
related to a task (/attachments/) in a special directory.  Once in the
system, tasks and projects need to be moved around.  Moving completed
project trees to an archive file keeps the system compact and fast.

** Capture
:PROPERTIES:
:DESCRIPTION: 
:END:

Org's method for capturing new items is heavily inspired by John
Wiegley excellent remember package.  It lets you store quick notes
with little interruption of your work flow.  Org lets you define
templates for new entries and associate them with different targets
for storing notes.

*** Setting up a capture location
:PROPERTIES:
:DESCRIPTION:   Where notes will be stored
:END:

The following customization sets a default target[fn:9] file for
notes, and defines a global key[fn:10] for capturing new stuff.

#+begin_src emacs-lisp
  (setq org-default-notes-file (concat org-directory "/notes.org"))
  (define-key global-map "\C-cc" 'org-capture)
#+end_src

*** Using capture
:PROPERTIES:
:DESCRIPTION: Commands to invoke and terminate capture
:END:

- C-c c :: Start a capture process.  You will be placed into a
           narrowed indirect buffer to edit the item.
- C-c C-c :: Once you are done entering information into the capture
             buffer, @@info:@kbd{C-c C-c}@@ will return you to the
             window configuration before the capture process, so that
             you can resume your work without further distraction.
- C-c C-w :: Finalize by moving the entry to a refile location
             ([[Refiling notes]]).
- C-c C-k :: Abort the capture process and return to the previous
             state.

*** Capture templates
:PROPERTIES:
:DESCRIPTION: Define the outline of different note types
:END:

You can use templates to generate different types of capture notes,
and to store them in different places.  For example, if you would like
to store new tasks under a heading @@info:@samp{Tasks}@@ in file
@@info:@file{TODO.org}@@, and journal entries in a date tree in
@@info:@file{journal.org}@@ you could use:

#+begin_src emacs-lisp
  (setq org-capture-templates
   '(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks")
          "* TODO %?\n  %i\n  %a")
     ("j" "Journal" entry (file+datetree "~/org/journal.org")
          "* %?\nEntered on %U\n  %i\n  %a")))
#+end_src

@@info:@noindent@@ In these entries, the first string is the key to
reach the template, the second is a short description.  Then follows
the type of the entry and a definition of the target location for
storing the note.  Finally, the template itself, a string with
%-escapes to fill in information based on time and context.

When you call @@info:@kbd{M-x org-capture}@@, Org will prompt for a
key to select the template (if you have more than one template) and
then prepare the buffer like
#+begin_src org
  ,* TODO
  ,  [[file:@var{link to where you were when initiating capture}]]
#+end_src

@@info:@noindent@@ During expansion of the template, special
@@info:@kbd{%}@@-escapes[fn:11] allow dynamic insertion of content.
Here is a small selection of the possibilities, consult the manual for
more.

: %a          @r{annotation, normally the link created with @code{org-store-link}}
: %i          @r{initial content, the region when remember is called with C-u.}
: %t          @r{timestamp, date only}
: %T          @r{timestamp with date and time}
: %u, %U      @r{like the above, but inactive timestamps}

** Refiling notes
:PROPERTIES:
:DESCRIPTION: Moving a tree from one place to another
:END:
When reviewing the captured data, you may want to refile some of the entries
into a different list, for example into a project.  Cutting, finding the
right location, and then pasting the note is cumbersome.  To simplify this
process, you can use the following special command:

- C-c C-w :: Refile the entry or region at point.  This command offers
             possible locations for refiling the entry and lets you
             select one with completion.  The item (or all items in
             the region) is filed below the target heading as a
             subitem.\\ 
             By default, all level 1 headlines in the current buffer
             are considered to be targets, but you can have more
             complex definitions across a number of files. See the
             variable ~org-refile-targets~ for details.
- C-u C-c C-w :: Use the refile interface to jump to a heading.
- C-u C-u C-c C-w :: Jump to the location where ~org-refile~ last
     moved a tree to.

** Archiving
:PROPERTIES:
:DESCRIPTION: What to do with finished projects
:END:

When a project represented by a (sub)tree is finished, you may want to
move the tree out of the way and to stop it from contributing to the
agenda.  Archiving is important to keep your working files compact and
global searches like the construction of agenda views fast.  The most
common archiving action is to move a project tree to another file, the
archive file.

- C-c C-x C-a :: Archive the current entry using the command specified
                 in the variable ~org-archive-default-command~.
- C-c C-x C-s@@info:@ @r{or short} @@@ C-c $ :: Archive the subtree starting at
     the cursor position to the location given by
     ~org-archive-location~.

The default archive location is a file in the same directory as the
current file, with the name derived by appending
@@info:@file{_archive}@@ to the current file name.  For information
and examples on how to change this, see the documentation string of
the variable ~org-archive-location~.  There is also an in-buffer
option for setting this variable, for example

#+begin_src org
  ,#+ARCHIVE: %s_done::
#+end_src

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Capture-_002d-Refile-_002d-Archive.html#Capture-_002d-Refile-_002d-Archive][Chapter 9 of the manual]]\\
[[http://members.optusnet.com.au/~charles57/GTD/remember.html][Charles Cave's remember tutorial]]\\
[[http://orgmode.org/worg/org-tutorials/org-protocol-custom-handler.php][Sebastian Rose's tutorial for capturing from a web browser]]

* Agenda Views
:PROPERTIES:
:DESCRIPTION: Collecting information into views
:END:

Due to the way Org works, TODO items, time-stamped items, and tagged
headlines can be scattered throughout a file or even a number of
files.  To get an overview of open action items, or of events that are
important for a particular date, this information must be collected,
sorted and displayed in an organized way.  There are several different
views, see below.

The extracted information is displayed in a special /agenda buffer/.
This buffer is read-only, but provides commands to visit the
corresponding locations in the original Org files, and even to edit
these files remotely.  Remote editing from the agenda buffer means,
for example, that you can change the dates of deadlines and
appointments from the agenda buffer.  The commands available in the
Agenda buffer are listed in [[Agenda commands]].

** Agenda files
:PROPERTIES:
:DESCRIPTION: Files being searched for agenda information
:END:

The information to be shown is normally collected from all /agenda
files/, the files listed in the variable ~org-agenda-files~.

- C-c [ :: Add current file to the list of agenda files.  The file is
           added to the front of the list.  If it was already in the
           list, it is moved to the front.  With a prefix argument,
           file is added/moved to the end.
- C-c ] :: Remove current file from the list of agenda files.
- C-, :: Cycle through agenda file list, visiting one file after the
         other.

** Agenda dispatcher
:PROPERTIES:
:DESCRIPTION: Keyboard access to agenda views
:END:

The views are created through a dispatcher, which should be bound to a
global key---for example @@info:@kbd{C-c a}@@ ([[Installation]]).  After
pressing @@info:@kbd{C-c a}@@, an additional letter is required to execute a
command:

- a :: The calendar-like agenda ([[Weekly/daily agenda]]).

- t @@info:@r{/}@@ T :: A list of all TODO items ([[Global TODO list]]).

- m @@info:@r{/}@@ M :: A list of headlines matching a TAGS expression
     ([[Matching tags and properties]]).

- L :: The timeline view for the current buffer ([[Timeline]]).

- s :: A list of entries selected by a boolean expression of keywords
       and/or regular expressions that must or must not occur in the
       entry.

** Built-in agenda views
:PROPERTIES:
:DESCRIPTION: What is available out of the box?
:END:
*** Weekly/daily agenda
:PROPERTIES:
:DESCRIPTION: The calendar page with current tasks
:END:

The purpose of the weekly/daily /agenda/ is to act like a page of a
paper agenda, showing all the tasks for the current week or day.

- C-c a a :: Compile an agenda for the current week from a list of Org
             files.  The agenda shows the entries for each day.

Emacs contains the calendar and diary by Edward M. Reingold.  Org-mode
understands the syntax of the diary and allows you to use diary sexp
entries directly in Org files:

#+begin_src org
  ,* Birthdays and similar stuff
  ,#+CATEGORY: Holiday
  ,%%(org-calendar-holiday)   ; special function for holiday names
  ,#+CATEGORY: Ann
  ,%%(diary-anniversary  5 14 1956)@footnote{Note that the order of the arguments (month, day, year) depends on the setting of @code{calendar-date-style}.}Arthur Dent is %d years old
  ,%%(diary-anniversary 10  2 1869) Mahatma Gandhi would be %d years old
#+end_src

Org can interact with Emacs appointments notification facility.  To add all
the appointments of your agenda files, use the command
~org-agenda-to-appt~.  See the docstring for details.

*** Global TODO list
:PROPERTIES:
:DESCRIPTION: All unfinished action items
:END:

The global TODO list contains all unfinished TODO items formatted and
collected into a single place.  Remote editing of TODO items lets you
can change the state of a TODO entry with a single key press.  The commands
available in the TODO list are described in [[Agenda commands]].

- C-c a t :: Show the global TODO list.  This collects the TODO items
             from all agenda files ([[Agenda Views]]) into a single
             buffer.
- C-c a T :: Like the above, but allows selection of a specific TODO
             keyword.

*** Matching tags and properties
:PROPERTIES:
:DESCRIPTION:   Structured information with fine-tuned search
:END:

If headlines in the agenda files are marked with /tags/ ([[Tags]]), or
have properties ([[Properties]]), you can select headlines based on this
metadata and collect them into an agenda buffer.  The match syntax
described here also applies when creating sparse trees with
@@info:@kbd{C-c / m}@@.  The commands available in the tags list are
described in [[Agenda commands]].

- C-c a m :: Produce a list of all headlines that match a given set of
             tags.  The command prompts for a selection criterion,
             which is a boolean logic expression with tags, like
             @@info:@samp{+work+urgent-withboss}@@ or
             @@info:@samp{work|home}@@ ([[Tags]]).  If you often need a
             specific search, define a custom command for it ([[Agenda%20dispatcher][Agenda dispatcher]]).
- C-c a M :: Like @@info:@kbd{C-c a m}@@, but only select headlines
             that are also TODO items.

@@info:@subsubheading Match syntax@@

A search string can use Boolean operators @@info:@samp{&}@@ for AND
and @@info:@samp{|}@@ for OR.  @@info:@samp{&}@@ binds more strongly
than @@info:@samp{|}@@.  Parentheses are currently not implemented.
Each element in the search is either a tag, a regular expression
matching tags, or an expression like ~PROPERTY OPERATOR VALUE~ with a
comparison operator, accessing a property value.  Each element may be
preceded by @@info:@samp{-}@@, to select against it, and
@@info:@samp{+}@@ is syntactic sugar for positive selection.  The AND
operator @@info:@samp{&}@@ is optional when @@info:@samp{+}@@ or
@@info:@samp{-}@@ is present.  Here are some examples, using only
tags.

- +work-boss :: Select headlines tagged @@info:@samp{:work:}@@, but
                discard those also tagged @@info:@samp{:boss:}@@.
- work|laptop :: Selects lines tagged @@info:@samp{:work:}@@ or
                 @@info:@samp{:laptop:}@@.
- work|laptop+night :: Like before, but require the
     @@info:@samp{:laptop:}@@ lines to be tagged also
     @@info:@samp{:night:}@@.

You may also test for properties at the same
time as matching tags, see the manual for more information.

*** Timeline
:PROPERTIES:
:DESCRIPTION: Time-sorted view for single file
:END:

The timeline summarizes all time-stamped items from a single Org mode
file in a /time-sorted view/.  The main purpose of this command is
to give an overview over events in a project.

- C-c a L :: Show a time-sorted view of the Org file, with all
             time-stamped items. When called with a @@info:@kbd{C-u}@@
             prefix, all unfinished TODO entries (scheduled or not)
             are also listed under the current date.

*** Search view
:PROPERTIES:
:DESCRIPTION: Find entries by searching for text
:END:

This agenda view is a general text search facility for Org mode entries.
It is particularly useful to find notes.

- C-c a s :: This is a special search that lets you select entries by
             matching a substring or specific words using a boolean
             logic.

For example, the search string @@info:@samp{computer equipment}@@ will find entries
that contain @@info:@samp{computer equipment}@@ as a substring. 
Search view can also search for specific keywords in the entry, using Boolean
logic.  The search string @@info:@samp{+computer +wifi -ethernet -@{8\.11[bg]@}}@@
will search for note entries that contain the keywords ~computer~
and ~wifi~, but not the keyword ~ethernet~, and which are also
not matched by the regular expression ~8\.11[bg]~, meaning to
exclude both 8.11b and 8.11g. 

Note that in addition to the agenda files, this command will also search
the files listed in ~org-agenda-text-search-extra-files~.

** Agenda commands
:PROPERTIES:
:DESCRIPTION: Remote editing of Org trees
:END:

Entries in the agenda buffer are linked back to the Org file or diary
file where they originate.  Commands are provided to show and jump to the
original entry location, and to edit the Org files "remotely" from
the agenda buffer.  This is just a selection of the many commands, explore
the ~Agenda~ menu and the manual for a complete list.

@@info:@subsubheading Motion@@
- n :: Next line (same as @@info:@key{up}@@ and @@info:@kbd{C-p}@@).
- p :: Previous line (same as @@info:@key{down}@@ and
       @@info:@kbd{C-n}@@).

@@info:@subsubheading View/Go to Org file@@
- mouse-3 :: @@info:@itemx @key{SPC}@@ 
             Display the original location of the item in another
             window.  With prefix arg, make sure that the entire entry
             is made visible in the outline, not only the heading.
             # 
             @@info:@itemx @key{TAB}@@
             Go to the original location of the item in another
             window.  Under Emacs 22, @@info:@kbd{mouse-1}@@ will also
             work for this.
             # 
             @@info:@itemx @key{RET}@@
             Go to the original location of the item and delete other
             windows.

@@info:@subsubheading Change display@@
- o :: Delete other windows.
- d @@info:@r{/}@@ w :: Switch to day/week view.
- f @@info:@r{and}@@ b :: Go forward/backward in time to display the
     following ~org-agenda-current-span~ days.  For example, if the
     display covers a week, switch to the following/previous week.
- . :: Go to today.
- j :: Prompt for a date and go there.
- v l @@info:@r{or short}@@ l :: Toggle Logbook mode.  In Logbook
     mode, entries that were marked DONE while logging was on
     (variable ~org-log-done~) are shown in the agenda, as are
     entries that have been clocked on that day.  When called with a
     @@info:@kbd{C-u}@@ prefix, show all possible logbook entries, including
     state changes.
- r @@info:@r{or}@@ g :: Recreate the agenda buffer, to reflect the
     changes.
- s :: Save all Org buffers in the current Emacs session, and also the
       locations of IDs.

@@info:@subsubheading Secondary filtering and query editing@@
- / :: Filter the current agenda view with respect to a tag.  You are
       prompted for a letter to select a tag.  Press @@info:@samp{-}@@ first to
       select against the tag.
- \ :: Narrow the current agenda filter by an additional condition.

@@info:@subsubheading Remote editing (see the manual for many more commands)@@
- 0-9 :: Digit argument.
- t :: Change the TODO state of the item, in the agenda and in the org
       file.
- C-k :: Delete the current agenda item along with the entire subtree
         belonging to it in the original Org file.
- C-c C-w :: Refile the entry at point.
- C-c C-x C-a @@info:@r{or short}@@ a :: Archive the subtree
     corresponding to the entry at point using the default archiving
     command set in ~org-archive-default-command~.
- C-c C-x C-s @@info:@r{or short}@@ $ :: Archive the subtree
     corresponding to the current headline.
- C-c C-s :: Schedule this item, with prefix arg remove the scheduling
             timestamp
- C-c C-d :: Set a deadline for this item, with prefix arg remove the
             deadline.
- S-@@info:@key{right} @r{and} S-@key{left}@@ :: Change the timestamp
     associated with the current line by one day.
- I :: Start the clock on the current item.
- O / X :: Stop/cancel the previously started clock.
- J :: Jump to the running clock in another window.

** Custom agenda views
:PROPERTIES:
:DESCRIPTION: Defining special searches and views
:END:

The main application of custom searches is the definition of keyboard
shortcuts for frequently used searches, either creating an agenda
buffer, or a sparse tree (the latter covering of course only the
current buffer).
Custom commands are configured in the variable
~org-agenda-custom-commands~.  You can customize this variable, for
example by pressing @@info:@kbd{C-c a C}@@.  You can also directly set
it with Emacs Lisp in @@info:@file{.emacs}@@.  The following example
contains all valid search types:

#+begin_src emacs-lisp
(setq org-agenda-custom-commands
      '(("w" todo "WAITING")
        ("u" tags "+boss-urgent")
        ("v" tags-todo "+boss-urgent")))
#+end_src

@@info:@noindent@@ The initial string in each entry defines the keys
you have to press after the dispatcher command @@info:@kbd{C-c a}@@ in
order to access the command.  Usually this will be just a single
character.  The second parameter is the search type, followed by the
string or regular expression to be used for the matching.  The example
above will therefore define:

- C-c a w :: as a global search for TODO entries with
             @@info:@samp{WAITING}@@ as the TODO keyword
- C-c a u :: as a global tags search for headlines marked
             @@info:@samp{:boss:}@@ but not @@info:@samp{:urgent:}@@
- C-c a v :: as the same search as @@info:@kbd{C-c a u}@@, but
             limiting the search to headlines that are also TODO items

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Agenda-Views.html#Agenda-Views][Chapter 10 of the manual]]\\
[[http://orgmode.org/worg/org-tutorials/org-custom-agenda-commands.php][Mat Lundin's tutorial about custom agenda commands]]\\
[[http://www.newartisans.com/2007/08/using-org-mode-as-a-day-planner.html][John Wiegley's setup]]

* Markup
:PROPERTIES:
:DESCRIPTION: Prepare text for rich export
:END:

When exporting Org-mode documents, the exporter tries to reflect the
structure of the document as accurately as possible in the backend.  Since
export targets like HTML, LaTeX, or DocBook allow much richer formatting,
Org mode has rules on how to prepare text for rich export.  This section
summarizes the markup rules used in an Org-mode buffer.

** Structural markup elements
:PROPERTIES:
:DESCRIPTION: The basic structure as seen by the exporter
:END:

*** Document title
:PROPERTIES:
:DESCRIPTION: Where the title is taken from
:END:

@@info:@noindent@@ The title of the exported document is taken from
the special line

#+begin_src org
  ,#+TITLE: This is the title of the document
#+end_src

*** Headings and sections
:PROPERTIES:
:DESCRIPTION: The document structure as seen by the exporter
:END:

The outline structure of the document as described in [[Document%20Structure][Document Structure]],
forms the basis for defining sections of the exported document.
However, since the outline structure is also used for (for example)
lists of tasks, only the first three outline levels will be used as
headings.  Deeper levels will become itemized lists.  You can change
the location of this switch globally by setting the variable
~org-export-headline-levels~, or on a per-file basis with a line

#+begin_src org
  ,#+OPTIONS: H:4
#+end_src

*** Table of contents
:PROPERTIES:
:DESCRIPTION: The if and where of the table of contents
:END:

The table of contents is normally inserted directly before the first headline
of the file.

#+begin_src org
  ,#+OPTIONS: toc:2          (only to two levels in TOC)
  ,#+OPTIONS: toc:nil        (no TOC at all)
#+end_src 

*** Paragraphs
:PROPERTIES:
:DESCRIPTION: Paragraphs
:END:

Paragraphs are separated by at least one empty line.  If you need to enforce
a line break within a paragraph, use @@info:@samp{\\}@@ at the end of a line.

To keep the line breaks in a region, but otherwise use normal formatting, you
can use this construct, which can also be used to format poetry.

#+begin_src org
  ,#+BEGIN_VERSE
  , Great clouds overhead
  , Tiny black birds rise and fall
  , Snow covers Emacs
  
  ,     -- AlexSchroeder
  ,#+END_VERSE
#+end_src

When quoting a passage from another document, it is customary to format this
as a paragraph that is indented on both the left and the right margin.  You
can include quotations in Org-mode documents like this:

#+begin_src org
  ,#+BEGIN_QUOTE
  ,Everything should be made as simple as possible,
  ,but not any simpler -- Albert Einstein
  ,#+END_QUOTE
#+end_src

If you would like to center some text, do it like this:
#+begin_src org
  ,#+BEGIN_CENTER
  ,Everything should be made as simple as possible, \\
  ,but not any simpler
  ,#+END_CENTER
#+end_src

*** Emphasis and monospace
:PROPERTIES:
:DESCRIPTION: Bold, italic, etc.
:END:

You can make words @@info:@b{*bold*}@@, @@info:@i{/italic/}@@,
_underlined_, @@info:@code{=code=}@@ and @@info:@code{~verbatim~}@@,
and, if you must, @@info:@samp{+strike-through+}@@.  Text in the code
and verbatim string is not processed for Org-mode specific syntax, it
is exported verbatim.  To insert a horizontal rules, use a line
consisting of only dashes, and at least 5 of them.

*** Comment lines
:PROPERTIES:
:DESCRIPTION: What will *not* be exported
:END:

Lines starting with @@info:@samp{#}@@ in column zero are treated as
comments and will never be exported.  If you want an indented line to
be treated as a comment, start it with @@info:@samp{#+ }@@.  Also
entire subtrees starting with the word @@info:@samp{COMMENT}@@ will
never be exported.  Finally, regions surrounded by
@@info:@samp{#+BEGIN_COMMENT}@@ ... @@info:@samp{#+END_COMMENT}@@ will
not be exported.

- C-c ; :: Toggle the COMMENT keyword at the beginning of an entry.

** Images and tables
:PROPERTIES:
:DESCRIPTION: Tables and Images will be included
:END:

For Org mode tables, the lines before the first horizontal separator line
will become table header lines.  You can use the following lines somewhere
before the table to assign a caption and a label for cross references, and in
the text you can refer to the object with ~\ref{tab:basic-data}~:

#+begin_src org
  ,#+CAPTION: This is the caption for the next table (or link)
  ,#+LABEL:   tbl:basic-data
  ,   | ... | ...|
  ,   |-----|----|
#+end_src

Some backends (HTML, LaTeX, and DocBook) allow you to directly include
images into the exported document.  Org does this, if a link to an image
files does not have a description part, for example ~[[./img/a.jpg]]~.
If you wish to define a caption for the image and maybe a label for internal
cross references, you sure that the link is on a line by itself precede it
with:

#+begin_src org
  ,#+CAPTION: This is the caption for the next figure link (or table)
  ,#+LABEL:   fig:SED-HR4049
  ,[[./img/a.jpg]]
#+end_src

You may also define additional attributes for the figure.  As this is
backend-specific, see the sections about the individual backends for more
information.

** Literal examples
:PROPERTIES:
:DESCRIPTION: Source code examples with special formatting
:END:

You can include literal examples that should not be subjected to
markup.  Such examples will be typeset in monospace, so this is well suited
for source code and similar examples.

#+begin_src org
  ,#+BEGIN_EXAMPLE
  ,Some example from a text file.
  ,#+END_EXAMPLE
#+end_src

For simplicity when using small examples, you can also start the example
lines with a colon followed by a space.  There may also be additional
whitespace before the colon:

#+begin_src org
  ,Here is an example
  ,   : Some example from a text file.
#+end_src

For source code from a programming language, or any other text
that can be marked up by font-lock in Emacs, you can ask for it to
look like the fontified Emacs buffer

#+begin_example
  ,#+BEGIN_SRC emacs-lisp
  (defun org-xor (a b)
     "Exclusive or."
     (if a (not b) b))
  ,#+END_SRC
#+end_example

To edit the example in a special buffer supporting this language, use
@@info:@kbd{C-c '}@@ to both enter and leave the editing buffer.

** Include files
:PROPERTIES:
:DESCRIPTION: Include additional files into a document
:END:

During export, you can include the content of another file.  For example, to
include your @@info:@file{.emacs}@@ file, you could use:

#+begin_src org
  ,#+INCLUDE: "~/.emacs" src emacs-lisp
#+end_src
@@info:@noindent@@ The optional second and third parameter are the
markup (e.g.@@info:@: @samp{quote}@@, @@info:@samp{example}@@, or
@@info:@samp{src}@@), and, if the markup is @@info:@samp{src}@@, the
language for formatting the contents.  The markup is optional, if it
is not given, the text will be assumed to be in Org mode format and
will be processed normally. @@info:@kbd{C-c '}@@ will visit the
included file.

** Embedded LaTeX
:PROPERTIES:
:DESCRIPTION: LaTeX can be freely used inside Org documents
:END:

For scientific notes which need to be able to contain mathematical
symbols and the occasional formula, Org-mode supports embedding LaTeX
code into its files.  You can directly use TeX-like macros for special
symbols, enter formulas and entire LaTeX environments.

#+begin_src org
  ,Angles are written as Greek letters \alpha, \beta and \gamma.  The mass if
  ,the sun is M_sun = 1.989 x 10^30 kg.  The radius of the sun is R_@{sun@} =
  ,6.96 x 10^8 m.  If $a^2=b$ and $b=2$, then the solution must be either
  ,$a=+\sqrt@{2@}$ or $a=-\sqrt@{2@}$.
  
  ,\begin@{equation@}
  ,x=\sqrt@{b@}
  ,\end@{equation@}
#+end_src

@@info:@noindent@@ With [[http://orgmode.org/manual/LaTeX-fragments.html#LaTeX-fragments][special setup]], LaTeX snippets will be included as images when exporting to HTML.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Markup.html#Markup][Chapter 11 of the manual]]

* Exporting
:PROPERTIES:
:DESCRIPTION: Sharing and publishing of notes
:END:

Org-mode documents can be exported into a variety of other formats: ASCII
export for inclusion into emails, HTML to publish on the web, LaTeX/PDF
for beautiful printed documents and DocBook to enter the world of many other
formats using DocBook tools.  There is also export to iCalendar format so
that planning information can be incorporated into desktop calendars.

** Export options
:PROPERTIES:
:DESCRIPTION: Per-file export settings
:END:

The exporter recognizes special lines in the buffer which provide
additional information.  These lines may be put anywhere in the file.
The whole set of lines can be inserted into the buffer with
@@info:@kbd{C-c C-e t}@@.

- C-c C-e t :: Insert template with export options, see example below.

: #+TITLE:       the title to be shown (default is the buffer name)
: #+AUTHOR:      the author (default taken from @code{user-full-name})
: #+DATE:        a date, fixed, of a format string for @code{format-time-string}
: #+EMAIL:       his/her email address (default from @code{user-mail-address})
: #+DESCRIPTION: the page description, e.g.@: for the XHTML meta tag
: #+KEYWORDS:    the page keywords, e.g.@: for the XHTML meta tag
: #+LANGUAGE:    language for HTML, e.g.@: @samp{en} (@code{org-export-default-language})
: #+TEXT:        Some descriptive text to be inserted at the beginning.
: #+TEXT:        Several lines may be given.
: #+OPTIONS:     H:2 num:t toc:t \n:nil @@:t ::t |:t ^:t f:t TeX:t ...
: #+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@}

** The export dispatcher
:PROPERTIES:
:DESCRIPTION: How to access exporter commands
:END:

All export commands can be reached using the export dispatcher, which
is a prefix key that prompts for an additional key specifying the
command.  Normally the entire file is exported, but if there is an
active region that contains one outline tree, the first heading is
used as document title and the subtrees are exported.

- C-c C-e :: Dispatcher for export and publishing commands.

** ASCII/Latin-1/UTF-8 export
:PROPERTIES:
:DESCRIPTION: Exporting to flat files with encoding
:END:

ASCII export produces a simple and very readable version of an
Org-mode file, containing only plain ASCII.  Latin-1 and UTF-8 export
augment the file with special characters and symbols available in
these encodings.

- C-c C-e a :: Export as ASCII file.
- C-c C-e n @@info:@ @ @r{and} @ @@@ C-c C-e N :: Like the above
     commands, but use Latin-1 encoding.
- C-c C-e u @@info:@ @ @r{and} @ @@@ C-c C-e U :: Like the above
     commands, but use UTF-8 encoding.

** HTML export
:PROPERTIES:
:DESCRIPTION: Exporting to HTML
:END:

- C-c C-e h :: Export as HTML file @@info:@file{myfile.html}@@.
- C-c C-e b :: Export as HTML file and immediately open it with a
               browser.

To insert HTML that should be copied verbatim to the exported file use
either

#+begin_src org
#+HTML: Literal HTML code for export
#+end_src
@@info:@noindent@@ or
#+begin_src org
#+BEGIN_HTML
All lines between these markers are exported literally
#+END_HTML
#+end_src

** LaTeX and PDF export
:PROPERTIES:
:DESCRIPTION: Exporting to LaTeX, and processing to PDF
:END:

- C-c C-e l :: Export as LaTeX file @@info:@file{myfile.tex}@@.
- C-c C-e p :: Export as LaTeX and then process to PDF.
- C-c C-e d :: Export as LaTeX and then process to PDF, then open the
               resulting PDF file.

By default, the LaTeX output uses the class ~article~.  You can
change this by adding an option like ~#+LaTeX_CLASS: myclass~ in your
file.  The class must be listed in ~org-export-latex-classes~.

Embedded LaTeX as described in [[Embedded LaTeX]], will be correctly
inserted into the LaTeX file.  Similarly to the HTML exporter, you can use
~#+LaTeX:~ and ~#+BEGIN_LaTeX ... #+END_LaTeX~ construct to add
verbatim LaTeX code.

** DocBook export
:PROPERTIES:
:DESCRIPTION: Exporting to DocBook
:END:

- C-c C-e D :: Export as DocBook file.

Similarly to the HTML exporter, you can use ~#+DOCBOOK:~ and
~#+BEGIN_DOCBOOK ... #+END_DOCBOOK~ construct to add verbatim LaTeX
code.

** iCalendar export
:PROPERTIES:
:DESCRIPTION: 
:END:

- C-c C-e i :: Create iCalendar entries for the current file in a
               @@info:@file{.ics}@@ file.
- C-c C-e c :: Create a single large iCalendar file from all files in
               ~org-agenda-files~ and write it to the file given
               by ~org-combined-agenda-icalendar-file~.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Exporting.html#Exporting][Chapter 12 of the manual]]\\
[[http://orgmode.org/worg/org-tutorials/images-and-xhtml-export.php][Sebastian Rose's image handling tutorial]]\\
[[http://orgmode.org/worg/org-tutorials/org-latex-export.php][Thomas Dye's LaTeX export tutorial]]\\
[[http://orgmode.org/worg/org-tutorials/org-beamer/tutorial.php][Eric Fraga's BEAMER presentation tutorial]]

* Publishing
:PROPERTIES:
:DESCRIPTION: Create a web site of linked Org files
:END:


Org includes a publishing management system that allows you to configure
automatic HTML conversion of /projects/ composed of interlinked org
files.  You can also configure Org to automatically upload your exported HTML
pages and related attachments, such as images and source code files, to a web
server.  For detailed instructions about setup, see the manual.

Here is an example:

#+begin_src emacs-lisp
  (setq org-publish-project-alist
        '(("org"
           :base-directory "~/org/"
           :publishing-directory "~/public_html"
           :section-numbers nil
           :table-of-contents nil
           :style "<link rel=\"stylesheet\"
                  href=\"../other/mystyle.css\"
                  type=\"text/css\"/>")))
#+end_src

- C-c C-e C :: Prompt for a specific project and publish all files
               that belong to it.
- C-c C-e P :: Publish the project containing the current file.
- C-c C-e F :: Publish only the current file.
- C-c C-e E :: Publish every project.

Org uses timestamps to track when a file has changed.  The above functions
normally only publish changed files.  You can override this and force
publishing of all files by giving a prefix argument to any of the commands
above.

@@info:@noindent@@ *Further Reading*
[[http://orgmode.org/manual/Publishing.html#Publishing][Chapter 13 of the manual]]\\
[[http://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.php][Sebastian Rose's publishing tutorial]]\\
[[http://orgmode.org/worg/org-tutorials/org-jekyll.php][Ian Barton's Jekyll/blogging setup]]

* Working With Source Code
:PROPERTIES:
:DESCRIPTION: Source code snippets embedded in Org
:END:

Org-mode provides a number of features for working with source code,
including editing of code blocks in their native major-mode,
evaluation of code blocks, tangling of code blocks, and exporting code
blocks and their results in several formats.

@@info:@subheading Structure of Code Blocks@@
The structure of code blocks is as follows:

: #+NAME: <name>
: #+BEGIN_SRC <language> <switches> <header arguments>
:   <body>
: #+END_SRC


Where ~<name>~ is a string used to name the code block, ~<language>~
specifies the language of the code block (e.g.: ~emacs-lisp~, ~shell~,
~R~, ~python~, etc...), ~<switches>~ can be used to control export of
the code block, ~<header arguments>~ can be used to control many
aspects of code block behavior as demonstrated below, and ~<body>~
contains the actual source code.

@@info:@subheading Editing source code@@
Use @@info:@kbd{C-c '}@@ to edit the current code block.  This brings
up a language major-mode edit buffer containing the body of the code
block.  Saving this buffer will write the new contents back to the Org
buffer.  Use @@info:@kbd{C-c '}@@ again to exit the edit buffer.

@@info:@subheading Evaluating code blocks@@
Use @@info:@kbd{C-c C-c}@@ to evaluate the current code block and
insert its results in the Org-mode buffer.  By default, evaluation is
only turned on for ~emacs-lisp~ code blocks, however support exists
for evaluating blocks in many languages.  For a complete list of
supported languages see the manual.  The following shows a code block
and its results.

: #+BEGIN_SRC emacs-lisp
:   (+ 1 2 3 4)
: #+END_SRC
:  
: #+RESULTS:
: : 10

@@info:@subheading Extracting source code@@
Use @@info:@kbd{C-c C-v t}@@ to create pure source code files by
extracting code from source blocks in the current buffer.  This is
referred to as "tangling"---a term adopted from the literate
programming community.  During "tangling" of code blocks their bodies
are expanded using ~org-babel-expand-src-block~ which can expand both
variable and "noweb" style references.  In order to tangle a code
block it must have a ~:tangle~ header argument, see the manual for
details.

@@info:@subheading Library of Babel@@
Use @@info:@kbd{C-c C-v l}@@ to load the code blocks from an Org-mode
files into the "Library of Babel", these blocks can then be evaluated
from any Org-mode buffer.  A collection of generally useful code
blocks is distributed with Org-mode in ~contrib/library-of-babel.org~.

@@info:@subheading Header Arguments@@
Many aspects of the evaluation and export of code blocks are
controlled through header arguments.  These can be specified globally,
at the file level, at the outline subtree level, and at the individual
code block level.  The following describes some of the header
arguments.

- ~:var~ :: The ~:var~ header argument is used to pass arguments to
            code blocks.  The values passed to arguments can be
            literal values, values from org-mode tables and literal
            example blocks, or the results of other named code blocks.
- ~:results~ :: The ~:results~ header argument controls the
                /collection/, /type/, and /handling/ of code block
                results.  Values of ~output~ or ~value~ (the default)
                specify how results are collected from a code block's
                evaluation.  Values of ~vector~, ~scalar~ ~file~ ~raw~
                ~html~ ~latex~ and ~code~ specify the type of the
                results of the code block which dictates how they will
                be incorporated into the Org-mode buffer.  Values of
                ~silent~, ~replace~, ~prepend~, and ~append~ specify
                handling of code block results, specifically if and
                how the results should be inserted into the Org-mode
                buffer.
- ~:session~ :: A header argument of ~:session~ will cause the code
                block to be evaluated in a persistent interactive
                inferior process in Emacs.  This allows for persisting
                state between code block evaluations, and for manual
                inspection of the results of evaluation.
- ~:exports~ :: Any combination of the /code/ or the /results/ of a
                block can be retained on export, this is specified by
                setting the ~:results~ header argument to ~code~
                ~results~ ~none~ or ~both~.
- ~:tangle~ :: A header argument of ~:tangle yes~ will cause a code
               block's contents to be tangled to a file named after
               the filename of the Org-mode buffer.  An alternate file
               name can be specified with ~:tangle filename~.
- ~:cache~ :: A header argument of ~:cache yes~ will cause associate a
              hash of the expanded code block with the results,
              ensuring that code blocks are only re-run when their
              inputs have changed.
- ~:noweb~ :: A header argument of ~:noweb yes~ will expand "noweb"
              style references on evaluation and tangling.
- ~:file~ :: Code blocks which output results to files (e.g.: graphs,
             diagrams and figures) can accept a ~:file filename~
             header argument in which case the results are saved to
             the named file, and a link to the file is inserted into
             the Org-mode buffer.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Literal-examples.html#Literal-examples][Chapter 11.3 of the manual]]\\
[[http://orgmode.org/worg/org-contrib/babel/index.php][The Babel site on Worg]]

* Miscellaneous
:PROPERTIES:
:DESCRIPTION: All the rest which did not fit elsewhere
:END:

** Completion
:PROPERTIES:
:DESCRIPTION: M-TAB knows what you need
:END:

Org supports in-buffer completion with @@info:@kbd{M-@key{TAB}}@@.  This type of
completion does not make use of the minibuffer.  You simply type a few
letters into the buffer and use the key to complete text right there.  For
example, this command will complete TeX symbols after @@info:@samp{\}@@, TODO
keywords at the beginning of a headline, and tags after @@info:@samp{:}@@ in a
headline.

** Clean view
:PROPERTIES:
:DESCRIPTION: Getting rid of leading stars in the outline
:END:

Some people find it noisy and distracting that the Org headlines start with a
potentially large number of stars, and that text below the headlines is not
indented.  While this is no problem when writing a /book-like/ document
where the outline headings are really section headings, in a more
/list-oriented/ outline, indented structure is a lot cleaner:

: * Top level headline             |    * Top level headline
: ** Second level                  |      * Second level
: *** 3rd level                    |        * 3rd level
: some text                        |          some text
: *** 3rd level                    |        * 3rd level
: more text                        |          more text
: * Another top level headline     |    * Another top level headline

@@info:@noindent@@ If you are using at least Emacs 23.1.50.3 and
version 6.29 of Org, this kind of view can be achieved dynamically at
display time using ~org-indent-mode~, which will prepend
intangible space to each line.  You can turn on ~org-indent-mode~
for all files by customizing the variable ~org-startup-indented~,
or you can turn it on for individual files using

#+begin_src org
  ,#+STARTUP: indent
#+end_src

If you want a similar effect in earlier version of Emacs and/or Org,
or if you want the indentation to be hard space characters so that the
plain text file looks as similar as possible to the Emacs display, Org
supports you by helping to indent (with @@info:@key{TAB}@@) text below
each headline, by hiding leading stars, and by only using levels 1, 3,
etc to get two characters indentation for each level.  To get this
support in a file, use

#+begin_src org
  ,#+STARTUP: hidestars odd
#+end_src

** MobileOrg
:PROPERTIES:
:DESCRIPTION: Org-mode on the iPhone
:END:

/MobileOrg/ is the name of the mobile companion app for Org mode, currently
available for iOS and for Android.  /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 [[http://mobileorg.ncogni.to/][iOS implementation]] for the
/iPhone/iPod Touch/iPad/ series of devices, was developed by Richard
Moreland. Android users should check out [[http://wiki.github.com/matburt/mobileorg-android/][MobileOrg Android]] by Matt
Jones.  The two implementations are not identical but offer similar
features.

@@info:@noindent@@ *Further Reading*\\
[[http://orgmode.org/manual/Miscellaneous.html#Miscellaneous][Chapter 15 of the manual]]\\
[[http://orgmode.org/manual/MobileOrg.html#MobileOrg][Appendix B of the manual]]\\
[[http://orgmode.org/orgcard.pdf][Key reference card]]

* Footnotes
:PROPERTIES:
:DESCRIPTION: How footnotes are defined in Org's syntax
:END:

[fn:1] See the variable ~org-special-ctrl-a/e~ to configure special
behavior of @@info:@kbd{C-a}@@ and @@info:@kbd{C-e}@@ in headlines.

[fn:2] If you do not want the line to be split, customize the variable
~org-M-RET-may-split-line~.

[fn:3] Of course, you can make a document that contains only long
lists of TODO items, but this is not required.

[fn:4] The corresponding in-buffer setting is: ~#+STARTUP: logdone~

[fn:5] The corresponding in-buffer setting is: ~#+STARTUP:
lognotedone~

[fn:6] As with all these in-buffer settings, pressing @@info:@kbd{C-c
C-c}@@ activates any changes in the line.

[fn:7] This is quite different from what is normally understood by
/scheduling a meeting/, which is done in Org-mode by just inserting a
time stamp without keyword.

[fn:8] It will still be listed on that date after it has been marked
DONE.  If you don't like this, set the variable
~org-agenda-skip-scheduled-if-done~.

[fn:9] Using capture templates, you can define more fine-grained
capture locations, see [[Capture templates]].

[fn:10] Please select your own key, @@info:@kbd{C-c c}@@ is only a suggestion.

[fn:11] If you need one of these sequences literally, escape the
@@info:@kbd{%}@@ with a backslash.

[fn:12] See also the variables ~org-show-hierarchy-above~,
~org-show-following-heading~, ~org-show-siblings~, and
~org-show-entry-below~ for detailed control on how much context is
shown around each match.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-31 21:03       ` Jonathan Leech-Pepin
@ 2012-07-31 21:18         ` Nicolas Goaziou
  2012-07-31 22:35           ` Jonathan Leech-Pepin
  2012-08-02 15:34         ` Bastien
  1 sibling, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2012-07-31 21:18 UTC (permalink / raw)
  To: Jonathan Leech-Pepin; +Cc: François Pinard, Org Mode Mailing List

Hello,

Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:

> I've done some further work on the org-e-texinfo exporter and have
> gotten it to a point where it should be usable with only a few
> shortcomings.

Thanks for your work. I hope that you will get feedback on it.

> - Two-column tables are restricted to a single "indicating" command,
>   defined by ~org-e-texinfo-def-table-markup~.  I'm not sure how to
>   get around these limitations since they are created from description
>   lists (which do not recognize #+attr lines).

What makes you think they don't?  Plain lists accept affiliated
keywords, items don't.

> Prior to exporting the following must be evaluated:
>
>   (add-to-list 'org-export-snippet-translation-alist
>                '("info" . "e-texinfo"))

Again, this is an user-oriented variable. You don't need it to accept
@@info:...@@ export snippets and you shouldn't require the user to set
it.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-31 21:18         ` Nicolas Goaziou
@ 2012-07-31 22:35           ` Jonathan Leech-Pepin
  2012-07-31 23:45             ` Jonathan Leech-Pepin
  0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-07-31 22:35 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: François Pinard, Org Mode Mailing List

On Tue, Jul 31, 2012 at 5:18 PM, Nicolas Goaziou <n.goaziou@gmail.com> wrote:
> Hello,
>
> Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:
>
>> I've done some further work on the org-e-texinfo exporter and have
>> gotten it to a point where it should be usable with only a few
>> shortcomings.
>
> Thanks for your work. I hope that you will get feedback on it.
>
>> - Two-column tables are restricted to a single "indicating" command,
>>   defined by ~org-e-texinfo-def-table-markup~.  I'm not sure how to
>>   get around these limitations since they are created from description
>>   lists (which do not recognize #+attr lines).
>
> What makes you think they don't?  Plain lists accept affiliated
> keywords, items don't.
>
I thought I'd tested them against a plain list when trying to find a
way around that limitation.  I'll have to try again tomorrow so that I
can eliminate the limitations still present regarding descriptive
lists.

>> Prior to exporting the following must be evaluated:
>>
>>   (add-to-list 'org-export-snippet-translation-alist
>>                '("info" . "e-texinfo"))
>
> Again, this is an user-oriented variable. You don't need it to accept
> @@info:...@@ export snippets and you shouldn't require the user to set
> it.
>
Usually no, but the sample (orgguide.org) document uses @@info:...@@
to create @kbd, @key and @samp output, without it the document will
fail to export correctly (especially since @ is used for texinfo
commands).

I suppose I should have clarified that those two commands were
required prior to exporting that specific document (for testing and
demonstration purposes).
>
> Regards,
>
> --
> Nicolas Goaziou

Regards,

Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-31 22:35           ` Jonathan Leech-Pepin
@ 2012-07-31 23:45             ` Jonathan Leech-Pepin
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-07-31 23:45 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: François Pinard, Org Mode Mailing List

On 31 July 2012 18:35, Jonathan Leech-Pepin
<jonathan.leechpepin@gmail.com> wrote:
> On Tue, Jul 31, 2012 at 5:18 PM, Nicolas Goaziou <n.goaziou@gmail.com> wrote:
>> Hello,
>>
>> Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:
>>
>>> I've done some further work on the org-e-texinfo exporter and have
>>> gotten it to a point where it should be usable with only a few
>>> shortcomings.
>>
>> Thanks for your work. I hope that you will get feedback on it.
>>
>>> - Two-column tables are restricted to a single "indicating" command,
>>>   defined by ~org-e-texinfo-def-table-markup~.  I'm not sure how to
>>>   get around these limitations since they are created from description
>>>   lists (which do not recognize #+attr lines).
>>
>> What makes you think they don't?  Plain lists accept affiliated
>> keywords, items don't.
>>
> I thought I'd tested them against a plain list when trying to find a
> way around that limitation.  I'll have to try again tomorrow so that I
> can eliminate the limitations still present regarding descriptive
> lists.

I've just added changes to make use of #+attr_texinfo: with
descriptive lists.  Thank you for making me revisit this.  It accepts
two attributes at the moment:

- :table-type :: This accepts one of the following: "table" "ftable"
"vtable".  If the value is not one of these it will default to "table"
- :indic :: This is the markup to be used on the first column of the
table.  It requires the "@" prefix to the command to be used.

>>> Prior to exporting the following must be evaluated:
>>>
>>>   (add-to-list 'org-export-snippet-translation-alist
>>>                '("info" . "e-texinfo"))
>>
>> Again, this is an user-oriented variable. You don't need it to accept
>> @@info:...@@ export snippets and you shouldn't require the user to set
>> it.
>>
> Usually no, but the sample (orgguide.org) document uses @@info:...@@
> to create @kbd, @key and @samp output, without it the document will
> fail to export correctly (especially since @ is used for texinfo
> commands).
>
> I suppose I should have clarified that those two commands were
> required prior to exporting that specific document (for testing and
> demonstration purposes).
>>
>> Regards,
>>
>> --
>> Nicolas Goaziou
>
> Regards,
>
> Jon
>

Regards,

Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Export to Texinfo
  2012-07-31 21:03       ` Jonathan Leech-Pepin
  2012-07-31 21:18         ` Nicolas Goaziou
@ 2012-08-02 15:34         ` Bastien
       [not found]           ` <CAHRqSkQTzE-OYmTFs+BRjrER=jgS3=2BE5Yi4A6v8ipaZ1kWQA@mail.gmail.com>
  1 sibling, 1 reply; 13+ messages in thread
From: Bastien @ 2012-08-02 15:34 UTC (permalink / raw)
  To: Jonathan Leech-Pepin
  Cc: Nicolas Goaziou, François Pinard, Org Mode Mailing List

[-- Attachment #1: Type: text/plain, Size: 908 bytes --]

Hi Jonathan,

Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:

> I've done some further work on the org-e-texinfo exporter and have
> gotten it to a point where it should be usable with only a few
> shortcomings.

thanks *a lot* for this!  This is long-time wish from many org-ers, 
no doubt you will have many testers.

Do you want to continue to develop while adding the library to
contrib/lisp/?

One problem with the version you sent:

(org-export-first-sibling-p headline)
(org-export-last-sibling-p headline)

should be

(org-export-first-sibling-p headline info)
(org-export-last-sibling-p headline info)

With this change I can export files correctly.

Another thingy: headlines from level 4 are converted to lists, 
right?  I'm fine with this, as long as the list is not collapsed
with a previous one.  See the .org and .texi files attached.

Thanks again for this great contribution!


[-- Attachment #2: test-texinfo.org --]
[-- Type: application/vnd.lotus-organizer, Size: 112 bytes --]

[-- Attachment #3: test-texinfo.texi --]
[-- Type: application/x-texinfo, Size: 1046 bytes --]

[-- Attachment #4: Type: text/plain, Size: 14 bytes --]


-- 
 Bastien

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Fwd: Export to Texinfo
       [not found]           ` <CAHRqSkQTzE-OYmTFs+BRjrER=jgS3=2BE5Yi4A6v8ipaZ1kWQA@mail.gmail.com>
@ 2012-08-02 22:24             ` Jonathan Leech-Pepin
  2012-08-03  7:29               ` Bastien
  2012-08-03  8:41               ` Nicolas Goaziou
  0 siblings, 2 replies; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-08-02 22:24 UTC (permalink / raw)
  To: Org Mode Mailing List

[-- Attachment #1: Type: text/plain, Size: 2482 bytes --]

Forwarding to list, forgot to when replying


---------- Forwarded message ----------
From: Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com>
Date: Thu, Aug 2, 2012 at 4:54 PM
Subject: Re: Export to Texinfo
To: Bastien <bzg@gnu.org>


Hi Bastien

On Thu, Aug 2, 2012 at 11:34 AM, Bastien <bzg@gnu.org> wrote:
> Hi Jonathan,
>
> Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:
>
>> I've done some further work on the org-e-texinfo exporter and have
>> gotten it to a point where it should be usable with only a few
>> shortcomings.
>
> thanks *a lot* for this!  This is long-time wish from many org-ers,
> no doubt you will have many testers.
>
> Do you want to continue to develop while adding the library to
> contrib/lisp/?
>

Yes, that would be great.

> One problem with the version you sent:
>
> (org-export-first-sibling-p headline)
> (org-export-last-sibling-p headline)
>
> should be
>
> (org-export-first-sibling-p headline info)
> (org-export-last-sibling-p headline info)
>
> With this change I can export files correctly.

I'd caught that just after attaching the files the last time (I'd been
working with a slightly out of date copy so that change to
org-export-first-sibling-p hadn't affected me).  I'd updated it in my
working copy but hadn't added the changes in my next email to the
list.

The attached version fixes that and supports @ftable and @vtable
through #+attr_texinfo before descriptive lists.  (It can also be
found at :
https://github.com/jleechpe/org-mode/blob/texinfo/contrib/lisp/org-e-texinfo.el
)

>
> Another thingy: headlines from level 4 are converted to lists,
> right?  I'm fine with this, as long as the list is not collapsed
> with a previous one.  See the .org and .texi files attached.
>

It's able to export up to level 4 headlines (chapter, section,
subsection, subsubsection), however the default is H:3 so the last is
omitted.  Nested lists do work with only a small issue I can see at
the moment, if there are no blank lines between the items in org there
are none in the info file either, however there are 2 blank lines at
the end of the nested list (end of nested list+end of parent item).

When I export the attached .org file the only difference I get from
your .texi is the AUTHOR and the chapter/sections are numbered rather
than unnumbered (and the level 4 headline is an enumerate rather than
an itemize).

> Thanks again for this great contribution!
>

You're welcome

>
> --
>  Bastien
>

Regards,

--
Jon

[-- Attachment #2: org-e-texinfo.el --]
[-- Type: application/octet-stream, Size: 62862 bytes --]

;;; org-e-texinfo.el --- Texinfo Back-End For Org Export Engine

;; Author: Jonathan Leech-Pepin <jonathan.leechpepin 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 Texinfo back-end for Org generic
;; exporter.
;;
;; To test it, run
;;
;;   M-: (org-export-to-buffer 'e-texinfo "*Test e-texinfo*") RET
;;
;; in an org-mode buffer then switch to the buffer to see the Texinfo
;; export.  See contrib/lisp/org-export.el for more details on how
;; this exporter works.
;;
;; It introduces eight new buffer keywords: "TEXINFO_CLASS",
;; "TEXINFO_FILENAME", "TEXINFO_HEADER", "TEXINFO_DIR_CATEGORY",
;; "TEXINFO_DIR_TITLE", "TEXINFO_DIR_DESC" "SUBTITLE" and "SUBAUTHOR".
;;
;; To include inline code snippets (for example for generating @kbd{}
;; and @key{} commands), the following export-snippet keys are
;; accepted:
;; 
;;     info
;;     e-info
;;     e-texinfo
;;
;; You can add them for export snippets via any of the below:
;;
;;    (add-to-list 'org-export-snippet-translation-alist
;;                 '("e-info" . "e-texinfo"))
;;    (add-to-list 'org-export-snippet-translation-alist
;;                 '("e-texinfo" . "e-texinfo"))
;;    (add-to-list 'org-export-snippet-translation-alist
;;                 '("info" . "e-texinfo"))
;; 


;;; Code:

(eval-when-compile (require 'cl))
(require 'org-export)

(defvar orgtbl-exp-regexp)

\f
;;; Define Back-End

(defvar org-e-texinfo-translate-alist
  '((babel-call . org-e-texinfo-babel-call)
    (bold . org-e-texinfo-bold)
    (center-block . org-e-texinfo-center-block)
    (clock . org-e-texinfo-clock)
    (code . org-e-texinfo-code)
    (comment . org-e-texinfo-comment)
    (comment-block . org-e-texinfo-comment-block)
    (drawer . org-e-texinfo-drawer)
    (dynamic-block . org-e-texinfo-dynamic-block)
    (entity . org-e-texinfo-entity)
    (example-block . org-e-texinfo-example-block)
    (export-block . org-e-texinfo-export-block)
    (export-snippet . org-e-texinfo-export-snippet)
    (fixed-width . org-e-texinfo-fixed-width)
    (footnote-definition . org-e-texinfo-footnote-definition)
    (footnote-reference . org-e-texinfo-footnote-reference)
    (headline . org-e-texinfo-headline)
    (horizontal-rule . org-e-texinfo-horizontal-rule)
    (inline-babel-call . org-e-texinfo-inline-babel-call)
    (inline-src-block . org-e-texinfo-inline-src-block)
    (inlinetask . org-e-texinfo-inlinetask)
    (italic . org-e-texinfo-italic)
    (item . org-e-texinfo-item)
    (keyword . org-e-texinfo-keyword)
    (latex-environment . org-e-texinfo-latex-environment)
    (latex-fragment . org-e-texinfo-latex-fragment)
    (line-break . org-e-texinfo-line-break)
    (link . org-e-texinfo-link)
    (macro . org-e-texinfo-macro)
    (paragraph . org-e-texinfo-paragraph)
    (plain-list . org-e-texinfo-plain-list)
    (plain-text . org-e-texinfo-plain-text)
    (planning . org-e-texinfo-planning)
    (property-drawer . org-e-texinfo-property-drawer)
    (quote-block . org-e-texinfo-quote-block)
    (quote-section . org-e-texinfo-quote-section)
    (radio-target . org-e-texinfo-radio-target)
    (section . org-e-texinfo-section)
    (special-block . org-e-texinfo-special-block)
    (src-block . org-e-texinfo-src-block)
    (statistics-cookie . org-e-texinfo-statistics-cookie)
    (strike-through . org-e-texinfo-strike-through)
    (subscript . org-e-texinfo-subscript)
    (superscript . org-e-texinfo-superscript)
    (table . org-e-texinfo-table)
    (table-cell . org-e-texinfo-table-cell)
    (table-row . org-e-texinfo-table-row)
    (target . org-e-texinfo-target)
    (template . org-e-texinfo-template)
    (timestamp . org-e-texinfo-timestamp)
    (underline . org-e-texinfo-underline)
    (verbatim . org-e-texinfo-verbatim)
    (verse-block . org-e-texinfo-verse-block))
  "Alist between element or object types and translators.")

(defconst org-e-texinfo-options-alist
  '((:texinfo-filename "TEXINFO_FILENAME" nil org-e-texinfo-filename t)
    (:texinfo-class "TEXINFO_CLASS" nil org-e-texinfo-default-class t)
    (:texinfo-header "TEXINFO_HEADER" nil nil newline)
    (:subtitle "SUBTITLE" nil nil newline)
    (:subauthor "SUBAUTHOR" nil nil newline)
    (:texinfo-dircat "TEXINFO_DIR_CATEGORY" nil nil t)
    (:texinfo-dirtitle "TEXINFO_DIR_TITLE" nil nil t)
    (:texinfo-dirdesc "TEXINFO_DIR_DESC" nil nil t))
  "Alist between Texinfo export properties and ways to set them.
See `org-export-options-alist' for more information on the
structure of the values.

SUBAUTHOR and SUBTITLE are for the inclusion of additional author
and title information beyond the initial variable.")

(defconst org-e-texinfo-filters-alist
  '((:filter-headline . org-e-texinfo-filter-section-blank-lines)
    (:filter-section . org-e-texinfo-filter-section-blank-lines))
  "Alist between filters keywords and back-end specific filters.
  See `org-export-filters-alist' for more information")


\f
;;; Internal Variables

;; Add TEXINFO to the list of available of available export blocks.
(add-to-list 'org-element-block-name-alist
	     '("TEXINFO" . org-element-export-block-parser))
\f
;;; User Configurable Variables

(defgroup org-export-e-texinfo nil
  "Options for exporting Org mode files to Texinfo."
  :tag "Org Export Texinfo"
  :group 'org-export)


;;;; Preamble

(defcustom org-e-texinfo-filename nil
  "Default filename for texinfo output."
  :group 'org-export-e-texinfo
  :type '(string :tag "Export Filename"))

(defcustom org-e-texinfo-default-class "info"
  "The default Texinfo class."
  :group 'org-export-e-texinfo
  :type '(string :tag "Texinfo class"))

(defcustom org-e-texinfo-classes
  '(("info"
     "\\input texinfo    @c -*- texinfo -*-"
     ("@chapter %s" . "@unnumbered %s")
     ("@section %s" . "@unnumberedsec %s")
     ("@subsection %s" . "@unnumberedsubsec %s")
     ("@subsubsection %s" . "@unnumberedsubsubsec %s")))
  "Alist of Texinfo classes and associated header and structure.
If #+Texinfo_CLASS is set in the buffer, use its value and the
associated information.  Here is the structure of each cell:

  \(class-name
    header-string
    \(numbered-section . unnumbered-section\)
    ...\)

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.

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-texinfo
  :type '(repeat
	  (list (string :tag "Texinfo class")
		(string :tag "Texinfo header")
		(repeat :tag "Levels" :inline t
			(choice
			 (cons :tag "Heading"
			       (string :tag "  numbered")
			       (string :tag "unnumbered"))
			 (function :tag "Hook computing sectioning"))))))


;;;; Headline

(defcustom org-e-texinfo-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 as a list of strings (list of strings 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-texinfo-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}\"
              \(mapconcat 'identity tags \":\"))))"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Footnotes
;;
;; Footnotes are inserted directly

;;;; Timestamps

(defcustom org-e-texinfo-active-timestamp-format "@emph{%s}"
  "A printf format string to be applied to active timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

(defcustom org-e-texinfo-inactive-timestamp-format "@emph{%s}"
  "A printf format string to be applied to inactive timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

(defcustom org-e-texinfo-diary-timestamp-format "@emph{%s}"
  "A printf format string to be applied to diary timestamps."
  :group 'org-export-e-texinfo
  :type 'string)

;;;; Links

(defcustom org-e-texinfo-link-with-unknown-path-format "@indicateurl{%s}"
  "Format string for links with unknown path type."
  :group 'org-export-e-texinfo
  :type 'string)


;;;; Tables

(defcustom org-e-texinfo-tables-verbatim nil
  "When non-nil, tables are exported verbatim."
  :group 'org-export-e-texinfo
  :type 'boolean)

(defcustom org-e-texinfo-table-scientific-notation "%s\\,(%s)"
  "Format string to display numbers in scientific notation.
The format should have \"%s\" twice, for mantissa and exponent
\(i.e. \"%s\\\\times10^{%s}\").

When nil, no transformation is made."
  :group 'org-export-e-texinfo
  :type '(choice
	  (string :tag "Format string")
	  (const :tag "No formatting")))

(defcustom org-e-texinfo-def-table-markup "@samp"
  "Default setting for @table environments.")

;;;; Text markup

(defcustom org-e-texinfo-text-markup-alist '((bold . "@strong{%s}")
					   (code . code)
					   (italic . "@emph{%s}")
					   (verbatim . verb)
					   (comment . "@c %s"))
  "Alist of Texinfo expressions to convert text markup.

The key must be a symbol among `bold', `italic' and `comment'.
The value is a formatting string to wrap fontified text with.

Value can also be set to the following symbols: `verb' and
`code'.  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 \"@code\"
to typeset and try to protect special characters.

If no association can be found for a given markup, text will be
returned as-is."
  :group 'org-export-e-texinfo
  :type 'alist
  :options '(bold code italic verbatim comment))


;;;; Drawers

(defcustom org-e-texinfo-format-drawer-function nil
  "Function called to format a drawer in Texinfo 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-texinfo-format-drawer-default \(name contents\)
  \"Format a drawer element for Texinfo export.\"
  contents\)"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Inlinetasks

(defcustom org-e-texinfo-format-inlinetask-function nil
  "Function called to format an inlinetask in Texinfo 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 list of strings.
  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-texinfo-format-inlinetask \(todo type priority name tags contents\)
\"Format an inline task element for Texinfo export.\"
  \(let ((full-title
	 \(concat
	  \(when todo
            \(format \"@strong{%s} \" todo))
	  \(when priority (format \"#%c \" priority))
	  title
	  \(when tags
            \(format \":%s:\"
                    \(mapconcat 'identity tags \":\")))))
    \(format (concat \"@center %s\n\n\"
		    \"%s\"
                    \"\n\"))
	    full-title contents))"
  :group 'org-export-e-texinfo
  :type 'function)


;;;; Src blocks
;;
;; Src Blocks are example blocks, except for LISP

;;;; Plain text

(defcustom org-e-texinfo-quotes
  '(("quotes"
     ("\\(\\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-texinfo
  :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

(defcustom org-e-texinfo-info-process
  '("makeinfo %f")
  "Commands to process a texinfo file to an INFO file.
This is 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."
  :group 'org-export-texinfo
  :type '(repeat :tag "Shell command sequence"
		 (string :tag "Shell command")))

\f
;;; Internal Functions

(defun org-e-texinfo-filter-section-blank-lines (headline back-end info)
  "Filter controlling number of blank lines after a section."
  (if (not (eq back-end 'e-texinfo)) headline
    (let ((blanks (make-string 2 ?\n)))
      (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline))))

(defun org-e-texinfo--find-copying (info)
  "Retrieve the headline identified by the property :copying:.

INFO is the plist containing the export options and tree.  It is
used to find and extract the single desired headline.  This
cannot be treated as a standard headline since it must be
inserted in a specific location."
  (let (copying)
    (org-element-map (plist-get info :parse-tree) 'headline
		     (lambda (copy)
		       (when (org-element-property :copying copy)
			 (push copy copying))) info 't)
    ;; Retrieve the single entry
    (car copying)))

(defun org-e-texinfo--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-texinfo--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-texinfo--quotation-marks (text info)
  "Export quotation marks using ` and ' as the markers.
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 org-e-texinfo-quotes))
  text)

(defun org-e-texinfo--text-markup (text markup)
  "Format TEXT depending on MARKUP text markup.
See `org-e-texinfo-text-markup-alist' for details."
  (let ((fmt (cdr (assq markup org-e-texinfo-text-markup-alist))))
    (cond
     ;; No format string: Return raw text.
     ((not fmt) text)
     ((eq 'verb fmt)
      (let ((separator (org-e-texinfo--find-verb-separator text)))
	(concat "@verb{" separator text separator "}")))
     ((eq 'code fmt)
      (let ((start 0)
	    (rtn "")
	    char)
	(while (string-match "[@{}]" text)
	  (setq char (match-string 0 text))
	  (if (> (match-beginning 0) 0)
	      (setq rtn (concat rtn (substring text 0 (match-beginning 0)))))
	  (setq text (substring text (1+ (match-beginning 0))))
	  (setq char (concat "@" char)
		rtn (concat rtn char)))
	(setq text (concat rtn text)
	      fmt "@code{%s}")
	(format fmt text)))
     ;; Else use format string.
     (t (format fmt text)))))

;;;; Menu creation

(defun org-e-texinfo--build-menu (tree level info &optional detailed)
  "Create the @menu/@end menu information from TREE at headline
level LEVEL.

TREE contains the parse-tree to work with, either of the entire
document or of a specific parent headline.  LEVEL indicates what
level of headlines to look at when generating the menu.  INFO is
a plist containing contextual information.

Detailed determines whether to build a single level of menu, or
recurse into all children as well."
  (let ((menu (org-e-texinfo--generate-menu-list tree level info))
	output text-menu)
    (cond
     (detailed
      ;; Looping is done within the menu generation.
      (setq text-menu (org-e-texinfo--generate-detailed menu level info)))
     (t
      (setq text-menu (org-e-texinfo--generate-menu-items menu info))))
    (when text-menu
      (setq output (org-e-texinfo--format-menu text-menu))
      (mapconcat 'identity output "\n"))))

(defun org-e-texinfo--generate-detailed (menu level info)
  "Generate a detailed listing of all subheadings within MENU starting at LEVEL.

MENU is the parse-tree to work with.  LEVEL is the starting level
for the menu headlines and from which recursion occurs.  INFO is
a plist containing contextual information."
  (let ((max-depth (plist-get info :headline-levels)))
    (when (> max-depth level)
      (loop for headline in menu append
	    (let* ((title (org-e-texinfo--menu-headlines headline info))
		   ;; Create list of menu entries for the next level
		   (sublist (org-e-texinfo--generate-menu-list
			     headline (1+ level) info))
		   ;; Generate the menu items for that level.  If
		   ;; there are none omit that heading completely,
		   ;; otherwise join the title to it's related entries.
		   (submenu (if (org-e-texinfo--generate-menu-items sublist info)
				(append (list title)
					(org-e-texinfo--generate-menu-items sublist info))
			      'nil))
		   ;; Start the process over the next level down.
		   (recursion (org-e-texinfo--generate-detailed sublist (1+ level) info)))
	      (setq recursion (append submenu recursion))
	      recursion)))))

(defun org-e-texinfo--generate-menu-list (tree level info)
  "Generate the list of headlines that are within a given level
of the tree for further formatting.

TREE is the parse-tree containing the headlines.  LEVEL is the
headline level to generate a list of.  INFO is a plist holding
contextual information."
  (let (seq)
    (org-element-map
     tree 'headline
     (lambda (head)
       (when (org-element-property :level head)
	 (if (and (eq level (org-element-property :level head))
		  ;; Do not take note of footnotes or copying headlines
		  (not (org-element-property :copying head))
		  (not (org-element-property :footnote-section-p head)))
	     (push head seq)))))
    ;; Return the list of headlines (reverse to have in actual order)
    (reverse seq)))

(defun org-e-texinfo--generate-menu-items (items info)
  "Generate a list of headline information from the listing ITEMS.

ITEMS is a list of the headlines to be converted into entries.
INFO is a plist containing contextual information.

Returns a list containing the following information from each
headline: length, title, description.  This is used to format the
menu using `org-e-texinfo--format-menu'."
  (loop for headline in items collect
	(let* ((title (org-export-data
		       (org-element-property :title headline) info))
	       (descr (org-export-data
		       (org-element-property :description headline) info))
	       (len (length title))
	       (output (list len title descr)))
	  output)))

(defun org-e-texinfo--menu-headlines (headline info)
  "Retrieve the title from HEADLINE.

INFO is a plist holding contextual information.

Return the headline as a list of (length title description) with
length of -1 and nil description.  This is used in
`org-e-texinfo--format-menu' to identify headlines as opposed to
entries."
  (let ((title (org-export-data
		(org-element-property :title headline) info)))
    (list -1 title 'nil)))

(defun org-e-texinfo--format-menu (text-menu)
  "Format the TEXT-MENU items to be properly printed in the menu.

Each entry in the menu should be provided as (length title
description).

Headlines in the detailed menu are given length -1 to ensure they
are never confused with other entries.  They also have no
description.

Other menu items are output as:
    Title::     description

With the spacing between :: and description based on the length
of the longest menu entry."

  (let* ((lengths (mapcar 'car text-menu))
         (max-length (apply 'max lengths))
	 output)
    (setq output
          (mapcar (lambda (name)
                    (let* ((title (nth 1 name))
                           (desc (nth 2 name))
                           (length (nth 0 name)))
                      (if (> length -1)
                          (concat "* " title ":: "
                                  (make-string
				   (- (+ 3 max-length) length)
                                               ?\s)
                                  (if desc
                                      (concat desc)))
                        (concat "\n" title "\n"))))
		  text-menu))
    output))



;;; Template

(defun org-e-texinfo-template (contents info)
  "Return complete document string after Texinfo conversion.
CONTENTS is the transcoded contents string.  INFO is a plist
holding export options."
  (let* ((title (org-export-data (plist-get info :title) info))
	 (info-filename (or (plist-get info :texinfo-filename)
			    (file-name-nondirectory
			     (org-export-output-file-name ".info"))))
	 (author (org-export-data (plist-get info :author) info))
	 (texinfo-header (plist-get info :texinfo-header))
	 (subtitle (plist-get info :subtitle))
	 (subauthor (plist-get info :subauthor))
	 (class (plist-get info :texinfo-class))
	 (header (nth 1 (assoc class org-e-texinfo-classes)))
	 (copying (org-e-texinfo--find-copying info))
	 (dircat (plist-get info :texinfo-dircat))
	 (dirtitle (plist-get info :texinfo-dirtitle))
	 (dirdesc (plist-get info :texinfo-dirdesc))
	 ;; Spacing to align description (column 32 - 3 for `* ' and
	 ;; `.' in text.
	 (dirspacing (- 29 (length dirtitle))))
    (concat
     ;; Header
     header "\n"
     "@c %**start of header\n"
     ;; Filename and Title
     "@setfilename " info-filename "\n"
     "@settitle " title "\n"
     "\n\n"
     "@c Version and Contact Info\n"
     "@set AUTHOR " author "\n"

     ;; Additional Header Options set by `#+TEXINFO_HEADER
     (if texinfo-header
	 (concat "\n"
		 texinfo-header
		 "\n"))
     
     "@c %**end of header\n"
     "@finalout\n"
     "\n\n"

     ;; Copying
     "@copying\n"
     ;; Only export the content of the headline, do not need the
     ;; initial headline.
     (org-export-data (nth 2 copying) info)
     "@end copying\n"
     "\n\n"

     ;; Info directory information
     ;; Only supply if both title and category are provided
     (if (and dircat dirtitle)
	 (concat "@dircategory " dircat "\n"
		 "@direntry\n"
		 "* " dirtitle "."
		 (make-string dirspacing ?\s)
		 dirdesc "\n"
		 "@end direntry\n"))
     "\n\n"

     ;; Title
     "@titlepage\n"
     "@title " title "\n\n"
     (if subtitle
	 (concat "@subtitle " subtitle "\n"))
     "@author " author "\n"
     (if subauthor
	 (concat subauthor "\n"))
     "\n"
     "@c The following two commands start the copyright page.\n"
     "@page\n"
     "@vskip 0pt plus 1filll\n"
     "@insertcopying\n"
     "@end titlepage\n\n"
     "@c Output the table of contents at the beginning.\n"
     "@contents\n\n"

     ;; Configure Top Node when not for Tex
     "@ifnottex\n"
     "@node Top\n"
     "@top " title " Manual\n"
     "@insertcopying\n"
     "@end ifnottex\n\n"
     
     ;; Menu
     "@menu\n"
     (org-e-texinfo-make-menu info 'main)
     "\n\n"
     ;; Detailed Menu
     "@detailmenu\n"
     " --- The Detailed Node Listing ---\n"
     (org-e-texinfo-make-menu info 'detailed)
     "\n\n"
     "@end detailmenu\n"
     "@end menu\n"
     "\n\n"
     
     ;; Document's body.
     contents
     "\n"
     ;; Creator.
     (let ((creator-info (plist-get info :with-creator)))
       (cond
	((not creator-info) "")
	((eq creator-info 'comment)
	 (format "@c %s\n" (plist-get info :creator)))
	(t (concat (plist-get info :creator) "\n"))))
     ;; Document end.
     "\n@bye")))


\f
;;; Transcode Functions

;;;; Babel Call
;;
;; Babel Calls are ignored.


;;;; Bold

(defun org-e-texinfo-bold (bold contents info)
  "Transcode BOLD from Org to Texinfo.
CONTENTS is the text with bold markup.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup contents 'bold))


;;;; Center Block
;;
;; Center blocks are ignored


;;;; Clock

(defun org-e-texinfo-clock (clock contents info)
  "Transcode a CLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (concat
   "@noindent"
   (format "@strong{%s} " org-clock-string)
   (format org-e-texinfo-inactive-timestamp-format
	   (concat (org-translate-time (org-element-property :value clock))
		   (let ((time (org-element-property :time clock)))
		     (and time (format " (%s)" time)))))
   "@*"))


;;;; Code

(defun org-e-texinfo-code (code contents info)
  "Transcode a CODE object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist used as a communication
channel."
  (org-e-texinfo--text-markup (org-element-property :value code) 'code))

;;;; Comment

(defun org-e-texinfo-comment (comment contents info)
  "Transcode a COMMENT object from Org to Texinfo.
CONTENTS is the text in the comment.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup (org-element-property :value comment) 'comment))

;;;; Comment Block

(defun org-e-texinfo-comment-block (comment-block contents info)
  "Transcode a COMMENT-BLOCK object from Org to Texinfo.
CONTENTS is the text within the block.  INFO is a plist holding
contextual information."
  (format "@ignore\n%s@end ignore" (org-element-property :value comment-block)))

;;;; Drawer

(defun org-e-texinfo-drawer (drawer contents info)
  "Transcode a DRAWER element from Org to Texinfo.
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-texinfo-format-drawer-function)
		     (funcall org-e-texinfo-format-drawer-function
			      name contents)
		   ;; If there's no user defined function: simply
		   ;; display contents of the drawer.
		   contents)))
    output))


;;;; Dynamic Block

(defun org-e-texinfo-dynamic-block (dynamic-block contents info)
  "Transcode a DYNAMIC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information.  See `org-export-data'."
  contents)


;;;; Entity

(defun org-e-texinfo-entity (entity contents info)
  "Transcode an ENTITY object from Org to Texinfo.
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 "@math{%s}" ent) ent)))


;;;; Example Block

(defun org-e-texinfo-example-block (example-block contents info)
  "Transcode an EXAMPLE-BLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (format "@verbatim\n%s@end verbatim"
	  (org-export-format-code-default example-block info)))


;;;; Export Block

(defun org-e-texinfo-export-block (export-block contents info)
  "Transcode a EXPORT-BLOCK element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (when (string= (org-element-property :type export-block) "TEXINFO")
    (org-remove-indentation (org-element-property :value export-block))))


;;;; Export Snippet

(defun org-e-texinfo-export-snippet (export-snippet contents info)
  "Transcode a EXPORT-SNIPPET object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (when (eq (org-export-snippet-backend export-snippet) 'e-texinfo)
    (org-element-property :value export-snippet)))


;;;; Fixed Width

(defun org-e-texinfo-fixed-width (fixed-width contents info)
  "Transcode a FIXED-WIDTH element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (format "@example\n%s\n@end example"
	  (org-remove-indentation
	   (org-element-property :value fixed-width))))


;;;; Footnote Definition
;;
;; Footnote Definitions are ignored.


;;;; Footnote Reference
;;

(defun org-e-texinfo-footnote-reference (footnote contents info)
  "Create a footnote reference for FOOTNOTE.

FOOTNOTE is the footnote to define.  CONTENTS is nil.  INFO is a
plist holding contextual information."
  (let ((def (org-export-get-footnote-definition footnote info)))
    (format "@footnote{%s}"
	    (org-trim (org-export-data def info)))))

;;;; Headline

(defun org-e-texinfo-headline (headline contents info)
  "Transcode an HEADLINE element from Org to Texinfo.
CONTENTS holds the contents of the headline.  INFO is a plist
holding contextual information."
  (let* ((class (plist-get info :texinfo-class))
	 (level (org-export-get-relative-level headline info))
	 (numberedp (org-export-numbered-headline-p headline info))
	 (class-sectionning (assoc class org-e-texinfo-classes))
	 ;; Find the index type, if any
	 (index (org-element-property :index headline))
	 ;; Create node info, to insert it before section formatting.
	 (node (format "@node %s\n"
		       (org-export-data
			(org-element-property :title headline) info)))
	 ;; Menus must be generated with first child, otherwise they
	 ;; will not nest properly
	 (menu (let* ((first (org-export-first-sibling-p headline info))
		      (parent (org-export-get-parent-headline headline))
		      (title (org-export-data
			      (org-element-property :title parent) info))
		      heading listing
		      (tree (plist-get info :parse-tree)))
		 (if first
		     (org-element-map
		      (plist-get info :parse-tree) 'headline
		      (lambda (ref)
			(if (member title (org-element-property :title ref))
			    (push ref heading)))
		      info 't))
		 (setq listing (org-e-texinfo--build-menu
				(car heading) level info))
	 	 (if listing
	 	     (setq listing (format
				    "\n@menu\n%s\n@end menu\n\n" listing))
	 	   'nil)))
	 ;; 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)))
	      ;; If an index, always unnumbered
	      (if index
		  (concat menu node (cdr sec) "\n%s")
		;; Otherwise number as needed.
		(concat menu node
			(funcall
			 (if numberedp #'car #'cdr) sec) "\n%s"))))))
	 (text (org-export-data
		(org-element-property :title headline) info))
	 (todo
	  (and (plist-get info :with-todo-keywords)
	       (let ((todo (org-element-property :todo-keyword headline)))
		 (and todo (org-export-data todo info)))))
	 (todo-type (and todo (org-element-property :todo-type headline)))
	 (tags (and (plist-get info :with-tags)
		    (org-export-get-tags headline info)))
	 (priority (and (plist-get info :with-priority)
			(org-element-property :priority headline)))
	 ;; Create the headline text along with a no-tag version.  The
	 ;; latter is required to remove tags from table of contents.
	 (full-text (if (functionp org-e-texinfo-format-headline-function)
			;; User-defined formatting function.
			(funcall org-e-texinfo-format-headline-function
				 todo todo-type priority text tags)
		      ;; Default formatting.
		      (concat
		       (when todo
			 (format "@strong{%s} " todo))
		       (when priority (format "@emph{#%s} " priority))
		       text
		       (when tags
			 (format ":%s:"
				 (mapconcat 'identity tags ":"))))))
	 (full-text-no-tag
	  (if (functionp org-e-texinfo-format-headline-function)
	      ;; User-defined formatting function.
	      (funcall org-e-texinfo-format-headline-function
		       todo todo-type priority text nil)
	    ;; Default formatting.
	    (concat
	     (when todo (format "@strong{%s} " todo))
	     (when priority (format "@emph{#%c} " priority))
	     text)))
	 (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 the `copying' section: ignore it
     ;;         This is used elsewhere.
     ((org-element-property :copying headline) nil)
     ;; Case 3: An index.  If it matches one of the known indexes,
     ;;         print it as such following the contents, otherwise
     ;;         print the contents and leave the index up to the user.
     (index
      (format
       section-fmt full-text
       (concat pre-blanks contents "\n" 
	       (if (member index '("cp" "fn" "ky" "pg" "tp" "vr"))
		   (concat "@printindex " index)))))
     ;; Case 4: 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) (org-export-low-level-p headline info))
      ;; Build the real contents of the sub-tree.
      (let ((low-level-body
	     (concat
	      ;; If the headline is the first sibling, start a list.
	      (when (org-export-first-sibling-p headline info)
		(format "@%s\n" (if numberedp 'enumerate 'itemize)))
	      ;; Itemize headline
	      "@item\n" full-text "\n" 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 5: Standard headline.  Export it as a section.
     (t
      (cond
       ((not (and tags (eq (plist-get info :with-tags) 'not-in-toc)))
	;; Regular section.  Use specified format string.
	(format (replace-regexp-in-string "%]" "%%]" section-fmt) full-text
		(concat pre-blanks contents)))
       ((string-match "\\`@\\(.*?\\){" section-fmt)
	;; If tags should be removed from table of contents, insert
	;; title without tags as an alternative heading in sectioning
	;; command.
	(format (replace-match (concat (match-string 1 section-fmt) "[%s]")
			       nil nil section-fmt 1)
		;; Replace square brackets with parenthesis since
		;; square brackets are not supported in optional
		;; arguments.
		(replace-regexp-in-string
		 "\\[" "("
		 (replace-regexp-in-string
		  "\\]" ")"
		  full-text-no-tag))
		full-text
		(concat pre-blanks contents)))
       (t
	;; Impossible to add an alternative heading.  Fallback to
	;; regular sectioning format string.
	(format (replace-regexp-in-string "%]" "%%]" section-fmt) full-text
		(concat pre-blanks contents))))))))


;;;; Horizontal Rule
;;
;; Horizontal rules are ignored

;;;; Inline Babel Call
;;
;; Inline Babel Calls are ignored.


;;;; Inline Src Block

(defun org-e-texinfo-inline-src-block (inline-src-block contents info)
  "Transcode an INLINE-SRC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((code (org-element-property :value inline-src-block))
	 (separator (org-e-texinfo--find-verb-separator code)))
    (concat "@verb{" separator code separator "}")))


;;;; Inlinetask

(defun org-e-texinfo-inlinetask (inlinetask contents info)
  "Transcode an INLINETASK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  (let ((title (org-export-data (org-element-property :title inlinetask) info))
	(todo (and (plist-get info :with-todo-keywords)
		   (let ((todo (org-element-property :todo-keyword inlinetask)))
		     (and todo (org-export-data todo info)))))
	(todo-type (org-element-property :todo-type inlinetask))
	(tags (and (plist-get info :with-tags)
		   (org-export-get-tags inlinetask info)))
	(priority (and (plist-get info :with-priority)
		       (org-element-property :priority inlinetask))))
    ;; If `org-e-texinfo-format-inlinetask-function' is provided, call it
    ;; with appropriate arguments.
    (if (functionp org-e-texinfo-format-inlinetask-function)
	(funcall org-e-texinfo-format-inlinetask-function
		 todo todo-type priority title tags contents)
      ;; Otherwise, use a default template.
      (let ((full-title
	     (concat
	      (when todo (format "@strong{%s} " todo))
	      (when priority (format "#%c " priority))
	      title
	      (when tags (format ":%s:"
				 (mapconcat 'identity tags ":"))))))
	(format (concat "@center %s\n\n"
			"%s"
			"\n")
		full-title contents)))))


;;;; Italic

(defun org-e-texinfo-italic (italic contents info)
  "Transcode ITALIC from Org to Texinfo.
CONTENTS is the text with italic markup.  INFO is a plist holding
contextual information."
  (org-e-texinfo--text-markup contents 'italic))

;;;; Item

(defun org-e-texinfo-item (item contents info)
  "Transcode an ITEM element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((tag (org-element-property :tag item))
	 (desc (org-export-data tag info)))
   (concat "\n@item " (if tag desc) "\n"
	   (org-trim contents) "\n")))


;;;; Keyword

(defun org-e-texinfo-keyword (keyword contents info)
  "Transcode a KEYWORD element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((key (org-element-property :key keyword))
	(value (org-element-property :value keyword)))
    (cond
     ((string= key "TEXINFO") value)
     ((string= key "CINDEX") (format "@cindex %s" value))
     ((string= key "FINDEX") (format "@findex %s" value))
     ((string= key "KINDEX") (format "@kindex %s" value))
     ((string= key "PINDEX") (format "@pindex %s" value))
     ((string= key "TINDEX") (format "@tindex %s" value))
     ((string= key "VINDEX") (format "@vindex %s" value))
     )))


;;;; Latex Environment
;;
;; Latex environments are ignored


;;;; Latex Fragment
;;
;; Latex fragments are ignored.


;;;; Line Break

(defun org-e-texinfo-line-break (line-break contents info)
  "Transcode a LINE-BREAK object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  "@*")


;;;; Link

(defun org-e-texinfo-link (link desc info)
  "Transcode a LINK object from Org to Texinfo.

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"))
		 (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))
		   (concat "file://" raw-path)))
		(t raw-path)))
	 (email (if (string= type "mailto")
		    (let ((text (replace-regexp-in-string
				 "@" "@@" raw-path)))
		     (concat text (if desc (concat "," desc))))))
	 protocol)
    (cond
     ;; Links pointing to an headline: Find destination and build
     ;; appropriate referencing command.
     ((member type '("custom-id" "id"))
      (let ((destination (org-export-resolve-id-link link info)))
	(case (org-element-type destination)
	  ;; Id link points to an external file.
	  (plain-text
	   (if desc (format "@uref{file://%s,%s}" destination desc)
	     (format "@uref{file://%s}" destination)))
	  ;; LINK points to an headline.  Use the headline as the NODE target
	  (headline
	   (format "@ref{%s}"
		   (org-export-data
		    (org-element-property :title destination) info)))
	  (otherwise
	   (let ((path (org-export-solidify-link-text path)))
	     (if (not desc) (format "@ref{%s}" path)
	       (format "@ref{%s,,%s}" path desc)))))))
     ((member type '("fuzzy"))
      (let ((destination (org-export-resolve-fuzzy-link link info)))
	(case (org-element-type destination)
	  ;; Id link points to an external file.
	  (plain-text
	   (if desc (format "@uref{file://%s,%s}" destination desc)
	     (format "@uref{file://%s}" destination)))
	  ;; LINK points to an headline.  Use the headline as the NODE target
	  (headline
	   (format "@ref{%s}"
		   (org-export-data
		    (org-element-property :title destination) info)))
	  (otherwise
	   (let ((path (org-export-solidify-link-text path)))
	     (if (not desc) (format "@ref{%s}" path)
	       (format "@ref{%s,,%s}" path desc)))))))
     ;; Special case for email addresses
     (email
      (format "@email{%s}" email))
     ;; External link with a description part.
     ((and path desc) (format "@uref{%s,%s}" path desc))
     ;; External link without a description part.
     (path (format "@uref{%s}" path))
     ;; No path, only description.  Try to do something useful.
     (t (format org-e-texinfo-link-with-unknown-path-format desc)))))


;;;; Macro

(defun org-e-texinfo-macro (macro contents info)
  "Transcode a MACRO element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  ;; Use available tools.
  (org-export-expand-macro macro info))


;;;; Menu

(defun org-e-texinfo-make-menu (info level)
  "Create the menu for inclusion in the texifo document.

INFO is the parsed buffer that contains the headlines.  LEVEL
determines whether to make the main menu, or the detailed menu.

This is only used for generating the primary menu.  In-Node menus
are generated directly."
  (let* ((parse (plist-get info :parse-tree))
	 ;; Top determines level to build menu from, it finds the
	 ;; level of the first headline in the export.
	 (top (org-element-map
	       parse 'headline
	       (lambda (headline)
		 (org-element-property :level headline)) info 't)))
    (cond
     ;; Generate the main menu
     ((eq level 'main)
      (org-e-texinfo--build-menu parse top info))
     ;; Generate the detailed (recursive) menu
     ((eq level 'detailed)
      ;; Requires recursion
      ;;(org-e-texinfo--build-detailed-menu parse top info)
      (or (org-e-texinfo--build-menu parse top info 'detailed)
	  "detailed"))
     ;; Otherwise do nothing
     (t))))


;;;; Paragraph

(defun org-e-texinfo-paragraph (paragraph contents info)
  "Transcode a PARAGRAPH element from Org to Texinfo.
CONTENTS is the contents of the paragraph, as a string.  INFO is
the plist used as a communication channel."
  contents)


;;;; Plain List

(defun org-e-texinfo-plain-list (plain-list contents info)
  "Transcode a PLAIN-LIST element from Org to Texinfo.
CONTENTS is the contents of the list.  INFO is a plist holding
contextual information."
  (let* ((attr (org-export-read-attribute :attr_texinfo plain-list))
	 (indic (or (plist-get attr :indic)
		    org-e-texinfo-def-table-markup))
	 (type (org-element-property :type plain-list))
	 (table-type (or (plist-get attr :table-type)
			 "table"))
	 ;; Ensure valid texinfo table type.
	 (table-type (if (memq table-type '("table" "ftable" "vtable"))
			 table-type
		       "table"))
	 (list-type (cond
		     ((eq type 'ordered) "enumerate")
		     ((eq type 'unordered) "itemize")
		     ((eq type 'descriptive) table-type))))
    (format "@%s%s\n@end %s"
	    (if (eq type 'descriptive)
		(concat list-type " " indic)
	     list-type)
	    contents
	    list-type)))


;;;; Plain Text

(defun org-e-texinfo-plain-text (text info)
  "Transcode a TEXT string from Org to Texinfo.
TEXT is the string to transcode.  INFO is a plist holding
contextual information."
  ;; Protect @ { and }.
  (while (string-match "\\([^\\]\\|^\\)\\([@{}]\\)" text)
    (setq text
	  (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
  ;; LaTeX into @LaTeX{} 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-texinfo--quotation-marks text info))
  ;; Convert special strings.
  (when (plist-get info :with-special-strings)
    (while (string-match (regexp-quote "...") text)
      (setq text (replace-match "@dots{}" nil t 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)


;;;; Planning

(defun org-e-texinfo-planning (planning contents info)
  "Transcode a PLANNING element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (concat
   "@noindent"
   (mapconcat
    'identity
    (delq nil
	  (list
	   (let ((closed (org-element-property :closed planning)))
	     (when closed
	       (concat
		(format "@strong%s} " org-closed-string)
		(format org-e-texinfo-inactive-timestamp-format
			(org-translate-time closed)))))
	   (let ((deadline (org-element-property :deadline planning)))
	     (when deadline
	       (concat
		(format "@strong{%s} " org-deadline-string)
		(format org-e-texinfo-active-timestamp-format
			(org-translate-time deadline)))))
	   (let ((scheduled (org-element-property :scheduled planning)))
	     (when scheduled
	       (concat
		(format "@strong{%s} " org-scheduled-string)
		(format org-e-texinfo-active-timestamp-format
			(org-translate-time scheduled)))))))
    " ")
   "@*"))


;;;; Property Drawer

(defun org-e-texinfo-property-drawer (property-drawer contents info)
  "Transcode a PROPERTY-DRAWER element from Org to Texinfo.
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-texinfo-quote-block (quote-block contents info)
  "Transcode a QUOTE-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the block.  INFO is a plist
holding contextual information."
  
  (let* ((title (org-element-property :name quote-block))
	 (start-quote (concat "@quotation"

			      (if title
				 (format " %s" title)))))
    
    (format "%s\n%s@end quotation" start-quote contents)))


;;;; Quote Section

(defun org-e-texinfo-quote-section (quote-section contents info)
  "Transcode a QUOTE-SECTION element from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((value (org-remove-indentation
		(org-element-property :value quote-section))))
    (when value (format "@verbatim\n%s@end verbatim" value))))


;;;; Radio Target

(defun org-e-texinfo-radio-target (radio-target text info)
  "Transcode a RADIO-TARGET object from Org to Texinfo.
TEXT is the text of the target.  INFO is a plist holding
contextual information."
  (format "@anchor{%s}%s"
	  (org-export-solidify-link-text
	   (org-element-property :value radio-target))
	  text))


;;;; Section

(defun org-e-texinfo-section (section contents info)
  "Transcode a SECTION element from Org to Texinfo.
CONTENTS holds the contents of the section.  INFO is a plist
holding contextual information."
  contents)


;;;; Special Block
;;
;; Are ignored at the moment

;;;; Src Block

(defun org-e-texinfo-src-block (src-block contents info)
  "Transcode a SRC-BLOCK element from Org to Texinfo.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (let* ((lang (org-element-property :language src-block))
	 (lisp-p (string-match-p "lisp" lang)))
    (cond
     ;; Case 1.  Lisp Block
     (lisp-p
      (format "@lisp\n%s\n@end lisp"
	      (org-export-format-code-default src-block info)))
     ;; Case 2.  Other blocks
     (t
      (format "@example\n%s\n@end example"
	      (org-export-format-code-default src-block info))))))


;;;; Statistics Cookie

(defun org-e-texinfo-statistics-cookie (statistics-cookie contents info)
  "Transcode a STATISTICS-COOKIE object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (org-element-property :value statistics-cookie))


;;;; Strike-Through
;;
;; Strikethrough is ignored


;;;; Subscript

(defun org-e-texinfo-subscript (subscript contents info)
  "Transcode a SUBSCRIPT object from Org to Texinfo.
CONTENTS is the contents of the object.  INFO is a plist holding
contextual information."
  (format "@math{_%s}" contents))


;;;; Superscript

(defun org-e-texinfo-superscript (superscript contents info)
  "Transcode a SUPERSCRIPT object from Org to Texinfo.
CONTENTS is the contents of the object.  INFO is a plist holding
contextual information."
  (format "@math{^%s}" contents))


;;;; Table
;;
;; `org-e-texinfo-table' is the entry point for table transcoding.  It
;; takes care of tables with a "verbatim" attribute.  Otherwise, it
;; delegates the job to either `org-e-texinfo-table--table.el-table' or
;; `org-e-texinfo-table--org-table' functions, depending of the type of
;; the table.
;;
;; `org-e-texinfo-table--align-string' is a subroutine used to build
;; alignment string for Org tables.

(defun org-e-texinfo-table (table contents info)
  "Transcode a TABLE element from Org to Texinfo.
CONTENTS is the contents of the table.  INFO is a plist holding
contextual information."
  (cond
   ;; Case 1: verbatim table.
   ((or org-e-texinfo-tables-verbatim
	(let ((attr (mapconcat 'identity
			       (org-element-property :attr_latex table)
			       " ")))
	  (and attr (string-match "\\<verbatim\\>" attr))))
    (format "@verbatim \n%s\n@end verbatim"
	    ;; Re-create table, without affiliated keywords.
	    (org-trim
	     (org-element-interpret-data
	      `(table nil ,@(org-element-contents table))))))
   ;; Case 2: table.el table.  Convert it using appropriate tools.
   ((eq (org-element-property :type table) 'table.el)
    (org-e-texinfo-table--table.el-table table contents info))
   ;; Case 3: Standard table.
   (t (org-e-texinfo-table--org-table table contents info))))

(defun org-e-texinfo-table-column-widths (table info)
  "Determine the largest table cell in each column to process alignment.

TABLE is the table element to transcode.  INFO is a plist used as
a communication channel."
  (let* ((rows (org-element-map table 'table-row 'identity info))
	 (collected (loop for row in rows collect
			  (org-element-map
			   row 'table-cell 'identity info)))
	 (number-cells (length (car collected)))
	 cells counts)
    (loop for row in collected do
	  (push (mapcar (lambda (ref)
		     (let* ((start (org-element-property :contents-begin ref))
			    (end (org-element-property :contents-end ref))
			    (length (- end start)))
		       length)) row) cells))
    (setq cells (remove-if #'null cells))
    (push (loop for count from 0 to (- number-cells 1) collect
		   (loop for item in cells collect
			 (nth count item))) counts)
    (mapconcat '(lambda (size)
		  (make-string size ?a)) (mapcar (lambda (ref)
				   (apply 'max `,@ref)) (car counts))
	       "} {")
  ))

(defun org-e-texinfo-table--org-table (table contents info)
  "Return appropriate Texinfo code for an Org table.

TABLE is the table type element to transcode.  CONTENTS is its
contents, as a string.  INFO is a plist used as a communication
channel.

This function assumes TABLE has `org' as its `:type' attribute."
  (let* ((attr (org-export-read-attribute :attr_texinfo table))
	 (col-width (plist-get attr :columns))
	 (columns (if col-width
		      (format "@columnfractions %s"
			      col-width)
		    (format "{%s}"
			    (org-e-texinfo-table-column-widths
			     table info)))))
    ;; Prepare the final format string for the table.
    (cond
     ;; Longtable.
     ;; Others.
     (t (concat
	 (format "@multitable %s\n%s@end multitable"
		 columns
		 contents))))))

(defun org-e-texinfo-table--table.el-table (table contents info)
  "Returns nothing.

Rather than return an invalid table, nothing is returned."
  'nil)


;;;; Table Cell

(defun org-e-texinfo-table-cell (table-cell contents info)
  "Transcode a TABLE-CELL element from Org to Texinfo.
CONTENTS is the cell contents.  INFO is a plist used as
a communication channel."
  (concat (if (and contents
		   org-e-texinfo-table-scientific-notation
		   (string-match orgtbl-exp-regexp contents))
	      ;; Use appropriate format string for scientific
	      ;; notation.
	      (format org-e-texinfo-table-scientific-notation
		      (match-string 1 contents)
		      (match-string 2 contents))
	    contents)
	  (when (org-export-get-next-element table-cell info) "\n@tab ")))


;;;; Table Row

(defun org-e-texinfo-table-row (table-row contents info)
  "Transcode a TABLE-ROW element from Org to Texinfo.
CONTENTS is the contents of the row.  INFO is a plist used as
a communication channel."
  ;; Rules are ignored since table separators are deduced from
  ;; borders of the current row.
  (when (eq (org-element-property :type table-row) 'standard) 
    (concat "@item " contents "\n")))


;;;; Target

(defun org-e-texinfo-target (target contents info)
  "Transcode a TARGET object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (format "@anchor{%s}"
	  (org-export-solidify-link-text (org-element-property :value target))))


;;;; Timestamp

(defun org-e-texinfo-timestamp (timestamp contents info)
  "Transcode a TIMESTAMP object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist holding contextual
information."
  (let ((value (org-translate-time (org-element-property :value timestamp)))
	(type (org-element-property :type timestamp)))
    (cond ((memq type '(active active-range))
	   (format org-e-texinfo-active-timestamp-format value))
	  ((memq type '(inactive inactive-range))
	   (format org-e-texinfo-inactive-timestamp-format value))
	  (t (format org-e-texinfo-diary-timestamp-format value)))))


;;;; Underline
;;
;; Underline is ignored


;;;; Verbatim

(defun org-e-texinfo-verbatim (verbatim contents info)
  "Transcode a VERBATIM object from Org to Texinfo.
CONTENTS is nil.  INFO is a plist used as a communication
channel."
  (org-e-texinfo--text-markup (org-element-property :value verbatim) 'verbatim))


;;;; Verse Block

(defun org-e-texinfo-verse-block (verse-block contents info)
  "Transcode a VERSE-BLOCK element from Org to Texinfo.
CONTENTS is verse block contents. INFO is a plist holding
contextual information."
  ;; In a verse environment, add a line break to each newline
  ;; character and change each white space at beginning of a line
  ;; into a space of 1 em.  Also change each blank line with
  ;; a vertical space of 1 em.
  (progn
    (setq contents (replace-regexp-in-string
		    "^ *\\\\\\\\$" "\\\\vspace*{1em}"
		    (replace-regexp-in-string
		     "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n" contents)))
    (while (string-match "^[ \t]+" contents)
      (let ((new-str (format "\\hspace*{%dem}"
			     (length (match-string 0 contents)))))
	(setq contents (replace-match new-str nil t contents))))
    (format "\\begin{verse}\n%s\\end{verse}" contents)))


\f
;;; Interactive functions

(defun org-e-texinfo-export-to-texinfo
  (&optional subtreep visible-only body-only ext-plist pub-dir)
  "Export current buffer to a Texinfo 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 ".texi" subtreep pub-dir)))
    (org-export-to-file
     'e-texinfo outfile subtreep visible-only body-only ext-plist)))

(defun org-e-texinfo-export-to-info
  (&optional subtreep visible-only body-only ext-plist pub-dir)
  "Export current buffer to Texinfo then process through to INFO.

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 INFO file's name."
  (interactive)
  (org-e-texinfo-compile
   (org-e-texinfo-export-to-texinfo
    subtreep visible-only body-only ext-plist pub-dir)))

(defun org-e-texinfo-compile (texifile)
  "Compile a texinfo file.

TEXIFILE is the name of the file being compiled.  Processing is
done through the command specified in `org-e-texinfo-info-process'.

Return INFO file name or an error if it couldn't be produced."
  (let* ((wconfig (current-window-configuration))
	 (texifile (file-truename texifile))
	 (base (file-name-sans-extension texifile))
	 errors)
    (message (format "Processing Texinfo file %s ..." texifile))
    (unwind-protect
	(progn
	  (cond
	   ;; A function is provided: Apply it.
	   ((functionp org-e-texinfo-info-process)
	    (funcall org-e-texinfo-info-process (shell-quote-argument texifile)))
	   ;; A list is provided: Replace %b, %f and %o with appropriate
	   ;; values in each command before applying it.  Output is
	   ;; redirected to "*Org INFO Texinfo Output*" buffer.
	   ((consp org-e-texinfo-info-process)
	    (let* ((out-dir (or (file-name-directory texifile) "./"))
		   (outbuf (get-buffer-create "*Org Info Texinfo Output*")))
	      (mapc
	       (lambda (command)
		 (shell-command
		  (replace-regexp-in-string
		   "%b" (shell-quote-argument base)
		   (replace-regexp-in-string
		    "%f" (shell-quote-argument texifile)
		    (replace-regexp-in-string
		     "%o" (shell-quote-argument out-dir) command t t) t t) t t)
		  outbuf))
	       org-e-texinfo-info-process)
	      ;; Collect standard errors from output buffer.
	      (setq errors (org-e-texinfo-collect-errors outbuf))))
	   (t (error "No valid command to process to Info")))
	  (let ((infofile (concat base ".info")))
	    ;; Check for process failure.  Provide collected errors if
	    ;; possible.
	    (if (not (file-exists-p infofile))
		(error (concat (format "INFO file %s wasn't produced" infofile)
			       (when errors (concat ": " errors))))
	      ;; Else remove log files, when specified, and signal end of
	      ;; process to user, along with any error encountered.
	      (message (concat "Process completed"
			       (if (not errors) "."
				 (concat " with errors: " errors)))))
	    ;; Return output file name.
	    infofile))
      (set-window-configuration wconfig))))

(defun org-e-texinfo-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 "makeinfo" run.
      (when (re-search-backward "^makeinfo (GNU texinfo)" nil t)
	(let ((case-fold-search t)
	      (errors ""))
	  (when (save-excursion
		  (re-search-forward "perhaps incorrect sectioning?" nil t))
	    (setq errors (concat errors " [incorrect sectionnng]")))
	  (when (save-excursion
		  (re-search-forward "missing close brace" nil t))
	    (setq errors (concat errors " [syntax error]")))
	  (when (save-excursion
		  (re-search-forward "Unknown command" nil t))
	    (setq errors (concat errors " [undefined @command]")))
	  (when (save-excursion
		  (re-search-forward "No matching @end" nil t))
	    (setq errors (concat errors " [block incomplete]")))
	  (when (save-excursion
		  (re-search-forward "requires a sectioning" nil t))
	    (setq errors (concat errors " [invalid section command]")))
	  (when (save-excursion
		  (re-search-forward "[unexpected]" nil t))
	    (setq errors (concat errors " [unexpected error]")))
	  (and (org-string-nw-p errors) (org-trim errors)))))))


(provide 'org-e-texinfo)
;;; org-e-texinfo.el ends here

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fwd: Export to Texinfo
  2012-08-02 22:24             ` Fwd: " Jonathan Leech-Pepin
@ 2012-08-03  7:29               ` Bastien
  2012-08-03  8:41               ` Nicolas Goaziou
  1 sibling, 0 replies; 13+ messages in thread
From: Bastien @ 2012-08-03  7:29 UTC (permalink / raw)
  To: Jonathan Leech-Pepin; +Cc: Org Mode Mailing List

Hi Jonathan,

Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:

>> Do you want to continue to develop while adding the library to
>> contrib/lisp/?
>
> Yes, that would be great.

Thansk, I'll send you instructions in a private email.

> The attached version fixes that and supports @ftable and @vtable
> through #+attr_texinfo before descriptive lists.  (It can also be
> found at :
> https://github.com/jleechpe/org-mode/blob/texinfo/contrib/lisp/org-e-texinfo.el

Great,

> It's able to export up to level 4 headlines (chapter, section,
> subsection, subsubsection), however the default is H:3 so the last is
> omitted.  Nested lists do work with only a small issue I can see at
> the moment, if there are no blank lines between the items in org there
> are none in the info file either, however there are 2 blank lines at
> the end of the nested list (end of nested list+end of parent item).

A minor issue anyway, this can be fixed afterwards.

Best,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fwd: Export to Texinfo
  2012-08-02 22:24             ` Fwd: " Jonathan Leech-Pepin
  2012-08-03  7:29               ` Bastien
@ 2012-08-03  8:41               ` Nicolas Goaziou
  2012-08-03 13:30                 ` Jonathan Leech-Pepin
  1 sibling, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2012-08-03  8:41 UTC (permalink / raw)
  To: Jonathan Leech-Pepin; +Cc: Org Mode Mailing List

Hello,

Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:

> Nested lists do work with only a small issue I can see at the moment,
> if there are no blank lines between the items in org there are none in
> the info file either, however there are 2 blank lines at the end of
> the nested list (end of nested list+end of parent item).

By default, Org export preserves the number of blank lines during
conversion.  If no blank line separates two elements in the Org buffer,
no blank line will separate their transcoded version.

You can change this by using filters.  For example "md" back-end
enforces at least one blank line between elements (see
`org-md-separate-elements') and "e-ascii" back-end normalizes the number
of blank lines after an headline (see
`org-e-ascii-filter-headline-blank-lines').

Filters are installed by :filters-alist keyword in
`org-export-define-backend' and `org-export-define-derived-backend'.

> When I export the attached .org file the only difference I get from
> your .texi is the AUTHOR and the chapter/sections are numbered rather
> than unnumbered (and the level 4 headline is an enumerate rather than
> an itemize).

Ideally, for "listified" headlines, list type (ordered or not) should be
determined by `org-export-numbered-headline-p' predicate.


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fwd: Export to Texinfo
  2012-08-03  8:41               ` Nicolas Goaziou
@ 2012-08-03 13:30                 ` Jonathan Leech-Pepin
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Leech-Pepin @ 2012-08-03 13:30 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Org Mode Mailing List

Hello,

On Fri, Aug 3, 2012 at 4:41 AM, Nicolas Goaziou <n.goaziou@gmail.com> wrote:
> Hello,
>
> Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com> writes:
>
>> Nested lists do work with only a small issue I can see at the moment,
>> if there are no blank lines between the items in org there are none in
>> the info file either, however there are 2 blank lines at the end of
>> the nested list (end of nested list+end of parent item).
>
> By default, Org export preserves the number of blank lines during
> conversion.  If no blank line separates two elements in the Org buffer,
> no blank line will separate their transcoded version.
>
> You can change this by using filters.  For example "md" back-end
> enforces at least one blank line between elements (see
> `org-md-separate-elements') and "e-ascii" back-end normalizes the number
> of blank lines after an headline (see
> `org-e-ascii-filter-headline-blank-lines').
>
> Filters are installed by :filters-alist keyword in
> `org-export-define-backend' and `org-export-define-derived-backend'.
>

I thought I'd set it to normalize (set a filter similar to the
one in org-e-ascii), but I must have gotten some part not quite
right.  I'll look it over again.

>> When I export the attached .org file the only difference I get from
>> your .texi is the AUTHOR and the chapter/sections are numbered rather
>> than unnumbered (and the level 4 headline is an enumerate rather than
>> an itemize).
>
> Ideally, for "listified" headlines, list type (ordered or not) should be
> determined by `org-export-numbered-headline-p' predicate.
>

They do follow the numbered/unnumbered settings.  When I exported
every headline (listified or otherwise) was numbered, in
Bastien's example they were all unnumbered, so it was consistent.

>
> Regards,
>
> --
> Nicolas Goaziou

Regards,

--
Jon

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2012-08-03 13:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-20  0:29 Export to Texinfo Jonathan Leech-Pepin
2012-07-20  9:32 ` Nicolas Goaziou
2012-07-20 13:34   ` Jonathan Leech-Pepin
2012-07-20 13:42     ` Nicolas Goaziou
2012-07-31 21:03       ` Jonathan Leech-Pepin
2012-07-31 21:18         ` Nicolas Goaziou
2012-07-31 22:35           ` Jonathan Leech-Pepin
2012-07-31 23:45             ` Jonathan Leech-Pepin
2012-08-02 15:34         ` Bastien
     [not found]           ` <CAHRqSkQTzE-OYmTFs+BRjrER=jgS3=2BE5Yi4A6v8ipaZ1kWQA@mail.gmail.com>
2012-08-02 22:24             ` Fwd: " Jonathan Leech-Pepin
2012-08-03  7:29               ` Bastien
2012-08-03  8:41               ` Nicolas Goaziou
2012-08-03 13:30                 ` Jonathan Leech-Pepin

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).