From 083ff19f1622ee1a4212c5cd00283e763ccd6eb0 Mon Sep 17 00:00:00 2001 From: Gerard Vermeulen Date: Sat, 20 Aug 2022 15:22:55 +0200 Subject: [PATCH] Commit org-mode and engrave-faces-latex collaboration progress --- README.org | 138 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 130 insertions(+), 8 deletions(-) diff --git a/README.org b/README.org index 017ec1d..15dd961 100644 --- a/README.org +++ b/README.org @@ -2124,18 +2124,140 @@ 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. +specific output formats and it should work with =org-mode=. *However*, +[[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 sofar incapable +of handling this [[file:README.org]] file.* -I have tried to configure [[info:org#Source blocks in LaTeX export][Org source block export to LaTeX (info)]] setting -=org-latex-src-block-backend= to =engraved= instead of =minted=, but the LaTeX -backend chokes on multi-line documentation strings. +Listing [[lst:ensure-and-fix-engrave-faces-installation]] ensures installation of +=engrave-faces= and fixes =engrave-faces-latex= for multi-line documentation +strings. Listing [[lst:ox-latex-engraved-filter-emacs-lisp-setup]] and +[[lst:smart-latex-engrave-org-source-blocks]] allow to engrave =org-mode= source +blocks to "floating unbreakable" or "non-floating breakable" LaTeX environments. -#+caption[Ensure installation of =engrave= for experimentation]: -#+caption: Ensure installation of =engrave= for experimentation. -#+name: lst:ensure-engrave-installation +#+caption[Ensure =engrave-faces= installation and fix multiline docstrings]: +#+caption: Ensure =engrave-faces= installation and fix multiline docstrings. +#+name: lst:ensure-and-fix-engrave-faces-installation #+begin_src emacs-lisp (when (ensure-package-installation 'engrave-faces) - (message "Engrave-faces chokes on multi-line documentation strings.")) + (defun engrave-faces-latex-face-mapper-override (faces content) + "Create a LaTeX representation of CONTENT With FACES applied." + (autoload 'engrave-faces-latex-mathescape "engrave-faces-latex" nil t) + (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))) + (if (string-match-p "\\`[\n[:space:]]+\\'" content) + protected-content + ;; Move newlines with whitespace outside the engrave face commands. + (let ((regexp "\\(?1:[^\n]+\\)\\|\\(?2:\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) + (setq stack (cons (concat "\\EF" slug "{" pc "}") stack)) + (setq stack + (cons (engrave-faces-latex-face-apply faces pc) stack)))) + (when-let ((pc (match-string 2 protected-content))) + (setq stack (cons pc stack)))) + (apply #'concat (nreverse stack)))))) + + (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[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 +#+caption: breakable LaTeX environments. +#+name: lst:ox-latex-engraved-filter-emacs-lisp-setup +#+begin_src emacs-lisp :results silent + (defun org-latex-engraved-source-block-filter (data _backend _info) + "Replace \"Code\" with \"Breakable\" in non-floating environments. + + Customize `org-latex-engraved-preamble' to define a Breakable environment." + (unless (string-match "^\\\\DeclareTColorBox\\[\\]{Breakable}" + org-latex-engraved-preamble) + (user-error "`org-latex-engraved-preamble' defines no `Breakable' environment")) + (when (eq org-latex-src-block-backend 'engraved) + (let ((enter "^\\\\begin{Code}\n\\\\begin{Verbatim}") + (leave "^\\\\end{Verbatim}\n\\\\end{Code}")) + (when (and (string-match enter data) (eql 0 (match-beginning 0))) + (setq data (replace-match + "\\begin{Breakable}\n\\begin{Verbatim}" t t data)) + (when (string-match leave data (match-end 0)) + (setq data (replace-match + "\\end{Verbatim}\n\\end{Breakable}" t t data)) + (when (string-match enter data) + (user-error "The `enter' regexp `%s' should not match" enter)) + (when (string-match leave data) + (user-error "The `leave' regexp `%s' should not match" leave)) + data))))) +#+end_src + +#+caption[Enable smart LaTeX engraving of =org-src-mode= blocks]: +#+caption: Enable 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 () + "Enable smart LaTeX engraving of `org-src-mode' blocks. + + Sets backend and preamble locally to support floating unbreakable LaTeX + environments and non-floating breakable LaTeX environments by means of + `org-latex-engraved-source-block-filter'." + (interactive) + (autoload 'org-latex-src-block-backend "ox-latex" nil 'noerror) + (setq-local org-latex-src-block-backend 'engraved + org-latex-engraved-preamble "\\usepackage{fvextra} + [FVEXTRA-SETUP] + + % Make code and line numbers normalsize. Make line numbers grey. + \\renewcommand\\theFancyVerbLine{\\normalsize\\color{black!40!white}\\arabic{FancyVerbLine}} + % In case engrave-faces-latex-gen-preamble has not been run. + \\providecolor{EfD}{HTML}{f7f7f7} + \\providecolor{EFD}{HTML}{28292e} + % To use \\DeclareTColorBox from the tcolorbox package: + \\usepackage[breakable,xparse]{tcolorbox} + % Define a Breakable environment to wrap the fontified code outside floats. + \\DeclareTColorBox[]{Breakable}{o}% + { + colback=EfD, + colframe=EFD, + fontupper=\\normalsize\\setlength{\\fboxsep}{0pt}, + colupper=EFD, + IfNoValueTF={#1}% + {boxsep=1pt, arc=2.5pt, outer arc=1pt, boxrule=0.5pt, left=2pt}% + {boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1.5pt, left=0.5pt}, + right=2pt, top=1pt, bottom=1pt, + breakable + } + % Define an unbreakable Code environment to wrap the fontified code inside floats. + \\DeclareTColorBox[]{Code}{o}% + { + colback=EfD, + colframe=EFD, + fontupper=\\normalsize\\setlength{\\fboxsep}{0pt}, + colupper=EFD, + IfNoValueTF={#1}% + {boxsep=1pt, arc=1pt, outer arc=1pt, boxrule=0.5pt, left=2pt}% + {boxsep=2.5pt, arc=0pt, outer arc=0pt, boxrule=0pt, leftrule=1.5pt, left=0.5pt}, + right=2pt, top=1pt, bottom=1pt, + } + + [LISTINGS-SETUP]")) #+end_src *** [[info:org#Adding Hyperlink Types][Making Org hyperlink types (info)]]