From 905ba44bf4f8e632b88d06a97437d8bb7e559fc6 Mon Sep 17 00:00:00 2001 From: Gerard Vermeulen Date: Fri, 2 Jun 2023 17:12:00 +0200 Subject: [PATCH] Reorganize the easy LaTeX preamble editing in Org section --- README.org | 239 ++++++++++++++++++++++++++--------------------------- 1 file changed, 119 insertions(+), 120 deletions(-) diff --git a/README.org b/README.org index 2ef3a34..e8dc94e 100644 --- a/README.org +++ b/README.org @@ -3126,126 +3126,6 @@ The following posts provide programming information: (add-to-list 'safe-local-eval-forms '(org-eval-python-setup-blocks))) #+end_src -*** [[info:org#LaTeX header and sectioning][Easy LaTeX preamble editing]] -:PROPERTIES: -:CUSTOM_ID: sec:easy-latex-preamble-editing -:END: - -There are at least two ways (new and old) to edit the LateX preamble -=latex_header= and =latex-extra_header= export options easily in LaTeX source or -export blocks. This [[info:org#Top][Org (info)]] file uses the new way, but keeps the old way for -backwards compatibility. - -The new way -- exploiting an idea of [[https://www.matem.unam.mx/~omar/][Omar Antolin Camarena]] -- is to code new -[[info:org#Editing Source Code][-modes]] allowing to edit in LaTeX mode and to export to LaTeX code with -[[info:org#LaTeX specific export settings][correct LaTeX preamble export setting prefixes]]. Here, are links to three posts -exposing his idea: -1. [[https://www.reddit.com/r/orgmode/comments/7u2n0h/tip_for_defining_latex_macros_for_use_in_both/][Export LaTeX macros to LaTeX and HTML/MathJax preambles (reddit)]], -2. [[https://www.reddit.com/r/orgmode/comments/5bi6ku/tip_for_exporting_javascript_source_block_to/][Export JavaScript source blocks to script tags in HTML (reddit)]], -3. [[https://emacs.stackexchange.com/questions/28301/export-javascript-source-block-to-script-tag-in-html-when-exporting-org-file-to][Export JavaScript source blocks to script tags in HTML (SX)]]. -Listing [[lst:org-babel-latex-header-blocks]] implements this way by means of two -new [[info:org#Editing Source Code][-modes]]: =latex-header= and =latex-extra-header=. - -#+caption[New =-modes= to edit the LaTeX preamble easily]: -#+caption: Add =latex-header= and =latex-extra-header= language modes to edit -#+caption: LaTeX preamble =latex_header= and =latex_extra_header= export options -#+caption: easily. -#+name: lst:org-babel-latex-header-blocks -#+begin_src emacs-lisp -n :exports code :results silent -(with-eval-after-load 'emacs - (defun prefix-all-lines (prefix body) - (with-temp-buffer - (insert body) - (string-insert-rectangle (point-min) (point-max) prefix) - (buffer-string))) - - (defun org-babel-execute:latex-extra-header (body _params) - "Execute a block of LaTeX extra header lines with org-babel. -This function is called by `org-babel-execute-src-block' and -prefixes all lines with \"#+latex_extra_header: \"." - (prefix-all-lines "#+latex_extra_header: " body)) - - (defun org-babel-execute:latex-header (body _params) - "Execute a block of LaTeX header lines with org-babel. -This function is called by `org-babel-execute-src-block' and -prefixes all lines with \"#+latex_header: \"." - (prefix-all-lines "#+latex_header: " body)) - - (defvar org-babel-default-header-args:latex-extra-header - '((:exports . "results") (:results . "raw"))) - - (defvar org-babel-default-header-args:latex-header - '((:exports . "results") (:results . "raw"))) - - (with-eval-after-load 'org-src - (setopt org-src-window-setup 'current-window) - - (add-to-list 'org-src-lang-modes '("toml" . conf-toml)) - (add-to-list 'org-src-lang-modes '("latex-header" . latex)) - (add-to-list 'org-src-lang-modes '("latex-extra-header" . latex)))) -#+end_src - -The old way is to use a special export attribute as in the function -=org-latex-header-blocks-filter= in [[https://git.sr.ht/~bzg/org-contrib/tree/master/item/lisp/ox-extra.el][ox-extra.el]]. Apparently, nobody is using -this broken function (broken, since it relies on support only in org-mode before -=2014-11-11=). Listing [[lst:org-latex-header-blocks-filter]] proposes a fix for -=org-latex-header-blocks-filter=. - -#+caption[Convert marked LaTeX export blocks to LaTeX header lines]: -#+caption: Convert marked LaTeX export blocks to LaTeX header lines. -#+name: lst:org-latex-header-blocks-filter -#+begin_src emacs-lisp -n :results silent -(with-eval-after-load 'ox - (defun org-latex-header-blocks-filter (backend) - "Convert marked LaTeX export blocks to \"#+latex_header: \" lines. -The marker is a line \"#+header: :header yes\" preceding the block. - -For instance, the LaTeX export block - -,#+header: :header yes -,#+begin_export latex -% This line converts to a LaTeX header line. -,#+end_export - -converts to - -\"#+latex_header: % This line converts to a LaTeX header line.\"." - (when (org-export-derived-backend-p backend 'latex) - (let ((blocks - (org-element-map - (org-element-parse-buffer 'greater-element nil) 'export-block - (lambda (block) - (let ((type (org-element-property :type block)) - (header (org-export-read-attribute :header block :header))) - (when (and (string= type "LATEX") (string= header "yes")) - block)))))) - (mapc (lambda (block) - ;; Set point to where to insert LaTeX header lines - ;; after deleting the block. - (goto-char (org-element-property :post-affiliated block)) - (let ((lines - (split-string (org-element-property :value block) "\n"))) - (delete-region (org-element-property :begin block) - (org-element-property :end block)) - (dolist (line lines) - (insert (concat "#+latex_header: " - (replace-regexp-in-string "\\` *" "" line) - "\n"))))) - ;; Reverse to go upwards to avoid wrecking the list of - ;; block positions in the file that would occur in case - ;; of going downwards. - (reverse blocks))))) - - ;; Push the filter on the hook. - (cl-pushnew #'org-latex-header-blocks-filter - org-export-before-parsing-hook)) -#+end_src - -This file uses the new way, while keeping the old way for backwards -compatibility, because the new way feels less hackish than the old way. A -practical difference is that new way source blocks (contrary to old way export -blocks) do not work in [[info:org#Export Settings][#+SETUPFILE: ]], but only in [[info:org#Export Settings][#+INCLUDE: ]] files. - *** [[info:org#Macro Replacement][Org-mode macro utilities]] :PROPERTIES: :CUSTOM_ID: sec:org-macro-utilities @@ -3493,6 +3373,125 @@ inclusion (info)]] and [[info:org#Noweb Reference Syntax][noweb (info)]] tricker <> #+end_src +*** [[info:org#LaTeX header and sectioning][Deprecated easy LaTeX preamble editing methods]] +:PROPERTIES: +:CUSTOM_ID: sec:easy-latex-preamble-editing +:END: + +There are at least two deprecated (old and historic) ways to edit the LateX +preamble =latex_header= and =latex_extra_header= export options easily in LaTeX +source or export blocks. This [[info:org#Top][Org (info)]] file uses the recommended method of +noweb trickery in Section [[#sec:file-inclusion-and-noweb]]. + +The old way -- exploiting an idea of [[https://www.matem.unam.mx/~omar/][Omar Antolin Camarena]] -- is to code new +[[info:org#Editing Source Code][-modes]] allowing to edit in LaTeX mode and to export to LaTeX code with +[[info:org#LaTeX specific export settings][correct LaTeX preamble export setting prefixes]]. Here, are links to three posts +exposing his idea: +1. [[https://www.reddit.com/r/orgmode/comments/7u2n0h/tip_for_defining_latex_macros_for_use_in_both/][Export LaTeX macros to LaTeX and HTML/MathJax preambles (reddit)]], +2. [[https://www.reddit.com/r/orgmode/comments/5bi6ku/tip_for_exporting_javascript_source_block_to/][Export JavaScript source blocks to script tags in HTML (reddit)]], +3. [[https://emacs.stackexchange.com/questions/28301/export-javascript-source-block-to-script-tag-in-html-when-exporting-org-file-to][Export JavaScript source blocks to script tags in HTML (SX)]]. +Listing [[lst:org-babel-latex-header-blocks]] implements this way by means of two +new [[info:org#Editing Source Code][-modes]]: =latex-header= and =latex-extra-header=. + +#+caption[New =-modes= to edit the LaTeX preamble easily]: +#+caption: Add =latex-header= and =latex-extra-header= language modes to edit +#+caption: LaTeX preamble =latex_header= and =latex_extra_header= export options +#+caption: easily. +#+name: lst:org-babel-latex-header-blocks +#+begin_src emacs-lisp -n :exports code :results silent +(with-eval-after-load 'emacs + (defun prefix-all-lines (prefix body) + (with-temp-buffer + (insert body) + (string-insert-rectangle (point-min) (point-max) prefix) + (buffer-string))) + + (defun org-babel-execute:latex-extra-header (body _params) + "Execute a block of LaTeX extra header lines with org-babel. +This function is called by `org-babel-execute-src-block' and +prefixes all lines with \"#+latex_extra_header: \"." + (prefix-all-lines "#+latex_extra_header: " body)) + + (defun org-babel-execute:latex-header (body _params) + "Execute a block of LaTeX header lines with org-babel. +This function is called by `org-babel-execute-src-block' and +prefixes all lines with \"#+latex_header: \"." + (prefix-all-lines "#+latex_header: " body)) + + (defvar org-babel-default-header-args:latex-extra-header + '((:exports . "results") (:results . "raw"))) + + (defvar org-babel-default-header-args:latex-header + '((:exports . "results") (:results . "raw"))) + + (with-eval-after-load 'org-src + (setopt org-src-window-setup 'current-window) + + (add-to-list 'org-src-lang-modes '("latex-header" . latex)) + (add-to-list 'org-src-lang-modes '("latex-extra-header" . latex)))) +#+end_src + +The historic way is to use a special export attribute as in the function +=org-latex-header-blocks-filter= in [[https://git.sr.ht/~bzg/org-contrib/tree/master/item/lisp/ox-extra.el][ox-extra.el]]. Apparently, nobody is using +this broken function (broken, since it relies on support only in org-mode before +=2014-11-11=). Listing [[lst:org-latex-header-blocks-filter]] proposes a fix for +=org-latex-header-blocks-filter=. + +#+caption[Convert marked LaTeX export blocks to LaTeX header lines]: +#+caption: Convert marked LaTeX export blocks to LaTeX header lines. +#+name: lst:org-latex-header-blocks-filter +#+begin_src emacs-lisp -n :results silent +(with-eval-after-load 'ox + (defun org-latex-header-blocks-filter (backend) + "Convert marked LaTeX export blocks to \"#+latex_header: \" lines. +The marker is a line \"#+header: :header yes\" preceding the block. + +For instance, the LaTeX export block + +,#+header: :header yes +,#+begin_export latex +% This line converts to a LaTeX header line. +,#+end_export + +converts to + +\"#+latex_header: % This line converts to a LaTeX header line.\"." + (when (org-export-derived-backend-p backend 'latex) + (let ((blocks + (org-element-map + (org-element-parse-buffer 'greater-element nil) 'export-block + (lambda (block) + (let ((type (org-element-property :type block)) + (header (org-export-read-attribute :header block :header))) + (when (and (string= type "LATEX") (string= header "yes")) + block)))))) + (mapc (lambda (block) + ;; Set point to where to insert LaTeX header lines + ;; after deleting the block. + (goto-char (org-element-property :post-affiliated block)) + (let ((lines + (split-string (org-element-property :value block) "\n"))) + (delete-region (org-element-property :begin block) + (org-element-property :end block)) + (dolist (line lines) + (insert (concat "#+latex_header: " + (replace-regexp-in-string "\\` *" "" line) + "\n"))))) + ;; Reverse to go upwards to avoid wrecking the list of + ;; block positions in the file that would occur in case + ;; of going downwards. + (reverse blocks))))) + + ;; Push the filter on the hook. + (cl-pushnew #'org-latex-header-blocks-filter + org-export-before-parsing-hook)) +#+end_src + +This file uses the new most simple way, while keeping the deprecated ways for +backwards compatibility. A practical difference is that new way source blocks +(contrary to old way export blocks) do not work in [[info:org#Export Settings][#+SETUPFILE: ]], but only +in [[info:org#Export Settings][#+INCLUDE: ]] files. + *** [[info:org#LaTeX specific export settings][Advanced LaTeX export settings]] :PROPERTIES: :CUSTOM_ID: sec:advanced-latex-export-settings