Accueil > Informatique > Emacs > org-protocol : partie 1
org-protocol : partie 1
dimanche 7 février 2021, par
Cet article est le premier d’une série de trois autour d’org-protocol et org-roam
– partie 1 : marque-page et capture
– partie 2 : marque-page et notes roam
– partie 3 : gestion de documents pdf avec org-roam
Pré-requis et contexte
- Debian buster sid
- emacs 26+ (testé avec emacs 27 et emacs 28) en mode client/server
- straight pour la gestion de paquets d’emacs
- un bureau compatible avec freedesktop (gnome/xfce/ etc.)
- firefox (ou chromium avec quelques adaptations)
- pandoc pour la conversion html—>org-mode
- wget pour capturer les pages
Présentation
org-mode
org-mode est un mode majeur pour emacs. C’est au départ un langage de balisage comme markdown mais c’est également un outil pour prendre des notes, gérer ses agendas, faire de la programmation lettrée un peu comme les notebook (IPython, Jupyter, etc.) ou gérer un blog.
Les fichiers org ont une syntaxe simple et peuvent-être vus comme des notes (post-it) structurées et augmentées.
L’écosystème autour d’org-mode et la communauté afférente est très dynamique ; dans cet article je présente la mise en œuvre de deux extensions org-protocol-capture-html et org-web-tools du même auteur, merci à lui pour ces deux très bonnes extensions !
org-capture
Org-mode permet de « capturer » rapidement une idée ou une nouvelle tâche. Il s’agit de notes pré-remplies à l’aide de modèles que l’on peut saisir rapidement en utilisant une liste de choix. Ce système de capture est décrit ici par exemple ou dans le manuel d’org-mode.
org-protocol
Org-protocol est un outil qui permet de déclencher des actions dans emacs à partir d’autres applications. Il existe des « protocols » prédéfinis, org-protocol-capture-html et un « protocol » supplémentaire qui permet de gérer la conversion d’une page web en note org à l’aide de pandoc.
objectif de ce tutoriel
Il s’agit de gérer ses signets dans un document org. Ainsi les signets ne dépendent plus d’un navigateur particulier, ni d’un système d’exploitation particulier en mettant en place une synchronisation de fichiers avec syncthing par exemple. De plus chaque signet peut être accompagné de commentaires, de liens etc.
Avantages :
– indépendance du navigateur
– utilisable sur plusieurs postes (ordinateurs, téléphones, etc.)
– ne nécessite pas de recourir à un tiers de confiance pour la synchronisation (les signets restent privés)
– très bonne intégration à l’eco-système emacs/org-mode (tableau/latex/etc.)
– possibilité de capturer les pages pour une lecture hors connexion avec org-web-tools
– le stockage et la sauvegarde sont facilités : tout est dans un fichier texte.
Inconvénient :
– Long à mettre en œuvre, nécessite une bonne connaissance d’emacs et d’org-mode d’où ce tutoriel ;-)
Mise en œuvre
Les signets seront stockés dans le fichier ~/Documents/Memo/note.org qui contient une ligne
* Marque-pages
L’astérisque est importante car elle marque le début d’un titre (headline)
Configuration d’emacs
Voici un exemple de configuration qui utilise le gestionnaire de paquetage straight.
Commençons par charger org-protocol et créer deux modèles de capture.
Un premier repéré par la lettre b pour un signet simple. Le curseur sera placé entre l’entête et la citation issue du site web ; et un second repéré par la lettre c qui ajoute au premier la capture de la page pour une lecture hors-ligne. Au passage l’url est placée dans le tampon circulaire (kill-ring).
Pour adapter les modèles à vos beoins, rendez-vous sur la page du manuel d’org-mode : template-expansion.
(use-package org
:hook
((org-mode . auto-fill-mode))
:init
(require 'org-protocol)
:custom
(org-directory "~/Documents/Memo")
(org-capture-templates
'(
("b" "Signet" entry
(file+headline "~/Documents/Memo/note.org" "Marque-pages")
"** %c :website:
:PROPERTIES:
:URL: %(kill-new \"%:link\")
:TIMESTAMP: %t
:CAPTURE: 0
:CUSTOM_ID: signet:%(org-id-new)
:END:
%?
%:initial
" :empty-lines 1 :prepend t)
("c" "Signet et archive" entry
(file+headline "~/Documents/Memo/note.org" "Marque-pages")
"** %c :website:
:PROPERTIES:
:URL: %(kill-new \"%:link\")
:TIMESTAMP: %t
:CAPTURE: 1
:CUSTOM_ID: signet:%(org-id-new)
:END:
%?
%:initial
" :empty-lines 1 :prepend t)))
)Ensuite, on charge l’extension d’org-protocol qui gérera les pages web.
(use-package org-protocol-capture-html
:straight (org-protocol-capture-html :type git :host github :repo "alphapapa/org-protocol-capture-html")
:after (org)
:init
(require 'org-protocol-capture-html)
)Enfin, on charge une extension qui permet la capture de la page web. On remarquera
le crochet (add-hook 'org-capture-prepare-finalize-hook 'webarchivecustom)
qui déclenche (ou pas) l’archivage de la page grâce au mécanisme d’attachement d’org-mode.
(use-package org-web-tools
:straight t
:after (org)
:custom
(org-web-tools-archive-fn 'org-web-tools-archive--wget-tar)
(org-web-tools-archive-wget-html-only-options
'("-e robots=off" "--adjust-extension" "--timestamping" "--no-directories"))
(org-web-tools-archive-wget-options
'("--ignore-tags=script,iframe" "--reject=eot,ttf,svg,otf,*.woff*" "-e robots=off" "--adjust-extension" "--span-hosts" "--convert-links" "--page-requisites" "--timestamping" "--no-directories"))
(org-web-tools-attach-archive-max-attempts 3)
:config
(defun webarchivecustom ()
"Utilisation de org-web-tools pour sauvegarder la page dans une archive"
(if (cdr (assoc "CAPTURE" (org-entry-properties nil "CAPTURE")))
(let (
(mycap (cdr (assoc "CAPTURE" (org-entry-properties nil "CAPTURE"))))
(myurl (car (last (org-property-values "URL"))))
)
(if (equal mycap "1")
(progn
(org-web-tools-archive-attach myurl)
(message (concat "Création de l'archive de la page: " myurl))
)
(progn
(message (concat "Création du signet de la page: " myurl)))
)
)
)
)
:init
(add-hook 'org-capture-prepare-finalize-hook 'webarchivecustom)
(bind-key "C-c r a" 'org-web-tools-archive-attach)
(bind-key "C-c r v" 'org-web-tools-archive-view)
(bind-key "C-c r o" 'org-attach-open-in-emacs)
)Enregistrement d’org-protocol dans le bureau
Commençons par créer un fichier .desktop dans le répertoire /.local/share/applications/ qui utilisera emacsclient pour le type mime x-scheme-handler/org-protocol. Pour utiliser emacs en mode client/server voir par exemple cet article
mkdir -p ~/.local/share/applications/
<< FDF > ~/.local/share/applications/org-protocol.desktop
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
FDF
update-desktop-database ~/.local/share/applications/Enregistrement d’org-protocol dans le firefox
Il est possible de réaliser cette étape à l’aide d’extensions. Par exemple Org-capture. Détaillons ici la procédure.
Commençons par enregistrer la prise en charge de org-protocol
Saisir about:config dans la barre d’adresse et accepter de faire attention.
Puis créer une nouvelle clef network.protocol-handler.expose.org-protocol de type boolean et assigner lui la valeur True.
créons des bookmarklets pour activer les captures
Si la barre personnelle n’est pas apparente, l’afficher par un clic droit à côté de la barre de recherche.
Puis créer un bookmarklets en suivant la documentation de org-protocol-capture-html.
Dans le champ
javascript:location.href = 'org-protocol://capture-html?template=b&url=' + encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title || "[untitled page]") + '&body=' + encodeURIComponent(function () {var html = ""; if (typeof document.getSelection != "undefined") {var sel = document.getSelection(); if (sel.rangeCount) {var container = document.createElement("div"); for (var i = 0, len = sel.rangeCount; i < len; ++i) {container.appendChild(sel.getRangeAt(i).cloneContents());} html = container.innerHTML;}} else if (typeof document.selection != "undefined") {if (document.selection.type == "Text") {html = document.selection.createRange().htmlText;}} var relToAbs = function (href) {var a = document.createElement("a"); a.href = href; var abs = a.protocol + "//" + a.host + a.pathname + a.search + a.hash; a.remove(); return abs;}; var elementTypes = [['a', 'href'], ['img', 'src']]; var div = document.createElement('div'); div.innerHTML = html; elementTypes.map(function(elementType) {var elements = div.getElementsByTagName(elementType[0]); for (var i = 0; i < elements.length; i++) {elements[i].setAttribute(elementType[1], relToAbs(elements[i].getAttribute(elementType[1])));}}); return div.innerHTML;}());
Lors de la première capture, il faut lier les deux : les liens org-protocol sont à ouvrir avec org-protocol.desktop.
Utilisation
Lorsqu’une page est digne d’intérêt, il suffit de sélectionner un morceau de texte et de cliquer sur Signet dans la barre personnelle ; pour qu’un tampon s’ouvre dans une fenêtre emacsclient préalablement ouverte.
Dans ce tampon, apparaît le titre de la page, un lien vers cette page ainsi que la sélection formatée en org-mode. Ce tampon est modifiable, en utilisant uniquement des titres de niveau 3 (*** sous - titre) pour être cohérent avec la structure du fichier note.org. Une fois l’édition terminée, il suffit de saisir C-c C-c et le contenu tampon est ajouté au début du fichier note.org (prepend : 1)
Le principe est le même lors d’un clic sur Capture, à la différence qu’à l’enregistrement de la note une capture de la page est réalisée sous la forme d’une archive tar.gz et attachée à la note. Lorsque l’on visite le fichier note.org, les titres où apparaissent le mot clef ATTACH sont des sites où une capture est disponible. Pour voir le site hors-ligne il suffit de saisir C-c r v
Conclusion
De nombreuses améliorations sont possibles, (les paquetages org-protocol-capture-html et org-web-tools possèdent une multitude d’options et de fonctionnalités). Par exemple :
– améliorer la capture car wget ne donne pas toujours le résultat escompté...
– permettre la capture de pages, nécessitant des identifiants ;
– interagir avec l’extension de firefox tabfs
– assigner des raccourcis aux captures
–
Bonus
Un fichier note.org avec de nombreux liens sur le thème “org-capture”
le fichier init.el qui a servi à réaliser ce tutoriel.
Heptagone
