Improve section readability to prepare a mail to the list

This commit is contained in:
Gerard Vermeulen 2022-10-16 18:55:12 +02:00
parent c7c4d4bb15
commit 17f2dc78c8
1 changed files with 128 additions and 100 deletions

View File

@ -2322,109 +2322,40 @@ valid directories and files. In an [[https://orgmode.org/][Org-mode]] buffer th
This package aims to produce a versatile generic core which can process a
fontified buffer and pass the data to any number of backends to deal with
specific output formats and it should work with =org-mode=. *Thanks to the
listings below*, [[https://github.com/tecosaur/engrave-faces#readme][Engrave Faces]] and [[info:org#Source blocks in LaTeX export][Org source block export to LaTeX (info)]] *are
capable of handling this [[file:README.org]] file:*
1. Listing [[lst:ensure-engrave-faces-with-latex-face-mapper-fix]] ensures
installation of =engrave-faces= and makes =engrave-faces-latex-face-mapper=
handle multi-line documentation strings.
2. Listing [[lst:ensure-engrave-faces-with-latex-face-apply-fix]] ensures
installation of =engrave-faces= and makes =engrave-faces-latex-face-apply=
handle symbolic color name strings (in addition to the hexadecimal strings).
3. The =org-latex-engraved-source-block-filter= in listing
specific output formats and Org offers it as an alternative to =minted=. *The
listings below make* [[https://github.com/tecosaur/engrave-faces#readme][Engrave Faces]] and [[info:org#Source blocks in LaTeX export][Org source block export to LaTeX (info)]]
*capable of handling this [[file:README.org]] file to my satisfaction:*
1. The default Org export configuration for engraving listings produces =pdf=
output with a non-equidistant interline spacing in floating listings and
equidistant interline spaces non-floating =tcolorbox= environments. I have
traced non-equidistance interline spacing back to the =breakable= option in
=Code= environments inside =listing= environments. However, =tcolorbox=
requires =breakable= for listings that do not fit on a page. As a
work-around, the filter =org-latex-engraved-source-block-filter= in listing
[[lst:org-latex-engraved-source-block-filter]] and the
=org-latex-engraved-preamble= customization in listing
[[lst:smart-latex-engrave-org-source-blocks]] allow to engrave =org-mode= source
blocks to "floating unbreakable" or "non-floating breakable" LaTeX
environments.
blocks to "floating unbreakable with a caption" or "non-floating breakable
without a caption" LaTeX environments.
2. Listing [[lst:ensure-engrave-faces-with-latex-face-apply-fix]] makes
=engrave-faces-latex-face-apply= handle symbolic color name strings (in
addition to the hexadecimal strings). Since for instance the faces in
src_emacs-lisp{(find-library "org-faces")} have symbolic color names, this
fix allows to engrave org-mode source blocks during LaTeX export without any
further tweaking.
3. Listing [[lst:ensure-engrave-faces-with-latex-face-mapper-fix]] makes
=engrave-faces-latex-face-mapper= handle horizontal and vertical whitespace
in multiple line documentation strings correctly. For instance, *without this
fix* the empty line in the documentation string of
=org-latex-engraved-sourc-block-filter= of listing
[[lst:org-latex-engraved-source-block-filter]] is invisible in the exported =pdf=
file and *very obviously* the mishandling of the spacing destroys the
indentation in Python documentation strings. The idea of the fix is to let
the LaTeX face mapper wrap only groups of "words joined by blank characters"
in LaTeX commands and pass "newlines and other whitespace between those
groups" on without wrapping.
4. Listing [[lst:ox-engraved-emacs-lisp-setup]] shows how to use this configuration.
#+caption[Ensure =engrave-faces= installation and fix multiline docstrings]:
#+caption: Ensure =engrave-faces= installation and fix multiline docstrings.
#+name: lst:ensure-engrave-faces-with-latex-face-mapper-fix
#+begin_src emacs-lisp
(when (and (ensure-package-installation 'engrave-faces)
(require 'engrave-faces-latex nil t))
(defun engrave-faces-latex-face-mapper-override (faces content)
"Create a LaTeX representation of CONTENT With FACES applied."
(let* ((style (engrave-faces-preset-style faces))
(protected-content
(funcall
(if (and engrave-faces-latex-mathescape
(eq 'font-lock-comment-face (car style)))
#'engrave-faces-latex--protect-content-mathescape
#'engrave-faces-latex--protect-content)
content)))
;; Wrap groups of "words joined by blank characters" in LaTeX commands.
;; Do not wrap newlines and other whitespace between those groups.
(let ((regexp (rx (or (group-n 1 (+ graph ) (* (+ blank) (+ graph)))
(group-n 2 (+ (any "\n" space))))))
(slug (when (and style
(eq engrave-faces-latex-output-style 'preset))
(plist-get (cdr style) :slug)))
(start 0)
(stack))
(while (string-match regexp protected-content start)
(setq start (match-end 0))
(when-let ((pc (match-string 1 protected-content)))
(if (stringp slug)
(push (concat "\\EF" slug "{" pc "}") stack)
(push (engrave-faces-latex-face-apply faces pc) stack)))
(when-let ((pc (match-string 2 protected-content)))
(push pc stack)))
(apply #'concat (nreverse stack))))))
(with-eval-after-load 'emacs
(defun toggle-engrave-faces-latex-face-mapper-override ()
"Toggle `engrave-faces-latex-face-mapper' advice."
(interactive)
(toggle-advice 'engrave-faces-latex-face-mapper
:override #'engrave-faces-latex-face-mapper-override))
(toggle-engrave-faces-latex-face-mapper-override))
#+end_src
#+caption[Ensure =engrave-faces= installation and fix symbolic colors]:
#+caption: Ensure =engrave-faces= installation and fix symbolic colors.
#+name: lst:ensure-engrave-faces-with-latex-face-apply-fix
#+begin_src emacs-lisp
(when (and (ensure-package-installation 'engrave-faces)
(require 'engrave-faces-latex nil t))
(defun engrave-faces-latex--color (color)
"Convert COLOR loosely to a string of six hexadecimal digits."
(if (char-equal ?# (aref color 0))
(substring color 1 7)
(apply 'format "%02x%02x%02x"
(mapcar (lambda (c) (ash c -8))
(color-values color)))))
(defun engrave-faces-latex-face-apply-override (faces content)
"Convert attributes of FACES to LaTeX commands applied to CONTENT."
(let ((attrs (engrave-faces-merge-attributes faces)))
(let ((bg (plist-get attrs :background))
(fg (plist-get attrs :foreground))
(it (eql (plist-get attrs :slant) 'italic))
(bl (member (plist-get attrs :weight) '(bold extra-bold)))
(st (plist-get attrs :strike-through)))
(concat
(when bg (concat "\\colorbox[HTML]{"
(engrave-faces-latex--color bg) "}{"))
(when fg (concat "\\textcolor[HTML]{"
(engrave-faces-latex--color fg) "}{"))
(when st "\\sout{") (when bl "\\textbf{") (when it "\\textit{")
content
(when bg "}") (when fg "}") (when st "}") (when bl "}") (when it "}"))))))
(with-eval-after-load 'emacs
(defun toggle-engrave-faces-latex-face-apply-override ()
"Toggle `engrave-faces-latex-face-apply' advice."
(interactive)
(toggle-advice 'engrave-faces-latex-face-apply
:override #'engrave-faces-latex-face-apply-override))
(toggle-engrave-faces-latex-face-apply-override))
#+end_src
#+caption[Engrave to floating unbreakable or non-floating breakable environments]:
#+caption: Define an =org-export= filter function to engrave =org-src-mode=
#+caption: blocks to floating unbreakable LaTeX environments or non-floating
@ -2443,6 +2374,7 @@ capable of handling this [[file:README.org]] file:*
(let ((enter "^\\\\begin{Code}\n\\\\begin{Verbatim}")
(leave "^\\\\end{Verbatim}\n\\\\end{Code}"))
;; Transform only blocks matching the enter regexp at position 0.
;; Do not transform blocks that are listing environments.
(when (and (string-match enter data) (eql 0 (match-beginning 0)))
(setq data (replace-match
"\\begin{Breakable}\n\\begin{Verbatim}" t t data))
@ -2456,8 +2388,8 @@ capable of handling this [[file:README.org]] file:*
data)))))
#+end_src
#+caption[Enable smart LaTeX engraving of =org-src-mode= blocks]:
#+caption: Enable smart LaTeX engraving of =org-src-mode= blocks.
#+caption[Smart LaTeX engraving of =org-src-mode= blocks]:
#+caption: Smart LaTeX engraving of =org-src-mode= blocks.
#+name: lst:smart-latex-engrave-org-source-blocks
#+begin_src emacs-lisp
(defun smart-latex-engrave-org-source-blocks ()
@ -2506,6 +2438,102 @@ capable of handling this [[file:README.org]] file:*
[LISTINGS-SETUP]"))
#+end_src
#+caption[Fix engraving of symbolic color names]:
#+caption: Fix engraving of symbolic colors names.
#+name: lst:ensure-engrave-faces-with-latex-face-apply-fix
#+begin_src emacs-lisp
(when (and (ensure-package-installation 'engrave-faces)
(require 'engrave-faces-latex nil t))
(defun engrave-faces-latex--color (color)
"Convert COLOR loosely to a string of six hexadecimal digits."
(if (char-equal ?# (aref color 0))
(substring color 1 7)
(apply 'format "%02x%02x%02x"
(mapcar (lambda (c) (ash c -8))
(color-values color)))))
(defun engrave-faces-latex-face-apply-override (faces content)
"Convert attributes of FACES to LaTeX commands applied to CONTENT."
(let ((attrs (engrave-faces-merge-attributes faces)))
(let ((bg (plist-get attrs :background))
(fg (plist-get attrs :foreground))
(it (eql (plist-get attrs :slant) 'italic))
(bl (member (plist-get attrs :weight) '(bold extra-bold)))
(st (plist-get attrs :strike-through)))
(concat
(when bg (concat "\\colorbox[HTML]{"
(engrave-faces-latex--color bg) "}{"))
(when fg (concat "\\textcolor[HTML]{"
(engrave-faces-latex--color fg) "}{"))
(when st "\\sout{") (when bl "\\textbf{") (when it "\\textit{")
content
(when bg "}") (when fg "}") (when st "}") (when bl "}") (when it "}"))))))
(with-eval-after-load 'emacs
(defun toggle-advice (symbol where function &optional props)
"Toggle between states after `advice-remove' and `advice-add'."
(let ((how "%s `%s' advice `%s' %s `%s'"))
(if (advice-member-p function symbol)
(progn
(message how "Removal of" where function "from" symbol)
(advice-remove symbol function))
(message how "Addition of" where function "to" symbol)
(advice-add symbol where function props))))
(defun toggle-engrave-faces-latex-face-apply-override ()
"Toggle `engrave-faces-latex-face-apply' advice."
(interactive)
(toggle-advice 'engrave-faces-latex-face-apply
:override #'engrave-faces-latex-face-apply-override))
(toggle-engrave-faces-latex-face-apply-override))
#+end_src
#+caption[Fix engraving of horizontal/vertical spacing in multiline docstrings]:
#+caption: Fix engraving of horizontal and vertical spacing in multiple line
#+caption: documentation strings.
#+name: lst:ensure-engrave-faces-with-latex-face-mapper-fix
#+begin_src emacs-lisp
(when (and (ensure-package-installation 'engrave-faces)
(require 'engrave-faces-latex nil t))
(defun engrave-faces-latex-face-mapper-override (faces content)
"Create a LaTeX representation of CONTENT with FACES applied."
(let* ((style (engrave-faces-preset-style faces))
(protected-content
(funcall
(if (and engrave-faces-latex-mathescape
(eq 'font-lock-comment-face (car style)))
#'engrave-faces-latex--protect-content-mathescape
#'engrave-faces-latex--protect-content)
content)))
;; Wrap groups of "words joined by blank characters" in LaTeX commands.
;; Do not wrap newlines and other whitespace between those groups.
(let ((regexp (rx (or (group-n 1 (+ graph ) (* (+ blank) (+ graph)))
(group-n 2 (+ (any "\n" space))))))
(slug (when (and style
(eq engrave-faces-latex-output-style 'preset))
(plist-get (cdr style) :slug)))
(start 0) (stack))
(while (string-match regexp protected-content start)
(setq start (match-end 0))
(when-let ((pc (match-string 1 protected-content)))
(if (stringp slug)
(push (concat "\\EF" slug "{" pc "}") stack)
(push (engrave-faces-latex-face-apply faces pc) stack)))
(when-let ((pc (match-string 2 protected-content)))
(push pc stack)))
(apply #'concat (nreverse stack))))))
(with-eval-after-load 'emacs
(defun toggle-engrave-faces-latex-face-mapper-override ()
"Toggle `engrave-faces-latex-face-mapper' advice."
(interactive)
(toggle-advice 'engrave-faces-latex-face-mapper
:override #'engrave-faces-latex-face-mapper-override))
(toggle-engrave-faces-latex-face-mapper-override))
#+end_src
#+caption[Emacs setup to use =engrave-faces-latex= in =org-mode= smartly]:
#+caption: Emacs setup to use =engrave-faces-latex= in =org-mode= smartly.
#+name: lst:ox-engraved-emacs-lisp-setup