ox-texinfo: Include LaTeX in Texinfo exports
* lisp/ox-texinfo.el (org-texinfo-with-latex): New customize. * lisp/ox-texinfo.el (org-texinfo-latex-environment): New function. * lisp/ox-texinfo.el (org-texinfo-latex-fragment): New function. * lisp/ox-texinfo.el (org-texinfo-supports-math-p): New function. * lisp/ox-texinfo.el (org-texinfo-supports-math--cache): New variable. * lisp/ox-texinfo.el (texinfo): Set latex-environment. * lisp/ox-texinfo.el (texinfo): Set latex-fragment. * testing/lisp/test-ox-texinfo.el: Add basic tests.
This commit is contained in:
parent
4075662c29
commit
c940b460c7
|
@ -489,6 +489,13 @@ support in LaTeX. The new =babel= syntax for loading languages via
|
|||
=ini= files and the new command =\babelprovide= (see:
|
||||
https://mirrors.ctan.org/macros/latex/required/babel/base/babel.pdf)
|
||||
are also supported.
|
||||
*** Texinfo exports include LaTeX
|
||||
|
||||
With the new customization option ~org-texinfo-with-latex~ set to (its
|
||||
default value) ~'detect~, if the system runs Texinfo 6.8 (3 July 2021)
|
||||
or newer, Org will export all LaTeX fragments and environments using
|
||||
Texinfo ~@math~ and ~@displaymath~ commands respectively.
|
||||
|
||||
* Version 9.5
|
||||
|
||||
** Important announcements and breaking changes
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
(require 'ox)
|
||||
|
||||
(defvar orgtbl-exp-regexp)
|
||||
|
||||
(defvar org-texinfo-supports-math--cache)
|
||||
|
||||
|
||||
;;; Define Back-End
|
||||
|
@ -58,6 +58,8 @@
|
|||
(italic . org-texinfo-italic)
|
||||
(item . org-texinfo-item)
|
||||
(keyword . org-texinfo-keyword)
|
||||
(latex-environment . org-texinfo-latex-environment)
|
||||
(latex-fragment . org-texinfo-latex-fragment)
|
||||
(line-break . org-texinfo-line-break)
|
||||
(link . org-texinfo-link)
|
||||
(node-property . org-texinfo-node-property)
|
||||
|
@ -123,7 +125,9 @@
|
|||
(:texinfo-text-markup-alist nil nil org-texinfo-text-markup-alist)
|
||||
(:texinfo-format-drawer-function nil nil org-texinfo-format-drawer-function)
|
||||
(:texinfo-format-inlinetask-function nil nil org-texinfo-format-inlinetask-function)
|
||||
(:texinfo-compact-itemx nil "compact-itemx" org-texinfo-compact-itemx)))
|
||||
(:texinfo-compact-itemx nil "compact-itemx" org-texinfo-compact-itemx)
|
||||
;; Redefine regular options.
|
||||
(:with-latex nil "tex" org-texinfo-with-latex)))
|
||||
|
||||
|
||||
;;; User Configurable Variables
|
||||
|
@ -358,6 +362,22 @@ The function should return the string to be exported."
|
|||
:group 'org-export-texinfo
|
||||
:type 'function)
|
||||
|
||||
;;;; LaTeX
|
||||
|
||||
(defcustom org-texinfo-with-latex (and org-export-with-latex 'detect)
|
||||
"When non-nil, the Texinfo exporter attempts to process LaTeX math.
|
||||
|
||||
When set to t, the exporter will process LaTeX environments and
|
||||
fragments as Texinfo \"@displaymath\" and \"@math\" commands
|
||||
respectively. Alternatively, when set to `detect', the exporter
|
||||
does so only if the installed version of Texinfo supports the
|
||||
necessary commands."
|
||||
:group 'org-export-texinfo
|
||||
:type '(choice
|
||||
(const :tag "Detect" detect)
|
||||
(const :tag "Yes" t)
|
||||
(const :tag "No" nil)))
|
||||
|
||||
;;;; Itemx
|
||||
|
||||
(defcustom org-texinfo-compact-itemx nil
|
||||
|
@ -1215,6 +1235,52 @@ CONTENTS is nil. INFO is a plist holding contextual information."
|
|||
(concat "@listoffloats "
|
||||
(org-export-translate "Listing" :utf-8 info))))))))
|
||||
|
||||
;;;; LaTeX Environment
|
||||
|
||||
(defun org-texinfo-latex-environment (environment _contents info)
|
||||
"Transcode a LaTeX ENVIRONMENT from Org to Texinfo.
|
||||
CONTENTS is ignored. INFO is a plist holding contextual information."
|
||||
(let ((with-latex (plist-get info :with-latex)))
|
||||
(when (or (eq with-latex t)
|
||||
(and (eq with-latex 'detect)
|
||||
(org-texinfo-supports-math-p)))
|
||||
(let ((value (org-element-property :value environment)))
|
||||
(string-join (list "@displaymath"
|
||||
(string-trim (org-remove-indentation value))
|
||||
"@end displaymath")
|
||||
"\n")))))
|
||||
|
||||
;;;; LaTeX Fragment
|
||||
|
||||
(defun org-texinfo-latex-fragment (fragment _contents info)
|
||||
"Transcode a LaTeX FRAGMENT from Org to Texinfo.
|
||||
INFO is a plist holding contextual information."
|
||||
(let ((with-latex (plist-get info :with-latex)))
|
||||
(when (or (eq with-latex t)
|
||||
(and (eq with-latex 'detect)
|
||||
(org-texinfo-supports-math-p)))
|
||||
(let ((value (org-remove-indentation
|
||||
(org-element-property :value fragment))))
|
||||
(cond
|
||||
((or (string-match-p "^\\\\\\[" value)
|
||||
(string-match-p "^\\$\\$" value))
|
||||
(concat "\n"
|
||||
"@displaymath"
|
||||
"\n"
|
||||
(string-trim (substring value 2 -2))
|
||||
"\n"
|
||||
"@end displaymath"
|
||||
"\n"))
|
||||
((string-match-p "^\\$" value)
|
||||
(concat "@math{"
|
||||
(string-trim (substring value 1 -1))
|
||||
"}"))
|
||||
((string-match-p "^\\\\(" value)
|
||||
(concat "@math{"
|
||||
(string-trim (substring value 2 -2))
|
||||
"}"))
|
||||
(t value))))))
|
||||
|
||||
;;;; Line Break
|
||||
|
||||
(defun org-texinfo-line-break (_line-break _contents _info)
|
||||
|
@ -1951,6 +2017,31 @@ Return INFO file name or an error if it couldn't be produced."
|
|||
(message "Process completed.")
|
||||
output))
|
||||
|
||||
(defun org-texinfo-supports-math-p ()
|
||||
"Return t if the installed version of Texinfo supports \"@math\".
|
||||
|
||||
Once computed, the results remain cached."
|
||||
(unless (boundp 'org-texinfo-supports-math--cache)
|
||||
(setq org-texinfo-supports-math--cache
|
||||
(let ((math-example "1 + 1 = 2"))
|
||||
(let* ((input-file
|
||||
(make-temp-file "test" nil ".info"))
|
||||
(input-content
|
||||
(concat (format "@setfilename %s" input-file) "\n"
|
||||
"@node Top" "\n"
|
||||
(format "@displaymath{%s}" math-example) "\n")))
|
||||
(with-temp-file input-file
|
||||
(insert input-content))
|
||||
(let* ((output-file (org-texinfo-compile input-file))
|
||||
(output-content (with-temp-buffer
|
||||
(insert-file-contents output-file)
|
||||
(buffer-string))))
|
||||
(let ((result (string-match-p (regexp-quote math-example)
|
||||
output-content)))
|
||||
(delete-file input-file)
|
||||
(delete-file output-file)
|
||||
(if result t nil)))))))
|
||||
org-texinfo-supports-math--cache)
|
||||
|
||||
(provide 'ox-texinfo)
|
||||
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
;;; test-ox-texinfo.el --- Tests for ox-texinfo.el
|
||||
|
||||
;; Copyright (C) 2022 Rudolf Adamkovič
|
||||
|
||||
;; Author: Rudolf Adamkovič <salutis@me.com>
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'ox-texinfo)
|
||||
|
||||
(unless (featurep 'ox-texinfo)
|
||||
(signal 'missing-test-dependency "org-export-texinfo"))
|
||||
|
||||
|
||||
;;; TeX fragments
|
||||
|
||||
(ert-deftest test-ox-texinfo/tex-fragment-inline ()
|
||||
"Test inline TeX fragment."
|
||||
(should
|
||||
(equal "@math{a^2 = b}"
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
'(:value "$a^2 = b$"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/tex-fragment-inline-padded ()
|
||||
"Test inline TeX fragment padded with whitespace."
|
||||
(should
|
||||
(equal "@math{a^2 = b}"
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
'(:value "$ a^2 = b $"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/tex-fragment-displayed ()
|
||||
"Test displayed TeX fragment."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value "$$a ^ 2 = b$$"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/tex-fragment-displayed-padded ()
|
||||
"Test displayed TeX fragment padded with whitespace."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value "$$ a ^ 2 = b $$"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/tex-fragment-displayed-multi-line ()
|
||||
"Test displayed TeX fragment with multiple lines."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value
|
||||
(string-join
|
||||
(list "$$"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"$$")
|
||||
"\n")))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/tex-fragment-displayed-indented ()
|
||||
"Test displayed TeX fragment with indentation."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value
|
||||
(string-join
|
||||
(list " $$"
|
||||
" a ^ 2 = b"
|
||||
" b ^ 2 = c"
|
||||
" $$")
|
||||
"\n")))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
|
||||
;;; LaTeX fragments
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-fragment-inline ()
|
||||
"Test inline LaTeX fragment."
|
||||
(should
|
||||
(equal "@math{a^2 = b}"
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
'(:value "\\(a^2 = b\\)"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-fragment-inline-padded ()
|
||||
"Test inline LaTeX fragment padded with whitespace."
|
||||
(should
|
||||
(equal "@math{a^2 = b}"
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
'(:value "\\( a^2 = b \\)"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-fragment-displayed ()
|
||||
"Test displayed LaTeX fragment."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value "\\[a ^ 2 = b\\]"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-fragment-displayed-padded ()
|
||||
"Test displayed LaTeX fragment with multiple lines."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value "\\[ a ^ 2 = b \\]"))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-fragment-displayed-multi-line ()
|
||||
"Test displayed LaTeX fragment with multiple lines."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value
|
||||
(string-join
|
||||
(list "\\["
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"\\]")
|
||||
"\n")))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-fragment-displayed-indented ()
|
||||
"Test displayed LaTeX fragment with indentation."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list ""
|
||||
"@displaymath"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"@end displaymath"
|
||||
"")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-fragment
|
||||
(org-element-create 'latex-fragment
|
||||
(list :value
|
||||
(string-join
|
||||
(list " \\["
|
||||
" a ^ 2 = b"
|
||||
" b ^ 2 = c"
|
||||
" \\]")
|
||||
"\n")))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
|
||||
;;; LaTeX environments
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-environment ()
|
||||
"Test LaTeX environment."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list "@displaymath"
|
||||
"\\begin{equation}"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"\\end{equation}"
|
||||
"@end displaymath")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-environment
|
||||
(org-element-create 'latex-environment
|
||||
(list :value
|
||||
(string-join
|
||||
(list "\\begin{equation}"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"\\end{equation}")
|
||||
"\n")))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(ert-deftest test-ox-texinfo/latex-environment-indented ()
|
||||
"Test LaTeX environment with indentation."
|
||||
(should
|
||||
(equal (string-join
|
||||
(list "@displaymath"
|
||||
"\\begin{equation}"
|
||||
"a ^ 2 = b"
|
||||
"b ^ 2 = c"
|
||||
"\\end{equation}"
|
||||
"@end displaymath")
|
||||
"\n")
|
||||
(let ((org-texinfo-with-latex t))
|
||||
(org-texinfo-latex-environment
|
||||
(org-element-create 'latex-environment
|
||||
(list :value
|
||||
(string-join
|
||||
(list " \\begin{equation}"
|
||||
" a ^ 2 = b"
|
||||
" b ^ 2 = c"
|
||||
" \\end{equation}")
|
||||
"\n")))
|
||||
nil
|
||||
'(:with-latex t))))))
|
||||
|
||||
(provide 'test-ox-texinfo)
|
||||
;;; test-ox-texinfo.el end here
|
Loading…
Reference in New Issue