|
33 | 33 | (require 'ox) |
34 | 34 |
|
35 | 35 | (defvar orgtbl-exp-regexp) |
36 | | - |
| 36 | +(defvar org-texinfo-supports-math--cache) |
37 | 37 |
|
38 | 38 |
|
39 | 39 | ;;; Define Back-End |
|
58 | 58 | (italic . org-texinfo-italic) |
59 | 59 | (item . org-texinfo-item) |
60 | 60 | (keyword . org-texinfo-keyword) |
| 61 | + (latex-environment . org-texinfo-latex-environment) |
| 62 | + (latex-fragment . org-texinfo-latex-fragment) |
61 | 63 | (line-break . org-texinfo-line-break) |
62 | 64 | (link . org-texinfo-link) |
63 | 65 | (node-property . org-texinfo-node-property) |
|
123 | 125 | (:texinfo-text-markup-alist nil nil org-texinfo-text-markup-alist) |
124 | 126 | (:texinfo-format-drawer-function nil nil org-texinfo-format-drawer-function) |
125 | 127 | (:texinfo-format-inlinetask-function nil nil org-texinfo-format-inlinetask-function) |
126 | | - (:texinfo-compact-itemx nil "compact-itemx" org-texinfo-compact-itemx))) |
| 128 | + (:texinfo-compact-itemx nil "compact-itemx" org-texinfo-compact-itemx) |
| 129 | + ;; Redefine regular options. |
| 130 | + (:with-latex nil "tex" org-texinfo-with-latex))) |
127 | 131 |
|
128 | 132 |
|
129 | 133 | ;;; User Configurable Variables |
@@ -358,6 +362,22 @@ The function should return the string to be exported." |
358 | 362 | :group 'org-export-texinfo |
359 | 363 | :type 'function) |
360 | 364 |
|
| 365 | +;;;; LaTeX |
| 366 | + |
| 367 | +(defcustom org-texinfo-with-latex (and org-export-with-latex 'detect) |
| 368 | + "When non-nil, the Texinfo exporter attempts to process LaTeX math. |
| 369 | +
|
| 370 | +When set to t, the exporter will process LaTeX environments and |
| 371 | +fragments as Texinfo \"@displaymath\" and \"@math\" commands |
| 372 | +respectively. Alternatively, when set to `detect', the exporter |
| 373 | +does so only if the installed version of Texinfo supports the |
| 374 | +necessary commands." |
| 375 | + :group 'org-export-texinfo |
| 376 | + :type '(choice |
| 377 | + (const :tag "Detect" detect) |
| 378 | + (const :tag "Yes" t) |
| 379 | + (const :tag "No" nil))) |
| 380 | + |
361 | 381 | ;;;; Itemx |
362 | 382 |
|
363 | 383 | (defcustom org-texinfo-compact-itemx nil |
@@ -1215,6 +1235,52 @@ CONTENTS is nil. INFO is a plist holding contextual information." |
1215 | 1235 | (concat "@listoffloats " |
1216 | 1236 | (org-export-translate "Listing" :utf-8 info)))))))) |
1217 | 1237 |
|
| 1238 | +;;;; LaTeX Environment |
| 1239 | + |
| 1240 | +(defun org-texinfo-latex-environment (environment _contents info) |
| 1241 | + "Transcode a LaTeX ENVIRONMENT from Org to Texinfo. |
| 1242 | +CONTENTS is ignored. INFO is a plist holding contextual information." |
| 1243 | + (let ((with-latex (plist-get info :with-latex))) |
| 1244 | + (when (or (eq with-latex t) |
| 1245 | + (and (eq with-latex 'detect) |
| 1246 | + (org-texinfo-supports-math-p))) |
| 1247 | + (let ((value (org-element-property :value environment))) |
| 1248 | + (string-join (list "@displaymath" |
| 1249 | + (string-trim (org-remove-indentation value)) |
| 1250 | + "@end displaymath") |
| 1251 | + "\n"))))) |
| 1252 | + |
| 1253 | +;;;; LaTeX Fragment |
| 1254 | + |
| 1255 | +(defun org-texinfo-latex-fragment (fragment _contents info) |
| 1256 | + "Transcode a LaTeX FRAGMENT from Org to Texinfo. |
| 1257 | +INFO is a plist holding contextual information." |
| 1258 | + (let ((with-latex (plist-get info :with-latex))) |
| 1259 | + (when (or (eq with-latex t) |
| 1260 | + (and (eq with-latex 'detect) |
| 1261 | + (org-texinfo-supports-math-p))) |
| 1262 | + (let ((value (org-remove-indentation |
| 1263 | + (org-element-property :value fragment)))) |
| 1264 | + (cond |
| 1265 | + ((or (string-match-p "^\\\\\\[" value) |
| 1266 | + (string-match-p "^\\$\\$" value)) |
| 1267 | + (concat "\n" |
| 1268 | + "@displaymath" |
| 1269 | + "\n" |
| 1270 | + (string-trim (substring value 2 -2)) |
| 1271 | + "\n" |
| 1272 | + "@end displaymath" |
| 1273 | + "\n")) |
| 1274 | + ((string-match-p "^\\$" value) |
| 1275 | + (concat "@math{" |
| 1276 | + (string-trim (substring value 1 -1)) |
| 1277 | + "}")) |
| 1278 | + ((string-match-p "^\\\\(" value) |
| 1279 | + (concat "@math{" |
| 1280 | + (string-trim (substring value 2 -2)) |
| 1281 | + "}")) |
| 1282 | + (t value)))))) |
| 1283 | + |
1218 | 1284 | ;;;; Line Break |
1219 | 1285 |
|
1220 | 1286 | (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." |
1951 | 2017 | (message "Process completed.") |
1952 | 2018 | output)) |
1953 | 2019 |
|
| 2020 | +(defun org-texinfo-supports-math-p () |
| 2021 | + "Return t if the installed version of Texinfo supports \"@math\". |
| 2022 | +
|
| 2023 | +Once computed, the results remain cached." |
| 2024 | + (unless (boundp 'org-texinfo-supports-math--cache) |
| 2025 | + (setq org-texinfo-supports-math--cache |
| 2026 | + (let ((math-example "1 + 1 = 2")) |
| 2027 | + (let* ((input-file |
| 2028 | + (make-temp-file "test" nil ".info")) |
| 2029 | + (input-content |
| 2030 | + (concat (format "@setfilename %s" input-file) "\n" |
| 2031 | + "@node Top" "\n" |
| 2032 | + (format "@displaymath{%s}" math-example) "\n"))) |
| 2033 | + (with-temp-file input-file |
| 2034 | + (insert input-content)) |
| 2035 | + (let* ((output-file (org-texinfo-compile input-file)) |
| 2036 | + (output-content (with-temp-buffer |
| 2037 | + (insert-file-contents output-file) |
| 2038 | + (buffer-string)))) |
| 2039 | + (let ((result (string-match-p (regexp-quote math-example) |
| 2040 | + output-content))) |
| 2041 | + (delete-file input-file) |
| 2042 | + (delete-file output-file) |
| 2043 | + (if result t nil))))))) |
| 2044 | + org-texinfo-supports-math--cache) |
1954 | 2045 |
|
1955 | 2046 | (provide 'ox-texinfo) |
1956 | 2047 |
|
|
0 commit comments