summaryrefslogtreecommitdiff
path: root/contrib/lisp/org-e-texinfo.el
diff options
context:
space:
mode:
authorSébastien Delafond <sdelafond@gmail.com>2014-07-13 13:35:27 +0200
committerSébastien Delafond <sdelafond@gmail.com>2014-07-13 13:35:27 +0200
commite32a45ed36d6000db4b39171149072d11b77af72 (patch)
treeb5f4a7d43022c08c3298e82b3e9fc50f68be660f /contrib/lisp/org-e-texinfo.el
parent7697fa4daf3ec84f85711a84035d8f0224afd4e3 (diff)
Imported Upstream version 8.0.7
Diffstat (limited to 'contrib/lisp/org-e-texinfo.el')
-rw-r--r--contrib/lisp/org-e-texinfo.el1844
1 files changed, 0 insertions, 1844 deletions
diff --git a/contrib/lisp/org-e-texinfo.el b/contrib/lisp/org-e-texinfo.el
deleted file mode 100644
index a19139f..0000000
--- a/contrib/lisp/org-e-texinfo.el
+++ /dev/null
@@ -1,1844 +0,0 @@
-;;; org-e-texinfo.el --- Texinfo Back-End For Org Export Engine
-
-;; Copyright (C) 2012 Jonathan Leech-Pepin
-;; Author: Jonathan Leech-Pepin <jonathan.leechpepin at gmail dot com>
-;; Keywords: outlines, hypermedia, calendar, wp
-;;
-;; This file is not part of GNU Emacs.
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; 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)
-
-
-;;; 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")
-
-
-;;; 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))
-
-;;; 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")))
-
-
-;;; Internal Functions
-
-(defun org-e-texinfo-filter-section-blank-lines (headline back-end info)
- "Filter controlling number of blank lines after a section."
- (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)))))
-
-;;; Headline sanitizing
-
-(defun org-e-texinfo--sanitize-headline (headline info)
- "Remove all formatting from the text of a headline for use in
- node and menu listing."
- (mapconcat 'identity
- (org-e-texinfo--sanitize-headline-contents headline info) " "))
-
-(defun org-e-texinfo--sanitize-headline-contents (headline info)
- "Retrieve the content of the headline.
-
-Any content that can contain further formatting is checked
-recursively, to ensure that nested content is also properly
-retrieved."
- (loop for contents in headline append
- (cond
- ;; already a string
- ((stringp contents)
- (list (replace-regexp-in-string " $" "" contents)))
- ;; Is exported as-is (value)
- ((org-element-map contents '(verbatim code)
- (lambda (value)
- (org-element-property :value value))))
- ;; Has content and recurse into the content
- ((org-element-contents contents)
- (org-e-texinfo--sanitize-headline-contents
- (org-element-contents contents) info)))))
-
-;;; Menu sanitizing
-
-(defun org-e-texinfo--sanitize-menu (title)
- "Remove invalid characters from TITLE for use in menus and
-nodes.
-
-Based on TEXINFO specifications, the following must be removed:
-@ { } ( ) : . ,"
- (replace-regexp-in-string "[@{}():,.]" "" title))
-
-;;; Content sanitizing
-
-(defun org-e-texinfo--sanitize-content (text)
- "Ensure characters are properly escaped when used in headlines or blocks.
-
-Escape characters are: @ { }"
- (replace-regexp-in-string "\\\([@{}]\\\)" "@\\1" 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."
- (when level
- (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-e-texinfo--sanitize-menu
- (org-e-texinfo--sanitize-headline
- (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)))
- (menu (org-e-texinfo-make-menu info 'main))
- (detail-menu (org-e-texinfo-make-menu info 'detailed)))
- (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"
-
- ;; Do not output menus if they are empty
- (if menu
- ;; Menu
- (concat "@menu\n"
- menu
- "\n\n"
- ;; Detailed Menu
- (if detail-menu
- (concat "@detailmenu\n"
- " --- The Detailed Node Listing ---\n"
- detail-menu
- "\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")))
-
-
-
-;;; 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-e-texinfo--sanitize-content
- (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))
- ;; Retrieve headline text
- (text (org-e-texinfo--sanitize-headline
- (org-element-property :title headline) info))
- ;; Create node info, to insert it before section formatting.
- (node (format "@node %s\n"
- (org-e-texinfo--sanitize-menu
- (replace-regexp-in-string "%" "%%" text))))
- ;; 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-e-texinfo--sanitize-headline
- (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 (replace-regexp-in-string
- "%" "%%" listing)
- 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"))))))
- (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 (org-e-texinfo--sanitize-content
- (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
- (org-e-texinfo--sanitize-content
- (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)
- (org-e-texinfo--build-menu parse top info '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."
- ;; 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 with @ { and } protected.
- (org-e-texinfo--sanitize-content 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)))
-
-
-;;; 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 \"makeinfo\" 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-min))
- ;; Find final "makeinfo" run.
- (when 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]")))
- (when (save-excursion
- (re-search-forward "misplaced " nil t))
- (setq errors (concat errors " [syntax error]")))
- (and (org-string-nw-p errors) (org-trim errors)))))))
-
-(provide 'org-e-texinfo)
-;;; org-e-texinfo.el ends here