Enlaces personalizados (II), org-capture y enlaces multimedia
En la anterior entrada de esta miniserie dedicada a los enlaces de Org Mode y su
personalización —que, presumo, terminará aquí—, habíamos visto cómo crear etiquetas
ad hoc para formar nuevos tipos de enlace. Ahora veremos un caso un poco más elaborado
que atañe a los enlaces de contenido multimedia y a la utilísima biblioteca de
org-capture
. Nos metemos en harina.
El escenario
Me resulta útil almacenar en un documento de Org los enlaces a vídeos de internet que me
van pareciendo interesantes. Casi todos pertenecen a la infame plataforma de YouTube, pero
accedo a ellos no desde la propia página del horroroso y fisgón servicio de Google, sino
mediante una instancia pública de la interfaz libre para YouTube, Invidious. Esto trae una
ventaja a un usuario cotidiano de GNU Emacs cual soy yo, además de la consabida profilaxis
ética. Y es que Invidious puede abrirse sin problemas desde el navegador interno de Emacs,
el eww-mode
, ya que no impone al usuario la ejecución de javascript privativo. Lo que no
se puede en el eww-node
, claro, es reproducir el vídeo. Pero para eso contamos con el
Emacs Multimedia System (abreviado EMMS) que reproducirá la URL del contenido
multimedia1.
Pues bien, para ir almacenando esos enlaces a vídeos de una forma ágil y rápida la mejor opción que tenemos es org-capture. Es necesario definir una plantilla que reconozca ese tipo de enlaces y los vaya acumulando en nuestro documento de Org preparado a tal efecto, y con el formato que deseemos. Pero vayamos por parte. Antes, necesitamos definir un nuevo tipo de enlace de Org que permita reproducir una ruta multimedia mediante EMMS.
Definiendo un enlace multimedia
Una vez más, nos ayudamos de org-link-set-parameters
. Nos basta con incluir, para este
caso de ejemplo, además del necesario parámetro :follow
, el color del enlace.
(org-link-set-parameters "url-media" :follow (lambda (ruta) (emms-play-url ruta)) :face '(:foreground "chocolate" :underline t))
Así, si escribimos [[url-media:ruta-del-enlace]]
y visitamos el enlace multimedia, se
nos abrirá el reproductor que tengamos ya configurado en nuestro EMMS. Pero como lo que
queremos es «capturar» de forma automática estos enlaces, y no tener que copiarlos a mano,
necesitamos otra función que nos recolecte la cadena completa del enlace allí donde
tengamos el cursor (recuérdese, siempre dentro del eww-mode
).
Una función para copiar la ruta del enlace
Definimos, primero, esta función que mandará a la cabecera de nuestro kill-ring
la ruta
del enlace donde está el cursor:
(defun copia-url-enlace () (let ((url (get-text-property (point) 'shr-url))) (kill-new (format "%s" url))))
Pero queremos activarla cada vez que llamemos a org-capture
. Definimos esta segunda
función con un condicional, para que se evalúe (naturalmente) sólo si estamos en el
eww-mode
:
(defun copia-url-para-capture-multimedia () (when (equal (format "%s" major-mode) "eww-mode") (copia-url-enlace)))
Y la añadimos entonces a un advice-add:
, para que se ejecute justo tras una llamada a
org-capture
:
(advice-add 'org-capture :before #'copia-url-para-capture-multimedia)
Ahora ya sólo nos queda definir nuestra plantilla de org-capture
La plantilla para org-capture
Org-capture, y su sistema de plantillas, merecería ya una GNUta completa. Aquí nos limitaremos a dar unas pinceladas con trazo grueso. Y, para más información, remitimos como siempre a la completa documentación de esta biblioteca.
Para empezar, una plantilla de org-capture
consiste en una serie de instrucciones a fin
de que una entrada determinada se incluya en un determinado documento de Org. Se trata de
un esqueleto para cada entrada que capturemos donde indicamos cómo queremos capturarla.
Podemos escoger entre un amplio muestrario de instrucciones y variables, incluyendo la
posibilidad de evaluar código Elisp entre medias. Y todo eso se recoge en la variable
org-capture-templates
, que es forzosamente una lista. Cada elemento de esa lista será
una plantilla. En nuestro init se vería algo así como:
(setq org-capture-templates '((plantilla-1)
(plantilla-2)
(plantilla-etc)))
Nuestra plantilla para capturar enlaces multimedia en un documento de Org (que, recordemos, tenemos ya preparado) luciría tal que así:
("M" "Enlace multimedia" entry (file "ruta/hacia/nuestro-archivo.org") "* [[url-media:%(car kill-ring)][%:description]] %^g Capturado en: %U" :prepend t)
Expliquemos un poco por encima los elementos.
- «M»
- es la letra que hemos escogido para activar nuestra captura, cuando hayamos
desplegado el menú de
org-capture
medianteC-c c
; - «Enlace multimedia»
- es el nombre de ese tipo de capturas que aparecerá en el menú;
- La expresión
file
- toma como argumento la ruta de nuestro archivo para almacenar los enlaces. Cada enlace será un encabezado de Org;
%(car kill-ring)
- evaluamos ese Elisp como ruta del enlace. Simplemente extraemos el
car
(el primer elemento de la lista) de nuestrokill-ring
. O sea, como al llamar aorg-capture
hemos copiado automáticamente la ruta del enlace en que está el cursor, eso estará al principio delkill-ring
; %:description
- es la descripción del link. Por defecto,
org-capture
pondrá el nombre de la página web donde hacemos la captura; %^g
- Para que se nos abra un
prompt
a fin de incluir las etiquetas que queramos en la entrada capturada. Admite autocompletado para las etiquetas del documento; %U
- la fecha;
:prepend t
- con valor
non-nil
, la variable:prepend
nos colocará la última entrada capturada al principio de la lista.
Si queremos, podemos incluir algo más de información. Por ejemplo, bajo la línea de la entrada, que es la que contiene el enlace que reproducirá el medio, añadir otro enlace que sería la dirección web del medio:
"... Capturado en: %U Fuente: [[%:link][%:description]]"
Una floritura final
Ya que nos hemos venido arriba, igual queremos también que nuestros flamantes enlaces
multimedia luzcan con un pequeño icono al principio, en cada entrada. Yo he encontrado una
solución gracias al paquete all-the-icons
, que si bien no resulta el colmo de la
elegancia, hace un apaño. Al fin y al cabo, esto es meramente decorativo. Como a la postre
siempre va a acabar mandando la fuente del enlace, tenemos que definir una cadena de texto
«comodín». En mi caso, mi comodín es «¡¡¡» que debe sustituirse por el icono de una nota
musical. Por supuesto, tendríamos que añadir el comodín a nuestra plantilla:
"* [[url-media:%(car kill-ring)][¡¡¡ %:description]] %^g
Y definir una función como ésta:
(require 'all-the-icons) (defun icono-nota () "Sustituye la cadena `¡¡¡' por el glifo de una nota musical y salva el búfer" (save-excursion (goto-char (point-min)) (while (re-search-forward "\\(¡¡¡\\)" nil t) (put-text-property (match-beginning 0) (match-end 0) 'display (propertize (all-the-icons-material "music_note") 'face `(:inherit nil :family ,(all-the-icons-material-family)))))) (save-buffer))
Y, por último, incluir la función anterior en un advice-add
para que se ejecute al
guardar la captura:
(advice-add 'org-capture-finalize :before #'icono-nota)
Como he dicho, esto es un apaño, y el icono de la nota musical no se mantendrá al guardar y cerrar el búfer. Así que, si insistimos en nuestra floritura (que, vuelvo a recordar, no es necesaria), tendríamos que evaluar la función anterior como variable local en nuestro documento. Por ejemplo, incluyendo al principio de todo la línea:
# -*- eval: (icono-nota) -*-
A medida que vayamos almacenando enlaces de vídeos y de otros archivos multimedia, nuestro documento acabará teniendo esta pinta:
Figura 1: Nuestra lista de enlaces a vídeos en internet
∞
Publicado: 28/08/20
Última actualización: 07/08/22
Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.
Notas al pie de página:
En esta otra Gnuta ya habíamos visto cómo reproducir dentro del eww-mode
un
enlace multimedia mediante el EMMS.