Accueil > Informatique > Emacs > org-protocol : partie 3
org-protocol : partie 3
mercredi 10 février 2021, par
Cet article est le dernier 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.)
Objectifs
L’objectif est de créer facilement des notes roam pour des fichiers pdf en essayant de pré-remplir certains champs du modèle de note à l’aide des meta-données. Une fois la note créée, elle pourra contenir des annotations synchronisées avec le fichier pdf.
Plus précisément, le déroulé sera le suivant :
– une fenêtre emacs client est ouverte (comment ça emacs n’est pas toujours ouvert sur votre bureau :) )
– clic droit sur un fichier pdf
– ouvrir le fichier avec emacs
– remplir la note roam pré-remplie
– C-c C-c pour enregistrer la note
– ouvrir la note, pour lire le pdf et l’annoter avec la possibilité de créer des liens avec d’autres notes roam
On obtient des notes bibliographiques qui s’intègrent parfaitement avec le système de gestion de connaissances mis en place dans les articles précédents.
installation de pdf-tools
Commençons par créer le répertoire qui accueillera une copie des fichiers pdf.
mkdir -p ~/Documents/Memo/pdfs
Pour ce qui concerne pdf-tools, il suffit de suivre les instructions d’installation de pdf-tools sur la page github du projet. Au chargement de pdf-tools la ligne (pdf-tools-install) déclenche la compilation du programme epdfinfo. La compilation nécessite les paquetages debian suivant :
apt-get install libpng-dev zlib1g-dev libpoppler-glib-dev libpoppler-private-dev imagemagick automake
La fonction parsepdf se charge de :
– copier un pdf dans le répertoire Memo/pdfs ;
– récupérer les métadonnées du pdf ;
– de sortir une note roam préremplie.
Par ailleurs, un modèle est enregistré dans org-roam-capture-ref-templates et sera appelé via org-protocol.
(use-package pdf-tools
:straight t
:hook (org-load . org-pdftools-setup-link)
(pdf-view-mode . pdf-misc-menu-bar-minor-mode)
:config
(setq-default pdf-view-display-size 'fit-page)
(setq parsepdf-directory "~/Documents/Memo/pdfs")
(setq pdf-annot-activate-created-annotations t)
(define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)
;(add-hook 'pdf-view-mode-hook (lambda () (cua-mode 0)))
(setq pdf-view-resize-factor 1.1)
(define-key pdf-view-mode-map (kbd "h") 'pdf-annot-add-highlight-markup-annotation)
(define-key pdf-view-mode-map (kbd "t") 'pdf-annot-add-text-annotation)
(define-key pdf-view-mode-map (kbd "D") 'pdf-annot-delete)
(defun parsepdf(fichier)
"""Ouvre un fichier pdf avec pdfview, récupère les informations et pré-rempli une note roam"
(let* (
(inputfile (replace-regexp-in-string "file:'\\(.*\\)'" "\\1" fichier ))
(filename (concat (format-time-string "%Hh%M--%d-%m-%y--") (file-name-nondirectory inputfile) ))
(valeurs '(()))
(file (concat parsepdf-directory "/" filename))
)
; (message (concat "je travaille sur " file))
;;copie du fichier
(copy-file inputfile file)
;;récupération des metadonnées
;(split-window-right)
(find-file file)
(let
(
(oldbufpdf (current-buffer))
)
(pdf-misc-display-metadata)
(with-current-buffer "*PDF-Metadata*"
(text-mode)
(goto-char (point-min))
(dolist (ligne (mapcar 'substring-no-properties (split-string (buffer-string) "\n")))
(if (string-match "\\s-*\\(.*?\\):\\(.*\\)" ligne )
(progn
(push (cons (match-string 1 ligne) (match-string 2 ligne )) valeurs)
)
)
)
)
;(pop valeurs)
(kill-buffer "*PDF-Metadata*")
(kill-buffer oldbufpdf)
)
; Écriture de la roam-note
(let* (
(auteur (cdr (assoc "author" valeurs )))
(motclefs (concat "\"" (replace-regexp-in-string "," "\" \"" (cdr (assoc "keywords" valeurs ))) "\""))
(titre (cdr (assoc "title" valeurs )))
(annee (max (nth 5 (parse-time-string (cdr (assoc "modified" valeurs ))))
(nth 5 (parse-time-string (cdr (assoc "created" valeurs ))))))
)
(if (equal "\"\"" motclefs)
(setq motclefs nil))
(if (equal "" titre)
(setq titre (replace-regexp-in-string ".pdf" "" (file-name-nondirectory inputfile) ))
)
(if (equal "" auteur)
(setq auteur "%^{auteur}")
)
(if (> annee 1970 )
(setq annee (format "%d" annee))
(setq annee "")
)
(setq titre (concat "%^{titre|" titre "}"))
(concat
"#+title:"
titre
"\n"
"#+ROAM_KEY: file:"
file
"\n#+ROAM_TAGS: pdf " motclefs "\n"
"[[file:" file "][%\\1]]\n"
"\n* Meta information\n"
":PROPERTIES: \n"
":AUTEUR: "
auteur
"\n"
; ":JOURNAL: ${journaltitle}\n"
; ":DATE: ${date}\n"
":TIMESTAMP: %T\n"
":ANNÉE: "
annee
; ":DOI: ${doi}\n"
; ":URL: ${url}\n"
"\n:URL: \n:JOURNAL: "
"\n:END:\n\n\n* Notes\n"
":PROPERTIES:\n"
":INTERLEAVE_PDF: "
(replace-regexp-in-string "file:" "" file )
"\n:END:"
)
)
)
)
:hook (pdf-view-mode . pdf-misc-menu-bar-minor-mode)
:custom
(org-roam-capture-ref-templates
'(("p" "ref" plain #'org-roam--capture-get-point "%(parsepdf \"${ref}\")%?" :file-name "pdfcapture:%<%Y%m%d%H%M%S>" :unnarrowed t)))
:init
(pdf-tools-install)
(add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode))
)Installation de org-noter
Ce paquetage permet d’annoter les pdf dans un fichier org synchronisé.
(use-package org-noter
:straight t
:bind
("C-c r n" . org-noter)
:config
(setq org-noter-always-create-frame t
org-noter-separate-notes-from-heading t
org-noter-default-heading-title "Page $p$"
org-noter-auto-save-last-location t
org-noter-separate-notes-from-heading t
org-noter-doc-property-in-notes t
)
(setq org-noter-property-doc-file "INTERLEAVE_PDF"
org-noter-property-note-location "INTERLEAVE_PAGE_NOTE")
)Intégration avec le bureau
Créons un fichier emacscapture.desktop dans le répertoire ~/.local/share/applications/.
[Desktop Entry]
Version=1.0
Name=Emacs (pdf capture)
GenericName=Emacs
GenericName[fr]=Emacs(Capture pdf)
Exec=emacsclient "org-protocol://roam-ref?template=p&ref=file:%U"
Icon=emacs
Type=Application
Terminal=false
Categories=Utility;Development;TextEditor;
StartupWMClass=Emacs
Keywords=Text;Editor;Org;
MimeType=application/pdf;application/x-pdf;et créons ou mettons à jour le fichier mimeapps.list (toujours dans le répertoire ~/.local/share/applications/ ) en ajoutant sous la clef [Added Applications] la ligne application/pdf=emacscapture.desktop.
on obtient par exemple ce fichier
[Added Applications]
application/pdf=emacscapture.desktopEnfin mettons à jour le bureau
update-desktop-database ~/.local/share/applications/
Utilisation
Une fenêtre emacsclient étant ouverte, après un clic droit sur un fichier pdf, on ouvre avec EmacsCapture le fichier.
Une note-roam pré-remplie s’affiche, après l’avoir complétée : C-c C-c pour l’enregistrer.
On souhaite lire et commenter le pdf. (C-c r d pour sélectionner la note, C-c r n pour lire le pdf avec pdf-tools et org-noter)
Par exemple, si le fichier pdf contient une table des matières, on peut l’importer dans la note org-noter-create-skeleton ou . La navigation dans la note et dans le fichier pdf sera synchronisée.
On peut réaliser des annotations, soit dans la note,
soit dans le pdf.
Les possibilités sont nombreuses, je vous renvoie aux documentations des paquets pdf-tools et org-noter pour explorer toutes les possiblités.
Pour aller plus loin
– Capturer des captures d’écran dans des notes org-download
– Gérer une bibliographie orb, qui fait le lien entre org-roam, l’excellent org-ref et bibtex.
Et comme d’habitude le fichier init.el de synthèse.
Heptagone