1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336 |
- ;;; ox-latex.el --- LaTeX Back-End for Org Export Engine -*- lexical-binding: t; -*-
- ;; Copyright (C) 2011-2022 Free Software Foundation, Inc.
- ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
- ;; Maintainer: Daniel Fleischer <danflscr@gmail.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 'org-macs)
- (org-assert-version)
- (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)
- (declare-function engrave-faces-latex-gen-preamble "ext:engrave-faces-latex")
- (declare-function engrave-faces-latex-buffer "ext:engrave-faces-latex")
- (declare-function engrave-faces-latex-gen-preamble-line "ext:engrave-faces-latex")
- (declare-function engrave-faces-get-theme "ext:engrave-faces")
- (defvar engrave-faces-latex-output-style)
- (defvar engrave-faces-current-preset-style)
- (defvar engrave-faces-latex-mathescape)
- ;;; 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-engraved-options nil nil org-latex-engraved-options)
- (:latex-engraved-preamble nil nil org-latex-engraved-preamble)
- (:latex-engraved-theme "LATEX_ENGRAVED_THEME" nil org-latex-engraved-theme)
- (: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-src-block-backend nil nil org-latex-src-block-backend)
- (: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-language-alist
- '(("am" :babel-ini-only "amharic" :polyglossia "amharic" :lang-name "Amharic")
- ("ar" :babel "arabic" :polyglossia "arabic" :lang-name "Arabic")
- ("ast" :babel-ini-only "asturian" :polyglossia "asturian" :lang-name "Asturian")
- ("bg" :babel "bulgarian" :polyglossia "bulgarian" :lang-name "Bulgarian")
- ("bn" :babel-ini-only "bengali" :polyglossia "bengali" :lang-name "Bengali")
- ("bo" :babel-ini-only "tibetan" :polyglossia "tibetan" :lang-name "Tibetan")
- ("br" :babel "breton" :polyglossia "breton" :lang-name "Breton")
- ("ca" :babel "catalan" :polyglossia "catalan" :lang-name "Catalan")
- ("cop" :babel-ini-only "coptic" :polyglossia "coptic" :lang-name "Coptic")
- ("cs" :babel "czech" :polyglossia "czech" :lang-name "Czech")
- ("cy" :babel "welsh" :polyglossia "welsh" :lang-name "Welsh")
- ("da" :babel "danish" :polyglossia "danish" :lang-name "Danish")
- ("de" :babel "ngerman" :polyglossia "german" :polyglossia-variant "german" :lang-name "German")
- ("de-at" :babel "naustrian" :polyglossia "german" :polyglossia-variant "austrian" :lang-name "German")
- ("dsb" :babel "lsorbian" :polyglossia "sorbian" :polyglossia-variant "lower" :lang-name "Lower Sorbian")
- ("dv" :babel-ini-only "divehi" :polyglossia "divehi" :lang-name "Divehi")
- ("el" :babel "greek" :polyglossia "greek" :lang-name "Greek")
- ("el-polyton" :babel "polutonikogreek" :polyglossia "greek" :polyglossia-variant "polytonic" :lang-name "Polytonic Greek")
- ("en" :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English")
- ("en-au" :babel "australian" :polyglossia "english" :polyglossia-variant "australian" :lang-name "English")
- ("en-gb" :babel "british" :polyglossia "english" :polyglossia-variant "uk" :lang-name "English")
- ("en-nz" :babel "newzealand" :polyglossia "english" :polyglossia-variant "newzealand" :lang-name "English")
- ("en-us" :babel "american" :polyglossia "english" :polyglossia-variant "usmax" :lang-name "English")
- ("eo" :babel "esperanto" :polyglossia "esperanto" :lang-name "Esperanto")
- ("es" :babel "spanish" :polyglossia "spanish" :lang-name "Spanish")
- ("es-mx" :babel "spanishmx" :polyglossia "spanish" :polyglossia-variant "mexican" :lang-name "Spanish")
- ("et" :babel "estonian" :polyglossia "estonian" :lang-name "Estonian")
- ("eu" :babel "basque" :polyglossia "basque" :lang-name "Basque")
- ("fa" :babel "farsi" :polyglossia "farsi" :lang-name "Farsi")
- ("fi" :babel "finnish" :polyglossia "finnish" :lang-name "Finnish")
- ("fr" :babel "french" :polyglossia "french" :lang-name "French")
- ("fr-ca" :babel "canadien" :polyglossia "french" :polyglossia-variant "canadian" :lang-name "French")
- ("fur" :babel "friulan" :polyglossia "friulan" :lang-name "Friulian")
- ("ga" :babel "irish" :polyglossia "irish" :lang-name "Irish")
- ("gd" :babel "scottish" :polyglossia "scottish" :lang-name "Scottish Gaelic")
- ("gl" :babel "galician" :polyglossia "galician" :lang-name "Galician")
- ("he" :babel "hebrew" :polyglossia "hebrew" :lang-name "Hebrew")
- ("hi" :babel "hindi" :polyglossia "hindi" :lang-name "Hindi")
- ("hr" :babel "croatian" :polyglossia "croatian" :lang-name "Croatian")
- ("hsb" :babel "uppersorbian" :polyglossia "sorbian" :polyglossia-variant "upper" :lang-name "Upper Sorbian")
- ("hu" :babel "magyar" :polyglossia "magyar" :lang-name "Magyar")
- ("hy" :babel-ini-only "armenian" :polyglossia "armenian" :lang-name "Armenian")
- ("ia" :babel "interlingua" :polyglossia "interlingua" :lang-name "Interlingua")
- ("id" :babel-ini-only "bahasai" :polyglossia "bahasai" :lang-name "Bahasai")
- ("is" :babel "icelandic" :polyglossia "icelandic" :lang-name "Icelandic")
- ("it" :babel "italian" :polyglossia "italian" :lang-name "Italian")
- ("kn" :babel-ini-only "kannada" :polyglossia "kannada" :lang-name "Kannada")
- ("la" :babel "latin" :polyglossia "latin" :lang-name "Latin")
- ("la-classic" :babel "classiclatin" :polyglossia "latin" :polyglossia-variant "classic" :lang-name "Classic Latin")
- ("la-medieval" :babel "medievallatin" :polyglossia "latin" :polyglossia-variant "medieval" :lang-name "Medieval Latin")
- ("la-ecclesiastic" :babel "ecclesiasticlatin" :polyglossia "latin" :polyglossia-variant "ecclesiastic" :lang-name "Ecclesiastic Latin")
- ("lo" :babel-ini-only "lao" :polyglossia "lao" :lang-name "Lao")
- ("lt" :babel "lithuanian" :polyglossia "lithuanian" :lang-name "Lithuanian")
- ("lv" :babel "latvian" :polyglossia "latvian" :lang-name "Latvian")
- ("ml" :babel-ini-only "malayalam" :polyglossia "malayalam" :lang-name "Malayalam")
- ("mr" :babel-ini-only "maranthi" :polyglossia "maranthi" :lang-name "Maranthi")
- ("nb" :babel "norsk" :polyglossia "norwegian" :polyglossia-variant "bokmal" :lang-name "Norwegian Bokmål")
- ("nl" :babel "dutch" :polyglossia "dutch" :lang-name "Dutch")
- ("nn" :babel "nynorsk" :polyglossia "norwegian" :polyglossia-variant "nynorsk" :lang-name "Norwegian Nynorsk")
- ("no" :babel "norsk" :polyglossia "norsk" :lang-name "Norwegian")
- ("oc" :babel "occitan" :polyglossia "occitan" :lang-name "Occitan")
- ("pl" :babel "polish" :polyglossia "polish" :lang-name "Polish")
- ("pms" :babel "piedmontese" :polyglossia "piedmontese" :lang-name "Piedmontese")
- ("pt" :babel "portuges" :polyglossia "portuges" :lang-name "Portuges")
- ("pt-br" :babel "brazilian" :polyglossia "brazilian" :lang-name "Portuges")
- ("rm" :babel-ini-only "romansh" :polyglossia "romansh" :lang-name "Romansh")
- ("ro" :babel "romanian" :polyglossia "romanian" :lang-name "Romanian")
- ("ru" :babel "russian" :polyglossia "russian" :lang-name "Russian")
- ("sa" :babel-ini-only "sanskrit" :polyglossia "sanskrit" :lang-name "Sanskrit")
- ("sk" :babel "slovak" :polyglossia "slovak" :lang-name "Slovak")
- ("sl" :babel "slovene" :polyglossia "slovene" :lang-name "Slovene")
- ("sq" :babel "albanian" :polyglossia "albanian" :lang-name "Albanian")
- ("sr" :babel "serbian" :polyglossia "serbian" :lang-name "Serbian")
- ("sv" :babel "swedish" :polyglossia "swedish" :lang-name "Swedish")
- ("syr" :babel-ini-only "syriac" :polyglossia "syriac" :lang-name "Syriac")
- ("ta" :babel-ini-only "tamil" :polyglossia "tamil" :lang-name "Tamil")
- ("te" :babel-ini-only "telugu" :polyglossia "telugu" :lang-name "Telugu")
- ("th" :babel "thai" :polyglossia "thai" :lang-name "Thai")
- ("tk" :babel "turkmen" :polyglossia "turkmen" :lang-name "Turkmen")
- ("tr" :babel "turkish" :polyglossia "turkish" :lang-name "Turkish")
- ("uk" :babel "ukrainian" :polyglossia "ukrainian" :lang-name "Ukrainian")
- ("ur" :babel-ini-only "urdu" :polyglossia "urdu" :lang-name "Urdu")
- ("vi" :babel "vietnamese" :polyglossia "vietnamese" :lang-name "Vietnamese"))
- "Alist between language code and its properties for LaTeX export.
- In each element of the list car is always the code of the
- language and cdr is a property list. Valid keywords for this
- list can be:
- - `:babel' the name of the language loaded by the Babel LaTeX package
- - `:polyglossia' the name of the language loaded by the Polyglossia
- LaTeX package
- - `:babel-ini-only' the name of the language loaded by Babel
- exclusively through the new ini files method. See
- `http://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf'
- - `:polyglossia-variant' the language variant loaded by Polyglossia
- - `:lang-name' the actual name of the language.")
- (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))
- ("https" . ,(rx "."
- (or "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-src-block-backend 'verbatim
- "Backend used to generate source code listings.
- This sets the behaviour for fontifying source code, possibly even with
- color. There are four implementations of this functionality you may
- choose from (ordered from least to most capable):
- 1. Verbatim
- 2. Listings
- 3. Minted
- 4. Engraved
- The first two options provide basic syntax
- highlighting (listings), or none at all (verbatim).
- When using listings, you also need to make use of LaTeX package
- \"listings\"e. The \"color\" LaTeX package is also needed if you
- would like color too. These can simply be added to
- `org-latex-packages-alist', using customise or something like:
- (require \\='ox-latex)
- (add-to-list \\='org-latex-packages-alist \\='(\"\" \"listings\"))
- (add-to-list \\='org-latex-packages-alist \\='(\"\" \"color\"))
- There are two further options for more comprehensive
- fontification. The first can be set with,
- (setq org-latex-src-block-backend \\='minted)
- which causes source code to be exported using the LaTeX package
- minted 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'.
- The most comprehensive option can be set with,
- (setq org-latex-src-block-backend \\='engraved)
- which causes source code to be run through
- `engrave-faces-latex-buffer', which generates colorings using
- Emacs' font-lock information. This requires the Emacs package
- engrave-faces (available from ELPA), and the LaTeX package
- fvextra be installed.
- The styling of the engraved result can customised with
- `org-latex-engraved-preamble' and `org-latex-engraved-options'.
- The default preamble also uses the LaTeX package tcolorbox in
- addition to fvextra."
- :group 'org-export-latex
- :type '(choice
- (const :tag "Use listings" listings)
- (const :tag "Use minted" minted)
- (const :tag "Use engrave-faces-latex" engraved)
- (const :tag "Export verbatim" verbatim))
- :safe (lambda (s) (memq s '(listings minted engraved verbatim))))
- (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 or cons cell 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\")))
- ; or
- (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 or cons cell containing two strings: the name of the
- option, and the value. For example,
- (setq org-latex-minted-options
- \\='((\"bgcolor\" \"bg\") (\"frame\" \"lines\")))
- ; or
- (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"))
- (defcustom org-latex-engraved-preamble
- "\\usepackage{fvextra}
- [FVEXTRA-SETUP]
- % Make line numbers smaller and grey.
- \\renewcommand\\theFancyVerbLine{\\footnotesize\\color{black!40!white}\\arabic{FancyVerbLine}}
- \\usepackage{xcolor}
- % In case engrave-faces-latex-gen-preamble has not been run.
- \\providecolor{EfD}{HTML}{f7f7f7}
- \\providecolor{EFD}{HTML}{28292e}
- % Define a Code environment to prettily wrap the fontified code.
- \\usepackage[breakable,xparse]{tcolorbox}
- \\DeclareTColorBox[]{Code}{o}%
- {colback=EfD!98!EFD, colframe=EfD!95!EFD,
- fontupper=\\footnotesize\\setlength{\\fboxsep}{0pt},
- colupper=EFD,
- IfNoValueTF={#1}%
- {boxsep=2pt, arc=2.5pt, outer arc=2.5pt,
- boxrule=0.5pt, left=2pt}%
- {boxsep=2.5pt, arc=0pt, outer arc=0pt,
- boxrule=0pt, leftrule=1.5pt, left=0.5pt},
- right=2pt, top=1pt, bottom=0.5pt,
- breakable}
- [LISTINGS-SETUP]"
- "Preamble content injected when using engrave-faces-latex for source blocks.
- This is relevant when `org-latex-src-block-backend' is set to `engraved'.
- There is quite a lot of flexibility in what this preamble can be,
- as long as it:
- - Loads the fvextra package.
- - Loads the package xcolor (if it is not already loaded elsewhere).
- - Defines a \"Code\" environment (note the capital C), which all
- \"Verbatim\" environments (provided by fvextra) will be wrapped with.
- In the default value the colors \"EFD\" and \"EfD\" are provided
- as they are respectively the foreground and background colours,
- just in case they aren't provided by the generated preamble, so
- we can assume they are always set.
- Within this preamble there are two recognised macro-like placeholders:
- [FVEXTRA-SETUP]
- [LISTINGS-SETUP]
- Unless you have a very good reason, both of these placeholders
- should be included in the preamble.
- FVEXTRA-SETUP sets fvextra's defaults according to
- `org-latex-engraved-options', and LISTINGS-SETUP creates the
- listings environment used for captioned or floating code blocks,
- as well as defining \\listoflistings."
- :group 'org-export-latex
- :type 'string
- :package-version '(Org . "9.6"))
- (defcustom org-latex-engraved-options
- '(("commandchars" . "\\\\\\{\\}")
- ("highlightcolor" . "white!95!black!80!blue")
- ("breaklines" . "true")
- ("breaksymbol" . "\\color{white!60!black}\\tiny\\ensuremath{\\hookrightarrow}"))
- "Association list of options for the latex fvextra package when engraving code.
- These options are set using \\fvset{...} in the preamble of the
- LaTeX export. Each element of the alist should be a list or cons
- cell containing two strings: the name of the option, and the
- value. For example,
- (setq org-latex-engraved-options
- \\='((\"highlightcolor\" \"green\") (\"frame\" \"lines\")))
- ; or
- (setq org-latex-engraved-options
- \\='((\"highlightcolor\" . \"green\") (\"frame\" . \"lines\")))
- will result in the following LaTeX in the preamble
- \\fvset{%
- bgcolor=bg,
- frame=lines}
- This will affect all fvextra environments. Note that the same
- options will be applied to all blocks. 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 '(alist :key-type (string :tag "option")
- :value-type (string :tag "value")))
- (defcustom org-latex-engraved-theme nil
- "The theme that should be used for engraved code, when non-nil.
- This can be set to any theme defined in `engrave-faces-themes' or
- loadable by Emacs. When set to t, the current Emacs theme is
- used. When nil, no theme is applied."
- :group 'org-export-latex
- :type 'symbol)
- (defun org-latex-generate-engraved-preamble (info)
- "Generate the preamble to setup engraved code.
- The result is constructed from the :latex-engraved-preamble and
- :latex-engraved-optionsn export options, the default values of
- which are given by `org-latex-engraved-preamble' and
- `org-latex-engraved-options' respectively."
- (let* ((engraved-options
- (plist-get info :latex-engraved-options))
- (engraved-preamble (plist-get info :latex-engraved-preamble))
- (engraved-theme (plist-get info :latex-engraved-theme))
- (engraved-themes
- (mapcar
- #'intern
- (cl-delete-duplicates
- (org-element-map
- (plist-get info :parse-tree)
- '(src-block inline-src-block)
- (lambda (src)
- (plist-get
- (org-export-read-attribute :attr_latex src)
- :engraved-theme))
- info))))
- (gen-theme-spec
- (lambda (theme)
- (if (eq engrave-faces-latex-output-style 'preset)
- (engrave-faces-latex-gen-preamble theme)
- (engrave-faces-latex-gen-preamble-line
- 'default
- (alist-get 'default
- (if theme
- (engrave-faces-get-theme (intern theme))
- engrave-faces-current-preset-style)))))))
- (when (stringp engraved-theme)
- (setq engraved-theme (intern engraved-theme)))
- (when (string-match "^[ \t]*\\[FVEXTRA-SETUP\\][ \t]*\n?" engraved-preamble)
- (setq engraved-preamble
- (replace-match
- (concat
- "\\fvset{%\n "
- (org-latex--make-option-string engraved-options ",\n ")
- "}\n")
- t t
- engraved-preamble)))
- (when (string-match "^[ \t]*\\[LISTINGS-SETUP\\][ \t]*\n?" engraved-preamble)
- (setq engraved-preamble
- (replace-match
- (format
- "%% Support listings with captions
- \\usepackage{float}
- \\floatstyle{%s}
- \\newfloat{listing}{htbp}{lst}
- \\newcommand{\\listingsname}{Listing}
- \\floatname{listing}{\\listingsname}
- \\newcommand{\\listoflistingsname}{List of Listings}
- \\providecommand{\\listoflistings}{\\listof{listing}{\\listoflistingsname}}\n"
- (if (memq 'src-block org-latex-caption-above)
- "plaintop" "plain"))
- t t
- engraved-preamble)))
- (concat
- "\n% Setup for code blocks [1/2]\n\n"
- engraved-preamble
- "\n\n% Setup for code blocks [2/2]: syntax highlighting colors\n\n"
- (if (require 'engrave-faces-latex nil t)
- (if engraved-themes
- (concat
- (mapconcat
- (lambda (theme)
- (format
- "\n\\newcommand{\\engravedtheme%s}{%%\n%s\n}"
- (replace-regexp-in-string "[^A-Za-z]" "" (symbol-name theme))
- (replace-regexp-in-string
- "newcommand" "renewcommand"
- (replace-regexp-in-string
- "#" "##"
- (funcall gen-theme-spec theme)))))
- engraved-themes
- "\n")
- "\n\n"
- (cond
- ((memq engraved-theme engraved-themes)
- (concat "\\engravedtheme"
- (replace-regexp-in-string
- "[^A-Za-z]" "" engraved-theme)
- "\n"))
- (t (funcall gen-theme-spec engraved-theme))))
- (funcall gen-theme-spec engraved-theme))
- (message "Cannot engrave source blocks. Consider installing `engrave-faces'.")
- "% WARNING syntax highlighting unavailable as engrave-faces-latex was missing.\n")
- "\n")))
- ;;;; 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.
- The command output will be parsed to extract compilation errors and
- warnings according to `org-latex-known-warnings'.
- 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:"))
- (`src-block "lst:")
- (_ 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))
- (memq (plist-get info :latex-src-block-backend)
- '(verbatim nil)))))
- (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 (not (memq (plist-get info :latex-src-block-backend)
- '(verbatim nil)))
- "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 optional argument to Babel or the mandatory argument to
- `\babelprovide' command 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))
- (plist (cdr
- (assoc language-code org-latex-language-alist)))
- (language (plist-get plist :babel))
- (language-ini-only (plist-get plist :babel-ini-only))
- ;; If no language is set, or Babel package is not loaded, or
- ;; LANGUAGE keyword value is a language served by Babel
- ;; exclusively through ini files, return HEADER as-is.
- (header (if (or language-ini-only
- (not (stringp language-code))
- (not (string-match "\\\\usepackage\\[\\(.*\\)\\]{babel}" header)))
- header
- (let ((options (save-match-data
- (org-split-string (match-string 1 header) ",[ \t]*"))))
- ;; If LANGUAGE is already loaded, return header
- ;; without AUTO. Otherwise, replace AUTO with language or
- ;; append language if AUTO is not present. Languages that are
- ;; served in Babel exclusively through ini files are not added
- ;; to the babel argument, and must be loaded using
- ;; `\babelprovide'.
- (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)))))
- ;; If `\babelprovide[args]{AUTO}' is present, AUTO is
- ;; replaced by LANGUAGE.
- (if (not (string-match "\\\\babelprovide\\[.*\\]{\\(.+\\)}" header))
- header
- (let ((prov (match-string 1 header)))
- (when (equal "AUTO" prov)
- (replace-regexp-in-string (format
- "\\(\\\\babelprovide\\[.*\\]\\)\\({\\)%s}" prov)
- (format "\\1\\2%s}"
- (or language language-ini-only))
- header t))))))
- (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* ((plist (cdr
- (assoc language org-latex-language-alist)))
- (polyglossia-variant (plist-get plist :polyglossia-variant))
- (polyglossia-lang (plist-get plist :polyglossia))
- (l (if (equal l language)
- polyglossia-lang
- l)))
- (format (if main-language-set (format "\\setotherlanguage{%s}\n" l)
- (setq main-language-set t)
- "\\setmainlanguage%s{%s}\n")
- (if polyglossia-variant
- (format "[variant=%s]" polyglossia-variant)
- "")
- 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 &optional separator)
- "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)
- (let ((keyword (car pair))
- (value (pcase (cdr pair)
- ((pred stringp) (cdr pair))
- ((pred consp) (cadr pair)))))
- (concat keyword
- (when value
- (concat "="
- (if (string-match-p (rx (any "[]")) value)
- (format "{%s}" value)
- value))))))
- options
- (or separator ",")))
- (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))
- (plist (cdr
- (assoc lang org-latex-language-alist))))
- ;; Here the actual name of the LANGUAGE or LANG is used.
- (or (plist-get plist :lang-name)
- 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.
- ;; LaTeX displays today's date by default. One can override this by
- ;; inserting \date{} for no date, or \date{string} with any other
- ;; string to be displayed as the 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)))
- ;; engrave-faces-latex preamble
- (when (and (eq org-latex-src-block-backend 'engraved)
- (org-element-map (plist-get info :parse-tree)
- '(src-block inline-src-block) #'identity
- info t))
- (org-latex-generate-engraved-preamble info))
- ;; 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))
- (lang (org-element-property :language inline-src-block)))
- (pcase (plist-get info :latex-src-block-backend)
- (`verbatim (org-latex--text-markup code 'code info))
- (`minted (org-latex-inline-src-block--minted info code lang))
- (`engraved (org-latex-inline-src-block--engraved info code lang))
- (`listings (org-latex-inline-src-block--listings info code lang))
- (oldval
- (message "Please update the LaTeX src-block-backend to %s"
- (if oldval "listings" "verbatim"))
- (if oldval
- (org-latex-inline-src-block--listings info code lang)
- (org-latex--text-markup code 'code info))))))
- (defun org-latex-inline-src-block--minted (info code lang)
- "Transcode an inline src block's content from Org to LaTeX, using minted.
- INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
- (let ((mint-lang (or (cadr (assq (intern lang)
- (plist-get info :latex-minted-langs)))
- (downcase 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)))
- (defun org-latex-inline-src-block--engraved (info code lang)
- "Transcode an inline src block's content from Org to LaTeX, using engrave-faces.
- INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
- (org-latex-src--engrave-code
- code lang nil (plist-get info :latex-engraved-options) t))
- (defun org-latex-inline-src-block--listings (info code lang)
- "Transcode an inline src block's content from Org to LaTeX, using lstlistings.
- INFO, CODE, and LANG are provided by `org-latex-inline-src-block'."
- (let* ((lst-lang (or (cadr (assq (intern lang)
- (plist-get info :latex-listings-langs)))
- lang))
- (separator (org-latex--find-verb-separator code))
- (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\\linewidth}\n"
- full-title "\n\n"
- (and (org-string-nw-p contents)
- (concat "\\rule[.8em]{\\linewidth}{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-src-block-backend)
- ((nil) "\\listoffigures")
- (minted "\\listoflistings")
- (engraved "\\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)
- ((string= float "t") 'figure)
- ((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)))
- ;; While \includegraphics is fine with unicode in the path,
- ;; \includesvg is prone to producing errors.
- (if (and (string-match-p "[^[:ascii:]]" path)
- (equal filetype "svg"))
- (concat "\\detokenize{" path "}")
- 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 (org-export-link-localise 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)))
- (funcall
- (pcase (plist-get info :latex-src-block-backend)
- ((or `verbatim (guard (not lang))) #'org-latex-src-block--verbatim)
- (`minted #'org-latex-src-block--minted)
- (`engraved #'org-latex-src-block--engraved)
- (`listings #'org-latex-src-block--listings)
- ((guard custom-env) #'org-latex-src-block--custom)
- (oldval
- (message "Please update the LaTeX src-block-backend to %s"
- (if oldval "listings" "verbatim"))
- (if oldval
- #'org-latex-src-block--listings
- #'org-latex-src-block--verbatim)))
- :src-block src-block
- :info info
- :lang lang
- :caption caption
- :caption-above-p caption-above-p
- :label label
- :num-start num-start
- :retain-labels retain-labels
- :attributes attributes
- :float float
- :custom-env custom-env))))
- (cl-defun org-latex-src-block--verbatim
- (&key src-block info caption caption-above-p float &allow-other-keys)
- "Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
- LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
- and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
- (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))))
- (cl-defun org-latex-src-block--custom
- (&key src-block info caption caption-above-p attributes float custom-env &allow-other-keys)
- "Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
- LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
- and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
- (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) "")))))))
- (cl-defun org-latex-src-block--minted
- (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
- "Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
- LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
- and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
- (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)))
- (multicolumn-p (string= "multicolumn" float))
- (float-env
- (cond
- ((or caption multicolumn-p)
- (cons
- (concat "\\begin{listing" (when multicolumn-p "*")
- "}[" placement "]\n"
- (if caption-above-p caption-str ""))
- (concat "\n" (if caption-above-p "" caption-str)
- "\\end{listing" (when multicolumn-p "*") "}")))
- ((string= "t" float)
- (cons
- (concat "\\begin{listing}[" placement "]\n")
- "\n\\end{listing}"))))
- (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 'string-width
- (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)))))))
- (concat (car float-env) body (cdr float-env))))
- (defun org-latex-src--engrave-mathescape-p (info options)
- "From the export INFO plist, and the per-block OPTIONS, determine mathescape."
- (let ((default-options (plist-get info :latex-engraved-options))
- (mathescape-status
- (lambda (opts)
- (cl-some
- (lambda (opt)
- (or (and
- (null (cdr opt))
- (cond
- ((string-match-p
- "\\(?:^\\|,\\)mathescape=false\\(?:,\\|$\\)"
- (car opt))
- 'no)
- ((or (string-match-p
- "\\(?:^\\|,\\)mathescape\\(?:=true\\)?\\(?:,\\|$\\)"
- (car opt))
- (string= "mathescape" (car opt)))
- 'yes)))
- (and
- (string= (car opt) "mathescape")
- (cond
- ((or (and (stringp (cdr opt)) (string= (cdr opt) "true"))
- (equal '("true") (cdr opt)))
- 'yes)
- ((or (and (stringp (cdr opt)) (string= "false" (cdr opt)))
- (equal '("false") (cdr opt)))
- 'no)))))
- opts))))
- (let ((mathescape (or (funcall mathescape-status default-options)
- (funcall mathescape-status options))))
- (when (eq mathescape 'yes)
- (or engrave-faces-latex-mathescape t)))))
- (defun org-latex-src--engrave-code (content lang &optional theme options inline)
- "Engrave CONTENT to LaTeX in a LANG-mode buffer, and give the result.
- When the THEME symbol is non-nil, that theme will be used.
- When INLINE is nil, a Verbatim environment wrapped in a Code
- environment will be used. When t, a Verb command will be used.
- When OPTIONS is provided, as either a string or list of key-value
- pairs accepted by `org-latex--make-option-string', it is passed
- to the Verbatim environment or Verb command."
- (if (require 'engrave-faces-latex nil t)
- (let* ((lang-mode (and lang (org-src-get-lang-mode lang)))
- (engrave-faces-current-preset-style
- (if theme
- (engrave-faces-get-theme theme)
- engrave-faces-current-preset-style))
- (engraved-buffer
- (with-temp-buffer
- (insert (replace-regexp-in-string "\n\\'" "" content))
- (when lang-mode
- (if (functionp lang-mode)
- (funcall lang-mode)
- (message "Cannot engrave code as %s. %s is undefined."
- lang lang-mode)))
- (engrave-faces-latex-buffer)))
- (engraved-code
- (with-current-buffer engraved-buffer
- (buffer-string)))
- (engraved-options
- (when options
- (concat "["
- (if (listp options)
- (org-latex--make-option-string options)
- options)
- "]")))
- (engraved-wrapped
- (if inline
- (concat "\\Verb" engraved-options "{" engraved-code "}")
- (concat "\\begin{Code}\n\\begin{Verbatim}" engraved-options "\n"
- engraved-code "\n\\end{Verbatim}\n\\end{Code}"))))
- (kill-buffer engraved-buffer)
- (if theme
- (concat "{\\engravedtheme"
- (replace-regexp-in-string "[^A-Za-z]" ""
- (symbol-name theme))
- engraved-wrapped
- "}")
- engraved-wrapped))
- (user-error "Cannot engrave code as `engrave-faces-latex' is unavailable.")))
- (cl-defun org-latex-src-block--engraved
- (&key src-block info lang caption caption-above-p num-start retain-labels attributes float &allow-other-keys)
- "Transcode a SRC-BLOCK element from Org to LaTeX, using engrave-faces-latex.
- LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
- and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
- (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)))
- (multicolumn-p (string= "multicolumn" float))
- (float-env
- (cond
- ((or caption multicolumn-p)
- (cons
- (concat "\\begin{listing" (when multicolumn-p "*")
- "}[" placement "]\n"
- (if caption-above-p caption-str ""))
- (concat "\n" (if caption-above-p "" caption-str)
- "\\end{listing" (when multicolumn-p "*") "}")))
- ((string= "t" float)
- (cons
- (concat "\\begin{listing}[" placement "]\n")
- "\n\\end{listing}"))))
- (options
- (let ((engraved-options (plist-get info :latex-engraved-options))
- (local-options (plist-get attributes :options)))
- (append
- (when (and num-start (not (assoc "linenos" engraved-options)))
- `(("linenos")
- ("firstnumber" ,(number-to-string (1+ num-start)))))
- (and local-options `((,local-options))))))
- (engraved-theme (plist-get attributes :engraved-theme))
- (content
- (let* ((code-info (org-export-unravel-code src-block))
- (max-width
- (apply 'max
- (mapcar 'string-width
- (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)))))
- (body
- (let ((engrave-faces-latex-mathescape
- (org-latex-src--engrave-mathescape-p info options)))
- (org-latex-src--engrave-code
- content lang
- (when engraved-theme (intern engraved-theme))
- options))))
- (concat (car float-env) body (cdr float-env))))
- (cl-defun org-latex-src-block--listings
- (&key src-block info lang caption caption-above-p label num-start retain-labels attributes float &allow-other-keys)
- "Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
- LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
- and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
- (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 'string-width
- (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', `org-latex--math-table' or
- ;; `org-latex--org-tabbing' 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: Tabbing
- ((string= type "tabbing")
- (org-table--org-tabbing table contents info))
- ;; Case 4: 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--align-string-tabbing (table info)
- "Return LaTeX alignment string using tabbing environment.
- TABLE is the considered table. INFO is a plist used as
- a communication channel."
- (or (org-export-read-attribute :attr_latex table :align)
- (let* ((count
- ;; Count the number of cells in the first row.
- (length
- (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 #'identity)))
- ;; Calculate the column width, using a proportion of
- ;; the document's textwidth.
- (separator
- (format "\\hspace{%s\\textwidth} \\= "
- (- (/ 1.0 count) 0.01))))
- (concat (apply 'concat (make-list count separator))
- "\\kill"))))
- (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*")
- ((string= float "t") "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))
- (opt (org-export-read-attribute :attr_latex table :options))
- (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{%s}\n%s\\end{%s}"
- table-env
- (if opt (format "[%s]" opt) "")
- width
- alignment
- contents
- table-env)))
- (org-latex--decorate-table output attr caption above? info))))))
- (defun org-table--org-tabbing (table contents info)
- "Return tabbing environment LaTeX code for 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
- `tabbing' as its `:mode' attribute."
- (format "\\begin{%s}\n%s\n%s\\end{%s}"
- "tabbing"
- (org-latex--align-string-tabbing table info)
- contents
- "tabbing"))
- (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."
- (let ((type (org-export-read-attribute
- :attr_latex (org-export-get-parent-table table-cell) :mode))
- (scientific-format (plist-get info :latex-table-scientific-notation)))
- (concat
- (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)
- (if (string= type "tabbing") " \\> " " & ")))))
- ;;;; 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)))
- ;; Cannot find the compiler inserted by
- ;; `org-latex-template' -> `org-latex--insert-compiler'.
- ;; Use a fallback.
- "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
|