Hi all, As discussed already, I would like to introduce fontspec configuration and fallback fonts incrementally.
My main justification is that the mother of all solutions covering all kinds of corner cases can only be achieved if we start introducing things little by little and test them against *real life* use cases, ie. documents we all use on a daily basis. So... what is this first patch about ? If you use lualatex, Org mode will include fontspec in the LaTeX preamble, unless you tell it not to. So, my take is that if it is there, we can use this hint to activate font definitions à la fontspec and fallback fonts if needed. All definitions are placed *before* the LaTeX header, so anything you have there re. fonts will hopefully prevail. ** Next steps: 1. Examine the combinations of fontspec, babel and polyglossia and determine which are viable and which not to warn the user. 2. If the configuration is viable and we are using polyglossia or babel, put the fonts and localisation info as soon as possible in the latex preamble and clean up redundancies. This second part will come after the summer break. Best, /PA -- Fragen sind nicht da, um beantwortet zu werden, Fragen sind da um gestellt zu werden Georg Kreisler "Sagen's Paradeiser" (ORF: Als Radiohören gefährlich war) => write BE! Year 2 of the New Koprocracy This was produced by a human (implied virtues and weaknesses acknowledged) I'd hate this being fed to any form of AS (sorry AI)...
From fbdb750b20981642d1d60a3fbeeac42235e10c30 Mon Sep 17 00:00:00 2001 From: "Pedro A. Aranda" <[email protected]> Date: Wed, 8 Jul 2026 09:14:37 +0200 Subject: [PATCH 1/2] LaTeX export: add org-latex-fontspec-config * doc/org-manual.org (*** Controlling font setup for LuaLaTeX andXeLaTeX): New section describing org-latex-fontspec-config. * etc/ORG-NEWS: Annouce org-latex-fontspec-config. * lisp/org.el (org-get-string-scripts): New function to extract the script information from a string. This function is currently used by ox-latex and ox-beamer. * lisp/ox-beamer.el (org-beamer-template): Add the document script information to the information channel before anything else. * lisp/ox-latex.el (Information channel): Add the fontspec configuration. (org-latex-fontspec-config): New custom variable to store the font configuration for the fontspec package. (org-latex--fontspec-prelude): New function to create the fontspec configuration as a string. (org-latex-guess-fontspec): New funciton to insert the fontspec configuration when the fontspec package is requested in the LaTeX prelude. (org-latex-make-preamble): Add the previous function in the chain of guessers, just before the babel and polyglossia guessers. Fix null class options or empty string. * lisp/ox-latex.el (org-latex--mk-options): Options can be a list of strings. * testing/lisp/test-ox-latex.el (test-ox-latex/pdf-metadata): Clean up output. (test-ox-latex/lualatex-fontspec-recognised): Test correct implementation of fontspec handling. (test-ox-latex/lualatex-fontspec-recognised): Test fallbacks. (test-ox-latex/lualatex-fontspec-latex-header-not-lost): LATEX_HEADER prevails over fontspec configuration. Cater for legacy documents. --- doc/org-manual.org | 131 ++++++++++++++++++++++++++++++++ etc/ORG-NEWS | 6 ++ lisp/org.el | 25 +++++++ lisp/ox-beamer.el | 11 +++ lisp/ox-latex.el | 168 +++++++++++++++++++++++++++++++++++++----- testing/lisp/test-ox-latex.el | 78 +++++++++++++++++++- 6 files changed, 400 insertions(+), 19 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index cd8903a7e..e04417dfe 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -15187,6 +15187,137 @@ contents, unless you set the =UNNUMBERED= property to =notoc=: :END: #+end_example +*** Controlling font setup for LuaLaTeX and XeLaTeX +:PROPERTIES: +:CUSTOM_ID: fontspec-configuration +:END: +#+cindex: fontspec in @LaTeX{} export +#+vindex: org-latex-fontspec-config + +Modern, UTF8-capable LaTeX compilers LuaLaTeX and XeLaTeX configure +fonts using the [[https://latex3.github.io/fontspec/][~fontspec~]] +package. Org provides a custom variable to fine-tune font +configuration when the ~fontspec~ package is used. With the default +configuration provided by Org, this package is included when LuaLaTeX +or XeLaTeX are declared as the LaTeX target compiler. + +LaTeX document classes include a set of default fonts, usually from +the [[https://www.gust.org.pl/projects/e-foundry/latin-modern][Latin +Modern (LM) Family of Fonts]]. If you need to use other fonts, you can +do so by mapping your font preferences to the four main font families +defined in LaTeX: + +| "main" | Roman or Serif font (default) | +| "sans" | Sans Serif font | +| "mono" | Monospaced (terminal) font | +| "math" | Font for mathematical expressions | + +This mapping takes place in ~org-latex-fontspec-config~. Although not +mandatory, it is recommended that you define mapping for the four +families. An example mapping the fonts to use another popular font family, +[[https://www.gust.org.pl/projects/e-foundry/tex-gyre][the TeX Gyre +(TG) Collection of Fonts]] could be [fn::We use this family, because +it is also included in most LaTeX distributions.]: + +#+BEGIN_SRC emacs-lisp +(setq org-latex-fontspec-config + '(("main" :font "TeX Gyre Termes") + ("sans" :font "TeX Gyre Heros") + ("mono" :font "TeX Gyre Cursor") + ("math" :font "TeX Gyre Math")) +#+END_SRC + +As you see, each element in the list maps one of the LaTeX font +families to a property =:font=, that indicates the font to use for the +specific family. This font must be installed in your system, + +Additionally, you can also define "=:features="[fn::You may also use +=:props= as a synonym for =:features=.] for each of the fonts. +Features are additional +[[https://latex3.github.io/fontspec/user.html][font options]] that +modify their appearance. A common example is scaling the mono-typed +font to approximately match the size of the ~main~ font and provide a +more uniform appearance to your document: + +#+BEGIN_SRC emacs-lisp +(setq org-latex-fontspec-config + '(("main" :font "TeX Gyre Termes") + ("sans" :font "TeX Gyre Heros") + ("mono" :font "TeX Gyre Cursor" :features "Scale=MatchLowercase") + ("math" :font "TeX Gyre Math"))) +#+END_SRC + +**** Fallback fonts with LuaLaTeX +:PROPERTIES: +:UNNUMBERED: t +:END: + +You will be warned by Org that your document could not be correctly +typeset, if your selection of fonts doesn't cover all scripts used +in the document: +#+BEGIN_EXAMPLE +Warning (ox-latex): PDF file produced with warnings: [Missing +character(s): please load an appropriate font with the fontspec package] +#+END_EXAMPLE + +In the event this message appears, Emacs also provides you with a list +of fonts and *Emacs* script families that caused problems: + +#+BEGIN_EXAMPLE +Warning (emacs): Missing scripts: +For font TeXGyreHeros: emoji +#+END_EXAMPLE + +Although modern Unicode-compatible fonts can represent a wide range of +characters (or glyphs), it is virtually impossible to cover all possible +glyphs in one font. In this case, *and only if you are using +LuaLaTeX*, you will be able to use other fonts you have installed in +your system to provide the missing glyphs. LuaLaTeX can replace glyphs +that are not provided by the document's fonts on the fly, using a +feature called /fallback fonts/. + +An example is a document using emojis. In this case, and provided you +have the =Noto Color Emoji= font installed in your system[fn::Another +font providing emojis is =Apple Color Emoji=], you can use it to add +the missing glyph set, by using the =:fallback= property for the +reported font. [fn::The +[[https://www.gust.org.pl/projects/e-foundry/latin-modern#download][Latin +Modern fonts]], are reported abbreviated as =lm...=. They are used by +default in well-known LaTeX classes as =article=, =report=, etc.] + +#+BEGIN_SRC emacs-lisp +(setq org-latex-fontspec-config + '(("main" :font "Latin Modern Roman") + ("sans" :font "Latin Modern Sans" + :fallback (("emoji" . "Noto Color Emoji:mode=harf"))) + ("mono" :font "Latin Modern Mono" :props "Scale=MatchLowercase") + ("math" :font "Latin Modern Math"))) +#+END_SRC + +Note the following in the code above: +1. The fallback font is followed by additional indications + (=:mode=harf=). You need them in this case to instruct LuaLaTeX to + use a special glyph renderer (harfbuzz). This is not always + needed. These and other options are described in + [[https://mirrors.mit.edu/CTAN/macros/luatex/generic/luaotfload/luaotfload-latex.pdf][the + luaotfload package manual]]. +2. You can add fallback fonts for more Emacs scripts by adding + elements to the =:fallback= property, which is an associative list: + #+BEGIN_SRC emacs-lisp + ("main" :font "Latin Modern Roman" + :fallback (("emoji" . "Noto Color Emoji:mode=harf") + ("han" . "Noto Serif CJK JP") + ("kana" . "Noto Serif CJK JP"))) + #+END_SRC + Org will adjust the fallback font list depending on the document's + contents. You can maintain this variable in a /grow-as-you-go/ + fashion, adding new elements when you need them. You can keep them, + because they will not be added in documents that don't need them. +3. The font names reported by Org are the font names used by + =lualatex=. The spaces may not be included in the system font + names. + + ** Markdown Export :PROPERTIES: :DESCRIPTION: Exporting to Markdown. diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index bb965c02a..f81450f89 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -260,6 +260,12 @@ information. Given the completed and total number of tasks, format the percent cookie =[N%]=. +*** New custom variable ~org-latex-fontspec-config~ + +When using LuaLaTeX (or XeLaTeX in a reduced scope), you can use the +new custom variable ~org-latex-fontspec-config~ to change the +document's fonts and add fallback fonts for missing scripts. + ** Removed or renamed functions and variables *** ~org-babel-remote-temporary-directory~ is now obsolete diff --git a/lisp/org.el b/lisp/org.el index 294a5eb52..c34132202 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -21163,6 +21163,31 @@ (defun org-reftex-citation () org--rds (list (list 'bib bib)))))) (call-interactively 'reftex-citation))) +;;; Emacs scripts in Org documents + +(defun org-get-string-scripts (str) + "Return the list of Emacs scripts in STR. + +This function is called by ox-latex and ox-beamer (initially) and +returns a list of strings with the names of scripts in STR. +An empty list implies that all characters in STR are Latin-1. + +Derived from the initial version proposed by Juan Manuel Macías in +https://list.orgmode.org/orgmode/[email protected]/ +" + (save-match-data + (let ((scripts) + (match-offset t) + (offset 0)) + (while match-offset + (setq match-offset (string-match "\\([^\u0000-\u007F\u0080-\u00FF\u0100-\u017F]\\)" str offset)) + (when match-offset + (when-let* ((matched (match-string 0 str)) + (script (aref char-script-table (string-to-char matched)))) + (setq offset (match-end 1)) + (cl-pushnew (prin1-to-string script) scripts :test #'string=)))) + scripts))) + ;;;; Functions extending outline functionality (defun org-beginning-of-line (&optional n) diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el index 4548d77bf..e8a8e5021 100644 --- a/lisp/ox-beamer.el +++ b/lisp/ox-beamer.el @@ -36,6 +36,10 @@ (org-assert-version) (require 'cl-lib) (require 'ox-latex) +;;; Function declarations + +(declare-function org-get-string-scripts "org" (str)) + ;; Install a default set-up for Beamer export. (unless (assoc "beamer" org-latex-classes) (add-to-list 'org-latex-classes @@ -914,6 +918,13 @@ (defun org-beamer-template (contents info) "Return complete document string after Beamer conversion. CONTENTS is the transcoded contents string. INFO is a plist holding export options." + ;; Before doing anything else, add the script information + ;; to the INFO channel. Used by org-latex-make-preamble + ;; to add fallback fonts for lualatex. + (setq info (plist-put info + :doc-scripts + (org-get-string-scripts contents))) + (let ((title (org-export-data (plist-get info :title) info)) (subtitle (org-export-data (plist-get info :subtitle) info)) (beamer-class (plist-get info :latex-class))) diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index dc5201053..403428c33 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -49,6 +49,7 @@ (defvar engrave-faces-latex-output-style) (defvar engrave-faces-current-preset-style) (defvar engrave-faces-latex-mathescape) +(declare-function org-get-string-scripts "org" (str)) ;;; Define Backend @@ -174,6 +175,7 @@ (org-export-define-backend 'latex (:latex-compiler "LATEX_COMPILER" nil org-latex-compiler) (:latex-descriptive-env "LATEX_DESCRIPTIVE_ENV" nil org-latex-descriptive-environment) (:latex-use-sans nil "latex-use-sans" org-latex-use-sans) + (:latex-fontspec-config nil nil org-latex-fontspec-config) ;; Redefine regular options. (:date "DATE" nil "\\today" parse))) @@ -1602,6 +1604,29 @@ (defcustom org-latex-toc-include-unnumbered nil :type 'boolean :safe #'booleanp) +;;;; Font management + +(defcustom org-latex-fontspec-config nil + "An alist with the configuration for the fontspec package. + +This configuration will be generated when using lualatex or xelatex. + +Each element is defined as +(`font-name' . `font-plist') + where `font-name' one of \"main\", \"sans\", \"mono\" or \"math\" + and `font-plist' is a plist. The keys for this plist are + `:font': font name for font installed in your system + `:features': string or list of strings with font features (optional). + `:fallback': an alist of (`script' . `mapping') to map _Emacs_ script names + to their fallback font (optional). The exporter will warn you + about scripts in your document that need a fallback font." + + :group 'org-export-latex + :package-version '(Org . "10.0") + :type 'alist + :safe #'listp +) + ;;; Internal Functions @@ -1841,7 +1866,103 @@ (defun org-latex-guess-polyglossia-language (header info) languages "")) t t header 0))))) - +;;; +(defun org-latex--fontspec-prelude (info) + "Return the fontspec configuration for the INFO channel as a string. + +If COMPILER is \"xelatex\", omit fallback font detection." + (let ((doc-scripts (plist-get info :doc-scripts)) + (compiler (plist-get info :latex-compiler)) + (fontspec-config (plist-get info :latex-fontspec-config)) + ;; (fontspec-defaults (plist-get info :latex-fontspec-defaults)) + (fallback-found) ;; a list of fallbacks that are really needed + (fallback-alist)) ;; an alist (font_name . fallback-name) + + ;; (message "fontspec-prelude") + (with-temp-buffer + ;; add all fonts with fallback to fallback-alist for lualatex + ;; leave empty for xelatex + (when (string= compiler "lualatex") + (dolist (fconfig fontspec-config) + (when-let* ((fname (car fconfig)) + (config-plist (cdr fconfig)) + (fallback (plist-get config-plist :fallback))) + (push (cons fname (concat "fallback_" fname)) fallback-alist)))) + ;; (message "fallback-alist ==> %s" fallback-alist) + (when fallback-alist ;; if there are fonts with fallbacks (and we use lualatex) + (let ((directlua nil)) ;; Did we write the beginning of this block? + ;; create the directlua header + (dolist (fallback fallback-alist) + ;; (message "fallback ===> %s" fallback) + (when-let* + ((fbf-fname (car fallback)) + (fbf-name (cdr fallback)) + (fbf-plist (alist-get fbf-fname fontspec-config nil nil #'string=)) + (fbf-flist (plist-get fbf-plist :fallback))) + ;; collect all falbacks for scripts that are present in the doc + (let ((fallback-flist + (cl-loop for fpair in fbf-flist + ;; check (car fpair) is in document scripts + ;; and the fallback is not already in the result + when (and (member-ignore-case (car fpair) doc-scripts) + (null (member-ignore-case (cdr fpair) fresult))) + collect (cdr fpair) into fresult + finally return fresult))) + ;; (message "fallback-flist ==> %s" fallback-flist) + (when fallback-flist + (unless directlua ;; add the heading before the first lua block + (insert "\\directlua{\n") + (setq directlua t)) + ;; (setq fallback-flist (cl-remove-duplicates fallback-flist + ;; :test #'string=)) + (setq fallback-found (append fallback-found (list fbf-name))) + (insert (format " luaotfload.add_fallback (\"%s\",{\n" fbf-name)) + ;; Here we get the font fallbacks list + (dolist (fname fallback-flist) + ;; TODO; when (car fpair) in document charsets + (unless (string-match-p ":" fname) ;; fallback declarations may omit ending ':' + (setq fname (concat fname ":"))) ;; when they are plain font names + (insert (format " \"%s\",\n" fname))) + (insert " })\n"))))) + (when directlua ;; if we have found any lua fallbacks, close the lua block + (insert "}\n")))) + ;; (message "fallbacks: %s" fallback-alist) + (dolist (fpair fontspec-config) + (when-let* ((ffamily (car fpair)) + (fplist (cdr fpair)) + (ffont (plist-get fplist :font))) + (insert (format "\\set%sfont{%s}" ffamily ffont)) + ;; add the features + (let ((ffeatures (or (plist-get fplist :features) + (plist-get fplist :props)))) + (when (stringp ffeatures) + (setq ffeatures (list ffeatures))) ;; needs to be a list to concat a possible fallback + ;; (message "--> ffeatures: %s" ffeatures) + (when-let* ((fallback-fn (alist-get ffamily fallback-alist nil nil #'string=)) + (fallback-test (member fallback-fn fallback-found)) ;; nil if not found -> don't add to ffeatures + (fallback-spec (format "RawFeature={fallback=%s}" fallback-fn))) + ;; Add the fallback font spec + (setq ffeatures (cl-concatenate #'list ffeatures (list fallback-spec)))) + ;; (message "ffeatures %s" ffeatures) + (when ffeatures + (insert (org-latex--mk-options ffeatures)))) + (insert "\n"))) + (buffer-string)))) +;;;; +(defun org-latex-guess-fontspec (header info) + "Add the fontspec package configuration passed in INFO to HEADER. + +The HEADER contains \"\\usepackage{fontspec}\", +and INFO contains fontspec font conguration and +add the fontspec configuration after the package." + (when-let* ((fonst (plist-get info :latex-fontspec-config)) + (matched (string-match "\\\\usepackage{fontspec}\n" header)) + (matcher (match-string 0 header)) + (replacer (concat matcher + (org-latex--fontspec-prelude info)))) + (setq header (string-replace matcher replacer header))) + header) +;;; (defun org-latex--remove-packages (pkg-alist info) "Remove packages based on the current LaTeX compiler. @@ -2054,9 +2175,12 @@ ;;; Template (defun org-latex--mk-options (str) "Make STR be enclosed in [ ] or return an empty string if nil or empty. +If STR is a list of strings, join them with \",\". If STR is nil or an empty string, return STR. If STR is a traditional LATEX_CLASS_OPTIONS enclosed in [ ], return it as is. If the square brackets are missing, return STR enclosed in square brackets." + (when (listp str) + (setq str (mapconcat #'identity str ","))) (if (or (not str) (length= str 0)) str (save-match-data ; just in case it is used in a search/replace context (let ((str (concat "[" str "]"))) ; make sure it is enclosed in [] @@ -2088,7 +2212,8 @@ (defun org-latex-make-preamble (info &optional template snippet?) (format "\\DocumentMetadata{%s}" doc-metadata)) (and (not snippet?) (plist-get info :latex-class-pre)) - (if (not class-options) header + (if (or (not class-options) + (string-empty-p class-options)) header (replace-regexp-in-string "^[ \t]*\\\\documentclass\\(\\(\\[[^]]*\\]\\)?\\)" class-options header t nil 1))) @@ -2096,22 +2221,24 @@ (defun org-latex-make-preamble (info &optional template snippet?) (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)) - (and (not snippet?) - (plist-get info :latex-use-sans) - "\\renewcommand*\\familydefault{\\sfdefault}")) - - "")))) + (org-latex-guess-fontspec + (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)) + (and (not snippet?) + (plist-get info :latex-use-sans) + "\\renewcommand*\\familydefault{\\sfdefault}")) + + "")))) + info) info) info))) @@ -2119,6 +2246,11 @@ (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." + ;; Before doing anything else, add the script information + ;; to the INFO channel + (setq info (plist-put info + :doc-scripts + (org-get-string-scripts contents))) (let ((title (org-export-data (plist-get info :title) info)) (spec (org-latex--format-spec info))) (concat diff --git a/testing/lisp/test-ox-latex.el b/testing/lisp/test-ox-latex.el index 74789f85d..3f5cabb02 100644 --- a/testing/lisp/test-ox-latex.el +++ b/testing/lisp/test-ox-latex.el @@ -537,11 +537,87 @@ (ert-deftest test-ox-latex/pdf-metadata () Just to see that DocumentMetadata comes before PassOptions and documentclass " - (message "pdf-metadata: %s" (buffer-string)) + ;; (message "pdf-metadata: %s" (buffer-string)) (goto-char (point-min)) (should (search-forward "\\DocumentMetadata{tagging = on}" nil t)) (should (search-forward "\\PassOptionsToPackage{dvipsnames}{xcolor}" nil t)) (should (re-search-forward "^\\\\documentclass\\[.+?]{report}" nil t)))) +(ert-deftest test-ox-latex/lualatex-fontspec-recognised () + "Test that org-latex-fontspec-config is recognised for lualatex." + (let ((org-latex-fontspec-config + '(("main" :font "FreeSerif") + ("sans" :font "FreeSans")))) + (org-test-with-exported-text + 'latex + "#+TITLE: LuaLaTeX fonts +#+LANGUAGE: en-gb es +#+OPTIONS: toc:nil H:3 num:nil +#+LATEX_COMPILER: lualatex +#+LATEX_CLASS: report +* Testing + +Just to see that I get the fonts Iwant... +" + ;; (message "simple fontspec: %s" (buffer-string)) + (goto-char (point-min)) + (should (search-forward "\\usepackage{fontspec}" nil t)) + (should (search-forward "\\setmainfont{FreeSerif}" nil t)) + (should (search-forward "\\setsansfont{FreeSans}" nil t))))) + +(ert-deftest test-ox-latex/lualatex-fontspec-fallback () + "Test that org-latex-fontspec-config is recognised for lualatex. +Emojis are added." + (let ((org-latex-fontspec-config + '(("main" :font "FreeSerif" + :fallback (("emoji" . "Noto Color Emoji:mode=harf"))) + ("sans" :font "FreeSans")))) + (org-test-with-exported-text + 'latex + "#+TITLE: LuaLaTeX fonts with emojis +#+LANGUAGE: en-gb es +#+OPTIONS: toc:nil H:3 num:nil +#+LATEX_COMPILER: lualatex +#+LATEX_CLASS: report +* Testing + +Just to see that I get the fonts I want... + +And my emojis too, 😀 +" + ;; (message "lualatex fallback: %s" (buffer-string)) + (goto-char (point-min)) + (should (search-forward "\\usepackage{fontspec}" nil t)) + (should (search-forward "\\directlua{" nil t)) + (should (search-forward "\\setmainfont{FreeSerif}[RawFeature={fallback=" nil t)) + (should (search-forward "\\setsansfont{FreeSans}" nil t))))) + +(ert-deftest test-ox-latex/lualatex-fontspec-latex-header-not-lost () + "Test that org-latex-fontspec-config is recognised for lualatex. + +It will be placed *before* LATEX_HEADER, so that any font configuration +there will prevail." + (let ((org-latex-fontspec-config + '(("main" :font "FreeSerif") + ("sans" :font "FreeSans")))) + (org-test-with-exported-text + 'latex + "#+TITLE: LuaLaTeX fonts +#+LANGUAGE: en-gb es +#+OPTIONS: toc:nil H:3 num:nil +#+LATEX_COMPILER: lualatex +#+LATEX_HEADER: \\setsansfont{TeX Gyre Heros} +#+LATEX_CLASS: report +* Testing + +Just to see that I get the fonts Iwant... +" + ;; (message "fontspec: latex-header\n%s" (buffer-string)) + (goto-char (point-min)) + (should (search-forward "\\usepackage{fontspec}" nil t)) + (should (search-forward "\\setmainfont{FreeSerif}" nil t)) + (should (search-forward "\\setsansfont{FreeSans}" nil t)) + (should (search-forward "\\setsansfont{TeX Gyre Heros}" nil t))))) + (provide 'test-ox-latex) ;;; test-ox-latex.el ends here
