(feat)graph: allow customized graph links and access to the temporary filenames (#1988)

This commit is contained in:
mtbakerguy
2021-11-30 03:52:40 -08:00
committed by GitHub
parent c3889b3b17
commit e992fc27e2
3 changed files with 211 additions and 11 deletions

View File

@ -1439,6 +1439,82 @@ Essentially, to migrate notes from v1 to v2, one must:
and the ~ROAM_TAGS~ property for headline nodes and the ~ROAM_TAGS~ property for headline nodes
6. Replace existing file links with ID links. 6. Replace existing file links with ID links.
** How do I publish my notes with an Internet-friendly graph?
The default graph builder creates a graph with an [[https://orgmode.org/worg/org-contrib/org-protocol.html][org-protocol]]
handler which is convenient when you're working locally but
inconvenient when you want to publish your notes for remote access.
Likewise, it defaults to displaying the graph in Emacs which has the
exact same caveats. This problem is solvable in the following way
using org-mode's native [[https://orgmode.org/manual/Publishing.html][publishing]] capability:
1. configure org-mode to publish your org-roam notes as a project.
2. create a function that overrides the default org-protocol link
creation function(=org-roam-default-link-builder=).
3. create a hook that's called at the end of graph creation to copy
the generated graph to the appropriate place.
The example code below is used to publish to a local directory where a
separate shell script copies the files to the remote site.
*** Configure org-mode for publishing
This has two steps:
1. Setting of a /roam/ project that publishes your notes.
2. Configuring the /sitemap.html/ generation.
3. Setting up =org-publish= to generate the graph.
This will require code like the following:
#+begin_src emacs-lisp
(defun roam-sitemap (title list)
(concat "#+OPTIONS: ^:nil author:nil html-postamble:nil\n"
"#+SETUPFILE: ./simple_inline.theme\n"
"#+TITLE: " title "\n\n"
(org-list-to-org list) "\nfile:sitemap.svg"))
(setq my-publish-time 0) ; see the next section for context
(defun roam-publication-wrapper (plist filename pubdir)
(org-roam-graph)
(org-html-publish-to-html plist filename pubdir)
(setq my-publish-time (cadr (current-time))))
(setq org-publish-project-alist
'(("roam"
:base-directory "~/roam"
:auto-sitemap t
:sitemap-function roam-sitemap
:sitemap-title "Roam notes"
:publishing-function roam-publication-wrapper
:publishing-directory "~/roam-export"
:section-number nil
:table-of-contents nil
:style "<link rel=\"stylesheet\" href=\"../other/mystyle.cs\" type=\"text/css\">")))
#+end_src
*** Overriding the default link creation function
The code below will generate a link to the generated html file instead
of the default org-protocol link.
#+begin_src emacs-lisp
(defun org-roam-custom-link-builder (node)
(let ((file (org-roam-node-file node)))
(concat (file-name-base file) ".html")))
(setq org-roam-graph-link-builder 'org-roam-custom-link-builder)
#+end_src
*** Copying the generated file to the export directory
The default behavior of =org-roam-graph= is to generate the graph and
display it in Emacs. There is an =org-roam-graph-generation-hook=
available that provides access to the file names so they can be copied
to the publishing directory. Example code follows:
#+begin_src emacs-lisp
(add-hook 'org-roam-graph-generation-hook
(lambda (dot svg) (if (< (- (cadr (current-time)) my-publish-time) 5)
(progn (copy-file svg "~/roam-export/sitemap.svg" 't)
(kill-buffer (file-name-nondirectory svg))
(setq my-publish-time 0)))))
#+end_src
* Developer's Guide to Org-roam * Developer's Guide to Org-roam
** Org-roam's Design Principle ** Org-roam's Design Principle

View File

@ -86,7 +86,6 @@ General Public License for more details.
* Command Index:: * Command Index::
* Function Index:: * Function Index::
* Variable Index:: * Variable Index::
* Bibliography: Bibliography (1).
@detailmenu @detailmenu
--- The Detailed Node Listing --- --- The Detailed Node Listing ---
@ -190,6 +189,13 @@ FAQ
* How can I stop Org-roam from creating IDs everywhere?:: * How can I stop Org-roam from creating IDs everywhere?::
* How do I migrate from Roam Research?:: * How do I migrate from Roam Research?::
* How to migrate from Org-roam v1?:: * How to migrate from Org-roam v1?::
* How do I publish my notes with an Internet-friendly graph?::
How do I publish my notes with an Internet-friendly graph?
* Configure org-mode for publishing::
* Overriding the default link creation function::
* Copying the generated file to the export directory::
Developer's Guide to Org-roam Developer's Guide to Org-roam
@ -1059,7 +1065,7 @@ Remove a ref from the node at point.
Since version 9.5, Org has first-class support for citations. Org-roam supports Since version 9.5, Org has first-class support for citations. Org-roam supports
the caching of both these in-built citations (of form @code{[cite:@@key]}) and @uref{https://github.com/jkitchin/org-ref, org-ref} the caching of both these in-built citations (of form @code{[cite:@@key]}) and @uref{https://github.com/jkitchin/org-ref, org-ref}
citations (of form (NO@math{_ITEM}@math{_DATA}:key)). citations (of form @uref{key}).
Org-roam attempts to load both the @code{org-ref} and @code{org-cite} package when Org-roam attempts to load both the @code{org-ref} and @code{org-cite} package when
indexing files, so no further setup from the user is required for citation indexing files, so no further setup from the user is required for citation
@ -1914,6 +1920,7 @@ Org-mode, and sync your cards to Anki via @uref{https://github.com/FooSoft/anki-
* How can I stop Org-roam from creating IDs everywhere?:: * How can I stop Org-roam from creating IDs everywhere?::
* How do I migrate from Roam Research?:: * How do I migrate from Roam Research?::
* How to migrate from Org-roam v1?:: * How to migrate from Org-roam v1?::
* How do I publish my notes with an Internet-friendly graph?::
@end menu @end menu
@node How do I have more than one Org-roam directory? @node How do I have more than one Org-roam directory?
@ -2008,6 +2015,109 @@ and the @code{ROAM_TAGS} property for headline nodes
Replace existing file links with ID links. Replace existing file links with ID links.
@end itemize @end itemize
@node How do I publish my notes with an Internet-friendly graph?
@section How do I publish my notes with an Internet-friendly graph?
The default graph builder creates a graph with an @uref{https://orgmode.org/worg/org-contrib/org-protocol.html, org-protocol}
handler which is convenient when you're working locally but
inconvenient when you want to publish your notes for remote access.
Likewise, it defaults to displaying the graph in Emacs which has the
exact same caveats. This problem is solvable in the following way
using org-mode's native @uref{https://orgmode.org/manual/Publishing.html, publishing} capability:
@itemize
@item
configure org-mode to publish your org-roam notes as a project.
@item
create a function that overrides the default org-protocol link
creation function(@samp{org-roam-default-link-builder}).
@item
create a hook that's called at the end of graph creation to copy
the generated graph to the appropriate place.
@end itemize
The example code below is used to publish to a local directory where a
separate shell script copies the files to the remote site.
@menu
* Configure org-mode for publishing::
* Overriding the default link creation function::
* Copying the generated file to the export directory::
@end menu
@node Configure org-mode for publishing
@subsection Configure org-mode for publishing
This has two steps:
@itemize
@item
Setting of a @emph{roam} project that publishes your notes.
@item
Configuring the @emph{sitemap.html} generation.
@item
Setting up @samp{org-publish} to generate the graph.
@end itemize
This will require code like the following:
@lisp
(defun roam-sitemap (title list)
(concat "#+OPTIONS: ^:nil author:nil html-postamble:nil\n"
"#+SETUPFILE: ./simple_inline.theme\n"
"#+TITLE: " title "\n\n"
(org-list-to-org list) "\nfile:sitemap.svg"))
(setq my-publish-time 0) ; see the next section for context
(defun roam-publication-wrapper (plist filename pubdir)
(org-roam-graph)
(org-html-publish-to-html plist filename pubdir)
(setq my-publish-time (cadr (current-time))))
(setq org-publish-project-alist
'(("roam"
:base-directory "~/roam"
:auto-sitemap t
:sitemap-function roam-sitemap
:sitemap-title "Roam notes"
:publishing-function roam-publication-wrapper
:publishing-directory "~/roam-export"
:section-number nil
:table-of-contents nil
:style "<link rel=\"stylesheet\" href=\"../other/mystyle.cs\" type=\"text/css\">")))
@end lisp
@node Overriding the default link creation function
@subsection Overriding the default link creation function
The code below will generate a link to the generated html file instead
of the default org-protocol link.
@lisp
(defun org-roam-custom-link-builder (node)
(let ((file (org-roam-node-file node)))
(concat (file-name-base file) ".html")))
(setq org-roam-graph-link-builder 'org-roam-custom-link-builder)
@end lisp
@node Copying the generated file to the export directory
@subsection Copying the generated file to the export directory
The default behavior of @samp{org-roam-graph} is to generate the graph and
display it in Emacs. There is an @samp{org-roam-graph-generation-hook}
available that provides access to the file names so they can be copied
to the publishing directory. Example code follows:
@lisp
(add-hook 'org-roam-graph-generation-hook
(lambda (dot svg) (if (< (- (cadr (current-time)) my-publish-time) 5)
(progn (copy-file svg "~/roam-export/sitemap.svg" 't)
(kill-buffer (file-name-nondirectory svg))
(setq my-publish-time 0)))))
@end lisp
@node Developer's Guide to Org-roam @node Developer's Guide to Org-roam
@chapter Developer's Guide to Org-roam @chapter Developer's Guide to Org-roam
@ -2260,10 +2370,5 @@ When GOTO is non-nil, go the note without creating an entry."
@printindex vr @printindex vr
@node Bibliography (1) Emacs 29.0.50 (Org mode 9.6)
@chapter Bibliography
NO@math{_ITEM}@math{_DATA}:key
Emacs 28.0.50 (Org mode N/A)
@bye @bye

View File

@ -113,6 +113,25 @@ All other values including nil will have no effect."
(const :tag "no" nil)) (const :tag "no" nil))
:group 'org-roam) :group 'org-roam)
(defcustom org-roam-graph-link-builder 'org-roam-org-protocol-link-builder
"Function used to build the Org-roam graph links.
Given a node name, return a string to be used for the link fed to
the graph generation utility."
:type 'function
:group 'org-roam)
(defcustom org-roam-graph-generation-hook nil
"Functions to run after the graph has been generated.
Each function is called with two arguments: the filename
containing the graph generation tool, and the generated graph."
:type 'hook
:group 'org-roam)
(defun org-roam-org-protocol-link-builder (node)
"Default org-roam link builder. Generate an org-protocol link using NODE."
(concat "org-protocol://roam-node?node="
(url-hexify-string (org-roam-node-id node))))
;;; Interactive command ;;; Interactive command
;;;###autoload ;;;###autoload
(defun org-roam-graph (&optional arg node) (defun org-roam-graph (&optional arg node)
@ -153,7 +172,8 @@ CALLBACK is passed the graph file as its sole argument."
:sentinel (when callback :sentinel (when callback
(lambda (process _event) (lambda (process _event)
(when (= 0 (process-exit-status process)) (when (= 0 (process-exit-status process))
(funcall callback temp-graph))))))) (progn (funcall callback temp-graph)
(run-hook-with-args 'org-roam-graph-generation-hook temp-dot temp-graph))))))))
(defun org-roam-graph--dot (&optional edges all-nodes) (defun org-roam-graph--dot (&optional edges all-nodes)
"Build the graphviz given the EDGES of the graph. "Build the graphviz given the EDGES of the graph.
@ -250,8 +270,7 @@ Handles both Org-roam nodes, and string nodes (e.g. urls)."
(_ title))))) (_ title)))))
(setq node-id (org-roam-node-id node) (setq node-id (org-roam-node-id node)
node-properties `(("label" . ,shortened-title) node-properties `(("label" . ,shortened-title)
("URL" . ,(concat "org-protocol://roam-node?node=" ("URL" . ,(funcall org-roam-graph-link-builder node))
(url-hexify-string (org-roam-node-id node))))
("tooltip" . ,(xml-escape-string title))))) ("tooltip" . ,(xml-escape-string title)))))
(setq node-id node (setq node-id node
node-properties (append `(("label" . ,(concat type ":" node))) node-properties (append `(("label" . ,(concat type ":" node)))