12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132 |
- ;;; org-e-latex.el --- LaTeX Back-End For Org Export Engine
- ;; Copyright (C) 2011-2012 Free Software Foundation, Inc.
- ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
- ;; Keywords: outlines, hypermedia, calendar, wp
- ;; This program is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation, either version 3 of the License, or
- ;; (at your option) any later version.
- ;; This program is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public License
- ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;; This library implements a LaTeX back-end for Org generic exporter.
- ;; To test it, run
- ;;
- ;; M-: (org-export-to-buffer 'e-latex "*Test e-LaTeX*") RET
- ;;
- ;; in an org-mode buffer then switch to the buffer to see the LaTeX
- ;; export. See contrib/lisp/org-export.el for more details on how
- ;; this exporter works.
- ;; It introduces three new buffer keywords: "LATEX_CLASS",
- ;; "LATEX_CLASS_OPTIONS" and "LATEX_HEADER".
- ;;; Code:
- (eval-when-compile (require 'cl))
- (defvar org-export-latex-default-packages-alist)
- (defvar org-export-latex-packages-alist)
- (declare-function org-element-get-property "org-element" (property element))
- (declare-function org-element-normalize-string "org-element" (s))
- (declare-function org-element-parse-secondary-string
- "org-element" (string restriction &optional buffer))
- (defvar org-element-string-restrictions)
- (declare-function org-export-clean-table "org-export" (table specialp))
- (declare-function org-export-data "org-export" (data backend info))
- (declare-function org-export-directory "org-export" (type plist))
- (declare-function org-export-expand-macro "org-export" (macro info))
- (declare-function org-export-first-sibling-p "org-export" (headline info))
- (declare-function org-export-footnote-first-reference-p "org-export" (footnote-reference info))
- (declare-function org-export-get-coderef-format "org-export" (path desc))
- (declare-function org-export-get-footnote-definition "org-export" (footnote-reference info))
- (declare-function org-export-get-footnote-number "org-export" (footnote info))
- (declare-function org-export-get-previous-element "org-export" (blob info))
- (declare-function org-export-get-relative-level "org-export" (headline info))
- (declare-function org-export-handle-code
- "org-export" (element info &optional num-fmt ref-fmt delayed))
- (declare-function org-export-included-file "org-export" (keyword backend info))
- (declare-function org-export-inline-image-p "org-export" (link &optional extensions))
- (declare-function org-export-last-sibling-p "org-export" (headline info))
- (declare-function org-export-low-level-p "org-export" (headline info))
- (declare-function org-export-output-file-name
- "org-export" (extension &optional subtreep pub-dir))
- (declare-function org-export-resolve-coderef "org-export" (ref info))
- (declare-function org-export-resolve-fuzzy-link "org-export" (link info))
- (declare-function org-export-secondary-string "org-export" (secondary backend info))
- (declare-function org-export-solidify-link-text "org-export" (s))
- (declare-function org-export-table-format-info "org-export" (table))
- (declare-function
- org-export-to-buffer "org-export"
- (backend buffer &optional subtreep visible-only body-only ext-plist))
- (declare-function
- org-export-to-file "org-export"
- (backend file &optional subtreep visible-only body-only ext-plist))
- ;;; Internal Variables
- (defconst org-e-latex-option-alist
- '((:date "DATE" nil org-e-latex-date-format t)
- (:latex-class "LATEX_CLASS" nil org-e-latex-default-class t)
- (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t)
- (:latex-header-extra "LATEX_HEADER" nil nil newline))
- "Alist between LaTeX export properties and ways to set them.
- See `org-export-option-alist' for more information on the
- structure of the value.")
- ;;; User Configurable Variables
- (defgroup org-export-e-latex nil
- "Options for exporting Org mode files to LaTeX."
- :tag "Org Export LaTeX"
- :group 'org-export)
- ;;;; Preamble
- (defcustom org-e-latex-default-class "article"
- "The default LaTeX class."
- :group 'org-export-e-latex
- :type '(string :tag "LaTeX class"))
- (defcustom org-e-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-e-latex-default-packages-alist' and
- `org-e-latex-packages-alist'. Thus, your header definitions should
- avoid to also request these packages.
- - Lines specified via \"#+LaTeX_HEADER:\"
- If you need more control about the sequence in which the header is built
- up, or if you want to exclude one of these building blocks for a particular
- class, you can use the following macro-like placeholders.
- [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
- [NO-EXTRA] do not include #+LaTeX_HEADER stuff
- [BEAMER-HEADER-EXTRA] the beamer extra headers
- 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 lines,
- then have a call to \\providecommand, and then place \\usepackage commands
- based on the content of `org-e-latex-packages-alist'.
- If your header or `org-e-latex-default-packages-alist' inserts
- \"\\usepackage[AUTO]{inputenc}\", AUTO will automatically be replaced with
- a coding system derived from `buffer-file-coding-system'. See also the
- variable `org-e-latex-inputenc-alist' for a way to influence this
- mechanism.
- The sectioning structure
- ------------------------
- The sectioning structure of the class is given by the elements following
- the header string. For each sectioning level, a number of strings is
- specified. A %s formatter is mandatory in each section string and will
- be replaced by the title of the section.
- 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-e-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-e-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-e-latex
- :type '(repeat
- (cons
- (string :tag "Derived from buffer")
- (string :tag "Use this instead"))))
- (defcustom org-e-latex-date-format
- "\\today"
- "Format string for \\date{...}."
- :group 'org-export-e-latex
- :type 'boolean)
- (defcustom org-e-latex-title-command "\\maketitle"
- "The command used to insert the title just after \\begin{document}.
- If this string contains the formatting specification \"%s\" then
- it will be used as a formatting string, passing the title as an
- argument."
- :group 'org-export-e-latex
- :type 'string)
- ;;;; Headline
- (defcustom org-e-latex-format-headline-function nil
- "Function to format headline text.
- This function will be called with 5 arguments:
- TODO the todo keyword \(string or nil\).
- TODO-TYPE the type of todo \(symbol: `todo', `done', nil\)
- PRIORITY the priority of the headline \(integer or nil\)
- TEXT the main headline text \(string\).
- TAGS the tags string, separated with colons \(string or nil\).
- The function result will be used in the section format string.
- As an example, one could set the variable to the following, in
- order to reproduce the default set-up:
- \(defun org-e-latex-format-headline \(todo todo-type priority text tags\)
- \"Default format function for an headline.\"
- \(concat \(when todo
- \(format \"\\\\textbf{\\\\textsc{\\\\textsf{%s}}} \" todo\)\)
- \(when priority
- \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
- text
- \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)"
- :group 'org-export-e-latex
- :type 'function)
- ;;;; Emphasis
- (defcustom org-e-latex-emphasis-alist
- '(("*" . "\\textbf{%s}")
- ("/" . "\\emph{%s}")
- ("_" . "\\underline{%s}")
- ("+" . "\\st{%s}")
- ("=" . protectedtexttt)
- ("~" . verb))
- "Alist of LaTeX expressions to convert emphasis fontifiers.
- The key is the character used as a marker for fontification. The
- value is a formatting string to wrap fontified text with.
- Value can also be set to the following symbols: `verb' and
- `protectedtexttt'. For the former, Org will use \"\\verb\" to
- create a format string and select a delimiter character that
- isn't in the string. For the latter, Org will use \"\\texttt\"
- to typeset and try to protect special characters."
- :group 'org-export-e-latex
- :type 'alist)
- ;;;; Footnotes
- (defcustom org-e-latex-footnote-separator "\\textsuperscript{,}\\,"
- "Text used to separate footnotes."
- :group 'org-export-e-latex
- :type 'string)
- ;;;; Time-stamps
- (defcustom org-e-latex-active-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to active time-stamps."
- :group 'org-export-e-latex
- :type 'string)
- (defcustom org-e-latex-inactive-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to inactive time-stamps."
- :group 'org-export-e-latex
- :type 'string)
- (defcustom org-e-latex-diary-timestamp-format "\\textit{%s}"
- "A printf format string to be applied to diary time-stamps."
- :group 'org-export-e-latex
- :type 'string)
- ;;;; Links
- (defcustom org-e-latex-image-default-option "width=.9\\linewidth"
- "Default option for images."
- :group 'org-export-e-latex
- :type 'string)
- (defcustom org-e-latex-default-figure-position "htb"
- "Default position for latex figures."
- :group 'org-export-e-latex
- :type 'string)
- (defcustom org-e-latex-inline-image-extensions
- '("pdf" "jpeg" "jpg" "png" "ps" "eps")
- "Extensions of image files that can be inlined into LaTeX.
- Note that the image extension *actually* allowed depend on the
- way the LaTeX file is processed. When used with pdflatex, pdf,
- jpg and png images are OK. When processing through dvi to
- Postscript, only ps and eps are allowed. The default we use here
- encompasses both."
- :group 'org-export-e-latex
- :type '(repeat (string :tag "Extension")))
- ;;;; Tables
- (defcustom org-e-latex-default-table-environment "tabular"
- "Default environment used to build tables."
- :group 'org-export-e-latex
- :type 'string)
- (defcustom org-e-latex-tables-centered t
- "When non-nil, tables are exported in a center environment."
- :group 'org-export-e-latex
- :type 'boolean)
- (defcustom org-e-latex-tables-verbatim nil
- "When non-nil, tables are exported verbatim."
- :group 'org-export-e-latex
- :type 'boolean)
- (defcustom org-e-latex-table-caption-above t
- "When non-nil, place caption string at the beginning of the table.
- Otherwise, place it near the end."
- :group 'org-export-e-latex
- :type 'boolean)
- ;;;; Drawers
- (defcustom org-e-latex-format-drawer-function nil
- "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.
- For example, the variable could be set to the following function
- in order to mimic default behaviour:
- \(defun org-e-latex-format-drawer-default \(name contents\)
- \"Format a drawer element for LaTeX export.\"
- contents\)"
- :group 'org-export-e-latex
- :type 'function)
- ;;;; Inlinetasks
- (defcustom org-e-latex-format-inlinetask-function nil
- "Function called to format an inlinetask in LaTeX code.
- The function must accept six parameters:
- TODO the todo keyword, as a string
- TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
- PRIORITY the inlinetask priority, as a string
- NAME the inlinetask name, as a string.
- TAGS the inlinetask tags, as a string.
- CONTENTS the contents of the inlinetask, as a string.
- The function should return the string to be exported.
- For example, the variable could be set to the following function
- in order to mimic default behaviour:
- \(defun org-e-latex-format-inlinetask \(todo type priority name tags contents\)
- \"Format an inline task element for LaTeX export.\"
- \(let \(\(full-title
- \(concat
- \(when todo
- \(format \"\\\\textbf{\\\\textsf{\\\\textsc{%s}}} \" todo\)\)
- \(when priority \(format \"\\\\framebox{\\\\#%c} \" priority\)\)
- title
- \(when tags \(format \"\\\\hfill{}\\\\textsc{%s}\" tags\)\)\)\)\)
- \(format \(concat \"\\\\begin{center}\\n\"
- \"\\\\fbox{\\n\"
- \"\\\\begin{minipage}[c]{.6\\\\textwidth}\\n\"
- \"%s\\n\\n\"
- \"\\\\rule[.8em]{\\\\textwidth}{2pt}\\n\\n\"
- \"%s\"
- \"\\\\end{minipage}}\"
- \"\\\\end{center}\"\)
- full-title contents\)\)"
- :group 'org-export-e-latex
- :type 'function)
- ;; Src blocks
- (defcustom org-e-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-e-latex-packages-alist',
- for example using customize, or with something like
- (require 'org-e-latex)
- (add-to-list 'org-e-latex-packages-alist '(\"\" \"listings\"))
- (add-to-list 'org-e-latex-packages-alist '(\"\" \"color\"))
- Alternatively,
- (setq org-e-latex-listings 'minted)
- causes source code to be exported using the minted package as
- opposed to listings. If you want to use minted, you need to add
- the minted package to `org-e-latex-packages-alist', for
- example using customize, or with
- (require 'org-e-latex)
- (add-to-list 'org-e-latex-packages-alist '(\"\" \"minted\"))
- In addition, it is necessary to install
- pygments (http://pygments.org), and to configure the variable
- `org-e-latex-to-pdf-process' so that the -shell-escape option is
- passed to pdflatex."
- :group 'org-export-e-latex
- :type '(choice
- (const :tag "Use listings" t)
- (const :tag "Use minted" 'minted)
- (const :tag "Export verbatim" nil)))
- (defcustom org-e-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 "TeX")
- (shell-script "bash")
- (gnuplot "Gnuplot")
- (ocaml "Caml") (caml "Caml")
- (sql "SQL") (sqlite "sql"))
- "Alist mapping languages to their listing language counterpart.
- The key is a symbol, the major mode symbol without the \"-mode\".
- The value is the string that should be inserted as the language parameter
- for the listings package. If the mode name and the listings name are
- the same, the language does not need an entry in this list - but it does not
- hurt if it is present."
- :group 'org-export-e-latex
- :type '(repeat
- (list
- (symbol :tag "Major mode ")
- (string :tag "Listings language"))))
- (defcustom org-e-latex-listings-options nil
- "Association list of options for the latex listings package.
- These options are supplied as a comma-separated list to the
- \\lstset command. Each element of the association list should be
- a list containing two strings: the name of the option, and the
- value. For example,
- (setq org-e-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."
- :group 'org-export-e-latex
- :type '(repeat
- (list
- (string :tag "Listings option name ")
- (string :tag "Listings option value"))))
- (defcustom org-e-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-e-latex
- :type '(repeat
- (list
- (symbol :tag "Major mode ")
- (string :tag "Minted language"))))
- (defcustom org-e-latex-minted-options nil
- "Association list of options for the latex minted package.
- These options are supplied within square brackets in
- \\begin{minted} environments. Each element of the alist should
- be a list containing two strings: the name of the option, and the
- value. For example,
- (setq org-e-latex-minted-options
- '((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
- will result in src 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."
- :group 'org-export-e-latex
- :type '(repeat
- (list
- (string :tag "Minted option name ")
- (string :tag "Minted option value"))))
- (defvar org-e-latex-custom-lang-environments nil
- "Alist mapping languages to language-specific LaTeX environments.
- It is used during export of src blocks by the listings and minted
- latex packages. For example,
- \(setq org-e-latex-custom-lang-environments
- '\(\(python \"pythoncode\"\)\)\)
- would have the effect that if org encounters begin_src python
- during latex export it will output
- \\begin{pythoncode}
- <src block body>
- \\end{pythoncode}")
- ;;;; Plain text
- (defcustom org-e-latex-quotes
- '(("fr" ("\\(\\s-\\|[[(]\\)\"" . "«~") ("\\(\\S-\\)\"" . "~»") ("\\(\\s-\\|(\\)'" . "'"))
- ("en" ("\\(\\s-\\|[[(]\\)\"" . "``") ("\\(\\S-\\)\"" . "''") ("\\(\\s-\\|(\\)'" . "`")))
- "Alist for quotes to use when converting english double-quotes.
- The CAR of each item in this alist is the language code.
- The CDR of each item in this alist is a list of three CONS:
- - the first CONS defines the opening quote;
- - the second CONS defines the closing quote;
- - the last CONS defines single quotes.
- For each item in a CONS, the first string is a regexp
- for allowed characters before/after the quote, the second
- string defines the replacement string for this quote."
- :group 'org-export-e-latex
- :type '(list
- (cons :tag "Opening quote"
- (string :tag "Regexp for char before")
- (string :tag "Replacement quote "))
- (cons :tag "Closing quote"
- (string :tag "Regexp for char after ")
- (string :tag "Replacement quote "))
- (cons :tag "Single quote"
- (string :tag "Regexp for char before")
- (string :tag "Replacement quote "))))
- ;;;; Compilation
- (defcustom org-e-latex-pdf-process
- '("pdflatex -interaction nonstopmode -output-directory %o %f"
- "pdflatex -interaction nonstopmode -output-directory %o %f"
- "pdflatex -interaction nonstopmode -output-directory %o %f")
- "Commands to process a LaTeX file to a PDF file.
- This is a list of strings, each of them will be given to the shell
- as a command. %f in the command will be replaced by the full file name, %b
- by the file base name (i.e. without extension) and %o by the base directory
- of the file.
- The reason why this is a list is that it usually takes several runs of
- `pdflatex', maybe mixed with a call to `bibtex'. Org does not have a clever
- mechanism to detect which of these commands have to be run to get to a stable
- result, and it also does not do any error checking.
- By default, Org uses 3 runs of `pdflatex' to do the processing. If you
- have texi2dvi on your system and if that does not cause the infamous
- egrep/locale bug:
- http://lists.gnu.org/archive/html/bug-texinfo/2010-03/msg00031.html
- then `texi2dvi' is the superior choice. Org does offer it as one
- of the customize options.
- Alternatively, this may be a Lisp function that does the processing, so you
- could use this to apply the machinery of AUCTeX or the Emacs LaTeX mode.
- This function should accept the file name as its single argument."
- :group 'org-export-pdf
- :type '(choice
- (repeat :tag "Shell command sequence"
- (string :tag "Shell command"))
- (const :tag "2 runs of pdflatex"
- ("pdflatex -interaction nonstopmode -output-directory %o %f"
- "pdflatex -interaction nonstopmode -output-directory %o %f"))
- (const :tag "3 runs of pdflatex"
- ("pdflatex -interaction nonstopmode -output-directory %o %f"
- "pdflatex -interaction nonstopmode -output-directory %o %f"
- "pdflatex -interaction nonstopmode -output-directory %o %f"))
- (const :tag "pdflatex,bibtex,pdflatex,pdflatex"
- ("pdflatex -interaction nonstopmode -output-directory %o %f"
- "bibtex %b"
- "pdflatex -interaction nonstopmode -output-directory %o %f"
- "pdflatex -interaction nonstopmode -output-directory %o %f"))
- (const :tag "texi2dvi"
- ("texi2dvi -p -b -c -V %f"))
- (const :tag "rubber"
- ("rubber -d --into %o %f"))
- (function)))
- (defcustom org-e-latex-logfiles-extensions
- '("aux" "idx" "log" "out" "toc" "nav" "snm" "vrb")
- "The list of file extensions to consider as LaTeX logfiles."
- :group 'org-export-e-latex
- :type '(repeat (string :tag "Extension")))
- (defcustom org-e-latex-remove-logfiles t
- "Non-nil means remove the logfiles produced by PDF production.
- These are the .aux, .log, .out, and .toc files."
- :group 'org-export-e-latex
- :type 'boolean)
- ;;; Internal Functions
- (defun org-e-latex--caption/label-string (caption label info)
- "Return caption and label LaTeX string for floats.
- CAPTION is a cons cell of secondary strings, the car being the
- standard caption and the cdr its short form. LABEL is a string
- representing the label. INFO is a plist holding contextual
- information.
- If there's no caption nor label, return the empty string.
- For non-floats, see `org-e-latex--wrap-label'."
- (let ((label-str (if label (format "\\label{%s}" label) "")))
- (cond
- ((and (not caption) (not label)) "")
- ((not caption) (format "\\label{%s}\n" label))
- ;; Option caption format with short name.
- ((cdr caption)
- (format "\\caption[%s]{%s%s}\n"
- (org-export-secondary-string (cdr caption) 'e-latex info)
- label-str
- (org-export-secondary-string (car caption) 'e-latex info)))
- ;; Standard caption format.
- (t (format "\\caption{%s%s}\n"
- label-str
- (org-export-secondary-string (car caption) 'e-latex info))))))
- (defun org-e-latex--guess-inputenc (header)
- "Set the coding system in inputenc to what the buffer is.
- HEADER is the LaTeX header string.
- Return the new header."
- (let* ((cs (or (ignore-errors
- (latexenc-coding-system-to-inputenc
- buffer-file-coding-system))
- "utf8")))
- (if (not cs)
- header
- ;; First translate if that is requested.
- (setq cs (or (cdr (assoc cs org-e-latex-inputenc-alist)) cs))
- ;; Then find the \usepackage statement and replace the option.
- (replace-regexp-in-string "\\\\usepackage\\[\\(AUTO\\)\\]{inputenc}"
- cs header t nil 1))))
- (defun org-e-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<>()[]{}"))
- (loop for c across ll
- when (not (string-match (regexp-quote (char-to-string c)) s))
- return (char-to-string c))))
- (defun org-e-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)
- (concat (first pair)
- (when (> (length (second pair)) 0)
- (concat "=" (second pair)))))
- options
- ","))
- (defun org-e-latex--quotation-marks (text info)
- "Export quotation marks depending on language conventions.
- TEXT is a string containing quotation marks to be replaced. INFO
- is a plist used as a communication channel."
- (mapc (lambda(l)
- (let ((start 0))
- (while (setq start (string-match (car l) text start))
- (let ((new-quote (concat (match-string 1 text) (cdr l))))
- (setq text (replace-match new-quote t t text))))))
- (cdr (or (assoc (plist-get info :language) org-e-latex-quotes)
- ;; Falls back on English.
- (assoc "en" org-e-latex-quotes))))
- text)
- (defun org-e-latex--wrap-label (element output)
- "Wrap label associated to ELEMENT around OUTPUT, if appropriate.
- This function shouldn't be used for floats. See
- `org-e-latex--caption/label-string'."
- (let ((label (org-element-get-property :name element)))
- (if (or (not output) (not label) (string= output "") (string= label ""))
- output
- (concat (format "\\label{%s}\n" label) output))))
- ;;; Template
- (defun org-e-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-secondary-string
- (plist-get info :title) 'e-latex info)))
- (concat
- ;; 1. Time-stamp.
- (and (plist-get info :time-stamp-file)
- (format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
- ;; 2. Document class and packages.
- (let ((class (plist-get info :latex-class))
- (class-options (plist-get info :latex-class-options)))
- (org-element-normalize-string
- (let* ((header (nth 1 (assoc class org-e-latex-classes)))
- (document-class-string
- (and (stringp header)
- (if class-options
- (replace-regexp-in-string
- "^[ \t]*\\\\documentclass\\(\\[.*?\\]\\)"
- class-options header t nil 1)
- header))))
- (org-e-latex--guess-inputenc
- (org-splice-latex-header
- document-class-string
- org-export-latex-default-packages-alist ; defined in org.el
- org-export-latex-packages-alist nil ; defined in org.el
- (plist-get info :latex-header-extra))))))
- ;; 3. Define alert if not yet defined.
- "\\providecommand{\\alert}[1]{\\textbf{#1}}\n"
- ;; 4. Author.
- (let ((author (and (plist-get info :with-author)
- (let ((auth (plist-get info :author)))
- (and auth (org-export-secondary-string
- auth 'e-latex info)))))
- (email (and (plist-get info :with-email)
- (org-export-secondary-string
- (plist-get info :email) 'e-latex info))))
- (cond ((and author email (not (string= "" email)))
- (format "\\author{%s\\thanks{%s}}\n" author email))
- (author (format "\\author{%s}\n" author))
- (t "\\author{}\n")))
- ;; 5. Date.
- (let ((date (plist-get info :date)))
- (and date (format "\\date{%s}\n" date)))
- ;; 6. Title
- (format "\\title{%s}\n" title)
- ;; 7. Hyperref options.
- (format "\\hypersetup{\n pdfkeywords={%s},\n pdfsubject={%s},\n pdfcreator={%s}}\n"
- (or (plist-get info :keywords) "")
- (or (plist-get info :description) "")
- (let ((creator-info (plist-get info :with-creator)))
- (cond
- ((not creator-info) "")
- ((eq creator-info 'comment) "")
- (t (plist-get info :creator)))))
- ;; 7. Document start.
- "\\begin{document}\n\n"
- ;; 8. Title command.
- (org-element-normalize-string
- (cond ((string= "" title) nil)
- ((not (stringp org-e-latex-title-command)) nil)
- ((string-match "\\(?:[^%]\\|^\\)%s"
- org-e-latex-title-command)
- (format org-e-latex-title-command title))
- (t org-e-latex-title-command)))
- ;; 9. Table of contents.
- (let ((depth (plist-get info :with-toc)))
- (when depth
- (concat (when (wholenump depth)
- (format "\\setcounter{tocdepth}{%d}\n" depth))
- "\\tableofcontents\n\\vspace*{1cm}\n\n")))
- ;; 10. Document's body.
- contents
- ;; 11. Creator.
- (let ((creator-info (plist-get info :with-creator)))
- (cond
- ((not creator-info))
- ((eq creator-info 'comment)
- (format "%% %s\n" (plist-get info :creator)))
- (t (concat (plist-get info :creator) "\n"))))
- ;; 12. Document end.
- "\\end{document}")))
- ;;; Transcode Functions
- ;;;; Block
- (defun org-e-latex-center-block (center-block contents info)
- "Transcode a CENTER-BLOCK element from Org to LaTeX.
- CONTENTS holds the contents of the block. INFO is a plist
- holding contextual information."
- (org-e-latex--wrap-label
- center-block
- (format "\\begin{center}\n%s\\end{center}" contents)))
- ;;;; Comment
- ;; Comments are ignored.
- ;;;; Comment Block
- ;; Comment Blocks are ignored.
- ;;;; Drawer
- (defun org-e-latex-drawer (drawer contents info)
- "Transcode a DRAWER element from Org to LaTeX.
- CONTENTS holds the contents of the block. INFO is a plist
- holding contextual information."
- (let* ((name (org-element-get-property :drawer-name drawer))
- (output (if (functionp org-e-latex-format-drawer-function)
- (funcall org-e-latex-format-drawer-function
- name contents)
- ;; If there's no user defined function: simply
- ;; display contents of the drawer.
- contents)))
- (org-e-latex--wrap-label drawer output)))
- ;;;; Dynamic Block
- (defun org-e-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-e-latex--wrap-label dynamic-block contents))
- ;;;; Emphasis
- (defun org-e-latex-emphasis (emphasis contents info)
- "Transcode EMPHASIS from Org to LaTeX.
- CONTENTS is the contents of the emphasized text. INFO is a plist
- holding contextual information.."
- (format (cdr (assoc (org-element-get-property :marker emphasis)
- org-e-latex-emphasis-alist))
- contents))
- ;;;; Entity
- (defun org-e-latex-entity (entity contents info)
- "Transcode an ENTITY object from Org to LaTeX.
- CONTENTS are the definition itself. INFO is a plist holding
- contextual information."
- (let ((ent (org-element-get-property :latex entity)))
- (if (org-element-get-property :latex-math-p entity)
- (format "$%s$" ent)
- ent)))
- ;;;; Example Block
- (defun org-e-latex-example-block (example-block contents info)
- "Transcode a EXAMPLE-BLOCK element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (let* ((options (or (org-element-get-property :options example-block) ""))
- (value (org-export-handle-code example-block info)))
- (org-e-latex--wrap-label
- example-block (format "\\begin{verbatim}\n%s\\end{verbatim}" value))))
- ;;;; Export Snippet
- (defun org-e-latex-export-snippet (export-snippet contents info)
- "Transcode a EXPORT-SNIPPET object from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-get-property :value export-snippet))
- ;;;; Export Block
- (defun org-e-latex-export-block (export-block contents info)
- "Transcode a EXPORT-BLOCK element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (when (string= (org-element-get-property :type export-block) "latex")
- (org-remove-indentation (org-element-get-property :value export-block))))
- ;;;; Fixed Width
- (defun org-e-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."
- (let* ((value (org-element-normalize-string
- (replace-regexp-in-string
- "^[ \t]*: ?" ""
- (org-element-get-property :value fixed-width)))))
- (org-e-latex--wrap-label
- fixed-width (format "\\begin{verbatim}\n%s\\end{verbatim}" value))))
- ;;;; Footnote Definition
- ;; Footnote Definitions are ignored.
- ;;;; Footnote Reference
- (defun org-e-latex-footnote-reference (footnote-reference contents info)
- "Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (concat
- ;; Insert separator between two footnotes in a row.
- (let ((prev (org-export-get-previous-element footnote-reference info)))
- (when (and (listp prev) (eq (car prev) 'footnote-reference))
- org-e-latex-footnote-separator))
- ;; Use \footnotemark if the footnote has already been defined.
- ;; Otherwise, define it with \footnote command.
- (cond
- ((not (org-export-footnote-first-reference-p footnote-reference info))
- (format "\\footnotemark[%s]"
- (org-export-get-footnote-number footnote-reference info)))
- ;; Inline definitions are secondary strings.
- ((eq (org-element-get-property :type footnote-reference) 'inline)
- (format "\\footnote{%s}"
- (org-trim
- (org-export-secondary-string
- (org-export-get-footnote-definition footnote-reference info)
- 'e-latex info))))
- ;; Non-inline footnotes definitions are full Org data.
- (t
- (format "\\footnote{%s}"
- (org-trim
- (org-export-data
- (org-export-get-footnote-definition footnote-reference info)
- 'e-latex info)))))))
- ;;;; Headline
- (defun org-e-latex-headline (headline contents info)
- "Transcode an HEADLINE element from Org to LaTeX.
- CONTENTS holds the contents of the headline. INFO is a plist
- holding contextual information."
- (let* ((class (plist-get info :latex-class))
- (numberedp (plist-get info :section-numbers))
- ;; Get level relative to current parsed data.
- (level (org-export-get-relative-level headline info))
- (class-sectionning (assoc class org-e-latex-classes))
- ;; Section formatting will set two placeholders: one for the
- ;; title and the other for the contents.
- (section-fmt
- (let ((sec (if (and (symbolp (nth 2 class-sectionning))
- (fboundp (nth 2 class-sectionning)))
- (funcall (nth 2 class-sectionning) level numberedp)
- (nth (1+ level) class-sectionning))))
- (cond
- ;; No section available for that LEVEL.
- ((not sec) nil)
- ;; Section format directly returned by a function.
- ((stringp sec) sec)
- ;; (numbered-section . unnumbered-section)
- ((not (consp (cdr sec)))
- (concat (funcall (if numberedp #'car #'cdr) sec) "\n%s"))
- ;; (numbered-open numbered-close)
- ((= (length sec) 2)
- (when numberedp (concat (car sec) "\n%s" (nth 1 sec))))
- ;; (num-in num-out no-num-in no-num-out)
- ((= (length sec) 4)
- (if numberedp
- (concat (car sec) "\n%s" (nth 1 sec))
- (concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
- (text (org-export-secondary-string
- (org-element-get-property :title headline) 'e-latex info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-get-property
- :todo-keyword headline)))
- (and todo
- (org-export-secondary-string todo 'e-latex info)))))
- (todo-type (and todo (org-element-get-property :todo-type headline)))
- (tags (and (plist-get info :with-tags)
- (org-element-get-property :tags headline)))
- (priority (and (plist-get info :with-priority)
- (org-element-get-property :priority headline)))
- ;; Create the headline text.
- (full-text (if (functionp org-e-latex-format-headline-function)
- ;; User-defined formatting function.
- (funcall org-e-latex-format-headline-function
- todo todo-type priority text tags)
- ;; Default formatting.
- (concat
- (when todo
- (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
- (when priority (format "\\framebox{\\#%c} " priority))
- text
- (when tags (format "\\hfill{}\\textsc{%s}" tags)))))
- ;; Associate some \label to the headline for internal links.
- (headline-label
- (format "\\label{sec-%s}\n"
- (mapconcat 'number-to-string
- (org-export-get-headline-number headline info)
- "-")))
- (pre-blanks (make-string
- (org-element-get-property :pre-blank headline) 10)))
- (cond
- ;; Case 1: This is a footnote section: ignore it.
- ((org-element-get-property :footnote-section-p headline) nil)
- ;; Case 2. This is a deep sub-tree: export it as a list item.
- ;; Also export as items headlines for which no section
- ;; format has been found.
- ((or (not section-fmt) (org-export-low-level-p headline info))
- ;; Build the real contents of the sub-tree.
- (let ((low-level-body
- (concat
- ;; If the headline is the first sibling, start a list.
- (when (org-export-first-sibling-p headline info)
- (format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize)))
- ;; Itemize headline
- "\\item " full-text "\n" headline-label pre-blanks contents)))
- ;; If headline in the last sibling, close the list, before any
- ;; blank line. Otherwise, simply return LOW-LEVEL-BODY.
- (if (org-export-last-sibling-p headline info)
- (replace-regexp-in-string
- "[ \t\n]*\\'"
- (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
- low-level-body)
- low-level-body)))
- ;; Case 3. Standard headline. Export it as a section.
- (t (format section-fmt full-text
- (concat headline-label pre-blanks contents))))))
- ;;;; Horizontal Rule
- (defun org-e-latex-horizontal-rule (horizontal-rule contents info)
- "Transcode an HORIZONTAL-RULE object from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((attr (mapconcat #'identity
- (org-element-get-property :attr_latex horizontal-rule)
- " ")))
- (org-e-latex--wrap-label horizontal-rule (concat "\\hrule " attr))))
- ;;;; Inline Babel Call
- ;; Inline Babel Calls are ignored.
- ;;;; Inline Src Block
- (defun org-e-latex-inline-src-block (inline-src-block contents info)
- "Transcode an INLINE-SRC-BLOCK element from Org to LaTeX.
- CONTENTS holds the contents of the item. INFO is a plist holding
- contextual information."
- (let* ((code (org-element-get-property :value inline-src-block))
- (separator (org-e-latex--find-verb-separator code)))
- (cond
- ;; Do not use a special package: transcode it verbatim.
- ((not org-e-latex-listings)
- (concat "\\verb" separator code separator))
- ;; Use minted package.
- ((eq org-e-latex-listings 'minted)
- (let* ((org-lang (org-element-get-property :language inline-src-block))
- (mint-lang (or (cadr (assq (intern org-lang)
- org-e-latex-minted-langs))
- org-lang))
- (options (org-e-latex--make-option-string
- org-e-latex-minted-options)))
- (concat (format "\\mint%s{%s}"
- (if (string= options "") "" (format "[%s]" options))
- mint-lang)
- separator code separator)))
- ;; Use listings package.
- (t
- ;; Maybe translate language's name.
- (let* ((org-lang (org-element-get-property :language inline-src-block))
- (lst-lang (or (cadr (assq (intern org-lang)
- org-e-latex-listings-langs))
- org-lang))
- (options (org-e-latex--make-option-string
- (append org-e-latex-listings-options
- `(("language" ,lst-lang))))))
- (concat (format "\\lstinline[%s]" options)
- separator code separator))))))
- ;;;; Inlinetask
- (defun org-e-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-secondary-string
- (org-element-get-property :title inlinetask) 'e-latex info))
- (todo (and (plist-get info :with-todo-keywords)
- (let ((todo (org-element-get-property
- :todo-keyword inlinetask)))
- (and todo
- (org-export-secondary-string todo 'e-latex info)))))
- (todo-type (org-element-get-property :todo-type inlinetask))
- (tags (and (plist-get info :with-tags)
- (org-element-get-property :tags inlinetask)))
- (priority (and (plist-get info :with-priority)
- (org-element-get-property :priority inlinetask))))
- ;; If `org-e-latex-format-inlinetask-function' is provided, call it
- ;; with appropriate arguments.
- (if (functionp org-e-latex-format-inlinetask-function)
- (funcall org-e-latex-format-inlinetask-function
- todo todo-type priority title tags contents)
- ;; Otherwise, use a default template.
- (org-e-latex--wrap-label
- inlinetask
- (let ((full-title
- (concat
- (when todo (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
- (when priority (format "\\framebox{\\#%c} " priority))
- title
- (when tags (format "\\hfill{}\\textsc{%s}" tags)))))
- (format (concat "\\begin{center}\n"
- "\\fbox{\n"
- "\\begin{minipage}[c]{.6\\textwidth}\n"
- "%s\n\n"
- "\\rule[.8em]{\\textwidth}{2pt}\n\n"
- "%s"
- "\\end{minipage}\n"
- "}\n"
- "\\end{center}")
- full-title contents))))))
- ;;;; Item
- (defun org-e-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."
- ;; Grab `:level' from plain-list properties, which is always the
- ;; first element above current item.
- (let* ((level (org-element-get-property
- :level (car (plist-get info :genealogy))))
- (counter (let ((count (org-element-get-property :counter item)))
- (and count
- (< level 4)
- (format "\\setcounter{enum%s}{%s}\n"
- (nth level '("i" "ii" "iii" "iv"))
- (1- count)))))
- (checkbox (let ((checkbox (org-element-get-property :checkbox item)))
- (cond ((eq checkbox 'on) "$\\boxtimes$ ")
- ((eq checkbox 'off) "$\\Box$ ")
- ((eq checkbox 'trans) "$\\boxminus$ "))))
- (tag (let ((tag (org-element-get-property :tag item)))
- (and tag
- (format "[%s]" (org-export-secondary-string
- tag 'e-latex info))))))
- (concat counter "\\item" tag " " checkbox contents)))
- ;;;; Keyword
- (defun org-e-latex-keyword (keyword contents info)
- "Transcode a KEYWORD element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((key (downcase (org-element-get-property :key keyword)))
- (value (org-element-get-property :value keyword)))
- (cond
- ((string= key "latex") value)
- ((string= key "index") (format "\\index{%s}" value))
- ((string= key "target")
- (format "\\label{%s}" (org-export-solidify-link-text value)))
- ((string= key "toc")
- (let ((value (downcase value)))
- (cond
- ((string-match "\\<headlines\\>" value)
- (let ((depth (or (and (string-match "[0-9]+" value)
- (string-to-number (match-string 0 value)))
- (plist-get info :with-toc))))
- (concat
- (when (wholenump depth)
- (format "\\setcounter{tocdepth}{%s}\n" depth))
- "\\tableofcontents")))
- ((string= "tables" value) "\\listoftables")
- ((string= "figures" value) "\\listoffigures")
- ((string= "listings" value) "\\listoflistings"))))
- ((string= key "include")
- (org-export-included-file keyword 'e-latex info)))))
- ;;;; Latex Environment
- (defun org-e-latex-latex-environment (latex-environment contents info)
- "Transcode a LATEX-ENVIRONMENT element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-latex--wrap-label
- latex-environment
- (org-remove-indentation (org-element-get-property :value latex-environment))))
- ;;;; Latex Fragment
- (defun org-e-latex-latex-fragment (latex-fragment contents info)
- "Transcode a LATEX-FRAGMENT object from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-get-property :value latex-fragment))
- ;;;; Line Break
- (defun org-e-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."
- "\\\\")
- ;;;; Link
- (defun org-e-latex-link--inline-image (path info)
- "Return LaTeX code for an image at PATH.
- INFO is a plist containing export options."
- (let* ((parent-props (nth 1 (car (plist-get info :genealogy))))
- (caption (org-e-latex--caption/label-string
- (plist-get parent-props :caption)
- (plist-get parent-props :name)
- info))
- ;; Retrieve latex attributes from the element around.
- (attr (let ((raw-attr
- (mapconcat #'identity
- (plist-get parent-props :attr_latex) " ")))
- (unless (string= raw-attr "") raw-attr)))
- (disposition
- (cond
- ((and attr (string-match "\\<wrap\\>" attr)) 'wrap)
- ((and attr (string-match "\\<multicolumn\\>" attr)) 'multicolumn)
- ((or (and attr (string-match "\\<float\\>" attr))
- (not (string= caption "")))
- 'float)))
- (placement
- (cond
- ((and attr (string-match "\\<placement=\\(\\S-+\\)" attr))
- (org-match-string-no-properties 1 attr))
- ((eq disposition 'wrap) "{l}{0.5\\textwidth}")
- ((eq disposition 'float)
- (concat "[" org-e-latex-default-figure-position "]"))
- (t ""))))
- ;; Now clear ATTR from any special keyword and set a default
- ;; value if nothing is left.
- (setq attr
- (if (not attr) ""
- (org-trim
- (replace-regexp-in-string
- "\\(wrap\\|multicolumn\\|float\\|placement=\\S-+\\)" "" attr))))
- (setq attr (cond ((not (string= attr "")) attr)
- ((eq disposition 'float) "width=0.7\\textwidth")
- ((eq disposition 'wrap) "width=0.48\\textwidth")
- (t (or org-e-latex-image-default-option ""))))
- ;; Return proper string, depending on DISPOSITION.
- (case disposition
- ('wrap (format "\\begin{wrapfigure}%s
- \\centering
- \\includegraphics[%s]{%s}
- %s\\end{wrapfigure}" placement attr path caption))
- ('mulicolumn (format "\\begin{figure*}%s
- \\centering
- \\includegraphics[%s]{%s}
- %s\\end{figure*}" placement attr path caption))
- ('float (format "\\begin{figure}%s
- \\centering
- \\includegraphics[%s]{%s}
- %s\\end{figure}" placement attr path caption))
- (t (format "\\includegraphics[%s]{%s}" attr path)))))
- (defun org-e-latex-link (link desc info)
- "Transcode a LINK object from Org to LaTeX.
- DESC is the description part of the link, or the empty string.
- INFO is a plist holding contextual information. See
- `org-export-data'."
- (let* ((type (org-element-get-property :type link))
- (raw-path (org-element-get-property :path link))
- ;; Ensure DESC really exists, or set it to nil.
- (desc (and (not (string= desc "")) desc))
- (imagep (org-export-inline-image-p
- link org-e-latex-inline-image-extensions))
- (path (cond
- ((member type '("http" "https" "ftp" "mailto"))
- (concat type ":" raw-path))
- (imagep (if (not (file-name-absolute-p raw-path)) raw-path
- (expand-file-name raw-path)))
- ((string= type "file")
- (when (string-match "\\(.+\\)::.+" raw-path)
- (setq raw-path (match-string 1 raw-path)))
- (if (file-name-absolute-p raw-path)
- (concat "file://" (expand-file-name raw-path))
- ;; TODO: Not implemented yet. Concat also:
- ;; (org-export-directory :LaTeX info)
- (concat "file://" raw-path)))
- (t raw-path)))
- protocol)
- (cond
- ;; Image file.
- (imagep (org-e-latex-link--inline-image path info))
- ;; Target or radioed target: replace link with the normalized
- ;; custom-id/target name.
- ((member type '("target" "radio"))
- (format "\\hyperref[%s]{%s}"
- (org-export-solidify-link-text path)
- (or desc (org-export-secondary-string path 'e-latex info))))
- ;; Links pointing to an headline: Find destination and build
- ;; appropriate referencing commanding.
- ((member type '("custom-id" "fuzzy" "id"))
- (let ((destination (if (string= type "fuzzy")
- (org-export-resolve-fuzzy-link link info)
- (org-export-resolve-id-link link info))))
- ;; Fuzzy link points to a target. Do as above.
- (case (car destination)
- (target
- (format "\\hyperref[%s]{%s}"
- (org-export-solidify-link-text
- (org-element-get-property :raw-value destination))
- (or desc
- (org-export-secondary-string
- (org-element-get-property :raw-link link)
- 'e-latex info))))
- ;; Fuzzy link points to an headline. If headlines are
- ;; numbered and the link has no description, display
- ;; headline's number. Otherwise, display description or
- ;; headline's title.
- (headline
- (let ((label
- (format "sec-%s"
- (mapconcat
- 'number-to-string
- (org-export-get-headline-number destination info)
- "-"))))
- (if (and (plist-get info :section-numbers) (not desc))
- (format "\\ref{%s}" label)
- (format "\\hyperref[%s]{%s}" label
- (or desc
- (org-export-secondary-string
- (org-element-get-property :title destination)
- 'e-latex info))))))
- ;; Fuzzy link points nowhere.
- (otherwise
- (format "\\texttt{%s}"
- (or desc
- (org-export-secondary-string
- (org-element-get-property :raw-link link)
- 'e-latex info)))))))
- ;; Coderef: replace link with the reference name or the
- ;; equivalent line number.
- ((string= type "coderef")
- (format (org-export-get-coderef-format path (or desc ""))
- (org-export-resolve-coderef path info)))
- ;; Link type is handled by a special function.
- ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
- (funcall protocol (org-link-unescape path) desc 'latex))
- ;; 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 "\\texttt{%s}" desc)))))
- ;;;; Babel Call
- ;; Babel Calls are ignored.
- ;;;; Macro
- (defun org-e-latex-macro (macro contents info)
- "Transcode a MACRO element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- ;; Use available tools.
- (org-export-expand-macro macro info))
- ;;;; Paragraph
- (defun org-e-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-e-latex-plain-list (plain-list contents info)
- "Transcode a PLAIN-LIST element from Org to LaTeX.
- CONTENTS is the contents of the list. INFO is a plist holding
- contextual information."
- (let* ((type (org-element-get-property :type plain-list))
- (paralist-types '("inparaenum" "asparaenum" "inparaitem" "asparaitem"
- "inparadesc" "asparadesc"))
- (paralist-regexp (concat
- "\\("
- (mapconcat 'identity paralist-types "\\|")
- "\\)"))
- (attr (mapconcat #'identity
- (org-element-get-property :attr_latex plain-list)
- " "))
- (latex-type (cond
- ((and attr
- (string-match
- (format "\\<%s\\>" paralist-regexp) attr))
- (match-string 1 attr))
- ((eq type 'ordered) "enumerate")
- ((eq type 'unordered) "itemize")
- ((eq type 'descriptive) "description"))))
- (org-e-latex--wrap-label
- plain-list
- (format "\\begin{%s}%s\n%s\\end{%s}"
- latex-type
- ;; Once special environment, if any, has been removed, the
- ;; rest of the attributes will be optional arguments.
- ;; They will be put inside square brackets if necessary.
- (let ((opt (replace-regexp-in-string
- (format " *%s *" paralist-regexp) "" attr)))
- (cond ((string= opt "") "")
- ((string-match "\\`\\[[^][]+\\]\\'" opt) opt)
- (t (format "[%s]" opt))))
- contents
- latex-type))))
- ;;;; Plain Text
- (defun org-e-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."
- ;; Protect %, #, &, $, ~, ^, _, { and }.
- (while (string-match "\\([^\\]\\|^\\)\\([%$#&{}~^_]\\)" text)
- (setq text
- (replace-match (format "\\%s" (match-string 2 text)) nil t text 2)))
- ;; Protect \
- (setq text (replace-regexp-in-string
- "\\(?:[^\\]\\|^\\)\\(\\\\\\)\\(?:[^%$#&{}~^_\\]\\|$\\)"
- "$\\backslash$" text nil t 1))
- ;; LaTeX into \LaTeX{} and TeX into \TeX{}.
- (let ((case-fold-search nil)
- (start 0))
- (while (string-match "\\<\\(\\(?:La\\)?TeX\\)\\>" text start)
- (setq text (replace-match
- (format "\\%s{}" (match-string 1 text)) nil t text)
- start (match-end 0))))
- ;; Handle quotation marks
- (setq text (org-e-latex--quotation-marks text info))
- ;; Convert special strings.
- (when (plist-get info :with-special-strings)
- (while (string-match (regexp-quote "...") text)
- (setq text (replace-match "\\ldots{}" nil t text))))
- ;; Handle break preservation if required.
- (when (plist-get info :preserve-breaks)
- (setq text (replace-regexp-in-string "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
- text)))
- ;; Return value.
- text)
- ;;;; Property Drawer
- (defun org-e-latex-property-drawer (property-drawer contents info)
- "Transcode a PROPERTY-DRAWER element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual
- information."
- ;; The property drawer isn't exported but we want separating blank
- ;; lines nonetheless.
- "")
- ;;;; Quote Block
- (defun org-e-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."
- (org-e-latex--wrap-label
- quote-block
- (format "\\begin{quote}\n%s\\end{quote}" contents)))
- ;;;; Quote Section
- (defun org-e-latex-quote-section (quote-section contents info)
- "Transcode a QUOTE-SECTION element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((value (org-remove-indentation
- (org-element-get-property :value quote-section))))
- (when value (format "\\begin{verbatim}\n%s\\end{verbatim}" value))))
- ;;;; Section
- (defun org-e-latex-section (section contents info)
- "Transcode a SECTION element from Org to LaTeX.
- CONTENTS holds the contents of the section. INFO is a plist
- holding contextual information."
- contents)
- ;;;; Radio Target
- (defun org-e-latex-radio-target (radio-target text info)
- "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-solidify-link-text
- (org-element-get-property :raw-value radio-target))
- text))
- ;;;; Special Block
- (defun org-e-latex-special-block (special-block contents info)
- "Transcode a SPECIAL-BLOCK element from Org to LaTeX.
- CONTENTS holds the contents of the block. INFO is a plist
- holding contextual information."
- (let ((type (downcase (org-element-get-property :type special-block))))
- (org-e-latex--wrap-label
- special-block
- (format "\\begin{%s}\n%s\\end{%s}" type contents type))))
- ;;;; Src Block
- (defun org-e-latex-src-block (src-block contents info)
- "Transcode a SRC-BLOCK element from Org to LaTeX.
- CONTENTS holds the contents of the item. INFO is a plist holding
- contextual information."
- (let* ((lang (org-element-get-property :language src-block))
- (code (org-export-handle-code src-block info))
- (caption (org-element-get-property :caption src-block))
- (label (org-element-get-property :name src-block))
- (custom-env (and lang
- (cadr (assq (intern lang)
- org-e-latex-custom-lang-environments)))))
- (cond
- ;; No source fontification.
- ((not org-e-latex-listings)
- (let ((caption-str (org-e-latex--caption/label-string
- caption label info))
- (float-env (when caption "\\begin{figure}[H]\n%s\n\\end{figure}")))
- (format (or float-env "%s")
- (concat
- caption-str
- (format "\\begin{verbatim}\n%s\\end{verbatim}" code)))))
- ;; Custom environment.
- (custom-env
- (format "\\begin{%s}\n%s\\end{%s}\n" custom-env code custom-env))
- ;; Use minted package.
- ((eq org-e-latex-listings 'minted)
- (let* ((mint-lang (or (cadr (assq (intern lang) org-e-latex-minted-langs))
- lang))
- (float-env (when (or label caption)
- (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}"
- (org-e-latex--caption/label-string
- caption label info))))
- (body (format "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
- (org-e-latex--make-option-string
- org-e-latex-minted-options)
- mint-lang code)))
- (if float-env (format float-env body) body)))
- ;; Use listings package.
- (t
- (let ((lst-lang
- (or (cadr (assq (intern lang) org-e-latex-listings-langs)) lang))
- (caption-str
- (when caption
- (let ((main (org-export-secondary-string
- (car caption) 'e-latex info)))
- (if (not (cdr caption)) (format "{%s}" main)
- (format
- "{[%s]%s}"
- (org-export-secondary-string (cdr caption) 'e-latex info)
- main))))))
- (concat (format "\\lstset{%s}\n"
- (org-e-latex--make-option-string
- (append org-e-latex-listings-options
- `(("language" ,lst-lang))
- (when label `(("label" ,label)))
- (when caption-str
- `(("caption" ,caption-str))))))
- (format "\\begin{lstlisting}\n%s\\end{lstlisting}" code)))))))
- ;;;; Statistics Cookie
- (defun org-e-latex-statistics-cookie (statistics-cookie contents info)
- "Transcode a STATISTICS-COOKIE object from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (org-element-get-property :value statistics-cookie))
- ;;;; Subscript
- (defun org-e-latex-subscript (subscript contents info)
- "Transcode a SUBSCRIPT object from Org to LaTeX.
- CONTENTS is the contents of the object. INFO is a plist holding
- contextual information."
- (format (if (= (length contents) 1) "$_%s$" "$_{\\mathrm{%s}}$") contents))
- ;;;; Superscript
- (defun org-e-latex-superscript (superscript contents info)
- "Transcode a SUPERSCRIPT object from Org to LaTeX.
- CONTENTS is the contents of the object. INFO is a plist holding
- contextual information."
- (format (if (= (length contents) 1) "$^%s$" "$^{\\mathrm{%s}}$") contents))
- ;;;; Table
- (defun org-e-latex-table--format-string (table table-info info)
- "Return an appropriate format string for TABLE.
- TABLE-INFO is the plist containing format info about the table,
- as returned by `org-export-table-format-info'. INFO is a plist
- used as a communication channel.
- The format string one placeholder for the body of the table."
- (let* ((label (org-element-get-property :name table))
- (caption (org-e-latex--caption/label-string
- (org-element-get-property :caption table) label info))
- (attr (mapconcat #'identity
- (org-element-get-property :attr_latex table)
- " "))
- ;; Determine alignment string.
- (alignment (org-e-latex-table--align-string attr table-info))
- ;; Determine environment for the table: longtable, tabular...
- (table-env (cond
- ((not attr) org-e-latex-default-table-environment)
- ((string-match "\\<longtable\\>" attr) "longtable")
- ((string-match "\\(tabular.\\)" attr)
- (org-match-string-no-properties 1 attr))
- (t org-e-latex-default-table-environment)))
- ;; If table is a float, determine environment: table or table*.
- (float-env (cond
- ((string= "longtable" table-env) nil)
- ((and attr
- (or (string-match (regexp-quote "table*") attr)
- (string-match "\\<multicolumn\\>" attr)))
- "table*")
- ((or (not (string= caption "")) label) "table")))
- ;; Extract others display options.
- (width (and attr
- (string-match "\\<width=\\(\\S-+\\)" attr)
- (org-match-string-no-properties 1 attr)))
- (placement (if (and attr
- (string-match "\\<placement=\\(\\S-+\\)" attr))
- (org-match-string-no-properties 1 attr)
- (concat "["
- org-e-latex-default-figure-position
- "]"))))
- ;; Prepare the final format string for the table.
- (cond
- ;; Longtable.
- ((string= "longtable" table-env)
- (format "\\begin{longtable}{%s}\n%s\n%%s\n%s\\end{longtable}"
- alignment
- (if (or (not org-e-latex-table-caption-above)
- (string= "" caption))
- ""
- (concat (org-trim caption) "\\\\"))
- (if (or org-e-latex-table-caption-above
- (string= "" caption))
- ""
- (concat (org-trim caption) "\\\\\n"))))
- ;; Others.
- (t (concat (when float-env
- (concat
- (format "\\begin{%s}%s\n" float-env placement)
- (if org-e-latex-table-caption-above caption "")))
- (when org-e-latex-tables-centered "\\begin{center}\n")
- (format "\\begin{%s}%s{%s}\n%%s\n\\end{%s}"
- table-env
- (if width (format "{%s}" width) "")
- alignment
- table-env)
- (when org-e-latex-tables-centered "\n\\end{center}")
- (when float-env
- (concat (if org-e-latex-table-caption-above "" caption)
- (format "\n\\end{%s}" float-env))))))))
- (defun org-e-latex-table--align-string (attr table-info)
- "Return an appropriate LaTeX alignment string.
- ATTR is a string containing table's LaTeX specific attributes.
- TABLE-INFO is the plist containing format info about the table,
- as returned by `org-export-table-format-info'."
- (or (and attr
- (string-match "\\<align=\\(\\S-+\\)" attr)
- (match-string 1 attr))
- (let* ((align (copy-sequence (plist-get table-info :alignment)))
- (colgroups (copy-sequence (plist-get table-info :column-groups)))
- (cols (length align))
- (separators (make-vector (1+ cols) "")))
- ;; Ignore the first column if it's special.
- (when (plist-get table-info :special-column-p)
- (aset align 0 "") (aset colgroups 0 nil))
- (let ((col 0))
- (mapc (lambda (el)
- (let ((gr (aref colgroups col)))
- (when (memq gr '(start start-end))
- (aset separators col "|"))
- (when (memq gr '(end start-end))
- (aset separators (1+ col) "|")))
- (incf col))
- align))
- ;; Build the LaTeX specific alignment string.
- (loop for al across align
- for sep across separators
- concat (concat sep al) into output
- finally return (concat output (aref separators cols))))))
- (defun org-e-latex-table (table contents info)
- "Transcode a TABLE element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (let ((attr (mapconcat #'identity
- (org-element-get-property :attr_latex table)
- " "))
- (raw-table (org-element-get-property :raw-table table)))
- (cond
- ;; Case 1: verbatim table.
- ((or org-e-latex-tables-verbatim
- (and attr (string-match "\\<verbatim\\>" attr)))
- (format "\\begin{verbatim}\n%s\n\\end{verbatim}"
- (org-export-clean-table
- raw-table
- (plist-get (org-export-table-format-info raw-table)
- :special-column-p))))
- ;; Case 2: table.el table. Convert it using appropriate tools.
- ((eq (org-element-get-property :type table) 'table.el)
- (require 'table)
- ;; Ensure "*org-export-table*" buffer is empty.
- (and (get-buffer "*org-export-table*")
- (kill-buffer (get-buffer "*org-export-table*")))
- (let ((output (with-temp-buffer
- (insert raw-table)
- (goto-char 1)
- (re-search-forward "^[ \t]*|[^|]" nil t)
- (table-generate-source 'latex "*org-export-table*")
- (with-current-buffer "*org-export-table*"
- (org-trim (buffer-string))))))
- (kill-buffer (get-buffer "*org-export-table*"))
- ;; Remove left out comments.
- (while (string-match "^%.*\n" output)
- (setq output (replace-match "" t t output)))
- ;; When the "rmlines" attribute is provided, remove all hlines
- ;; but the the one separating heading from the table body.
- (when (and attr (string-match "\\<rmlines\\>" attr))
- (let ((n 0) (pos 0))
- (while (and (< (length output) pos)
- (setq pos (string-match "^\\\\hline\n?" output pos)))
- (incf n)
- (unless (= n 2) (setq output (replace-match "" nil nil output))))))
- (if org-e-latex-tables-centered
- (format "\\begin{center}\n%s\n\\end{center}" output)
- output)))
- ;; Case 3: Standard table.
- (t
- (let* ((table-info (org-export-table-format-info raw-table))
- (clean-table (org-export-clean-table
- raw-table (plist-get table-info :special-column-p)))
- (columns-number (length (plist-get table-info :alignment))))
- ;; Convert ROWS to send them to `orgtbl-to-latex'. In
- ;; particular, send each cell to
- ;; `org-element-parse-secondary-string' to expand any Org
- ;; object within. Eventually, flesh the format string out with
- ;; the table.
- (format (org-e-latex-table--format-string table table-info info)
- (orgtbl-to-latex
- (mapcar
- (lambda (row)
- (if (string-match org-table-hline-regexp row)
- 'hline
- (mapcar
- (lambda (cell)
- (org-export-secondary-string
- (org-element-parse-secondary-string
- cell
- (cdr (assq 'table org-element-string-restrictions)))
- 'e-latex info))
- (org-split-string row "[ \t]*|[ \t]*"))))
- (org-split-string clean-table "\n"))
- `(:tstart nil :tend nil
- ;; Longtable environment requires specific
- ;; header line end.
- :hlend ,(and attr
- (string-match "\\<longtable\\>" attr)
- (format "\\\\
- \\hline
- \\endhead
- \\hline\\multicolumn{%d}{r}{Continued on next page}\\\\
- \\endfoot
- \\endlastfoot"
- columns-number))))))))))
- ;;;; Target
- (defun org-e-latex-target (target text info)
- "Transcode a TARGET object from Org to LaTeX.
- TEXT is the text of the target. INFO is a plist holding
- contextual information."
- (format "\\label{%s}%s"
- (org-export-solidify-link-text
- (org-element-get-property :raw-value target))
- text))
- ;;;; Time-stamp
- (defun org-e-latex-time-stamp (time-stamp contents info)
- "Transcode a TIME-STAMP object from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual
- information."
- (let ((value (org-element-get-property :value time-stamp))
- (type (org-element-get-property :type time-stamp))
- (appt-type (org-element-get-property :appt-type time-stamp)))
- (concat (cond ((eq appt-type 'scheduled)
- (format "\\textbf{\\textsc{%s}} " org-scheduled-string))
- ((eq appt-type 'deadline)
- (format "\\textbf{\\textsc{%s}} " org-deadline-string))
- ((eq appt-type 'closed)
- (format "\\textbf{\\textsc{%s}} " org-closed-string)))
- (cond ((memq type '(active active-range))
- (format org-e-latex-active-timestamp-format value))
- ((memq type '(inactive inactive-range))
- (format org-e-latex-inactive-timestamp-format value))
- (t
- (format org-e-latex-diary-timestamp-format value))))))
- ;;;; Verbatim
- (defun org-e-latex-verbatim (verbatim contents info)
- "Transcode a VERBATIM object from Org to LaTeX.
- CONTENTS is nil. INFO is a plist used as a communication
- channel."
- (let ((fmt (cdr (assoc (org-element-get-property :marker verbatim)
- org-e-latex-emphasis-alist)))
- (value (org-element-get-property :value verbatim)))
- (cond
- ;; Handle the `verb' special case.
- ((eq 'verb fmt)
- (let ((separator (org-e-latex--find-verb-separator value)))
- (concat "\\verb" separator value separator)))
- ;; Handle the `protectedtexttt' special case.
- ((eq 'protectedtexttt fmt)
- (let ((start 0)
- (trans '(("\\" . "\\textbackslash{}")
- ("~" . "\\textasciitilde{}")
- ("^" . "\\textasciicircum{}")))
- (rtn "")
- char)
- (while (string-match "[\\{}$%&_#~^]" value)
- (setq char (match-string 0 value))
- (if (> (match-beginning 0) 0)
- (setq rtn (concat rtn (substring value 0 (match-beginning 0)))))
- (setq value (substring value (1+ (match-beginning 0))))
- (setq char (or (cdr (assoc char trans)) (concat "\\" char))
- rtn (concat rtn char)))
- (setq value (concat rtn value)
- fmt "\\texttt{%s}")
- (while (string-match "--" value)
- (setq value (replace-match "-{}-" t t value)))
- (format fmt value)))
- ;; Else use format string.
- (t (format fmt value)))))
- ;;;; Verse Block
- (defun org-e-latex-verse-block (verse-block contents info)
- "Transcode a VERSE-BLOCK element from Org to LaTeX.
- CONTENTS is nil. INFO is a plist holding contextual information."
- (org-e-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.
- (progn
- (setq contents (replace-regexp-in-string
- "^ *\\\\\\\\$" "\\\\vspace*{1em}"
- (replace-regexp-in-string
- "\\(\\\\\\\\\\)?[ \t]*\n" " \\\\\\\\\n"
- (org-remove-indentation
- (org-export-secondary-string
- (org-element-get-property :value verse-block)
- 'e-latex info)))))
- (while (string-match "^[ \t]+" contents)
- (let ((new-str (format "\\hspace*{%dem}"
- (length (match-string 0 contents)))))
- (setq contents (replace-match new-str nil t contents))))
- (format "\\begin{verse}\n%s\\end{verse}" contents))))
- ;;; Interactive functions
- (defun org-e-latex-export-to-latex
- (&optional subtreep visible-only body-only ext-plist pub-dir)
- "Export current buffer to a LaTeX file.
- If narrowing is active in the current buffer, only export its
- narrowed part.
- If a region is active, export that region.
- When optional argument SUBTREEP is non-nil, export the sub-tree
- at point, extracting information from the headline properties
- first.
- When optional argument VISIBLE-ONLY is non-nil, don't export
- contents of hidden elements.
- When optional argument BODY-ONLY is non-nil, only write code
- between \"\\begin{document}\" and \"\\end{document}\".
- EXT-PLIST, when provided, is a property list with external
- parameters overriding Org default settings, but still inferior to
- file-local settings.
- When optional argument PUB-DIR is set, use it as the publishing
- directory.
- Return output file's name."
- (interactive)
- (let ((outfile (org-export-output-file-name ".tex" subtreep pub-dir)))
- (org-export-to-file
- 'e-latex outfile subtreep visible-only body-only ext-plist)))
- (defun org-e-latex-export-to-pdf
- (&optional subtreep visible-only body-only ext-plist pub-dir)
- "Export current buffer to LaTeX then process through to PDF.
- If narrowing is active in the current buffer, only export its
- narrowed part.
- If a region is active, export that region.
- When optional argument SUBTREEP is non-nil, export the sub-tree
- at point, extracting information from the headline properties
- first.
- When optional argument VISIBLE-ONLY is non-nil, don't export
- contents of hidden elements.
- When optional argument BODY-ONLY is non-nil, only write code
- between \"\\begin{document}\" and \"\\end{document}\".
- EXT-PLIST, when provided, is a property list with external
- parameters overriding Org default settings, but still inferior to
- file-local settings.
- When optional argument PUB-DIR is set, use it as the publishing
- directory.
- Return PDF file's name."
- (interactive)
- (org-e-latex-compile
- (org-e-latex-export-to-latex
- subtreep visible-only body-only ext-plist pub-dir)))
- (defun org-e-latex-compile (texfile)
- "Compile a TeX file.
- TEXFILE is the name of the file being compiled. Processing is
- done through the command specified in `org-e-latex-pdf-process'.
- Return PDF file name or an error if it couldn't be produced."
- (let* ((wconfig (current-window-configuration))
- (texfile (file-truename texfile))
- (base (file-name-sans-extension texfile))
- errors)
- (message (format "Processing LaTeX file %s ..." texfile))
- (unwind-protect
- (progn
- (cond
- ;; A function is provided: Apply it.
- ((functionp org-latex-to-pdf-process)
- (funcall org-latex-to-pdf-process (shell-quote-argument texfile)))
- ;; A list is provided: Replace %b, %f and %o with appropriate
- ;; values in each command before applying it. Output is
- ;; redirected to "*Org PDF LaTeX Output*" buffer.
- ((consp org-e-latex-pdf-process)
- (let* ((out-dir (or (file-name-directory texfile) "./"))
- (outbuf (get-buffer-create "*Org PDF LaTeX Output*")))
- (mapc
- (lambda (command)
- (shell-command
- (replace-regexp-in-string
- "%b" (shell-quote-argument base)
- (replace-regexp-in-string
- "%f" (shell-quote-argument texfile)
- (replace-regexp-in-string
- "%o" (shell-quote-argument out-dir) command)))
- outbuf))
- org-e-latex-pdf-process)
- ;; Collect standard errors from output buffer.
- (setq errors (org-e-latex-collect-errors outbuf))))
- (t (error "No valid command to process to PDF")))
- (let ((pdffile (concat base ".pdf")))
- ;; Check for process failure. Provide collected errors if
- ;; possible.
- (if (not (file-exists-p pdffile))
- (error (concat (format "PDF file %s wasn't produced" pdffile)
- (when errors (concat ": " errors))))
- ;; Else remove log files, when specified, and signal end of
- ;; process to user, along with any error encountered.
- (when org-e-latex-remove-logfiles
- (dolist (ext org-e-latex-logfiles-extensions)
- (let ((file (concat base "." ext)))
- (when (file-exists-p file) (delete-file file)))))
- (message (concat "Process completed"
- (if (not errors) "."
- (concat " with errors: " errors)))))
- ;; Return output file name.
- pdffile))
- (set-window-configuration wconfig))))
- (defun org-e-latex-collect-errors (buffer)
- "Collect some kind of errors from \"pdflatex\" command output.
- BUFFER is the buffer containing output.
- Return collected error types as a string, or nil if there was
- none."
- (with-current-buffer buffer
- (save-excursion
- (goto-char (point-max))
- ;; Find final "pdflatex" run.
- (when (re-search-backward "^[ \t]*This is pdf.*?TeX.*?Version" nil t)
- (let ((case-fold-search t)
- (errors ""))
- (when (save-excursion
- (re-search-forward "Reference.*?undefined" nil t))
- (setq errors (concat errors " [undefined reference]")))
- (when (save-excursion
- (re-search-forward "Citation.*?undefined" nil t))
- (setq errors (concat errors " [undefined citation]")))
- (when (save-excursion
- (re-search-forward "Undefined control sequence" nil t))
- (setq errors (concat errors " [undefined control sequence]")))
- (when (save-excursion
- (re-search-forward "^! LaTeX.*?Error" nil t))
- (setq errors (concat errors " [LaTeX error]")))
- (when (save-excursion
- (re-search-forward "^! Package.*?Error" nil t))
- (setq errors (concat errors " [package error]")))
- (and (org-string-nw-p errors) (org-trim errors)))))))
- (provide 'org-e-latex)
- ;;; org-e-latex.el ends here
|