Notas en Org no exportables
Una funcionalidad muy interesante que echo en falta en Org Mode es la de poder ignorar de
manera arbitraria algunas notas al pie durante el proceso de exportación. Podemos, por
supuesto, ignorarlas o activarlas todas en bloque, si añadimos a nuestra cabecera las
opciones #+OPTIONS: fn:nil
/ #+OPTIONS: fn:t
, respectivamente. Pero lo que yo quiero
es ser capaz de dejar algunas en concreto de lado, mientras que el resto sean exportadas
de manera normal. Creo que es una forma más y muy efectiva de gestionar un corpus
marginal para mi consumo privado. Bien es cierto que en Org tenemos para ese fin opciones
muy útiles, como los meros comentarios o los drawers («cajones») desplegables que sirven
para un roto como para un descosido. Pero hay contextos donde una nota al pie con carácter
secreto se vuelve indispensable, entre otras cosas por la gran agilidad de navegación
correlativa entre marca de nota y referencia. O porque no queremos alterar una determinada
sucesión de líneas al insertar un bloque de comentario o un cajón. Un ejemplo que me viene
muy a mano es el de un poema largo, como en mi traducción de la Odisea (work in
progress).
Así las cosas, ¿qué podemos hacer? Se imponen tres posibles soluciones:
- Esperar a que los desarrolladores de Org implementen la funcionalidad, cosa poco probable, pues no parece que sea algo muy demandado.
- Echarse al monte y ponerse a hacer código duro, como San Ignucio manda, e implementarla nosotros mismos.
- No echarse al monte sino salir a pasear por el solar de la esquina, y probar un remiendo chapucero pero que, sin embargo (y ante nuestra sorpresa), funcione.
Naturalmente, yo he seguido la tercera vía, y aquí resumo un poco por encima los pormenores. Se basa en dos cosas que tienen Emacs y Org, tremendamente útiles: su potente sistema (aunque también doloroso y muchas veces arcano) de expresiones regulares y la posibilidad de ejecutar funciones de elisp en la exportación desde Org, y hacerlo en los momentos tempranos, antes de que se expandan los comandos, y sólo si el formato de salida es uno determinado. Sobre esto último ya hablamos aquí.
Empezamos, primero, por definir una sencilla función que nos inserte una nota al pie con unas marcas especiales, tanto en la llamada de la nota como en su referencia. Será, pues, reconocida como una nota no exportable.
(defun nota-org-no-exportable () (interactive) (insert "!@!") (org-footnote-action) (insert "⁜no-exp⁜:") (newline 1) (save-excursion (newline 1) (insert "@@")))
Como se ve, la marca de esta nota comenzará por los caracteres !@!
, y el cuerpo de la
nota estará delimitado por las cadenas ⁜no-exp⁜:
y @@
, ambos encerrados
entre sendos símbolos que Unicode denomina DOTTED CROSS
. En la fig. 1 se
muestra el aspecto que tendría nuestra nueva nota. Dado que ya tenemos todo
convenientemente delimitado y marcado, no es difícil definir una función que efectúe las
correspondientes sustituciones mediante expresiones regulares, a fin de «anularnos» las
notas así marcadas, y anclar nuestra función al pre-proceso de exportación. Coser y
cantar. El cuerpo de la nota es fácil de eliminar. Basta con incluirlo en un snippet de
exportación con un backend inexistente, que aquí por conveniencia llamamos «null»,
aunque valdría cualquier palabra que no sea la de los backends conocidos.
Nuestra función, entonces, luciría tal que así para ignorar las notas no exportables en cualquier salida. Definimos antes una función para simplificar el proceso de reemplazo:
(defun reemplaza (antes despues) (interactive) (save-excursion (goto-char (point-min)) (while (re-search-forward antes nil t) (replace-match despues t nil))))
Y luego la función propiamente dicha. Nótese que evitamos el proceso de reemplazo en los bloques de ejemplo, de código y en los segmentos literales (véase la línea lin):
;; no exportar ciertas notas (defun no-exportar-notas-org (backend) "evita exportar las notas marcadas a html o LaTeX" (when backend (org-show-all) (let ((el (car (org-element-context)))) (lin) (unless (or (eq 'example-block el) (eq 'src-block el) (eq 'verbatim el)) (reemplaza (concat "!@!" org-footnote-re) "") (reemplaza (concat org-footnote-definition-re "\s*⁜no-exp⁜:") "@@null:") (reemplaza "@@" "@@")))))
Y para anclarla al pre-proceso de exportación, añadimos también lo siguiente a nuestro
/.emacs
1:
(add-hook 'org-export-before-processing-hook #'no-exportar-notas-org)
Así, cada vez que exportemos a esos dos formatos, nuestras notas no exportables quedarán en la más absoluta ignorancia. Para reconocer bien en nuestro texto las marcas que añadimos a dichas notas, podemos también definir un resaltado por color:
(defvar nota-muda (make-face 'nota-muda)) (set-face-foreground 'nota-muda "chocolate") (font-lock-add-keywords 'org-mode '(("⁜\\(.+\\)⁜" 0 nota-muda) ; esto para el cuerpo de la nota ("!@!\\[fn:[[:digit:]]+\\]" 0 nota-muda) ; y esto para la marca de la nota ))
∞
Publicado: 11/07/2019
Última actualización: 21/01/22
Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.
Notas:
Si vamos a introducir las notas no exportables en subdocumentos, que luego se
incluirán a un documento «maestro» mediante la directiva #+INCLUDE:
, nos interesará
mejor anclar esa función a org-export-before-parsing-hook
.