diff options
author | mattkae <mattkae@protonmail.com> | 2022-06-07 08:23:47 -0400 |
---|---|---|
committer | mattkae <mattkae@protonmail.com> | 2022-06-07 08:23:47 -0400 |
commit | bd18a38c2898548a3664a9ddab9f79c84f2caf4a (patch) | |
tree | 95b9933376770381bd8859782ae763be81c2d72b /elpa/org-9.5.2/ox-latex.el | |
parent | b07628dddf418d4f47b858e6c35fd3520fbaeed2 (diff) | |
parent | ef160dea332af4b4fe5e2717b962936c67e5fe9e (diff) |
Merge conflict
Diffstat (limited to 'elpa/org-9.5.2/ox-latex.el')
-rw-r--r-- | elpa/org-9.5.2/ox-latex.el | 3828 |
1 files changed, 0 insertions, 3828 deletions
diff --git a/elpa/org-9.5.2/ox-latex.el b/elpa/org-9.5.2/ox-latex.el deleted file mode 100644 index c45dc98..0000000 --- a/elpa/org-9.5.2/ox-latex.el +++ /dev/null @@ -1,3828 +0,0 @@ -;;; ox-latex.el --- LaTeX Back-End for Org Export Engine -*- lexical-binding: t; -*- - -;; Copyright (C) 2011-2021 Free Software Foundation, Inc. - -;; Author: Nicolas Goaziou <n.goaziou at gmail dot com> -;; Keywords: outlines, hypermedia, calendar, wp - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; See Org manual for details. - -;;; Code: - -(require 'cl-lib) -(require 'ox) -(require 'ox-publish) - -;;; Function Declarations - -(defvar org-latex-default-packages-alist) -(defvar org-latex-packages-alist) -(defvar orgtbl-exp-regexp) - - - -;;; Define Back-End - -(org-export-define-backend 'latex - '((bold . org-latex-bold) - (center-block . org-latex-center-block) - (clock . org-latex-clock) - (code . org-latex-code) - (drawer . org-latex-drawer) - (dynamic-block . org-latex-dynamic-block) - (entity . org-latex-entity) - (example-block . org-latex-example-block) - (export-block . org-latex-export-block) - (export-snippet . org-latex-export-snippet) - (fixed-width . org-latex-fixed-width) - (footnote-definition . org-latex-footnote-definition) - (footnote-reference . org-latex-footnote-reference) - (headline . org-latex-headline) - (horizontal-rule . org-latex-horizontal-rule) - (inline-src-block . org-latex-inline-src-block) - (inlinetask . org-latex-inlinetask) - (italic . org-latex-italic) - (item . org-latex-item) - (keyword . org-latex-keyword) - (latex-environment . org-latex-latex-environment) - (latex-fragment . org-latex-latex-fragment) - (line-break . org-latex-line-break) - (link . org-latex-link) - (node-property . org-latex-node-property) - (paragraph . org-latex-paragraph) - (plain-list . org-latex-plain-list) - (plain-text . org-latex-plain-text) - (planning . org-latex-planning) - (property-drawer . org-latex-property-drawer) - (quote-block . org-latex-quote-block) - (radio-target . org-latex-radio-target) - (section . org-latex-section) - (special-block . org-latex-special-block) - (src-block . org-latex-src-block) - (statistics-cookie . org-latex-statistics-cookie) - (strike-through . org-latex-strike-through) - (subscript . org-latex-subscript) - (superscript . org-latex-superscript) - (table . org-latex-table) - (table-cell . org-latex-table-cell) - (table-row . org-latex-table-row) - (target . org-latex-target) - (template . org-latex-template) - (timestamp . org-latex-timestamp) - (underline . org-latex-underline) - (verbatim . org-latex-verbatim) - (verse-block . org-latex-verse-block) - ;; Pseudo objects and elements. - (latex-math-block . org-latex-math-block) - (latex-matrices . org-latex-matrices)) - :menu-entry - '(?l "Export to LaTeX" - ((?L "As LaTeX buffer" org-latex-export-as-latex) - (?l "As LaTeX file" org-latex-export-to-latex) - (?p "As PDF file" org-latex-export-to-pdf) - (?o "As PDF file and open" - (lambda (a s v b) - (if a (org-latex-export-to-pdf t s v b) - (org-open-file (org-latex-export-to-pdf nil s v b))))))) - :filters-alist '((:filter-options . org-latex-math-block-options-filter) - (:filter-paragraph . org-latex-clean-invalid-line-breaks) - (:filter-parse-tree org-latex-math-block-tree-filter - org-latex-matrices-tree-filter - org-latex-image-link-filter) - (:filter-verse-block . org-latex-clean-invalid-line-breaks)) - :options-alist - '((:latex-class "LATEX_CLASS" nil org-latex-default-class t) - (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t) - (:latex-header "LATEX_HEADER" nil nil newline) - (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline) - (:description "DESCRIPTION" nil nil parse) - (:keywords "KEYWORDS" nil nil parse) - (:subtitle "SUBTITLE" nil nil parse) - ;; Other variables. - (:latex-active-timestamp-format nil nil org-latex-active-timestamp-format) - (:latex-caption-above nil nil org-latex-caption-above) - (:latex-classes nil nil org-latex-classes) - (:latex-default-figure-position nil nil org-latex-default-figure-position) - (:latex-default-table-environment nil nil org-latex-default-table-environment) - (:latex-default-quote-environment nil nil org-latex-default-quote-environment) - (:latex-default-table-mode nil nil org-latex-default-table-mode) - (:latex-diary-timestamp-format nil nil org-latex-diary-timestamp-format) - (:latex-footnote-defined-format nil nil org-latex-footnote-defined-format) - (:latex-footnote-separator nil nil org-latex-footnote-separator) - (:latex-format-drawer-function nil nil org-latex-format-drawer-function) - (:latex-format-headline-function nil nil org-latex-format-headline-function) - (:latex-format-inlinetask-function nil nil org-latex-format-inlinetask-function) - (:latex-hyperref-template nil nil org-latex-hyperref-template t) - (:latex-image-default-scale nil nil org-latex-image-default-scale) - (:latex-image-default-height nil nil org-latex-image-default-height) - (:latex-image-default-option nil nil org-latex-image-default-option) - (:latex-image-default-width nil nil org-latex-image-default-width) - (:latex-images-centered nil nil org-latex-images-centered) - (:latex-inactive-timestamp-format nil nil org-latex-inactive-timestamp-format) - (:latex-inline-image-rules nil nil org-latex-inline-image-rules) - (:latex-link-with-unknown-path-format nil nil org-latex-link-with-unknown-path-format) - (:latex-listings nil nil org-latex-listings) - (:latex-listings-langs nil nil org-latex-listings-langs) - (:latex-listings-options nil nil org-latex-listings-options) - (:latex-minted-langs nil nil org-latex-minted-langs) - (:latex-minted-options nil nil org-latex-minted-options) - (:latex-prefer-user-labels nil nil org-latex-prefer-user-labels) - (:latex-subtitle-format nil nil org-latex-subtitle-format) - (:latex-subtitle-separate nil nil org-latex-subtitle-separate) - (:latex-table-scientific-notation nil nil org-latex-table-scientific-notation) - (:latex-tables-booktabs nil nil org-latex-tables-booktabs) - (:latex-tables-centered nil nil org-latex-tables-centered) - (:latex-text-markup-alist nil nil org-latex-text-markup-alist) - (:latex-title-command nil nil org-latex-title-command) - (:latex-toc-command nil nil org-latex-toc-command) - (:latex-compiler "LATEX_COMPILER" nil org-latex-compiler) - ;; Redefine regular options. - (:date "DATE" nil "\\today" parse))) - - - -;;; Internal Variables - -(defconst org-latex-babel-language-alist - '(("af" . "afrikaans") - ("bg" . "bulgarian") - ("ca" . "catalan") - ("cs" . "czech") - ("cy" . "welsh") - ("da" . "danish") - ("de" . "germanb") - ("de-at" . "naustrian") - ("de-de" . "ngerman") - ("el" . "greek") - ("en" . "english") - ("en-au" . "australian") - ("en-ca" . "canadian") - ("en-gb" . "british") - ("en-ie" . "irish") - ("en-nz" . "newzealand") - ("en-us" . "american") - ("es" . "spanish") - ("et" . "estonian") - ("eu" . "basque") - ("fi" . "finnish") - ("fr" . "french") - ("fr-ca" . "canadien") - ("gl" . "galician") - ("hr" . "croatian") - ("hu" . "hungarian") - ("id" . "indonesian") - ("is" . "icelandic") - ("it" . "italian") - ("la" . "latin") - ("ms" . "malay") - ("nl" . "dutch") - ("nb" . "norsk") - ("nn" . "nynorsk") - ("no" . "norsk") - ("pl" . "polish") - ("pt" . "portuguese") - ("pt-br" . "brazilian") - ("ro" . "romanian") - ("ru" . "russian") - ("sa" . "sanskrit") - ("sb" . "uppersorbian") - ("sk" . "slovak") - ("sl" . "slovene") - ("sq" . "albanian") - ("sr" . "serbian") - ("sv" . "swedish") - ("ta" . "tamil") - ("tr" . "turkish") - ("uk" . "ukrainian")) - "Alist between language code and corresponding Babel option.") - -(defconst org-latex-polyglossia-language-alist - '(("am" "amharic") - ("ar" "arabic") - ("ast" "asturian") - ("bg" "bulgarian") - ("bn" "bengali") - ("bo" "tibetan") - ("br" "breton") - ("ca" "catalan") - ("cop" "coptic") - ("cs" "czech") - ("cy" "welsh") - ("da" "danish") - ("de" "german" "german") - ("de-at" "german" "austrian") - ("de-de" "german" "german") - ("dsb" "lsorbian") - ("dv" "divehi") - ("el" "greek") - ("en" "english" "usmax") - ("en-au" "english" "australian") - ("en-gb" "english" "uk") - ("en-nz" "english" "newzealand") - ("en-us" "english" "usmax") - ("eo" "esperanto") - ("es" "spanish") - ("et" "estonian") - ("eu" "basque") - ("fa" "farsi") - ("fi" "finnish") - ("fr" "french") - ("fu" "friulan") - ("ga" "irish") - ("gd" "scottish") - ("gl" "galician") - ("he" "hebrew") - ("hi" "hindi") - ("hr" "croatian") - ("hsb" "usorbian") - ("hu" "magyar") - ("hy" "armenian") - ("ia" "interlingua") - ("id" "bahasai") - ("is" "icelandic") - ("it" "italian") - ("kn" "kannada") - ("la" "latin" "modern") - ("la-classic" "latin" "classic") - ("la-medieval" "latin" "medieval") - ("la-modern" "latin" "modern") - ("lo" "lao") - ("lt" "lithuanian") - ("lv" "latvian") - ("ml" "malayalam") - ("mr" "maranthi") - ("nb" "norsk") - ("nko" "nko") - ("nl" "dutch") - ("nn" "nynorsk") - ("no" "norsk") - ("oc" "occitan") - ("pl" "polish") - ("pms" "piedmontese") - ("pt" "portuges") - ("pt-br" "brazilian") - ("rm" "romansh") - ("ro" "romanian") - ("ru" "russian") - ("sa" "sanskrit") - ("se" "samin") - ("sk" "slovak") - ("sl" "slovenian") - ("sq" "albanian") - ("sr" "serbian") - ("sv" "swedish") - ("syr" "syriac") - ("ta" "tamil") - ("te" "telugu") - ("th" "thai") - ("tk" "turkmen") - ("tr" "turkish") - ("uk" "ukrainian") - ("ur" "urdu") - ("vi" "vietnamese")) - "Alist between language code and corresponding Polyglossia option.") - -(defconst org-latex-table-matrix-macros '(("bordermatrix" . "\\cr") - ("qbordermatrix" . "\\cr") - ("kbordermatrix" . "\\\\")) - "Alist between matrix macros and their row ending.") - -(defconst org-latex-math-environments-re - (format - "\\`[ \t]*\\\\begin{%s\\*?}" - (regexp-opt - '("equation" "eqnarray" "math" "displaymath" - "align" "gather" "multline" "flalign" "alignat" - "xalignat" "xxalignat" - "subequations" - ;; breqn - "dmath" "dseries" "dgroup" "darray" - ;; empheq - "empheq"))) - "Regexp of LaTeX math environments.") - - -;;; User Configurable Variables - -(defgroup org-export-latex nil - "Options for exporting Org mode files to LaTeX." - :tag "Org Export LaTeX" - :group 'org-export) - -;;;; Generic - -(defcustom org-latex-caption-above '(table) - "When non-nil, place caption string at the beginning of elements. -Otherwise, place it near the end. When value is a list of -symbols, put caption above selected elements only. Allowed -symbols are: `image', `table', `src-block' and `special-block'." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type '(choice - (const :tag "For all elements" t) - (const :tag "For no element" nil) - (set :tag "For the following elements only" :greedy t - (const :tag "Images" image) - (const :tag "Tables" table) - (const :tag "Source code" src-block) - (const :tag "Special blocks" special-block)))) - -(defcustom org-latex-prefer-user-labels nil - "Use user-provided labels instead of internal ones when non-nil. - -When this variable is non-nil, Org will use the value of -CUSTOM_ID property, NAME keyword or Org target as the key for the -\\label commands generated. - -By default, Org generates its own internal labels during LaTeX -export. This process ensures that the \\label keys are unique -and valid, but it means the keys are not available in advance of -the export process. - -Setting this variable gives you control over how Org generates -labels during LaTeX export, so that you may know their keys in -advance. One reason to do this is that it allows you to refer to -various elements using a single label both in Org's link syntax -and in embedded LaTeX code. - -For example, when this variable is non-nil, a headline like this: - - ** Some section - :PROPERTIES: - :CUSTOM_ID: sec:foo - :END: - This is section [[#sec:foo]]. - #+BEGIN_EXPORT latex - And this is still section \\ref{sec:foo}. - #+END_EXPORT - -will be exported to LaTeX as: - - \\subsection{Some section} - \\label{sec:foo} - This is section \\ref{sec:foo}. - And this is still section \\ref{sec:foo}. - -A non-default value of `org-latex-reference-command' will change the -command (\\ref by default) used to create label references. - -Note, however, that setting this variable introduces a limitation -on the possible values for CUSTOM_ID and NAME. When this -variable is non-nil, Org passes their value to \\label unchanged. -You are responsible for ensuring that the value is a valid LaTeX -\\label key, and that no other \\label commands with the same key -appear elsewhere in your document. (Keys may contain letters, -numbers, and the following punctuation: `_' `.' `-' `:'.) There -are no such limitations on CUSTOM_ID and NAME when this variable -is nil. - -For headlines that do not define the CUSTOM_ID property or -elements without a NAME, Org will continue to use its default -labeling scheme to generate labels and resolve links into proper -references." - :group 'org-export-latex - :type 'boolean - :version "26.1" - :package-version '(Org . "8.3")) - -(defcustom org-latex-reference-command "\\ref{%s}" - "Format string that takes a reference to produce a LaTeX reference command. - -The reference is a label such as sec:intro. A format string of \"\\ref{%s}\" -produces numbered references and will always work. It may be desirable to make -use of a package such as hyperref or cleveref and then change the format string -to \"\\autoref{%s}\" or \"\\cref{%s}\" for example." - :group 'org-export-latex - :type 'string - :package-version '(Org . "9.5") - :safe #'stringp) - -;;;; Preamble - -(defcustom org-latex-default-class "article" - "The default LaTeX class." - :group 'org-export-latex - :type '(string :tag "LaTeX class")) - -(defcustom org-latex-classes - '(("article" - "\\documentclass[11pt]{article}" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}") - ("\\paragraph{%s}" . "\\paragraph*{%s}") - ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) - ("report" - "\\documentclass[11pt]{report}" - ("\\part{%s}" . "\\part*{%s}") - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("book" - "\\documentclass[11pt]{book}" - ("\\part{%s}" . "\\part*{%s}") - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))) - "Alist of LaTeX classes and associated header and structure. -If #+LATEX_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 header string ------------------ - -The HEADER-STRING is the header that will be inserted into the -LaTeX file. It should contain the \\documentclass macro, and -anything else that is needed for this setup. To this header, the -following commands will be added: - -- Calls to \\usepackage for all packages mentioned in the - variables `org-latex-default-packages-alist' and - `org-latex-packages-alist'. Thus, your header definitions - should avoid to also request these packages. - -- Lines specified via \"#+LATEX_HEADER:\" and - \"#+LATEX_HEADER_EXTRA:\" keywords. - -If you need more control about the sequence in which the header -is built up, or if you want to exclude one of these building -blocks for a particular class, you can use the following -macro-like placeholders. - - [DEFAULT-PACKAGES] \\usepackage statements for default packages - [NO-DEFAULT-PACKAGES] do not include any of the default packages - [PACKAGES] \\usepackage statements for packages - [NO-PACKAGES] do not include the packages - [EXTRA] the stuff from #+LATEX_HEADER(_EXTRA) - [NO-EXTRA] do not include #+LATEX_HEADER(_EXTRA) stuff - -So a header like - - \\documentclass{article} - [NO-DEFAULT-PACKAGES] - [EXTRA] - \\providecommand{\\alert}[1]{\\textbf{#1}} - [PACKAGES] - -will omit the default packages, and will include the -#+LATEX_HEADER and #+LATEX_HEADER_EXTRA lines, then have a call -to \\providecommand, and then place \\usepackage commands based -on the content of `org-latex-packages-alist'. - -If your header, `org-latex-default-packages-alist' or -`org-latex-packages-alist' inserts \"\\usepackage[AUTO]{inputenc}\", -AUTO will automatically be replaced with a coding system derived -from `buffer-file-coding-system'. See also the variable -`org-latex-inputenc-alist' for a way to influence this mechanism. - -Likewise, if your header contains \"\\usepackage[AUTO]{babel}\" -or \"\\usepackage[AUTO]{polyglossia}\", AUTO will be replaced -with the language related to the language code specified by -`org-export-default-language'. Note that constructions such as -\"\\usepackage[french,AUTO,english]{babel}\" are permitted. For -Polyglossia the language will be set via the macros -\"\\setmainlanguage\" and \"\\setotherlanguage\". See also -`org-latex-guess-babel-language' and -`org-latex-guess-polyglossia-language'. - -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 LaTeX environment -that should represent the document section. The opening clause -should have a %s to represent the section title. - -Instead of a list of sectioning commands, you can also specify -a function name. That function will be called with two -parameters, the (reduced) level of the headline, and a predicate -non-nil when the headline should be numbered. It must return -a format string in which the section title will be added." - :group 'org-export-latex - :type '(repeat - (list (string :tag "LaTeX class") - (string :tag "LaTeX 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")))))) - -(defcustom org-latex-inputenc-alist nil - "Alist of inputenc coding system names, and what should really be used. -For example, adding an entry - - (\"utf8\" . \"utf8x\") - -will cause \\usepackage[utf8x]{inputenc} to be used for buffers that -are written as utf8 files." - :group 'org-export-latex - :type '(repeat - (cons - (string :tag "Derived from buffer") - (string :tag "Use this instead")))) - -(defcustom org-latex-title-command "\\maketitle" - "The command used to insert the title just after \\begin{document}. - -This format string may contain these elements: - - %a for AUTHOR keyword - %t for TITLE keyword - %s for SUBTITLE keyword - %k for KEYWORDS line - %d for DESCRIPTION line - %c for CREATOR line - %l for Language keyword - %L for capitalized language keyword - %D for DATE keyword - -If you need to use a \"%\" character, you need to escape it -like that: \"%%\". - -Setting :latex-title-command in publishing projects will take -precedence over this variable." - :group 'org-export-latex - :type '(string :tag "Format string")) - -(defcustom org-latex-subtitle-format "\\\\\\medskip\n\\large %s" - "Format string used for transcoded subtitle. -The format string should have at most one \"%s\"-expression, -which is replaced with the subtitle." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type '(string :tag "Format string")) - -(defcustom org-latex-subtitle-separate nil - "Non-nil means the subtitle is not typeset as part of title." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type 'boolean) - -(defcustom org-latex-toc-command "\\tableofcontents\n\n" - "LaTeX command to set the table of contents, list of figures, etc. -This command only applies to the table of contents generated with -the toc:nil option, not to those generated with #+TOC keyword." - :group 'org-export-latex - :type 'string) - -(defcustom org-latex-hyperref-template - "\\hypersetup{\n pdfauthor={%a},\n pdftitle={%t},\n pdfkeywords={%k}, - pdfsubject={%d},\n pdfcreator={%c}, \n pdflang={%L}}\n" - "Template for hyperref package options. - -This format string may contain these elements: - - %a for AUTHOR keyword - %t for TITLE keyword - %s for SUBTITLE keyword - %k for KEYWORDS line - %d for DESCRIPTION line - %c for CREATOR line - %l for Language keyword - %L for capitalized language keyword - %D for DATE keyword - -If you need to use a \"%\" character, you need to escape it -like that: \"%%\". - -As a special case, a nil value prevents template from being -inserted. - -Setting :latex-hyperref-template in publishing projects will take -precedence over this variable." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type '(choice (const :tag "No template" nil) - (string :tag "Format string"))) - -;;;; Headline - -(defcustom org-latex-format-headline-function - 'org-latex-format-headline-default-function - "Function for formatting the headline's text. - -This function will be called with six 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 (list of strings or nil) -INFO the export options (plist) - -The function result will be used in the section format string." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type 'function) - - -;;;; Footnotes - -(defcustom org-latex-footnote-separator "\\textsuperscript{,}\\," - "Text used to separate footnotes." - :group 'org-export-latex - :type 'string) - -(defcustom org-latex-footnote-defined-format "\\textsuperscript{\\ref{%s}}" - "Format string used to format reference to footnote already defined. -%s will be replaced by the label of the referred footnote." - :group 'org-export-latex - :type '(choice - (const :tag "Use plain superscript (default)" "\\textsuperscript{\\ref{%s}}") - (const :tag "Use Memoir/KOMA-Script footref" "\\footref{%s}") - (string :tag "Other format string")) - :version "26.1" - :package-version '(Org . "9.0")) - -;;;; Timestamps - -(defcustom org-latex-active-timestamp-format "\\textit{%s}" - "A printf format string to be applied to active timestamps." - :group 'org-export-latex - :type 'string) - -(defcustom org-latex-inactive-timestamp-format "\\textit{%s}" - "A printf format string to be applied to inactive timestamps." - :group 'org-export-latex - :type 'string) - -(defcustom org-latex-diary-timestamp-format "\\textit{%s}" - "A printf format string to be applied to diary timestamps." - :group 'org-export-latex - :type 'string) - - -;;;; Links - -(defcustom org-latex-images-centered t - "When non-nil, images are centered." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "9.0") - :type 'boolean - :safe #'booleanp) - -(defcustom org-latex-image-default-option "" - "Default option for images." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type 'string) - -(defcustom org-latex-image-default-width ".9\\linewidth" - "Default width for images. -This value will not be used if a height is provided." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type 'string) - -(defcustom org-latex-image-default-scale "" - "Default scale for images. -This value will not be used if a width or a scale is provided, -or if the image is wrapped within a \"wrapfigure\" environment. -Scale overrides width and height." - :group 'org-export-latex - :package-version '(Org . "9.3") - :type 'string - :safe #'stringp) - -(defcustom org-latex-image-default-height "" - "Default height for images. -This value will not be used if a width is provided, or if the -image is wrapped within a \"figure\" or \"wrapfigure\" -environment." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type 'string) - -(defcustom org-latex-default-figure-position "htbp" - "Default position for LaTeX figures." - :group 'org-export-latex - :type 'string - :version "26.1" - :package-version '(Org . "9.0") - :safe #'stringp) - -(defcustom org-latex-inline-image-rules - `(("file" . ,(rx "." - (or "pdf" "jpeg" "jpg" "png" "ps" "eps" "tikz" "pgf" "svg") - eos))) - "Rules characterizing image files that can be inlined into LaTeX. - -A rule consists in an association whose key is the type of link -to consider, and value is a regexp that will be matched against -link's path. - -Note that, by default, the image extension *actually* allowed -depend on the way the LaTeX file is processed. When used with -pdflatex, pdf, jpg and png images are OK. When processing -through dvi to Postscript, only ps and eps are allowed. The -default we use here encompasses both." - :group 'org-export-latex - :package-version '(Org . "9.4") - :type '(alist :key-type (string :tag "Type") - :value-type (regexp :tag "Path"))) - -(defcustom org-latex-link-with-unknown-path-format "\\texttt{%s}" - "Format string for links with unknown path type." - :group 'org-export-latex - :type 'string) - - -;;;; Tables - -(defcustom org-latex-default-table-environment "tabular" - "Default environment used to build tables." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type 'string) - -(defcustom org-latex-default-quote-environment "quote" - "Default environment used to `quote' blocks." - :group 'org-export-latex - :package-version '(Org . "9.5") - :type 'string - :safe #'stringp) - -(defcustom org-latex-default-table-mode 'table - "Default mode for tables. - -Value can be a symbol among: - - `table' Regular LaTeX table. - - `math' In this mode, every cell is considered as being in math - mode and the complete table will be wrapped within a math - environment. It is particularly useful to write matrices. - - `inline-math' This mode is almost the same as `math', but the - math environment will be inlined. - - `verbatim' The table is exported as it appears in the Org - buffer, within a verbatim environment. - -This value can be overridden locally with, i.e. \":mode math\" in -LaTeX attributes. - -When modifying this variable, it may be useful to change -`org-latex-default-table-environment' accordingly." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type '(choice (const :tag "Table" table) - (const :tag "Matrix" math) - (const :tag "Inline matrix" inline-math) - (const :tag "Verbatim" verbatim)) - :safe (lambda (s) (memq s '(table math inline-math verbatim)))) - -(defcustom org-latex-tables-centered t - "When non-nil, tables are exported in a center environment." - :group 'org-export-latex - :type 'boolean - :safe #'booleanp) - -(defcustom org-latex-tables-booktabs nil - "When non-nil, display tables in a formal \"booktabs\" style. -This option assumes that the \"booktabs\" package is properly -loaded in the header of the document. This value can be ignored -locally with \":booktabs t\" and \":booktabs nil\" LaTeX -attributes." - :group 'org-export-latex - :version "24.4" - :package-version '(Org . "8.0") - :type 'boolean - :safe #'booleanp) - -(defcustom org-latex-table-scientific-notation nil - "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-latex - :version "24.4" - :package-version '(Org . "8.0") - :type '(choice - (string :tag "Format string") - (const :tag "No formatting" nil))) - -;;;; Text markup - -(defcustom org-latex-text-markup-alist '((bold . "\\textbf{%s}") - (code . protectedtexttt) - (italic . "\\emph{%s}") - (strike-through . "\\sout{%s}") - (underline . "\\uline{%s}") - (verbatim . protectedtexttt)) - "Alist of LaTeX 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-latex - :version "26.1" - :package-version '(Org . "8.3") - :type 'alist - :options '(bold code italic strike-through underline verbatim)) - - -;;;; Drawers - -(defcustom org-latex-format-drawer-function (lambda (_ contents) contents) - "Function called to format a drawer in LaTeX 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. - -The default function simply returns the value of CONTENTS." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type 'function) - - -;;;; Inlinetasks - -(defcustom org-latex-format-inlinetask-function - 'org-latex-format-inlinetask-default-function - "Function called to format an inlinetask in LaTeX code. - -The function must accept seven parameters: - TODO the todo keyword (string or nil) - TODO-TYPE the todo type (symbol: `todo', `done', nil) - PRIORITY the inlinetask priority (integer or nil) - NAME the inlinetask name (string) - TAGS the inlinetask tags (list of strings or nil) - CONTENTS the contents of the inlinetask (string or nil) - INFO the export options (plist) - -The function should return the string to be exported." - :group 'org-export-latex - :type 'function - :version "26.1" - :package-version '(Org . "8.3")) - - -;; Src blocks - -(defcustom org-latex-listings nil - "Non-nil means export source code using the listings package. - -This package will fontify source code, possibly even with color. -If you want to use this, you also need to make LaTeX use the -listings package, and if you want to have color, the color -package. Just add these to `org-latex-packages-alist', for -example using customize, or with something like: - - (require \\='ox-latex) - (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\")) - (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\")) - -Alternatively, - - (setq org-latex-listings \\='minted) - -causes source code to be exported using the minted package as -opposed to listings. If you want to use minted, you need to add -the minted package to `org-latex-packages-alist', for example -using customize, or with - - (require \\='ox-latex) - (add-to-list \\='org-latex-packages-alist \\='(\"newfloat\" \"minted\")) - -In addition, it is necessary to install pygments -\(URL `https://pygments.org>'), and to configure the variable -`org-latex-pdf-process' so that the -shell-escape option is -passed to pdflatex. - -The minted choice has possible repercussions on the preview of -latex fragments (see `org-preview-latex-fragment'). If you run -into previewing problems, please consult -URL `https://orgmode.org/worg/org-tutorials/org-latex-preview.html'." - :group 'org-export-latex - :type '(choice - (const :tag "Use listings" t) - (const :tag "Use minted" minted) - (const :tag "Export verbatim" nil)) - :safe (lambda (s) (memq s '(t nil minted)))) - -(defcustom org-latex-listings-langs - '((emacs-lisp "Lisp") (lisp "Lisp") (clojure "Lisp") - (c "C") (cc "C++") - (fortran "fortran") - (perl "Perl") (cperl "Perl") (python "Python") (ruby "Ruby") - (html "HTML") (xml "XML") - (tex "TeX") (latex "[LaTeX]TeX") - (shell-script "bash") - (gnuplot "Gnuplot") - (ocaml "[Objective]Caml") (caml "Caml") - (sql "SQL") (sqlite "sql") - (makefile "make") - (R "r")) - "Alist mapping languages to their listing language counterpart. -The key is a symbol, the major mode symbol without the \"-mode\". -The value is the string that should be inserted as the language -parameter for the listings package. If the mode name and the -listings name are the same, the language does not need an entry -in this list - but it does not hurt if it is present." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type '(repeat - (list - (symbol :tag "Major mode ") - (string :tag "Listings language")))) - -(defcustom org-latex-listings-options nil - "Association list of options for the latex listings package. - -These options are supplied as a comma-separated list to the -\\lstset command. Each element of the association list should be -a list containing two strings: the name of the option, and the -value. For example, - - (setq org-latex-listings-options - \\='((\"basicstyle\" \"\\\\small\") - (\"keywordstyle\" \"\\\\color{black}\\\\bfseries\\\\underbar\"))) - -will typeset the code in a small size font with underlined, bold -black keywords. - -Note that the same options will be applied to blocks of all -languages. If you need block-specific options, you may use the -following syntax: - - #+ATTR_LATEX: :options key1=value1,key2=value2 - #+BEGIN_SRC <LANG> - ... - #+END_SRC" - :group 'org-export-latex - :type '(repeat - (list - (string :tag "Listings option name ") - (string :tag "Listings option value")))) - -(defcustom org-latex-minted-langs - '((emacs-lisp "common-lisp") - (cc "c++") - (cperl "perl") - (shell-script "bash") - (caml "ocaml")) - "Alist mapping languages to their minted language counterpart. -The key is a symbol, the major mode symbol without the \"-mode\". -The value is the string that should be inserted as the language -parameter for the minted package. If the mode name and the -listings name are the same, the language does not need an entry -in this list - but it does not hurt if it is present. - -Note that minted uses all lower case for language identifiers, -and that the full list of language identifiers can be obtained -with: - - pygmentize -L lexers" - :group 'org-export-latex - :type '(repeat - (list - (symbol :tag "Major mode ") - (string :tag "Minted language")))) - -(defcustom org-latex-minted-options nil - "Association list of options for the latex minted package. - -These options are supplied within square brackets in -\\begin{minted} environments. Each element of the alist should -be a list containing two strings: the name of the option, and the -value. For example, - - (setq org-latex-minted-options - \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\"))) - -will result in source blocks being exported with - -\\begin{minted}[bgcolor=bg,frame=lines]{<LANG>} - -as the start of the minted environment. Note that the same -options will be applied to blocks of all languages. If you need -block-specific options, you may use the following syntax: - - #+ATTR_LATEX: :options key1=value1,key2=value2 - #+BEGIN_SRC <LANG> - ... - #+END_SRC" - :group 'org-export-latex - :type '(repeat - (list - (string :tag "Minted option name ") - (string :tag "Minted option value")))) - -(defcustom org-latex-custom-lang-environments nil - "Alist mapping languages to language-specific LaTeX environments. - -It is used during export of source blocks by the listings and -minted LaTeX packages. The environment may be a simple string, -composed of only letters and numbers. In this case, the string -is directly the name of the LaTeX environment to use. The -environment may also be a format string. In this case the format -string will be directly exported. This format string may contain -these elements: - - %s for the formatted source - %c for the caption - %f for the float attribute - %l for an appropriate label - %o for the LaTeX attributes - -For example, - - (setq org-latex-custom-lang-environments - \\='((python \"pythoncode\") - (ocaml \"\\\\begin{listing} -\\\\begin{minted}[%o]{ocaml} -%s\\\\end{minted} -\\\\caption{%c} -\\\\label{%l}\"))) - -would have the effect that if Org encounters a Python source block -during LaTeX export it will produce - - \\begin{pythoncode} - <source block body> - \\end{pythoncode} - -and if Org encounters an Ocaml source block during LaTeX export it -will produce - - \\begin{listing} - \\begin{minted}[<attr_latex options>]{ocaml} - <source block body> - \\end{minted} - \\caption{<caption>} - \\label{<label>} - \\end{listing}" - :group 'org-export-latex - :type '(repeat - (list - (symbol :tag "Language name ") - (string :tag "Environment name or format string"))) - :version "26.1" - :package-version '(Org . "9.0")) - - -;;;; Compilation - -(defcustom org-latex-compiler-file-string "%% Intended LaTeX compiler: %s\n" - "LaTeX compiler format-string. -See also `org-latex-compiler'." - :group 'org-export-latex - :type '(choice - (const :tag "Comment" "%% Intended LaTeX compiler: %s\n") - (const :tag "latex-mode file variable" "%% -*- latex-run-command: %s -*-\n") - (const :tag "AUCTeX file variable" "%% -*- LaTeX-command: %s -*-\n") - (string :tag "custom format" "%% %s")) - :version "26.1" - :package-version '(Org . "9.0")) - -(defcustom org-latex-compiler "pdflatex" - "LaTeX compiler to use. - -Must be an element in `org-latex-compilers' or the empty quote. -Can also be set in buffers via #+LATEX_COMPILER. See also -`org-latex-compiler-file-string'." - :group 'org-export-latex - :type '(choice - (const :tag "pdfLaTeX" "pdflatex") - (const :tag "XeLaTeX" "xelatex") - (const :tag "LuaLaTeX" "lualatex") - (const :tag "Unset" "")) - :version "26.1" - :package-version '(Org . "9.0")) - -(defconst org-latex-compilers '("pdflatex" "xelatex" "lualatex") - "Known LaTeX compilers. -See also `org-latex-compiler'.") - -(defcustom org-latex-bib-compiler "bibtex" - "Command to process a LaTeX file's bibliography. - -The shorthand %bib in `org-latex-pdf-process' is replaced with -this value. - -A better approach is to use a compiler suit such as `latexmk'." - :group 'org-export-latex - :type '(choice (const :tag "BibTeX" "bibtex") - (const :tag "Biber" "biber") - (string :tag "Other process")) - :version "26.1" - :package-version '(Org . "9.0")) - -(defcustom org-latex-pdf-process - (if (executable-find "latexmk") - '("latexmk -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f") - '("%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f")) - "Commands to process a LaTeX file to a PDF file. - -This is a list of strings, each of them will be given to the -shell as a command. %f in the command will be replaced by the -relative file name, %F by the absolute file name, %b by the file -base name (i.e. without directory and extension parts), %o by the -base directory of the file, %O by the absolute file name of the -output file, %latex is the LaTeX compiler (see -`org-latex-compiler'), and %bib is the BibTeX-like compiler (see -`org-latex-bib-compiler'). - -The reason why this is a list is that it usually takes several -runs of `pdflatex', maybe mixed with a call to `bibtex'. Org -does not have a clever mechanism to detect which of these -commands have to be run to get to a stable result, and it also -does not do any error checking. - -Consider a smart LaTeX compiler such as `texi2dvi' or `latexmk', -which calls the \"correct\" combinations of auxiliary programs. - -Alternatively, this may be a Lisp function that does the -processing, so you could use this to apply the machinery of -AUCTeX or the Emacs LaTeX mode. This function should accept the -file name as its single argument." - :group 'org-export-pdf - :type '(choice - (repeat :tag "Shell command sequence" - (string :tag "Shell command")) - (const :tag "2 runs of latex" - ("%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f")) - (const :tag "3 runs of latex" - ("%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f")) - (const :tag "latex,bibtex,latex,latex" - ("%latex -interaction nonstopmode -output-directory %o %f" - "%bib %b" - "%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f")) - (const :tag "texi2dvi" - ("cd %o; LATEX=\"%latex\" texi2dvi -p -b -V %b.tex")) - (const :tag "latexmk" - ("latexmk -f -pdf -%latex -interaction=nonstopmode -output-directory=%o %f")) - (function))) - -(defcustom org-latex-logfiles-extensions - '("aux" "bcf" "blg" "fdb_latexmk" "fls" "figlist" "idx" "log" "nav" "out" - "ptc" "run.xml" "snm" "toc" "vrb" "xdv") - "The list of file extensions to consider as LaTeX logfiles. -The logfiles will be removed if `org-latex-remove-logfiles' is -non-nil." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type '(repeat (string :tag "Extension"))) - -(defcustom org-latex-remove-logfiles t - "Non-nil means remove the logfiles produced by PDF production. -By default, logfiles are files with these extensions: .aux, .idx, -.log, .out, .toc, .nav, .snm and .vrb. To define the set of -logfiles to remove, set `org-latex-logfiles-extensions'." - :group 'org-export-latex - :type 'boolean) - -(defcustom org-latex-known-warnings - '(("Reference.*?undefined" . "[undefined reference]") - ("Runaway argument" . "[runaway argument]") - ("Underfull \\hbox" . "[underfull hbox]") - ("Overfull \\hbox" . "[overfull hbox]") - ("Citation.*?undefined" . "[undefined citation]") - ("Undefined control sequence" . "[undefined control sequence]")) - "Alist of regular expressions and associated messages for the user. -The regular expressions are used to find possible warnings in the -log of a LaTeX-run. These warnings will be reported after -calling `org-latex-compile'." - :group 'org-export-latex - :version "26.1" - :package-version '(Org . "8.3") - :type '(repeat - (cons - (regexp :tag "Regexp") - (string :tag "Message")))) - - - -;;; Internal Functions - -(defun org-latex--caption-above-p (element info) - "Non-nil when caption is expected to be located above ELEMENT. -INFO is a plist holding contextual information." - (let ((above (plist-get info :latex-caption-above))) - (if (symbolp above) above - (let ((type (org-element-type element))) - (memq (if (eq type 'link) 'image type) above))))) - -(defun org-latex--label (datum info &optional force full) - "Return an appropriate label for DATUM. -DATUM is an element or a `target' type object. INFO is the -current export state, as a plist. - -Return nil if element DATUM has no NAME or VALUE affiliated -keyword or no CUSTOM_ID property, unless FORCE is non-nil. In -this case always return a unique label. - -Eventually, if FULL is non-nil, wrap label within \"\\label{}\"." - (let* ((type (org-element-type datum)) - (user-label - (org-element-property - (cl-case type - ((headline inlinetask) :CUSTOM_ID) - (target :value) - (otherwise :name)) - datum)) - (label - (and (or user-label force) - (if (and user-label (plist-get info :latex-prefer-user-labels)) - user-label - (concat (pcase type - (`headline "sec:") - (`table "tab:") - (`latex-environment - (and (string-match-p - org-latex-math-environments-re - (org-element-property :value datum)) - "eq:")) - (`latex-matrices "eq:") - (`paragraph - (and (org-element-property :caption datum) - "fig:")) - (_ nil)) - (org-export-get-reference datum info)))))) - (cond ((not full) label) - (label (format "\\label{%s}%s" - label - (if (eq type 'target) "" "\n"))) - (t "")))) - -(defun org-latex--caption/label-string (element info) - "Return caption and label LaTeX string for ELEMENT. - -INFO is a plist holding contextual information. If there's no -caption nor label, return the empty string. - -For non-floats, see `org-latex--wrap-label'." - (let* ((label (org-latex--label element info nil t)) - (main (org-export-get-caption element)) - (attr (org-export-read-attribute :attr_latex element)) - (type (org-element-type element)) - (nonfloat (or (and (plist-member attr :float) - (not (plist-get attr :float)) - main) - (and (eq type 'src-block) - (not (plist-get attr :float)) - (null (plist-get info :latex-listings))))) - (short (org-export-get-caption element t)) - (caption-from-attr-latex (plist-get attr :caption))) - (cond - ((org-string-nw-p caption-from-attr-latex) - (concat caption-from-attr-latex "\n")) - ((and (not main) (equal label "")) "") - ((not main) label) - ;; Option caption format with short name. - (t - (format (if nonfloat "\\captionof{%s}%s{%s%s}\n" - "\\caption%s%s{%s%s}\n") - (let ((type* (if (eq type 'latex-environment) - (org-latex--environment-type element) - type))) - (if nonfloat - (cl-case type* - (paragraph "figure") - (image "figure") - (special-block "figure") - (src-block (if (plist-get info :latex-listings) - "listing" - "figure")) - (t (symbol-name type*))) - "")) - (if short (format "[%s]" (org-export-data short info)) "") - (org-trim label) - (org-export-data main info)))))) - -(defun org-latex-guess-inputenc (header) - "Set the coding system in inputenc to what the buffer is. - -HEADER is the LaTeX header string. This function only applies -when specified inputenc option is \"AUTO\". - -Return the new header, as a string." - (let* ((cs (or (ignore-errors - (latexenc-coding-system-to-inputenc - (or org-export-coding-system buffer-file-coding-system))) - "utf8"))) - (if (not cs) header - ;; First translate if that is requested. - (setq cs (or (cdr (assoc cs org-latex-inputenc-alist)) cs)) - ;; Then find the \usepackage statement and replace the option. - (replace-regexp-in-string "\\\\usepackage\\[\\(AUTO\\)\\]{inputenc}" - cs header t nil 1)))) - -(defun org-latex-guess-babel-language (header info) - "Set Babel's language according to LANGUAGE keyword. - -HEADER is the LaTeX header string. INFO is the plist used as -a communication channel. - -Insertion of guessed language only happens when Babel package has -explicitly been loaded. Then it is added to the rest of -package's options. - -The argument to Babel may be \"AUTO\" which is then replaced with -the language of the document or `org-export-default-language' -unless language in question is already loaded. - -Return the new header." - (let ((language-code (plist-get info :language))) - ;; If no language is set or Babel package is not loaded, return - ;; HEADER as-is. - (if (or (not (stringp language-code)) - (not (string-match "\\\\usepackage\\[\\(.*\\)\\]{babel}" header))) - header - (let ((options (save-match-data - (org-split-string (match-string 1 header) ",[ \t]*"))) - (language (cdr (assoc-string language-code - org-latex-babel-language-alist t)))) - ;; If LANGUAGE is already loaded, return header without AUTO. - ;; Otherwise, replace AUTO with language or append language if - ;; AUTO is not present. - (replace-match - (mapconcat (lambda (option) (if (equal "AUTO" option) language option)) - (cond ((member language options) (delete "AUTO" options)) - ((member "AUTO" options) options) - (t (append options (list language)))) - ", ") - t nil header 1))))) - -(defun org-latex-guess-polyglossia-language (header info) - "Set the Polyglossia language according to the LANGUAGE keyword. - -HEADER is the LaTeX header string. INFO is the plist used as -a communication channel. - -Insertion of guessed language only happens when the Polyglossia -package has been explicitly loaded. - -The argument to Polyglossia may be \"AUTO\" which is then -replaced with the language of the document or -`org-export-default-language'. Note, the language is really set -using \setdefaultlanguage and not as an option to the package. - -Return the new header." - (let ((language (plist-get info :language))) - ;; If no language is set or Polyglossia is not loaded, return - ;; HEADER as-is. - (if (or (not (stringp language)) - (not (string-match - "\\\\usepackage\\(?:\\[\\([^]]+?\\)\\]\\){polyglossia}\n" - header))) - header - (let* ((options (org-string-nw-p (match-string 1 header))) - (languages (and options - ;; Reverse as the last loaded language is - ;; the main language. - (nreverse - (delete-dups - (save-match-data - (org-split-string - (replace-regexp-in-string - "AUTO" language options t) - ",[ \t]*")))))) - (main-language-set - (string-match-p "\\\\setmainlanguage{.*?}" header))) - (replace-match - (concat "\\usepackage{polyglossia}\n" - (mapconcat - (lambda (l) - (let ((l (or (assoc l org-latex-polyglossia-language-alist) - l))) - (format (if main-language-set "\\setotherlanguage%s{%s}\n" - (setq main-language-set t) - "\\setmainlanguage%s{%s}\n") - (if (and (consp l) (= (length l) 3)) - (format "[variant=%s]" (nth 2 l)) - "") - (nth 1 l)))) - languages - "")) - t t header 0))))) - -(defun org-latex--remove-packages (pkg-alist info) - "Remove packages based on the current LaTeX compiler. - -PKG-ALIST is a list of packages, as in `org-latex-packages-alist' -and `org-latex-default-packages-alist'. If the fourth argument -of a package is neither nil nor a member of the LaTeX compiler -associated to the document, the package is removed. - -Return new list of packages." - (let ((compiler (or (plist-get info :latex-compiler) ""))) - (if (not (member-ignore-case compiler org-latex-compilers)) pkg-alist - (cl-remove-if-not - (lambda (package) - (pcase package - (`(,_ ,_ ,_ nil) t) - (`(,_ ,_ ,_ ,compilers) (member-ignore-case compiler compilers)) - (_ t))) - pkg-alist)))) - -(defun org-latex--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<>()[]{}")) - (cl-loop for c across ll - when (not (string-match (regexp-quote (char-to-string c)) s)) - return (char-to-string c)))) - -(defun org-latex--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) - (pcase-let ((`(,keyword ,value) pair)) - (concat keyword - (and (> (length value) 0) - (concat "=" - (if (string-match-p (rx (any "[]")) value) - (format "{%s}" value) - value)))))) - options - ",")) - -(defun org-latex--wrap-label (element output info) - "Wrap label associated to ELEMENT around OUTPUT, if appropriate. -INFO is the current export state, as a plist. This function -should not be used for floats. See -`org-latex--caption/label-string'." - (if (not (and (org-string-nw-p output) (org-element-property :name element))) - output - (concat (format "\\phantomsection\n\\label{%s}\n" - (org-latex--label element info)) - output))) - -(defun org-latex--protect-text (text) - "Protect special characters in string TEXT and return it." - (replace-regexp-in-string "[\\{}$%&_#~^]" "\\\\\\&" text)) - -(defun org-latex--text-markup (text markup info) - "Format TEXT depending on MARKUP text markup. -INFO is a plist used as a communication channel. See -`org-latex-text-markup-alist' for details." - (let ((fmt (cdr (assq markup (plist-get info :latex-text-markup-alist))))) - (cl-case fmt - ;; No format string: Return raw text. - ((nil) text) - ;; Handle the `verb' special case: Find an appropriate separator - ;; and use "\\verb" command. - (verb - (let ((separator (org-latex--find-verb-separator text))) - (concat "\\verb" - separator - (replace-regexp-in-string "\n" " " text) - separator))) - (protectedtexttt (org-latex--protect-texttt text)) - ;; Else use format string. - (t (format fmt text))))) - -(defun org-latex--protect-texttt (text) - "Protect special chars, then wrap TEXT in \"\\texttt{}\"." - (format "\\texttt{%s}" - (replace-regexp-in-string - "--\\|[\\{}$%&_#~^]" - (lambda (m) - (cond ((equal m "--") "-{}-") - ((equal m "\\") "\\textbackslash{}") - ((equal m "~") "\\textasciitilde{}") - ((equal m "^") "\\textasciicircum{}") - (t (org-latex--protect-text m)))) - text nil t))) - -(defun org-latex--delayed-footnotes-definitions (element info) - "Return footnotes definitions in ELEMENT as a string. - -INFO is a plist used as a communication channel. - -Footnotes definitions are returned within \"\\footnotetext{}\" -commands. - -This function is used within constructs that don't support -\"\\footnote{}\" command (e.g., an item tag). In that case, -\"\\footnotemark\" is used within the construct and the function -just outside of it." - (mapconcat - (lambda (ref) - (let ((def (org-export-get-footnote-definition ref info))) - (format "\\footnotetext[%d]{%s%s}" - (org-export-get-footnote-number ref info) - (org-trim (org-latex--label def info t t)) - (org-trim (org-export-data def info))))) - ;; Find every footnote reference in ELEMENT. - (letrec ((all-refs nil) - (search-refs - (lambda (data) - ;; Return a list of all footnote references never seen - ;; before in DATA. - (org-element-map data 'footnote-reference - (lambda (ref) - (when (org-export-footnote-first-reference-p ref info) - (push ref all-refs) - (when (eq (org-element-property :type ref) 'standard) - (funcall search-refs - (org-export-get-footnote-definition ref info))))) - info) - (reverse all-refs)))) - (funcall search-refs element)) - "")) - -(defun org-latex--translate (s info) - "Translate string S according to specified language. -INFO is a plist used as a communication channel." - (org-export-translate s :latex info)) - -(defun org-latex--format-spec (info) - "Create a format-spec for document meta-data. -INFO is a plist used as a communication channel." - (let ((language (let ((lang (plist-get info :language))) - (or (cdr (assoc-string lang org-latex-babel-language-alist t)) - (nth 1 (assoc-string lang org-latex-polyglossia-language-alist t)) - lang)))) - `((?a . ,(org-export-data (plist-get info :author) info)) - (?t . ,(org-export-data (plist-get info :title) info)) - (?s . ,(org-export-data (plist-get info :subtitle) info)) - (?k . ,(org-export-data (org-latex--wrap-latex-math-block - (plist-get info :keywords) info) - info)) - (?d . ,(org-export-data (org-latex--wrap-latex-math-block - (plist-get info :description) info) - info)) - (?c . ,(plist-get info :creator)) - (?l . ,language) - (?L . ,(capitalize language)) - (?D . ,(org-export-get-date info))))) - -(defun org-latex--insert-compiler (info) - "Insert LaTeX_compiler info into the document. -INFO is a plist used as a communication channel." - (let ((compiler (plist-get info :latex-compiler))) - (and (org-string-nw-p org-latex-compiler-file-string) - (member (or compiler "") org-latex-compilers) - (format org-latex-compiler-file-string compiler)))) - - -;;; Filters - -(defun org-latex-matrices-tree-filter (tree _backend info) - (org-latex--wrap-latex-matrices tree info)) - -(defun org-latex-math-block-tree-filter (tree _backend info) - (org-latex--wrap-latex-math-block tree info)) - -(defun org-latex-math-block-options-filter (info _backend) - (dolist (prop '(:author :date :title) info) - (plist-put info prop - (org-latex--wrap-latex-math-block (plist-get info prop) info)))) - -(defun org-latex-clean-invalid-line-breaks (data _backend _info) - (replace-regexp-in-string - "\\(\\\\end{[A-Za-z0-9*]+}\\|^\\)[ \t]*\\\\\\\\[ \t]*$" "\\1" - data)) - - -;;; Template - -;;;###autoload -(defun org-latex-make-preamble (info &optional template snippet?) - "Return a formatted LaTeX preamble. -INFO is a plist used as a communication channel. Optional -argument TEMPLATE, when non-nil, is the header template string, -as expected by `org-splice-latex-header'. When SNIPPET? is -non-nil, only includes packages relevant to image generation, as -specified in `org-latex-default-packages-alist' or -`org-latex-packages-alist'." - (let* ((class (plist-get info :latex-class)) - (class-template - (or template - (let* ((class-options (plist-get info :latex-class-options)) - (header (nth 1 (assoc class (plist-get info :latex-classes))))) - (and (stringp header) - (if (not class-options) header - (replace-regexp-in-string - "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)" - class-options header t nil 1)))) - (user-error "Unknown LaTeX class `%s'" class)))) - (org-latex-guess-polyglossia-language - (org-latex-guess-babel-language - (org-latex-guess-inputenc - (org-element-normalize-string - (org-splice-latex-header - class-template - (org-latex--remove-packages org-latex-default-packages-alist info) - (org-latex--remove-packages org-latex-packages-alist info) - snippet? - (mapconcat #'org-element-normalize-string - (list (plist-get info :latex-header) - (and (not snippet?) - (plist-get info :latex-header-extra))) - "")))) - info) - info))) - -(defun org-latex-template (contents info) - "Return complete document string after LaTeX conversion. -CONTENTS is the transcoded contents string. INFO is a plist -holding export options." - (let ((title (org-export-data (plist-get info :title) info)) - (spec (org-latex--format-spec info))) - (concat - ;; Time-stamp. - (and (plist-get info :time-stamp-file) - (format-time-string "%% Created %Y-%m-%d %a %H:%M\n")) - ;; LaTeX compiler. - (org-latex--insert-compiler info) - ;; Document class and packages. - (org-latex-make-preamble info) - ;; Possibly limit depth for headline numbering. - (let ((sec-num (plist-get info :section-numbers))) - (when (integerp sec-num) - (format "\\setcounter{secnumdepth}{%d}\n" sec-num))) - ;; Author. - (let ((author (and (plist-get info :with-author) - (let ((auth (plist-get info :author))) - (and auth (org-export-data auth info))))) - (email (and (plist-get info :with-email) - (org-export-data (plist-get info :email) info)))) - (cond ((and author email (not (string= "" email))) - (format "\\author{%s\\thanks{%s}}\n" author email)) - ((or author email) (format "\\author{%s}\n" (or author email))))) - ;; Date. - (let ((date (and (plist-get info :with-date) (org-export-get-date info)))) - (format "\\date{%s}\n" (org-export-data date info))) - ;; Title and subtitle. - (let* ((subtitle (plist-get info :subtitle)) - (formatted-subtitle - (when subtitle - (format (plist-get info :latex-subtitle-format) - (org-export-data subtitle info)))) - (separate (plist-get info :latex-subtitle-separate))) - (concat - (format "\\title{%s%s}\n" title - (if separate "" (or formatted-subtitle ""))) - (when (and separate subtitle) - (concat formatted-subtitle "\n")))) - ;; Hyperref options. - (let ((template (plist-get info :latex-hyperref-template))) - (and (stringp template) - (format-spec template spec))) - ;; Document start. - "\\begin{document}\n\n" - ;; Title command. - (let* ((title-command (plist-get info :latex-title-command)) - (command (and (stringp title-command) - (format-spec title-command spec)))) - (org-element-normalize-string - (cond ((not (plist-get info :with-title)) nil) - ((string= "" title) nil) - ((not (stringp command)) nil) - ((string-match "\\(?:[^%]\\|^\\)%s" command) - (format command title)) - (t command)))) - ;; Table of contents. - (let ((depth (plist-get info :with-toc))) - (when depth - (concat (when (integerp depth) - (format "\\setcounter{tocdepth}{%d}\n" depth)) - (plist-get info :latex-toc-command)))) - ;; Document's body. - contents - ;; Creator. - (and (plist-get info :with-creator) - (concat (plist-get info :creator) "\n")) - ;; Document end. - "\\end{document}"))) - - - -;;; Transcode Functions - -;;;; Bold - -(defun org-latex-bold (_bold contents info) - "Transcode BOLD from Org to LaTeX. -CONTENTS is the text with bold markup. INFO is a plist holding -contextual information." - (org-latex--text-markup contents 'bold info)) - - -;;;; Center Block - -(defun org-latex-center-block (center-block contents info) - "Transcode a CENTER-BLOCK element from Org to LaTeX. -CONTENTS holds the contents of the center block. INFO is a plist -holding contextual information." - (org-latex--wrap-label - center-block (format "\\begin{center}\n%s\\end{center}" contents) info)) - - -;;;; Clock - -(defun org-latex-clock (clock _contents info) - "Transcode a CLOCK element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual -information." - (concat - "\\noindent" - (format "\\textbf{%s} " org-clock-string) - (format (plist-get info :latex-inactive-timestamp-format) - (concat (org-timestamp-translate (org-element-property :value clock)) - (let ((time (org-element-property :duration clock))) - (and time (format " (%s)" time))))) - "\\\\")) - - -;;;; Code - -(defun org-latex-code (code _contents info) - "Transcode a CODE object from Org to LaTeX. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (org-latex--text-markup (org-element-property :value code) 'code info)) - - -;;;; Drawer - -(defun org-latex-drawer (drawer contents info) - "Transcode a DRAWER element from Org to LaTeX. -CONTENTS holds the contents of the block. INFO is a plist -holding contextual information." - (let* ((name (org-element-property :drawer-name drawer)) - (output (funcall (plist-get info :latex-format-drawer-function) - name contents))) - (org-latex--wrap-label drawer output info))) - - -;;;; Dynamic Block - -(defun org-latex-dynamic-block (dynamic-block contents info) - "Transcode a DYNAMIC-BLOCK element from Org to LaTeX. -CONTENTS holds the contents of the block. INFO is a plist -holding contextual information. See `org-export-data'." - (org-latex--wrap-label dynamic-block contents info)) - - -;;;; Entity - -(defun org-latex-entity (entity _contents _info) - "Transcode an ENTITY object from Org to LaTeX. -CONTENTS are the definition itself. INFO is a plist holding -contextual information." - (org-element-property :latex entity)) - - -;;;; Example Block - -(defun org-latex-example-block (example-block _contents info) - "Transcode an EXAMPLE-BLOCK element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual -information." - (when (org-string-nw-p (org-element-property :value example-block)) - (let ((environment (or (org-export-read-attribute - :attr_latex example-block :environment) - "verbatim"))) - (org-latex--wrap-label - example-block - (format "\\begin{%s}\n%s\\end{%s}" - environment - (org-export-format-code-default example-block info) - environment) - info)))) - - -;;;; Export Block - -(defun org-latex-export-block (export-block _contents _info) - "Transcode a EXPORT-BLOCK element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (when (member (org-element-property :type export-block) '("LATEX" "TEX")) - (org-remove-indentation (org-element-property :value export-block)))) - - -;;;; Export Snippet - -(defun org-latex-export-snippet (export-snippet _contents _info) - "Transcode a EXPORT-SNIPPET object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (when (eq (org-export-snippet-backend export-snippet) 'latex) - (org-element-property :value export-snippet))) - - -;;;; Fixed Width - -(defun org-latex-fixed-width (fixed-width _contents info) - "Transcode a FIXED-WIDTH element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (org-latex--wrap-label - fixed-width - (format "\\begin{verbatim}\n%s\n\\end{verbatim}" - (org-remove-indentation - (org-element-property :value fixed-width))) - info)) - - -;;;; Footnote Reference - -(defun org-latex-footnote-reference (footnote-reference _contents info) - "Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (let ((label (org-element-property :label footnote-reference))) - (concat - ;; Insert separator between two footnotes in a row. - (let ((prev (org-export-get-previous-element footnote-reference info))) - (when (eq (org-element-type prev) 'footnote-reference) - (plist-get info :latex-footnote-separator))) - (cond - ;; Use `:latex-footnote-defined-format' if the footnote has - ;; already been defined. - ((not (org-export-footnote-first-reference-p footnote-reference info)) - (format (plist-get info :latex-footnote-defined-format) - (org-latex--label - (org-export-get-footnote-definition footnote-reference info) - info t))) - ;; Use \footnotemark if reference is within another footnote - ;; reference, footnote definition, table cell, verse block, or - ;; item's tag. - ((or (org-element-lineage footnote-reference - '(footnote-reference footnote-definition - table-cell verse-block)) - (eq 'item (org-element-type - (org-export-get-parent-element footnote-reference)))) - "\\footnotemark") - ;; Otherwise, define it with \footnote command. - (t - (let ((def (org-export-get-footnote-definition footnote-reference info))) - (concat - (format "\\footnote{%s%s}" (org-trim (org-export-data def info)) - ;; Only insert a \label if there exist another - ;; reference to def. - (cond ((not label) "") - ((org-element-map (plist-get info :parse-tree) - 'footnote-reference - (lambda (f) - (and (not (eq f footnote-reference)) - (equal (org-element-property :label f) label) - (org-trim (org-latex--label def info t t)))) - info t)) - (t ""))) - ;; Retrieve all footnote references within the footnote and - ;; add their definition after it, since LaTeX doesn't support - ;; them inside. - (org-latex--delayed-footnotes-definitions def info)))))))) - - -;;;; Headline - -(defun org-latex-headline (headline contents info) - "Transcode a HEADLINE element from Org to LaTeX. -CONTENTS holds the contents of the headline. INFO is a plist -holding contextual information." - (unless (org-element-property :footnote-section-p headline) - (let* ((class (plist-get info :latex-class)) - (level (org-export-get-relative-level headline info)) - (numberedp (org-export-numbered-headline-p headline info)) - (class-sectioning (assoc class (plist-get info :latex-classes))) - ;; Section formatting will set two placeholders: one for - ;; the title and the other for the contents. - (section-fmt - (let ((sec (if (functionp (nth 2 class-sectioning)) - (funcall (nth 2 class-sectioning) level numberedp) - (nth (1+ level) class-sectioning)))) - (cond - ;; No section available for that LEVEL. - ((not sec) nil) - ;; Section format directly returned by a function. Add - ;; placeholder for contents. - ((stringp sec) (concat sec "\n%s")) - ;; (numbered-section . unnumbered-section) - ((not (consp (cdr sec))) - (concat (funcall (if numberedp #'car #'cdr) sec) "\n%s")) - ;; (numbered-open numbered-close) - ((= (length sec) 2) - (when numberedp (concat (car sec) "\n%s" (nth 1 sec)))) - ;; (num-in num-out no-num-in no-num-out) - ((= (length sec) 4) - (if numberedp (concat (car sec) "\n%s" (nth 1 sec)) - (concat (nth 2 sec) "\n%s" (nth 3 sec))))))) - ;; Create a temporary export back-end that hard-codes - ;; "\underline" within "\section" and alike. - (section-back-end - (org-export-create-backend - :parent 'latex - :transcoders - '((underline . (lambda (o c i) (format "\\underline{%s}" c))) - ;; LaTeX isn't happy when you try to use \verb inside the argument of other - ;; commands (like \section, etc.), and this causes compilation to fail. - ;; So, within headings it's a good idea to replace any instances of \verb - ;; with \texttt. - (code . (lambda (o _ _) (org-latex--protect-texttt (org-element-property :value o)))) - (verbatim . (lambda (o _ _) (org-latex--protect-texttt (org-element-property :value o))))))) - (text - (org-export-data-with-backend - (org-element-property :title headline) section-back-end 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 toc. - (full-text (funcall (plist-get info :latex-format-headline-function) - todo todo-type priority text tags info)) - ;; Associate \label to the headline for internal links. - (headline-label (org-latex--label headline info t t)) - (pre-blanks - (make-string (org-element-property :pre-blank headline) ?\n))) - (if (or (not section-fmt) (org-export-low-level-p headline info)) - ;; 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. - (let ((low-level-body - (concat - ;; If headline is the first sibling, start a list. - (when (org-export-first-sibling-p headline info) - (format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize))) - ;; Itemize headline - "\\item" - (and full-text - (string-match-p "\\`[ \t]*\\[" full-text) - "\\relax") - " " full-text "\n" - headline-label - pre-blanks - contents))) - ;; If headline is not the last sibling simply return - ;; LOW-LEVEL-BODY. Otherwise, also close the list, before - ;; any blank line. - (if (not (org-export-last-sibling-p headline info)) low-level-body - (replace-regexp-in-string - "[ \t\n]*\\'" - (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize)) - low-level-body))) - ;; This is a standard headline. Export it as a section. Add - ;; an alternative heading when possible, and when this is not - ;; identical to the usual heading. - (let ((opt-title - (funcall (plist-get info :latex-format-headline-function) - todo todo-type priority - (org-export-data-with-backend - (org-export-get-alt-title headline info) - section-back-end info) - (and (eq (plist-get info :with-tags) t) tags) - info)) - ;; Maybe end local TOC (see `org-latex-keyword'). - (contents - (concat - contents - (let ((case-fold-search t) - (section - (let ((first (car (org-element-contents headline)))) - (and (eq (org-element-type first) 'section) first)))) - (org-element-map section 'keyword - (lambda (k) - (and (equal (org-element-property :key k) "TOC") - (let ((v (org-element-property :value k))) - (and (string-match-p "\\<headlines\\>" v) - (string-match-p "\\<local\\>" v) - (format "\\stopcontents[level-%d]" level))))) - info t))))) - (if (and opt-title - (not (equal opt-title full-text)) - (string-match "\\`\\\\\\(.+?\\){" section-fmt)) - (format (replace-match "\\1[%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 "\\]" ")" opt-title)) - full-text - (concat headline-label pre-blanks contents)) - ;; Impossible to add an alternative heading. Fallback to - ;; regular sectioning format string. - (format section-fmt full-text - (concat headline-label pre-blanks contents)))))))) - -(defun org-latex-format-headline-default-function - (todo _todo-type priority text tags _info) - "Default format function for a headline. -See `org-latex-format-headline-function' for details." - (concat - (and todo (format "{\\bfseries\\sffamily %s} " todo)) - (and priority (format "\\framebox{\\#%c} " priority)) - text - (and tags - (format "\\hfill{}\\textsc{%s}" - (mapconcat #'org-latex--protect-text tags ":"))))) - - -;;;; Horizontal Rule - -(defun org-latex-horizontal-rule (horizontal-rule _contents info) - "Transcode an HORIZONTAL-RULE object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (let ((attr (org-export-read-attribute :attr_latex horizontal-rule)) - (prev (org-export-get-previous-element horizontal-rule info))) - (concat - ;; Make sure the rule doesn't start at the end of the current - ;; line by separating it with a blank line from previous element. - (when (and prev - (let ((prev-blank (org-element-property :post-blank prev))) - (or (not prev-blank) (zerop prev-blank)))) - "\n") - (org-latex--wrap-label - horizontal-rule - (format "\\noindent\\rule{%s}{%s}" - (or (plist-get attr :width) "\\textwidth") - (or (plist-get attr :thickness) "0.5pt")) - info)))) - - -;;;; Inline Src Block - -(defun org-latex-inline-src-block (inline-src-block _contents info) - "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX. -CONTENTS holds the contents of the item. INFO is a plist holding -contextual information." - (let* ((code (org-element-property :value inline-src-block)) - (separator (org-latex--find-verb-separator code))) - (cl-case (plist-get info :latex-listings) - ;; Do not use a special package: transcode it verbatim, as code. - ((nil) (org-latex--text-markup code 'code info)) - ;; Use minted package. - (minted - (let* ((org-lang (org-element-property :language inline-src-block)) - (mint-lang (or (cadr (assq (intern org-lang) - (plist-get info :latex-minted-langs))) - (downcase org-lang))) - (options (org-latex--make-option-string - (plist-get info :latex-minted-options)))) - (format "\\mintinline%s{%s}{%s}" - (if (string= options "") "" (format "[%s]" options)) - mint-lang - code))) - ;; Use listings package. - (otherwise - ;; Maybe translate language's name. - (let* ((org-lang (org-element-property :language inline-src-block)) - (lst-lang (or (cadr (assq (intern org-lang) - (plist-get info :latex-listings-langs))) - org-lang)) - (options (org-latex--make-option-string - (append (plist-get info :latex-listings-options) - `(("language" ,lst-lang)))))) - (concat (format "\\lstinline[%s]" options) - separator code separator)))))) - - -;;;; Inlinetask - -(defun org-latex-inlinetask (inlinetask contents info) - "Transcode an INLINETASK element from Org to LaTeX. -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))) - (contents (concat (org-latex--label inlinetask info) contents))) - (funcall (plist-get info :latex-format-inlinetask-function) - todo todo-type priority title tags contents info))) - -(defun org-latex-format-inlinetask-default-function - (todo _todo-type priority title tags contents _info) - "Default format function for inlinetasks. -See `org-latex-format-inlinetask-function' for details." - (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}" - (org-make-tag-string - (mapcar #'org-latex--protect-text tags))))))) - (concat "\\begin{center}\n" - "\\fbox{\n" - "\\begin{minipage}[c]{.6\\textwidth}\n" - full-title "\n\n" - (and (org-string-nw-p contents) - (concat "\\rule[.8em]{\\textwidth}{2pt}\n\n" contents)) - "\\end{minipage}\n" - "}\n" - "\\end{center}"))) - - -;;;; Italic - -(defun org-latex-italic (_italic contents info) - "Transcode ITALIC from Org to LaTeX. -CONTENTS is the text with italic markup. INFO is a plist holding -contextual information." - (org-latex--text-markup contents 'italic info)) - - -;;;; Item - -(defun org-latex-item (item contents info) - "Transcode an ITEM element from Org to LaTeX. -CONTENTS holds the contents of the item. INFO is a plist holding -contextual information." - (let* ((orderedp (eq (org-element-property - :type (org-export-get-parent item)) - 'ordered)) - (level - ;; Determine level of current item to determine the - ;; correct LaTeX counter to use (enumi, enumii...). - (let ((parent item) (level 0)) - (while (memq (org-element-type - (setq parent (org-export-get-parent parent))) - '(plain-list item)) - (when (and (eq (org-element-type parent) 'plain-list) - (eq (org-element-property :type parent) - 'ordered)) - (cl-incf level))) - level)) - (count (org-element-property :counter item)) - (counter (and count - (< level 5) - (format "\\setcounter{enum%s}{%s}\n" - (nth (1- level) '("i" "ii" "iii" "iv")) - (1- count)))) - (checkbox (cl-case (org-element-property :checkbox item) - (on "$\\boxtimes$") - (off "$\\square$") - (trans "$\\boxminus$"))) - (tag (let ((tag (org-element-property :tag item))) - (and tag (org-export-data tag info)))) - ;; If there are footnotes references in tag, be sure to add - ;; their definition at the end of the item. This workaround - ;; is necessary since "\footnote{}" command is not supported - ;; in tags. - (tag-footnotes - (or (and tag (org-latex--delayed-footnotes-definitions - (org-element-property :tag item) info)) - ""))) - (concat counter - "\\item" - (cond - ((and checkbox tag) - (format (if orderedp "{%s %s} %s" "[{%s %s}] %s") - checkbox tag tag-footnotes)) - ((or checkbox tag) - (format (if orderedp "{%s} %s" "[{%s}] %s") - (or checkbox tag) tag-footnotes)) - ;; Without a tag or a check-box, if CONTENTS starts with - ;; an opening square bracket, add "\relax" to "\item", - ;; unless the brackets comes from an initial export - ;; snippet (i.e. it is inserted willingly by the user). - ((and contents - (string-match-p "\\`[ \t]*\\[" contents) - (not (let ((e (car (org-element-contents item)))) - (and (eq (org-element-type e) 'paragraph) - (let ((o (car (org-element-contents e)))) - (and (eq (org-element-type o) 'export-snippet) - (eq (org-export-snippet-backend o) - 'latex))))))) - "\\relax ") - (t " ")) - (and contents (org-trim contents))))) - - -;;;; Keyword - -(defun org-latex-keyword (keyword _contents info) - "Transcode a KEYWORD element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (let ((key (org-element-property :key keyword)) - (value (org-element-property :value keyword))) - (cond - ((string= key "LATEX") value) - ((string= key "INDEX") (format "\\index{%s}" value)) - ((string= key "TOC") - (let ((case-fold-search t)) - (cond - ((string-match-p "\\<headlines\\>" value) - (let* ((localp (string-match-p "\\<local\\>" value)) - (parent (org-element-lineage keyword '(headline))) - (level (if (not (and localp parent)) 0 - (org-export-get-relative-level parent info))) - (depth - (and (string-match "\\<[0-9]+\\>" value) - (format - "\\setcounter{tocdepth}{%d}" - (+ (string-to-number (match-string 0 value)) level))))) - (if (and localp parent) - ;; Start local TOC, assuming package "titletoc" is - ;; required. - (format "\\startcontents[level-%d] -\\printcontents[level-%d]{}{0}{%s}" - level level (or depth "")) - (concat depth (and depth "\n") "\\tableofcontents")))) - ((string-match-p "\\<tables\\>" value) "\\listoftables") - ((string-match-p "\\<listings\\>" value) - (cl-case (plist-get info :latex-listings) - ((nil) "\\listoffigures") - (minted "\\listoflistings") - (otherwise "\\lstlistoflistings"))))))))) - - -;;;; Latex Environment - -(defun org-latex--environment-type (latex-environment) - "Return the TYPE of LATEX-ENVIRONMENT. - -The TYPE is determined from the actual latex environment, and -could be a member of `org-latex-caption-above' or `math'." - (let* ((latex-begin-re "\\\\begin{\\([A-Za-z0-9*]+\\)}") - (value (org-remove-indentation - (org-element-property :value latex-environment))) - (env (or (and (string-match latex-begin-re value) - (match-string 1 value)) - ""))) - (cond - ((string-match-p org-latex-math-environments-re value) 'math) - ((string-match-p - (eval-when-compile - (regexp-opt '("table" "longtable" "tabular" "tabu" "longtabu"))) - env) - 'table) - ((string-match-p "figure" env) 'image) - ((string-match-p - (eval-when-compile - (regexp-opt '("lstlisting" "listing" "verbatim" "minted"))) - env) - 'src-block) - (t 'special-block)))) - -(defun org-latex-latex-environment (latex-environment _contents info) - "Transcode a LATEX-ENVIRONMENT element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (when (plist-get info :with-latex) - (let* ((value (org-remove-indentation - (org-element-property :value latex-environment))) - (type (org-latex--environment-type latex-environment)) - (caption (if (eq type 'math) - (org-latex--label latex-environment info nil t) - (org-latex--caption/label-string latex-environment info))) - (caption-above-p - (memq type (append (plist-get info :latex-caption-above) '(math))))) - (if (not (or (org-element-property :name latex-environment) - (org-element-property :caption latex-environment))) - value - ;; Environment is labeled: label must be within the environment - ;; (otherwise, a reference pointing to that element will count - ;; the section instead). Also insert caption if `latex-environment' - ;; is not a math environment. - (with-temp-buffer - (insert value) - (if caption-above-p - (progn - (goto-char (point-min)) - (forward-line)) - (goto-char (point-max)) - (forward-line -1)) - (insert caption) - (buffer-string)))))) - -;;;; Latex Fragment - -(defun org-latex-latex-fragment (latex-fragment _contents _info) - "Transcode a LATEX-FRAGMENT object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (let ((value (org-element-property :value latex-fragment))) - ;; Trim math markers since the fragment is enclosed within - ;; a latex-math-block object anyway. - (cond ((string-match-p "\\`\\$[^$]" value) (substring value 1 -1)) - ((string-prefix-p "\\(" value) (substring value 2 -2)) - (t value)))) - - -;;;; Line Break - -(defun org-latex-line-break (_line-break _contents _info) - "Transcode a LINE-BREAK object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - "\\\\\n") - - -;;;; Link - -(defun org-latex-image-link-filter (data _backend info) - (org-export-insert-image-links data info org-latex-inline-image-rules)) - -(defun org-latex--inline-image (link info) - "Return LaTeX code for an inline image. -LINK is the link pointing to the inline image. INFO is a plist -used as a communication channel." - (let* ((parent (org-export-get-parent-element link)) - (path (let ((raw-path (org-element-property :path link))) - (if (not (file-name-absolute-p raw-path)) raw-path - (expand-file-name raw-path)))) - (filetype (file-name-extension path)) - (caption (org-latex--caption/label-string parent info)) - (caption-above-p (org-latex--caption-above-p link info)) - ;; Retrieve latex attributes from the element around. - (attr (org-export-read-attribute :attr_latex parent)) - (float (let ((float (plist-get attr :float))) - (cond ((string= float "wrap") 'wrap) - ((string= float "sideways") 'sideways) - ((string= float "multicolumn") 'multicolumn) - ((and (plist-member attr :float) (not float)) 'nonfloat) - (float float) - ((or (org-element-property :caption parent) - (org-string-nw-p (plist-get attr :caption))) - 'figure) - (t 'nonfloat)))) - (placement - (let ((place (plist-get attr :placement))) - (cond - (place (format "%s" place)) - ((eq float 'wrap) "{l}{0.5\\textwidth}") - ((eq float 'figure) - (format "[%s]" (plist-get info :latex-default-figure-position))) - (t "")))) - (center - (cond - ;; If link is an image link, do not center. - ((eq 'link (org-element-type (org-export-get-parent link))) nil) - ((plist-member attr :center) (plist-get attr :center)) - (t (plist-get info :latex-images-centered)))) - (comment-include (if (plist-get attr :comment-include) "%" "")) - ;; It is possible to specify scale or width and height in - ;; the ATTR_LATEX line, and also via default variables. - (scale (cond ((eq float 'wrap) "") - ((plist-get attr :scale)) - (t (plist-get info :latex-image-default-scale)))) - (width (cond ((org-string-nw-p scale) "") - ((plist-get attr :width)) - ((plist-get attr :height) "") - ((eq float 'wrap) "0.48\\textwidth") - (t (plist-get info :latex-image-default-width)))) - (height (cond ((org-string-nw-p scale) "") - ((plist-get attr :height)) - ((or (plist-get attr :width) - (memq float '(figure wrap))) "") - (t (plist-get info :latex-image-default-height)))) - (options (let ((opt (or (plist-get attr :options) - (plist-get info :latex-image-default-option)))) - (if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt - (match-string 1 opt)))) - image-code) - (if (member filetype '("tikz" "pgf")) - ;; For tikz images: - ;; - use \input to read in image file. - ;; - if options are present, wrap in a tikzpicture environment. - ;; - if width or height are present, use \resizebox to change - ;; the image size. - (progn - (setq image-code (format "\\input{%s}" path)) - (when (org-string-nw-p options) - (setq image-code - (format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}" - options - image-code))) - (setq image-code - (cond ((org-string-nw-p scale) - (format "\\scalebox{%s}{%s}" scale image-code)) - ((or (org-string-nw-p width) (org-string-nw-p height)) - (format "\\resizebox{%s}{%s}{%s}" - (if (org-string-nw-p width) width "!") - (if (org-string-nw-p height) height "!") - image-code)) - (t image-code)))) - ;; For other images: - ;; - add scale, or width and height to options. - ;; - include the image with \includegraphics. - (if (org-string-nw-p scale) - (setq options (concat options ",scale=" scale)) - (when (org-string-nw-p width) (setq options (concat options ",width=" width))) - (when (org-string-nw-p height) (setq options (concat options ",height=" height)))) - (let ((search-option (org-element-property :search-option link))) - (when (and search-option - (equal filetype "pdf") - (string-match-p "\\`[0-9]+\\'" search-option) - (not (string-match-p "page=" options))) - (setq options (concat options ",page=" search-option)))) - (setq image-code - (format "\\includegraphics%s{%s}" - (cond ((not (org-string-nw-p options)) "") - ((string-prefix-p "," options) - (format "[%s]" (substring options 1))) - (t (format "[%s]" options))) - path)) - (when (equal filetype "svg") - (setq image-code (replace-regexp-in-string "^\\\\includegraphics" - "\\includesvg" - image-code - nil t)) - (setq image-code (replace-regexp-in-string "\\.svg}" - "}" - image-code - nil t)))) - ;; Return proper string, depending on FLOAT. - (pcase float - ((and (pred stringp) env-string) - (format "\\begin{%s}%s -%s%s -%s%s -%s\\end{%s}" - env-string - placement - (if caption-above-p caption "") - (if center "\\centering" "") - comment-include image-code - (if caption-above-p "" caption) - env-string)) - (`wrap (format "\\begin{wrapfigure}%s -%s%s -%s%s -%s\\end{wrapfigure}" - placement - (if caption-above-p caption "") - (if center "\\centering" "") - comment-include image-code - (if caption-above-p "" caption))) - (`sideways (format "\\begin{sidewaysfigure} -%s%s -%s%s -%s\\end{sidewaysfigure}" - (if caption-above-p caption "") - (if center "\\centering" "") - comment-include image-code - (if caption-above-p "" caption))) - (`multicolumn (format "\\begin{figure*}%s -%s%s -%s%s -%s\\end{figure*}" - placement - (if caption-above-p caption "") - (if center "\\centering" "") - comment-include image-code - (if caption-above-p "" caption))) - (`figure (format "\\begin{figure}%s -%s%s -%s%s -%s\\end{figure}" - placement - (if caption-above-p caption "") - (if center "\\centering" "") - comment-include image-code - (if caption-above-p "" caption))) - ((guard center) - (format "\\begin{center} -%s%s -%s\\end{center}" - (if caption-above-p caption "") - image-code - (if caption-above-p "" caption))) - (_ - (concat (if caption-above-p caption "") - image-code - (if caption-above-p caption "")))))) - -(defun org-latex-link (link desc info) - "Transcode a LINK object from Org to LaTeX. - -DESC is the description part of the link, or the empty string. -INFO is a plist holding contextual information. See -`org-export-data'." - (let* ((type (org-element-property :type link)) - (raw-path (org-element-property :path link)) - ;; Ensure DESC really exists, or set it to nil. - (desc (and (not (string= desc "")) desc)) - (imagep (org-export-inline-image-p - link (plist-get info :latex-inline-image-rules))) - (path (org-latex--protect-text - (pcase type - ((or "http" "https" "ftp" "mailto" "doi") - (concat type ":" raw-path)) - ("file" - (org-export-file-uri raw-path)) - (_ - raw-path))))) - (cond - ;; Link type is handled by a special function. - ((org-export-custom-protocol-maybe link desc 'latex info)) - ;; Image file. - (imagep (org-latex--inline-image link info)) - ;; Radio link: Transcode target's contents and use them as link's - ;; description. - ((string= type "radio") - (let ((destination (org-export-resolve-radio-link link info))) - (if (not destination) desc - (format "\\hyperref[%s]{%s}" - (org-export-get-reference destination info) - desc)))) - ;; Links pointing to a headline: Find destination and build - ;; appropriate referencing command. - ((member type '("custom-id" "fuzzy" "id")) - (let ((destination - (if (string= type "fuzzy") - (org-export-resolve-fuzzy-link link info 'latex-matrices) - (org-export-resolve-id-link link info)))) - (cl-case (org-element-type destination) - ;; Id link points to an external file. - (plain-text - (if desc (format "\\href{%s}{%s}" destination desc) - (format "\\url{%s}" destination))) - ;; Fuzzy link points nowhere. - ((nil) - (format (plist-get info :latex-link-with-unknown-path-format) - (or desc - (org-export-data - (org-element-property :raw-link link) info)))) - ;; LINK points to a headline. If headlines are numbered - ;; and the link has no description, display headline's - ;; number. Otherwise, display description or headline's - ;; title. - (headline - (let ((label (org-latex--label destination info t))) - (if (and (not desc) - (org-export-numbered-headline-p destination info)) - (format org-latex-reference-command label) - (format "\\hyperref[%s]{%s}" label - (or desc - (org-export-data - (org-element-property :title destination) info)))))) - ;; Fuzzy link points to a target. Do as above. - (otherwise - (let ((ref (org-latex--label destination info t))) - (if (not desc) (format org-latex-reference-command ref) - (format "\\hyperref[%s]{%s}" ref desc))))))) - ;; Coderef: replace link with the reference name or the - ;; equivalent line number. - ((string= type "coderef") - (format (org-export-get-coderef-format path desc) - ;; Resolve with RAW-PATH since PATH could be tainted - ;; with `org-latex--protect-text' call above. - (org-export-resolve-coderef raw-path info))) - ;; External link with a description part. - ((and path desc) (format "\\href{%s}{%s}" path desc)) - ;; External link without a description part. - (path (format "\\url{%s}" path)) - ;; No path, only description. Try to do something useful. - (t (format (plist-get info :latex-link-with-unknown-path-format) desc))))) - - -;;;; Node Property - -(defun org-latex-node-property (node-property _contents _info) - "Transcode a NODE-PROPERTY element from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual -information." - (format "%s:%s" - (org-element-property :key node-property) - (let ((value (org-element-property :value node-property))) - (if value (concat " " value) "")))) - - -;;;; Paragraph - -(defun org-latex-paragraph (_paragraph contents _info) - "Transcode a PARAGRAPH element from Org to LaTeX. -CONTENTS is the contents of the paragraph, as a string. INFO is -the plist used as a communication channel." - contents) - - -;;;; Plain List - -(defun org-latex-plain-list (plain-list contents info) - "Transcode a PLAIN-LIST element from Org to LaTeX. -CONTENTS is the contents of the list. INFO is a plist holding -contextual information." - (let* ((type (org-element-property :type plain-list)) - (attr (org-export-read-attribute :attr_latex plain-list)) - (latex-type (let ((env (plist-get attr :environment))) - (cond (env (format "%s" env)) - ((eq type 'ordered) "enumerate") - ((eq type 'descriptive) "description") - (t "itemize"))))) - (org-latex--wrap-label - plain-list - (format "\\begin{%s}%s\n%s\\end{%s}" - latex-type - (or (plist-get attr :options) "") - contents - latex-type) - info))) - - -;;;; Plain Text - -(defun org-latex-plain-text (text info) - "Transcode a TEXT string from Org to LaTeX. -TEXT is the string to transcode. INFO is a plist holding -contextual information." - (let* ((specialp (plist-get info :with-special-strings)) - (output - ;; Turn LaTeX into \LaTeX{} and TeX into \TeX{}. - (let ((case-fold-search nil)) - (replace-regexp-in-string - "\\<\\(?:La\\)?TeX\\>" "\\\\\\&{}" - ;; Protect ^, ~, %, #, &, $, _, { and }. Also protect \. - ;; However, if special strings are used, be careful not - ;; to protect "\" in "\-" constructs. - (replace-regexp-in-string - (concat "[%$#&{}_~^]\\|\\\\" (and specialp "\\([^-]\\|$\\)")) - (lambda (m) - (cl-case (string-to-char m) - (?\\ "$\\\\backslash$\\1") - (?~ "\\\\textasciitilde{}") - (?^ "\\\\^{}") - (t "\\\\\\&"))) - text))))) - ;; Activate smart quotes. Be sure to provide original TEXT string - ;; since OUTPUT may have been modified. - (when (plist-get info :with-smart-quotes) - (setq output (org-export-activate-smart-quotes output :latex info text))) - ;; Convert special strings. - (when specialp - (setq output (replace-regexp-in-string "\\.\\.\\." "\\\\ldots{}" output))) - ;; Handle break preservation if required. - (when (plist-get info :preserve-breaks) - (setq output (replace-regexp-in-string - "\\(?:[ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" output nil t))) - ;; Return value. - output)) - - -;;;; Planning - -(defun org-latex-planning (planning _contents info) - "Transcode a PLANNING element from Org to LaTeX. -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 "\\textbf{%s} " org-closed-string) - (format (plist-get info :latex-inactive-timestamp-format) - (org-timestamp-translate closed))))) - (let ((deadline (org-element-property :deadline planning))) - (when deadline - (concat - (format "\\textbf{%s} " org-deadline-string) - (format (plist-get info :latex-active-timestamp-format) - (org-timestamp-translate deadline))))) - (let ((scheduled (org-element-property :scheduled planning))) - (when scheduled - (concat - (format "\\textbf{%s} " org-scheduled-string) - (format (plist-get info :latex-active-timestamp-format) - (org-timestamp-translate scheduled))))))) - " ") - "\\\\")) - - -;;;; Property Drawer - -(defun org-latex-property-drawer (_property-drawer contents _info) - "Transcode a PROPERTY-DRAWER element from Org to LaTeX. -CONTENTS holds the contents of the drawer. INFO is a plist -holding contextual information." - (and (org-string-nw-p contents) - (format "\\begin{verbatim}\n%s\\end{verbatim}" contents))) - - -;;;; Pseudo Element: LaTeX Matrices - -;; `latex-matrices' elements have the following properties: -;; `:caption', `:post-blank' and `:markup' (`inline', `equation' or -;; `math'). - -(defun org-latex--wrap-latex-matrices (data info) - "Merge contiguous tables with the same mode within a pseudo-element. -DATA is a parse tree or a secondary string. INFO is a plist -containing export options. Modify DATA by side-effect and return -it." - (org-element-map data 'table - (lambda (table) - (when (eq (org-element-property :type table) 'org) - (let ((mode (or (org-export-read-attribute :attr_latex table :mode) - (plist-get info :latex-default-table-mode)))) - (when (and (member mode '("inline-math" "math")) - ;; Do not wrap twice the same table. - (not (eq (org-element-type - (org-element-property :parent table)) - 'latex-matrices))) - (let* ((caption (and (not (string= mode "inline-math")) - (org-element-property :caption table))) - (name (and (not (string= mode "inline-math")) - (org-element-property :name table))) - (matrices - (list 'latex-matrices - ;; Inherit name from the first table. - (list :name name - ;; FIXME: what syntax for captions? - ;; - ;; :caption caption - :markup - (cond ((string= mode "inline-math") 'inline) - ((or caption name) 'equation) - (t 'math))))) - (previous table) - (next (org-export-get-next-element table info))) - (org-element-insert-before matrices table) - ;; Swallow all contiguous tables sharing the same mode. - (while (and - (zerop (or (org-element-property :post-blank previous) 0)) - (setq next (org-export-get-next-element previous info)) - (eq (org-element-type next) 'table) - (eq (org-element-property :type next) 'org) - (string= (or (org-export-read-attribute - :attr_latex next :mode) - (plist-get info :latex-default-table-mode)) - mode)) - (org-element-put-property table :name nil) - (org-element-put-property table :caption nil) - (org-element-extract-element previous) - (org-element-adopt-elements matrices previous) - (setq previous next)) - ;; Inherit `:post-blank' from the value of the last - ;; swallowed table. Set the latter's `:post-blank' - ;; value to 0 so as to not duplicate empty lines. - (org-element-put-property - matrices :post-blank (org-element-property :post-blank previous)) - (org-element-put-property previous :post-blank 0) - (org-element-put-property table :name nil) - (org-element-put-property table :caption nil) - (org-element-extract-element previous) - (org-element-adopt-elements matrices previous)))))) - info) - data) - -(defun org-latex-matrices (matrices contents info) - "Transcode a MATRICES element from Org to LaTeX. -CONTENTS is a string. INFO is a plist used as a communication -channel." - (pcase (org-element-property :markup matrices) - (`inline (format "\\(%s\\)" contents)) - (`equation - (let ((caption (org-latex--caption/label-string matrices info)) - (caption-above? (org-latex--caption-above-p matrices info))) - (concat "\\begin{equation}\n" - (and caption-above? caption) - contents - (and (not caption-above?) caption) - "\\end{equation}"))) - (_ - (format "\\[\n%s\\]" contents)))) - - -;;;; Pseudo Object: LaTeX Math Block - -;; `latex-math-block' objects have the following property: -;; `:post-blank'. - -(defun org-latex--wrap-latex-math-block (data info) - "Merge contiguous math objects in a pseudo-object container. -DATA is a parse tree or a secondary string. INFO is a plist -containing export options. Modify DATA by side-effect and return it." - (let ((valid-object-p - ;; Non-nil when OBJECT can be added to a latex math block. - (lambda (object) - (pcase (org-element-type object) - (`entity (org-element-property :latex-math-p object)) - (`latex-fragment - (let ((value (org-element-property :value object))) - (or (string-prefix-p "\\(" value) - (string-match-p "\\`\\$[^$]" value)))))))) - (org-element-map data '(entity latex-fragment) - (lambda (object) - ;; Skip objects already wrapped. - (when (and (not (eq (org-element-type - (org-element-property :parent object)) - 'latex-math-block)) - (funcall valid-object-p object)) - (let ((math-block (list 'latex-math-block nil)) - (next-elements (org-export-get-next-element object info t)) - (last object)) - ;; Wrap MATH-BLOCK around OBJECT in DATA. - (org-element-insert-before math-block object) - (org-element-extract-element object) - (org-element-adopt-elements math-block object) - (when (zerop (or (org-element-property :post-blank object) 0)) - ;; MATH-BLOCK swallows consecutive math objects. - (catch 'exit - (dolist (next next-elements) - (unless (funcall valid-object-p next) (throw 'exit nil)) - (org-element-extract-element next) - (org-element-adopt-elements math-block next) - ;; Eschew the case: \beta$x$ -> \(\betax\). - (org-element-put-property last :post-blank 1) - (setq last next) - (when (> (or (org-element-property :post-blank next) 0) 0) - (throw 'exit nil))))) - (org-element-put-property - math-block :post-blank (org-element-property :post-blank last))))) - info nil '(latex-math-block) t) - ;; Return updated DATA. - data)) - -(defun org-latex-math-block (_math-block contents _info) - "Transcode a MATH-BLOCK object from Org to LaTeX. -CONTENTS is a string. INFO is a plist used as a communication -channel." - (when (org-string-nw-p contents) - (format "\\(%s\\)" (org-trim contents)))) - -;;;; Quote Block - -(defun org-latex-quote-block (quote-block contents info) - "Transcode a QUOTE-BLOCK element from Org to LaTeX. -CONTENTS holds the contents of the block. INFO is a plist -holding contextual information." - (let ((environment - (or (org-export-read-attribute :attr_latex quote-block :environment) - (plist-get info :latex-default-quote-environment))) - (options - (or (org-export-read-attribute :attr_latex quote-block :options) - ""))) - (org-latex--wrap-label - quote-block (format "\\begin{%s}%s\n%s\\end{%s}" - environment - options - contents - environment) - info))) - -;;;; Radio Target - -(defun org-latex-radio-target (radio-target text info) - "Transcode a RADIO-TARGET object from Org to LaTeX. -TEXT is the text of the target. INFO is a plist holding -contextual information." - (format "\\label{%s}%s" (org-export-get-reference radio-target info) text)) - - -;;;; Section - -(defun org-latex-section (_section contents _info) - "Transcode a SECTION element from Org to LaTeX. -CONTENTS holds the contents of the section. INFO is a plist -holding contextual information." - contents) - - -;;;; Special Block - -(defun org-latex-special-block (special-block contents info) - "Transcode a SPECIAL-BLOCK element from Org to LaTeX. -CONTENTS holds the contents of the block. INFO is a plist -holding contextual information." - (let ((type (org-element-property :type special-block)) - (opt (org-export-read-attribute :attr_latex special-block :options)) - (caption (org-latex--caption/label-string special-block info)) - (caption-above-p (org-latex--caption-above-p special-block info))) - (concat (format "\\begin{%s}%s\n" type (or opt "")) - (and caption-above-p caption) - contents - (and (not caption-above-p) caption) - (format "\\end{%s}" type)))) - - -;;;; Src Block - -(defun org-latex-src-block (src-block _contents info) - "Transcode a SRC-BLOCK element from Org to LaTeX. -CONTENTS holds the contents of the item. INFO is a plist holding -contextual information." - (when (org-string-nw-p (org-element-property :value src-block)) - (let* ((lang (org-element-property :language src-block)) - (caption (org-element-property :caption src-block)) - (caption-above-p (org-latex--caption-above-p src-block info)) - (label (org-element-property :name src-block)) - (custom-env (and lang - (cadr (assq (intern lang) - org-latex-custom-lang-environments)))) - (num-start (org-export-get-loc src-block info)) - (retain-labels (org-element-property :retain-labels src-block)) - (attributes (org-export-read-attribute :attr_latex src-block)) - (float (plist-get attributes :float)) - (listings (plist-get info :latex-listings))) - (cond - ;; Case 1. No source fontification. - ((or (not lang) (not listings)) - (let ((caption-str (org-latex--caption/label-string src-block info)) - (verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}" - (org-export-format-code-default src-block info)))) - (cond ((string= "multicolumn" float) - (format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}" - (plist-get info :latex-default-figure-position) - (if caption-above-p caption-str "") - verbatim - (if caption-above-p "" caption-str))) - (caption (concat - (if caption-above-p caption-str "") - verbatim - (if caption-above-p "" (concat "\n" caption-str)))) - (t verbatim)))) - ;; Case 2. Custom environment. - (custom-env - (let ((caption-str (org-latex--caption/label-string src-block info)) - (formatted-src (org-export-format-code-default src-block info))) - (if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env) - (format "\\begin{%s}\n%s\\end{%s}\n" - custom-env - (concat (and caption-above-p caption-str) - formatted-src - (and (not caption-above-p) caption-str)) - custom-env) - (format-spec custom-env - `((?s . ,formatted-src) - (?c . ,caption) - (?f . ,float) - (?l . ,(org-latex--label src-block info)) - (?o . ,(or (plist-get attributes :options) ""))))))) - ;; Case 3. Use minted package. - ((eq listings 'minted) - (let* ((caption-str (org-latex--caption/label-string src-block info)) - (placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement)) - (plist-get info :latex-default-figure-position))) - (float-env - (cond - ((string= "multicolumn" float) - (format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}" - placement - (if caption-above-p caption-str "") - (if caption-above-p "" caption-str))) - (caption - (format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}" - placement - (if caption-above-p caption-str "") - (if caption-above-p "" caption-str))) - ((string= "t" float) - (concat (format "\\begin{listing}[%s]\n" - placement) - "%s\n\\end{listing}")) - (t "%s"))) - (options (plist-get info :latex-minted-options)) - (body - (format - "\\begin{minted}[%s]{%s}\n%s\\end{minted}" - ;; Options. - (concat - (org-latex--make-option-string - (if (or (not num-start) (assoc "linenos" options)) - options - (append - `(("linenos") - ("firstnumber" ,(number-to-string (1+ num-start)))) - options))) - (let ((local-options (plist-get attributes :options))) - (and local-options (concat "," local-options)))) - ;; Language. - (or (cadr (assq (intern lang) - (plist-get info :latex-minted-langs))) - (downcase lang)) - ;; Source code. - (let* ((code-info (org-export-unravel-code src-block)) - (max-width - (apply 'max - (mapcar 'length - (org-split-string (car code-info) - "\n"))))) - (org-export-format-code - (car code-info) - (lambda (loc _num ref) - (concat - loc - (when ref - ;; Ensure references are flushed to the right, - ;; separated with 6 spaces from the widest line - ;; of code. - (concat (make-string (+ (- max-width (length loc)) 6) - ?\s) - (format "(%s)" ref))))) - nil (and retain-labels (cdr code-info))))))) - ;; Return value. - (format float-env body))) - ;; Case 4. Use listings package. - (t - (let ((lst-lang - (or (cadr (assq (intern lang) - (plist-get info :latex-listings-langs))) - lang)) - (caption-str - (when caption - (let ((main (org-export-get-caption src-block)) - (secondary (org-export-get-caption src-block t))) - (if (not secondary) - (format "{%s}" (org-export-data main info)) - (format "{[%s]%s}" - (org-export-data secondary info) - (org-export-data main info)))))) - (lst-opt (plist-get info :latex-listings-options))) - (concat - ;; Options. - (format - "\\lstset{%s}\n" - (concat - (org-latex--make-option-string - (append - lst-opt - (cond - ((and (not float) (plist-member attributes :float)) nil) - ((string= "multicolumn" float) '(("float" "*"))) - ((and float (not (assoc "float" lst-opt))) - `(("float" ,(plist-get info :latex-default-figure-position))))) - `(("language" ,lst-lang)) - (if label - `(("label" ,(org-latex--label src-block info))) - '(("label" " "))) - (if caption-str `(("caption" ,caption-str)) '(("caption" " "))) - `(("captionpos" ,(if caption-above-p "t" "b"))) - (cond ((assoc "numbers" lst-opt) nil) - ((not num-start) '(("numbers" "none"))) - (t `(("firstnumber" ,(number-to-string (1+ num-start))) - ("numbers" "left")))))) - (let ((local-options (plist-get attributes :options))) - (and local-options (concat "," local-options))))) - ;; Source code. - (format - "\\begin{lstlisting}\n%s\\end{lstlisting}" - (let* ((code-info (org-export-unravel-code src-block)) - (max-width - (apply 'max - (mapcar 'length - (org-split-string (car code-info) "\n"))))) - (org-export-format-code - (car code-info) - (lambda (loc _num ref) - (concat - loc - (when ref - ;; Ensure references are flushed to the right, - ;; separated with 6 spaces from the widest line of - ;; code - (concat (make-string (+ (- max-width (length loc)) 6) ?\s) - (format "(%s)" ref))))) - nil (and retain-labels (cdr code-info)))))))))))) - - -;;;; Statistics Cookie - -(defun org-latex-statistics-cookie (statistics-cookie _contents _info) - "Transcode a STATISTICS-COOKIE object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual information." - (replace-regexp-in-string - "%" "\\%" (org-element-property :value statistics-cookie) nil t)) - - -;;;; Strike-Through - -(defun org-latex-strike-through (_strike-through contents info) - "Transcode STRIKE-THROUGH from Org to LaTeX. -CONTENTS is the text with strike-through markup. INFO is a plist -holding contextual information." - (org-latex--text-markup contents 'strike-through info)) - - -;;;; Subscript - -(defun org-latex-subscript (_subscript contents _info) - "Transcode a SUBSCRIPT object from Org to LaTeX. -CONTENTS is the contents of the object." - (format "\\textsubscript{%s}" contents)) - - -;;;; Superscript - -(defun org-latex-superscript (_superscript contents _info) - "Transcode a SUPERSCRIPT object from Org to LaTeX. -CONTENTS is the contents of the object." - (format "\\textsuperscript{%s}" contents)) - - -;;;; Table -;; -;; `org-latex-table' is the entry point for table transcoding. It -;; takes care of tables with a "verbatim" mode. Otherwise, it -;; delegates the job to either `org-latex--table.el-table', -;; `org-latex--org-table' or `org-latex--math-table' functions, -;; depending of the type of the table and the mode requested. -;; -;; `org-latex--align-string' is a subroutine used to build alignment -;; string for Org tables. - -(defun org-latex-table (table contents info) - "Transcode a TABLE element from Org to LaTeX. -CONTENTS is the contents of the table. INFO is a plist holding -contextual information." - (if (eq (org-element-property :type table) 'table.el) - ;; "table.el" table. Convert it using appropriate tools. - (org-latex--table.el-table table info) - (let ((type (or (org-export-read-attribute :attr_latex table :mode) - (plist-get info :latex-default-table-mode)))) - (cond - ;; Case 1: Verbatim table. - ((string= type "verbatim") - (format "\\begin{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: Matrix. - ((or (string= type "math") (string= type "inline-math")) - (org-latex--math-table table info)) - ;; Case 3: Standard table. - (t (concat (org-latex--org-table table contents info) - ;; When there are footnote references within the - ;; table, insert their definition just after it. - (org-latex--delayed-footnotes-definitions table info))))))) - -(defun org-latex--align-string (table info &optional math?) - "Return an appropriate LaTeX alignment string. -TABLE is the considered table. INFO is a plist used as -a communication channel. When optional argument MATH? is -non-nil, TABLE is meant to be a matrix, where all cells are -centered." - (or (org-export-read-attribute :attr_latex table :align) - (let (align) - ;; Extract column groups and alignment from first (non-rule) - ;; row. - (org-element-map - (org-element-map table 'table-row - (lambda (row) - (and (eq (org-element-property :type row) 'standard) row)) - info 'first-match) - 'table-cell - (lambda (cell) - (let ((borders (org-export-table-cell-borders cell info))) - ;; Check left border for the first cell only. - (when (and (memq 'left borders) (not align)) - (push "|" align)) - (push (if math? "c" ;center cells in matrices - (cl-case (org-export-table-cell-alignment cell info) - (left "l") - (right "r") - (center "c"))) - align) - (when (memq 'right borders) (push "|" align)))) - info) - (apply 'concat (nreverse align))))) - -(defun org-latex--decorate-table (table attributes caption above? info) - "Decorate TABLE string with caption and float environment. - -ATTRIBUTES is the plist containing LaTeX attributes. CAPTION is -its caption, as a string or nil. It is located above the table -if ABOVE? is non-nil. INFO is the plist containing current -export parameters. - -Return new environment, as a string." - (let* ((float-environment - (let ((float (plist-get attributes :float))) - (cond ((and (not float) (plist-member attributes :float)) nil) - ((member float '("sidewaystable" "sideways")) "sidewaystable") - ((equal float "multicolumn") "table*") - (float float) - ((org-string-nw-p caption) "table") - (t nil)))) - (placement - (or (plist-get attributes :placement) - (format "[%s]" (plist-get info :latex-default-figure-position)))) - (center? (if (plist-member attributes :center) - (plist-get attributes :center) - (plist-get info :latex-tables-centered))) - (fontsize (let ((font (plist-get attributes :font))) - (and font (concat font "\n"))))) - (concat (cond - (float-environment - (concat (format "\\begin{%s}%s\n" float-environment placement) - (if above? caption "") - (when center? "\\centering\n") - fontsize)) - (caption - (concat (and center? "\\begin{center}\n" ) - (if above? caption "") - (cond ((and fontsize center?) fontsize) - (fontsize (concat "{" fontsize)) - (t nil)))) - (center? (concat "\\begin{center}\n" fontsize)) - (fontsize (concat "{" fontsize))) - table - (cond - (float-environment - (concat (if above? "" (concat "\n" caption)) - (format "\n\\end{%s}" float-environment))) - (caption - (concat (if above? "" (concat "\n" caption)) - (and center? "\n\\end{center}") - (and fontsize (not center?) "}"))) - (center? "\n\\end{center}") - (fontsize "}"))))) - -(defun org-latex--org-table (table contents info) - "Return appropriate LaTeX 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' property and -`table' as its `:mode' attribute." - (let* ((attr (org-export-read-attribute :attr_latex table)) - (alignment (org-latex--align-string table info)) - (table-env (or (plist-get attr :environment) - (plist-get info :latex-default-table-environment))) - (width - (let ((w (plist-get attr :width))) - (cond ((not w) "") - ((member table-env '("tabular" "longtable")) "") - ((member table-env '("tabu" "longtabu")) - (format (if (plist-get attr :spread) " spread %s " - " to %s ") - w)) - (t (format "{%s}" w))))) - (caption (org-latex--caption/label-string table info)) - (above? (org-latex--caption-above-p table info))) - (cond - ((member table-env '("longtable" "longtabu")) - (let ((fontsize (let ((font (plist-get attr :font))) - (and font (concat font "\n"))))) - (concat (and fontsize (concat "{" fontsize)) - (format "\\begin{%s}%s{%s}\n" table-env width alignment) - (and above? - (org-string-nw-p caption) - (concat caption "\\\\\n")) - contents - (and (not above?) - (org-string-nw-p caption) - (concat caption "\\\\\n")) - (format "\\end{%s}" table-env) - (and fontsize "}")))) - (t - (let ((output (format "\\begin{%s}%s{%s}\n%s\\end{%s}" - table-env - width - alignment - contents - table-env))) - (org-latex--decorate-table output attr caption above? info)))))) - -(defun org-latex--table.el-table (table info) - "Return appropriate LaTeX code for a table.el table. - -TABLE is the table type element to transcode. INFO is a plist -used as a communication channel. - -This function assumes TABLE has `table.el' as its `:type' -property." - (require 'table) - ;; Ensure "*org-export-table*" buffer is empty. - (with-current-buffer (get-buffer-create "*org-export-table*") - (erase-buffer)) - (let ((output - (replace-regexp-in-string - "^%.*\n" "" ;remove comments - (with-temp-buffer - (save-excursion (insert (org-element-property :value table))) - (re-search-forward "^[ \t]*|[^|]" nil t) - (table-generate-source 'latex "*org-export-table*") - (with-current-buffer "*org-export-table*" - (org-trim (buffer-string)))) - t t))) - (kill-buffer (get-buffer "*org-export-table*")) - (let ((attr (org-export-read-attribute :attr_latex table)) - (caption (org-latex--caption/label-string table info)) - (above? (org-latex--caption-above-p table info))) - (when (plist-get attr :rmlines) - ;; When the "rmlines" attribute is provided, remove all hlines - ;; but the one separating heading from the table body. - (let ((n 0) (pos 0)) - (while (and (< (length output) pos) - (setq pos (string-match "^\\\\hline\n?" output pos))) - (cl-incf n) - (unless (= n 2) (setq output (replace-match "" nil nil output)))))) - (org-latex--decorate-table output attr caption above? info)))) - -(defun org-latex--math-table (table info) - "Return appropriate LaTeX code for a matrix. - -TABLE is the table type element to transcode. INFO is a plist -used as a communication channel. - -This function assumes TABLE has `org' as its `:type' property and -`inline-math' or `math' as its `:mode' attribute." - (let* ((attr (org-export-read-attribute :attr_latex table)) - (env (or (plist-get attr :environment) - (plist-get info :latex-default-table-environment))) - (contents - (mapconcat - (lambda (row) - (if (eq (org-element-property :type row) 'rule) "\\hline" - ;; Return each cell unmodified. - (concat - (mapconcat - (lambda (cell) - (substring (org-element-interpret-data cell) 0 -1)) - (org-element-map row 'table-cell #'identity info) "&") - (or (cdr (assoc env org-latex-table-matrix-macros)) "\\\\") - "\n"))) - (org-element-map table 'table-row #'identity info) ""))) - (concat - ;; Prefix. - (plist-get attr :math-prefix) - ;; Environment. Also treat special cases. - (cond ((member env '("array" "tabular")) - (format "\\begin{%s}{%s}\n%s\\end{%s}" - env (org-latex--align-string table info t) contents env)) - ((assoc env org-latex-table-matrix-macros) - (format "\\%s%s{\n%s}" - env - (or (plist-get attr :math-arguments) "") - contents)) - (t (format "\\begin{%s}\n%s\\end{%s}" env contents env))) - ;; Suffix. - (plist-get attr :math-suffix)))) - - -;;;; Table Cell - -(defun org-latex-table-cell (table-cell contents info) - "Transcode a TABLE-CELL element from Org to LaTeX. -CONTENTS is the cell contents. INFO is a plist used as -a communication channel." - (concat - (let ((scientific-format (plist-get info :latex-table-scientific-notation))) - (if (and contents - scientific-format - (string-match orgtbl-exp-regexp contents)) - ;; Use appropriate format string for scientific - ;; notation. - (format scientific-format - (match-string 1 contents) - (match-string 2 contents)) - contents)) - (when (org-export-get-next-element table-cell info) " & "))) - - -;;;; Table Row - -(defun org-latex-table-row (table-row contents info) - "Transcode a TABLE-ROW element from Org to LaTeX. -CONTENTS is the contents of the row. INFO is a plist used as -a communication channel." - (let* ((attr (org-export-read-attribute :attr_latex - (org-export-get-parent table-row))) - (booktabsp (if (plist-member attr :booktabs) (plist-get attr :booktabs) - (plist-get info :latex-tables-booktabs))) - (longtablep - (member (or (plist-get attr :environment) - (plist-get info :latex-default-table-environment)) - '("longtable" "longtabu")))) - (if (eq (org-element-property :type table-row) 'rule) - (cond - ((not booktabsp) "\\hline") - ((not (org-export-get-previous-element table-row info)) "\\toprule") - ((not (org-export-get-next-element table-row info)) "\\bottomrule") - ((and longtablep - (org-export-table-row-ends-header-p - (org-export-get-previous-element table-row info) info)) - "") - (t "\\midrule")) - (concat - ;; When BOOKTABS are activated enforce top-rule even when no - ;; hline was specifically marked. - (and booktabsp (not (org-export-get-previous-element table-row info)) - "\\toprule\n") - contents "\\\\\n" - (cond - ;; Special case for long tables. Define header and footers. - ((and longtablep (org-export-table-row-ends-header-p table-row info)) - (let ((columns (cdr (org-export-table-dimensions - (org-export-get-parent-table table-row) info)))) - (format "%s -\\endfirsthead -\\multicolumn{%d}{l}{%s} \\\\ -%s -%s \\\\\n -%s -\\endhead -%s\\multicolumn{%d}{r}{%s} \\\\ -\\endfoot -\\endlastfoot" - (if booktabsp "\\midrule" "\\hline") - columns - (org-latex--translate "Continued from previous page" info) - (cond - ((not (org-export-table-row-starts-header-p table-row info)) - "") - (booktabsp "\\toprule\n") - (t "\\hline\n")) - contents - (if booktabsp "\\midrule" "\\hline") - (if booktabsp "\\midrule" "\\hline") - columns - (org-latex--translate "Continued on next page" info)))) - ;; When BOOKTABS are activated enforce bottom rule even when - ;; no hline was specifically marked. - ((and booktabsp (not (org-export-get-next-element table-row info))) - "\\bottomrule")))))) - - -;;;; Target - -(defun org-latex-target (target _contents info) - "Transcode a TARGET object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual -information." - (format "\\label{%s}" (org-latex--label target info))) - - -;;;; Timestamp - -(defun org-latex-timestamp (timestamp _contents info) - "Transcode a TIMESTAMP object from Org to LaTeX. -CONTENTS is nil. INFO is a plist holding contextual -information." - (let ((value (org-latex-plain-text (org-timestamp-translate timestamp) info))) - (format - (plist-get info - (cl-case (org-element-property :type timestamp) - ((active active-range) :latex-active-timestamp-format) - ((inactive inactive-range) :latex-inactive-timestamp-format) - (otherwise :latex-diary-timestamp-format))) - value))) - - -;;;; Underline - -(defun org-latex-underline (_underline contents info) - "Transcode UNDERLINE from Org to LaTeX. -CONTENTS is the text with underline markup. INFO is a plist -holding contextual information." - (org-latex--text-markup contents 'underline info)) - - -;;;; Verbatim - -(defun org-latex-verbatim (verbatim _contents info) - "Transcode a VERBATIM object from Org to LaTeX. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (org-latex--text-markup - (org-element-property :value verbatim) 'verbatim info)) - - -;;;; Verse Block - -(defun org-latex-verse-block (verse-block contents info) - "Transcode a VERSE-BLOCK element from Org to LaTeX. -CONTENTS is verse block contents. INFO is a plist holding -contextual information." - (let* ((lin (org-export-read-attribute :attr_latex verse-block :lines)) - (latcode (org-export-read-attribute :attr_latex verse-block :latexcode)) - (cent (org-export-read-attribute :attr_latex verse-block :center)) - (attr (concat - (if cent "[\\versewidth]" "") - (if lin (format "\n\\poemlines{%s}" lin) "") - (if latcode (format "\n%s" latcode) ""))) - (versewidth (org-export-read-attribute :attr_latex verse-block :versewidth)) - (vwidth (if versewidth (format "\\settowidth{\\versewidth}{%s}\n" versewidth) "")) - (linreset (if lin "\n\\poemlines{0}" ""))) - (concat - (org-latex--wrap-label - verse-block - ;; 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. - (format "%s\\begin{verse}%s\n%s\\end{verse}%s" - vwidth - attr - (replace-regexp-in-string - "^[ \t]+" (lambda (m) (format "\\hspace*{%dem}" (length m))) - (replace-regexp-in-string - "^[ \t]*\\\\\\\\$" "\\vspace*{1em}" - (replace-regexp-in-string - "\\([ \t]*\\\\\\\\\\)?[ \t]*\n" "\\\\\n" - contents nil t) nil t) nil t) linreset) - info) - ;; Insert footnote definitions, if any, after the environment, so - ;; the special formatting above is not applied to them. - (org-latex--delayed-footnotes-definitions verse-block info)))) - - -;;; End-user functions - -;;;###autoload -(defun org-latex-export-as-latex - (&optional async subtreep visible-only body-only ext-plist) - "Export current buffer as a LaTeX buffer. - -If narrowing is active in the current buffer, only export its -narrowed part. - -If a region is active, export that region. - -A non-nil optional argument ASYNC means the process should happen -asynchronously. The resulting buffer should be accessible -through the `org-export-stack' interface. - -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. - -Export is done in a buffer named \"*Org LATEX Export*\", which -will be displayed when `org-export-show-temporary-export-buffer' -is non-nil." - (interactive) - (org-export-to-buffer 'latex "*Org LATEX Export*" - async subtreep visible-only body-only ext-plist (lambda () (LaTeX-mode)))) - -;;;###autoload -(defun org-latex-convert-region-to-latex () - "Assume the current region has Org syntax, and convert it to LaTeX. -This can be used in any buffer. For example, you can write an -itemized list in Org syntax in an LaTeX buffer and use this -command to convert it." - (interactive) - (org-export-replace-region-by 'latex)) - -;;;###autoload -(defun org-latex-export-to-latex - (&optional async subtreep visible-only body-only ext-plist) - "Export current buffer to a LaTeX file. - -If narrowing is active in the current buffer, only export its -narrowed part. - -If a region is active, export that region. - -A non-nil optional argument ASYNC means the process should happen -asynchronously. The resulting file should be accessible through -the `org-export-stack' interface. - -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." - (interactive) - (let ((outfile (org-export-output-file-name ".tex" subtreep))) - (org-export-to-file 'latex outfile - async subtreep visible-only body-only ext-plist))) - -;;;###autoload -(defun org-latex-export-to-pdf - (&optional async subtreep visible-only body-only ext-plist) - "Export current buffer to LaTeX then process through to PDF. - -If narrowing is active in the current buffer, only export its -narrowed part. - -If a region is active, export that region. - -A non-nil optional argument ASYNC means the process should happen -asynchronously. The resulting file should be accessible through -the `org-export-stack' interface. - -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. - -Return PDF file's name." - (interactive) - (let ((outfile (org-export-output-file-name ".tex" subtreep))) - (org-export-to-file 'latex outfile - async subtreep visible-only body-only ext-plist - #'org-latex-compile))) - -(defun org-latex-compile (texfile &optional snippet) - "Compile a TeX file. - -TEXFILE is the name of the file being compiled. Processing is -done through the command specified in `org-latex-pdf-process', -which see. Output is redirected to \"*Org PDF LaTeX Output*\" -buffer. - -When optional argument SNIPPET is non-nil, TEXFILE is a temporary -file used to preview a LaTeX snippet. In this case, do not -create a log buffer and do not remove log files. - -Return PDF file name or raise an error if it couldn't be -produced." - (unless snippet (message "Processing LaTeX file %s..." texfile)) - (let* ((compiler - (or (with-temp-buffer - (save-excursion (insert-file-contents texfile)) - (and (search-forward-regexp (regexp-opt org-latex-compilers) - (line-end-position 2) - t) - (progn (beginning-of-line) (looking-at-p "%")) - (match-string 0))) - "pdflatex")) - (process (if (functionp org-latex-pdf-process) org-latex-pdf-process - ;; Replace "%latex" with "%L" and "%bib" and - ;; "%bibtex" with "%B" to adhere to `format-spec' - ;; specifications. - (mapcar (lambda (command) - (replace-regexp-in-string - "%\\(?:\\(?:bib\\|la\\)tex\\|bib\\)\\>" - (lambda (m) (upcase (substring m 0 2))) - command)) - org-latex-pdf-process))) - (spec `((?B . ,(shell-quote-argument org-latex-bib-compiler)) - (?L . ,(shell-quote-argument compiler)))) - (log-buf-name "*Org PDF LaTeX Output*") - (log-buf (and (not snippet) (get-buffer-create log-buf-name))) - (outfile (org-compile-file texfile process "pdf" - (format "See %S for details" log-buf-name) - log-buf spec))) - (unless snippet - (when org-latex-remove-logfiles - (mapc #'delete-file - (directory-files - (file-name-directory outfile) - t - (concat (regexp-quote (file-name-base outfile)) - "\\(?:\\.[0-9]+\\)?\\." - (regexp-opt org-latex-logfiles-extensions)) - t))) - (let ((warnings (org-latex--collect-warnings log-buf))) - (message (concat "PDF file produced" - (cond - ((eq warnings 'error) " with errors.") - (warnings (concat " with warnings: " warnings)) - (t ".")))))) - ;; Return output file name. - outfile)) - -(defun org-latex--collect-warnings (buffer) - "Collect some warnings from \"pdflatex\" command output. -BUFFER is the buffer containing output. Return collected -warnings types as a string, `error' if a LaTeX error was -encountered or nil if there was none." - (with-current-buffer buffer - (save-excursion - (goto-char (point-max)) - (when (re-search-backward "^[ \t]*This is .*?TeX.*?Version" nil t) - (if (re-search-forward "^!" nil t) 'error - (let ((case-fold-search t) - (warnings "")) - (dolist (warning org-latex-known-warnings) - (when (save-excursion (re-search-forward (car warning) nil t)) - (setq warnings (concat warnings " " (cdr warning))))) - (org-string-nw-p (org-trim warnings)))))))) - -;;;###autoload -(defun org-latex-publish-to-latex (plist filename pub-dir) - "Publish an Org file to LaTeX. - -FILENAME is the filename of the Org file to be published. PLIST -is the property list for the given project. PUB-DIR is the -publishing directory. - -Return output file name." - (org-publish-org-to 'latex filename ".tex" plist pub-dir)) - -;;;###autoload -(defun org-latex-publish-to-pdf (plist filename pub-dir) - "Publish an Org file to PDF (via LaTeX). - -FILENAME is the filename of the Org file to be published. PLIST -is the property list for the given project. PUB-DIR is the -publishing directory. - -Return output file name." - ;; Unlike to `org-latex-publish-to-latex', PDF file is generated - ;; in working directory and then moved to publishing directory. - (org-publish-attachment - plist - ;; Default directory could be anywhere when this function is - ;; called. We ensure it is set to source file directory during - ;; compilation so as to not break links to external documents. - (let ((default-directory (file-name-directory filename))) - (org-latex-compile - (org-publish-org-to - 'latex filename ".tex" plist (file-name-directory filename)))) - pub-dir)) - - -(provide 'ox-latex) - -;; Local variables: -;; generated-autoload-file: "org-loaddefs.el" -;; End: - -;;; ox-latex.el ends here |