diff --git a/CHANGELOG.md b/CHANGELOG.md index 929d5fc..c4f2b74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## TBD ### Breaking ### Added +- [#2138](https://github.com/org-roam/org-roam/pull/2138) export: add new module + ### Removed ### Fixed - [#2130](https://github.com/org-roam/org-roam/pull/2130) buffer: unlinked-references section now also searches within symlinked directories diff --git a/doc/org-roam.org b/doc/org-roam.org index c572ba3..e36f215 100644 --- a/doc/org-roam.org +++ b/doc/org-roam.org @@ -134,7 +134,7 @@ A slip-box requires a method for quickly capturing ideas. These are called *fleeting notes*: they are simple reminders of information or ideas that will need to be processed later on, or trashed. This is typically accomplished using ~org-capture~ (see info:org#Capture), or using Org-roam's daily notes -functionality (see [[*Org-roam Dailies][Org-roam Dailies]]). This provides a central inbox for collecting +functionality (see [[*org-roam-dailies][org-roam-dailies]]). This provides a central inbox for collecting thoughts, to be processed later into permanent notes. *Permanent notes* @@ -765,7 +765,7 @@ With the above example, if another node links to https://www.google.com/, it will show up as a “reference backlink”. These keys also come in useful for when taking website notes, using the - ~roam-ref~ protocol (see [[*Org-roam Protocol][Roam Protocol]]). + ~roam-ref~ protocol (see [[*org-roam-protocol][org-roam-protocol]]). You may assign multiple refs to a single node, for example when you want multiple papers in a series to share the same note, or an article has a citation @@ -896,211 +896,6 @@ Note that the Org-roam database stores metadata information in plain-text (headline text, for example), so if this information is private to you then you should also ensure the database is encrypted. -* Org-roam Protocol - -Org-roam provides extensions for capturing content from external applications -such as the browser, via ~org-protocol~. Org-roam extends ~org-protocol~ with 2 -protocols: the ~roam-node~ and ~roam-ref~ protocols. - -** Installation - -To enable Org-roam's protocol extensions, simply add the following to your init -file: - -#+BEGIN_SRC emacs-lisp -(require 'org-roam-protocol) -#+END_SRC - -We also need to set up ~org-protocol~: the instructions for setting up -~org-protocol~ are reproduced here. - -On a high-level, external calls are passed to Emacs via ~emacsclient~. -~org-protocol~ intercepts these and runs custom actions based on the protocols -registered. Hence, to use ~org-protocol~, once must: - -1. launch the ~emacsclient~ process -2. Register ~org-protocol://~ as a valid scheme-handler - -The instructions for the latter for each operating system is detailed below. - -*** Linux -For Linux users, create a desktop application in -~~/.local/share/applications/org-protocol.desktop~: - -#+begin_example -[Desktop Entry] -Name=Org-Protocol -Exec=emacsclient %u -Icon=emacs-icon -Type=Application -Terminal=false -MimeType=x-scheme-handler/org-protocol -#+end_example - -Associate ~org-protocol://~ links with the desktop application by -running in your shell: - -#+BEGIN_SRC bash -xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol -#+END_SRC - -To disable the "confirm" prompt in Chrome, you can also make Chrome show a -checkbox to tick, so that the ~Org-Protocol Client~ app will be used without -confirmation. To do this, run in a shell: - -#+BEGIN_SRC bash -sudo mkdir -p /etc/opt/chrome/policies/managed/ -sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF' -{ - "ExternalProtocolDialogShowAlwaysOpenCheckbox": true -} -EOF -sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json -#+END_SRC - -and then restart Chrome (for example, by navigating to ) to -make the new policy take effect. - -See [[https://www.chromium.org/administrators/linux-quick-start][here]] for more info on the ~/etc/opt/chrome/policies/managed~ directory and -[[https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox][here]] for information on the ~ExternalProtocolDialogShowAlwaysOpenCheckbox~ policy. - -*** Mac OS -For Mac OS, we need to create our own application. - -1. Launch Script Editor -2. Use the following script, paying attention to the path to ~emacsclient~: - -#+begin_src emacs-lisp - on open location this_URL - set EC to "/usr/local/bin/emacsclient --no-wait " - set filePath to quoted form of this_URL - do shell script EC & filePath - tell application "Emacs" to activate - end open location -#+end_src - -3. Save the script in ~/Applications/OrgProtocolClient.app~, changing the script type to - "Application", rather than "Script". -4. Edit ~/Applications/OrgProtocolClient.app/Contents/Info.plist~, adding the - following before the last ~~ tag: - -#+begin_src text - CFBundleURLTypes - - - CFBundleURLName - org-protocol handler - CFBundleURLSchemes - - org-protocol - - - -#+end_src - -5. Save the file, and run the ~OrgProtocolClient.app~ to register the protocol. - -To disable the "confirm" prompt in Chrome, you can also make Chrome -show a checkbox to tick, so that the ~OrgProtocol~ app will be used -without confirmation. To do this, run in a shell: - -#+BEGIN_SRC bash -defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true -#+END_SRC - -If you're using [[https://github.com/railwaycat/homebrew-emacsmacport][Emacs Mac Port]], it registered its `Emacs.app` as the default -handler for the URL scheme `org-protocol`. To make ~OrgProtocol.app~ -the default handler instead, run: - -#+BEGIN_SRC bash -defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \ -'{"LSHandlerPreferredVersions" = { "LSHandlerRoleAll" = "-"; }; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";}' -#+END_SRC - -Then restart your computer. - -**** Testing org-protocol - -To test that you have the handler setup and registered properly from the command -line you can run: - -#+begin_src bash - open org-protocol://roam-ref\?template=r\&ref=test\&title=this -#+end_src - -If you get an error similar too this or the wrong handler is run: - -#+begin_quote -No application knows how to open URL org-protocol://roam-ref?template=r&ref=test&title=this (Error Domain=NSOSStatusErrorDomain Code=-10814 "kLSApplicationNotFoundErr: E.g. no application claims the file" UserInfo={_LSLine=1489, _LSFunction=runEvaluator}). - -#+end_quote - -You may need to manually register your handler, like this: - -#+begin_src bash -/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/OrgProtocolClient.app -#+end_src - -Here is a link to the lsregister command that is really useful: https://eclecticlight.co/2019/03/25/lsregister-a-valuable-undocumented-command-for-launchservices/ -*** Windows -For Windows, create a temporary ~org-protocol.reg~ file: - -#+BEGIN_SRC text -REGEDIT4 - -[HKEY_CLASSES_ROOT\org-protocol] -@="URL:Org Protocol" -"URL Protocol"="" -[HKEY_CLASSES_ROOT\org-protocol\shell] -[HKEY_CLASSES_ROOT\org-protocol\shell\open] -[HKEY_CLASSES_ROOT\org-protocol\shell\open\command] -@="\"C:\\Windows\\System32\\wsl.exe\" emacsclient \"%1\"" -#+END_SRC - -The above will forward the protocol to WSL. If you run Emacs natively on -Windows, replace the last line with: - -#+BEGIN_SRC text -@="\"c:\\path\\to\\emacs\\bin\\emacsclientw.exe\" \"%1\"" -#+END_SRC - -After executing the .reg file, the protocol is registered and you can delete the -file. - -** The roam-node protocol - -The roam-node protocol opens the node with ID specified by the ~node~ key (e.g. -~org-protocol://roam-node?node=node-id~). ~org-roam-graph~ uses this to make the -graph navigable. - -** The roam-ref protocol - -This protocol finds or creates a new note with a given ~ROAM_REFS~: - -[[file:images/roam-ref.gif]] - -To use this, create the following [[https://en.wikipedia.org/wiki/Bookmarklet][bookmarklet]] in your browser: - -#+BEGIN_SRC javascript - javascript:location.href = - 'org-protocol://roam-ref?template=r&ref=' - + encodeURIComponent(location.href) - + '&title=' - + encodeURIComponent(document.title) - + '&body=' - + encodeURIComponent(window.getSelection()) -#+END_SRC - -or as a keybinding in ~qutebrowser~ in , using the ~config.py~ file (see -[[https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc][Configuring qutebrowser]]): - -#+BEGIN_SRC python - config.bind("", "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)") -#+END_SRC - -where ~template~ is the template key for a template in -~org-roam-capture-ref-templates~ (see [[*The Templating System][The Templating System]]). - * The Templating System Org-roam extends the ~org-capture~ system, providing a smoother note-taking @@ -1182,12 +977,217 @@ One can check the list of available keys for nodes by inspecting the This makes ~${file}~, ~${file-hash}~ etc. all valid substitutions. -* Graphing +* Extensions +** org-roam-protocol + +Org-roam provides extensions for capturing content from external applications +such as the browser, via ~org-protocol~. Org-roam extends ~org-protocol~ with 2 +protocols: the ~roam-node~ and ~roam-ref~ protocols. + +*** Installation + +To enable Org-roam's protocol extensions, simply add the following to your init +file: + +#+BEGIN_SRC emacs-lisp +(require 'org-roam-protocol) +#+END_SRC + +We also need to set up ~org-protocol~: the instructions for setting up +~org-protocol~ are reproduced here. + +On a high-level, external calls are passed to Emacs via ~emacsclient~. +~org-protocol~ intercepts these and runs custom actions based on the protocols +registered. Hence, to use ~org-protocol~, once must: + +1. launch the ~emacsclient~ process +2. Register ~org-protocol://~ as a valid scheme-handler + +The instructions for the latter for each operating system is detailed below. + +**** Linux +For Linux users, create a desktop application in +~~/.local/share/applications/org-protocol.desktop~: + +#+begin_example +[Desktop Entry] +Name=Org-Protocol +Exec=emacsclient %u +Icon=emacs-icon +Type=Application +Terminal=false +MimeType=x-scheme-handler/org-protocol +#+end_example + +Associate ~org-protocol://~ links with the desktop application by +running in your shell: + +#+BEGIN_SRC bash +xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol +#+END_SRC + +To disable the "confirm" prompt in Chrome, you can also make Chrome show a +checkbox to tick, so that the ~Org-Protocol Client~ app will be used without +confirmation. To do this, run in a shell: + +#+BEGIN_SRC bash +sudo mkdir -p /etc/opt/chrome/policies/managed/ +sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF' +{ + "ExternalProtocolDialogShowAlwaysOpenCheckbox": true +} +EOF +sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json +#+END_SRC + +and then restart Chrome (for example, by navigating to ) to +make the new policy take effect. + +See [[https://www.chromium.org/administrators/linux-quick-start][here]] for more info on the ~/etc/opt/chrome/policies/managed~ directory and +[[https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox][here]] for information on the ~ExternalProtocolDialogShowAlwaysOpenCheckbox~ policy. + +**** Mac OS +For Mac OS, we need to create our own application. + +1. Launch Script Editor +2. Use the following script, paying attention to the path to ~emacsclient~: + +#+begin_src emacs-lisp + on open location this_URL + set EC to "/usr/local/bin/emacsclient --no-wait " + set filePath to quoted form of this_URL + do shell script EC & filePath + tell application "Emacs" to activate + end open location +#+end_src + +3. Save the script in ~/Applications/OrgProtocolClient.app~, changing the script type to + "Application", rather than "Script". +4. Edit ~/Applications/OrgProtocolClient.app/Contents/Info.plist~, adding the + following before the last ~~ tag: + +#+begin_src text + CFBundleURLTypes + + + CFBundleURLName + org-protocol handler + CFBundleURLSchemes + + org-protocol + + + +#+end_src + +5. Save the file, and run the ~OrgProtocolClient.app~ to register the protocol. + +To disable the "confirm" prompt in Chrome, you can also make Chrome +show a checkbox to tick, so that the ~OrgProtocol~ app will be used +without confirmation. To do this, run in a shell: + +#+BEGIN_SRC bash +defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true +#+END_SRC + +If you're using [[https://github.com/railwaycat/homebrew-emacsmacport][Emacs Mac Port]], it registered its `Emacs.app` as the default +handler for the URL scheme `org-protocol`. To make ~OrgProtocol.app~ +the default handler instead, run: + +#+BEGIN_SRC bash +defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \ +'{"LSHandlerPreferredVersions" = { "LSHandlerRoleAll" = "-"; }; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";}' +#+END_SRC + +Then restart your computer. + +***** Testing org-protocol + +To test that you have the handler setup and registered properly from the command +line you can run: + +#+begin_src bash + open org-protocol://roam-ref\?template=r\&ref=test\&title=this +#+end_src + +If you get an error similar too this or the wrong handler is run: + +#+begin_quote +No application knows how to open URL org-protocol://roam-ref?template=r&ref=test&title=this (Error Domain=NSOSStatusErrorDomain Code=-10814 "kLSApplicationNotFoundErr: E.g. no application claims the file" UserInfo={_LSLine=1489, _LSFunction=runEvaluator}). + +#+end_quote + +You may need to manually register your handler, like this: + +#+begin_src bash +/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/OrgProtocolClient.app +#+end_src + +Here is a link to the lsregister command that is really useful: https://eclecticlight.co/2019/03/25/lsregister-a-valuable-undocumented-command-for-launchservices/ +**** Windows +For Windows, create a temporary ~org-protocol.reg~ file: + +#+BEGIN_SRC text +REGEDIT4 + +[HKEY_CLASSES_ROOT\org-protocol] +@="URL:Org Protocol" +"URL Protocol"="" +[HKEY_CLASSES_ROOT\org-protocol\shell] +[HKEY_CLASSES_ROOT\org-protocol\shell\open] +[HKEY_CLASSES_ROOT\org-protocol\shell\open\command] +@="\"C:\\Windows\\System32\\wsl.exe\" emacsclient \"%1\"" +#+END_SRC + +The above will forward the protocol to WSL. If you run Emacs natively on +Windows, replace the last line with: + +#+BEGIN_SRC text +@="\"c:\\path\\to\\emacs\\bin\\emacsclientw.exe\" \"%1\"" +#+END_SRC + +After executing the .reg file, the protocol is registered and you can delete the +file. + +*** The roam-node protocol + +The roam-node protocol opens the node with ID specified by the ~node~ key (e.g. +~org-protocol://roam-node?node=node-id~). ~org-roam-graph~ uses this to make the +graph navigable. + +*** The roam-ref protocol + +This protocol finds or creates a new note with a given ~ROAM_REFS~: + +[[file:images/roam-ref.gif]] + +To use this, create the following [[https://en.wikipedia.org/wiki/Bookmarklet][bookmarklet]] in your browser: + +#+BEGIN_SRC javascript + javascript:location.href = + 'org-protocol://roam-ref?template=r&ref=' + + encodeURIComponent(location.href) + + '&title=' + + encodeURIComponent(document.title) + + '&body=' + + encodeURIComponent(window.getSelection()) +#+END_SRC + +or as a keybinding in ~qutebrowser~ in , using the ~config.py~ file (see +[[https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc][Configuring qutebrowser]]): + +#+BEGIN_SRC python + config.bind("", "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)") +#+END_SRC + +where ~template~ is the template key for a template in +~org-roam-capture-ref-templates~ (see [[*The Templating System][The Templating System]]). + +** org-roam-graph Org-roam provides basic graphing capabilities to explore interconnections between notes, in ~org-roam-graph~. This is done by performing SQL queries and -generating images using [[https://graphviz.org/][Graphviz]]. The graph can also be navigated: see [[*Org-roam Protocol][Roam -Protocol]]. +generating images using [[https://graphviz.org/][Graphviz]]. The graph can also be navigated: see [[*org-roam-protocol][org-roam-protocol]]. The entry point to graph creation is ~org-roam-graph~. @@ -1228,7 +1228,7 @@ ARG may be any of the following values: (org-roam-graph--open (concat "file://///wsl$/Ubuntu" file))))) #+END_SRC -** Graph Options +*** Graph Options Graphviz provides many options for customizing the graph output, and Org-roam supports some of them. See https://graphviz.gitlab.io/_pages/doc/info/attrs.html @@ -1254,12 +1254,12 @@ for customizable options. Extra options for edges in the graphviz output (The "E" attributes). Example: ~'(("dir" . "back"))~ -* Org-roam Dailies +** org-roam-dailies Org-roam provides journaling capabilities akin to Org-journal with ~org-roam-dailies~. -** Configuration +*** Configuration For ~org-roam-dailies~ to work, you need to define two variables: @@ -1285,7 +1285,7 @@ Here is a sane default configuration: See [[*The Templating System][The Templating System]] for creating new templates. -** Usage +*** Usage ~org-roam-dailies~ provides these interactive functions: @@ -1339,6 +1339,18 @@ There are also commands which allow you to use Emacs’s ~calendar~ to find the - Function: ~org-roam-dailies-goto-next-note~ When in an daily-note, find the next one. +** org-roam-export + +Because Org-roam files are plain org files, they can be exported easily using +~org-export~ to a variety of formats, including ~html~ and ~pdf~. However, +Org-roam relies heavily on ID links, which Org's html export has poor support +of. To fix this, Org-roam provides a bunch of overrides to better support +export. To use them, simply run: + +#+begin_src emacs-lisp + (require 'org-roam-export) +#+end_src + * Performance Optimization ** Garbage Collection @@ -1412,7 +1424,7 @@ The Deft interface can slow down quickly when the number of files get huge. [[https://github.com/bastibe/org-journal][Org-journal]] provides journaling capabilities to Org-mode. A lot of its functionalities have been incorporated into Org-roam under the name -[[*Org-roam Dailies][~org-roam-dailies~]]. It remains a good tool if you want to isolate your verbose +[[*org-roam-dailies][~org-roam-dailies~]]. It remains a good tool if you want to isolate your verbose journal entries from the ideas you would write on a scratchpad. #+BEGIN_SRC emacs-lisp diff --git a/doc/org-roam.texi b/doc/org-roam.texi index 0b164a7..23717e9 100644 --- a/doc/org-roam.texi +++ b/doc/org-roam.texi @@ -73,10 +73,8 @@ General Public License for more details. * Citations:: * Completion:: * Encryption:: -* Org-roam Protocol:: * The Templating System:: -* Graphing:: -* Org-roam Dailies:: +* Extensions:: * Performance Optimization:: * The Org-mode Ecosystem:: * FAQ:: @@ -141,7 +139,19 @@ Completion * Completing within Link Brackets:: * Completing anywhere:: -Org-roam Protocol +The Templating System + +* Template Walkthrough:: +* Org-roam Template Expansion:: + +Extensions + +* org-roam-protocol:: +* org-roam-graph:: +* org-roam-dailies:: +* org-roam-export:: + +org-roam-protocol * Installation: Installation (1). * The roam-node protocol:: @@ -153,20 +163,11 @@ Installation * Mac OS:: * Windows:: -Mac OS - -* Testing org-protocol:: - -The Templating System - -* Template Walkthrough:: -* Org-roam Template Expansion:: - -Graphing +org-roam-graph * Graph Options:: -Org-roam Dailies +org-roam-dailies * Configuration:: * Usage:: @@ -342,7 +343,7 @@ A slip-box requires a method for quickly capturing ideas. These are called @strong{fleeting notes}: they are simple reminders of information or ideas that will need to be processed later on, or trashed. This is typically accomplished using @code{org-capture} (see @ref{Capture,,,org,}), or using Org-roam's daily notes -functionality (see @ref{Org-roam Dailies}). This provides a central inbox for collecting +functionality (see @ref{org-roam-dailies}). This provides a central inbox for collecting thoughts, to be processed later into permanent notes. @strong{Permanent notes} @@ -1141,7 +1142,7 @@ With the above example, if another node links to @uref{https://www.google.com/}, will show up as a “reference backlink”. These keys also come in useful for when taking website notes, using the - @code{roam-ref} protocol (see @ref{Org-roam Protocol, , Roam Protocol}). + @code{roam-ref} protocol (see @ref{org-roam-protocol}). You may assign multiple refs to a single node, for example when you want multiple papers in a series to share the same note, or an article has a citation @@ -1295,257 +1296,6 @@ Note that the Org-roam database stores metadata information in plain-text (headline text, for example), so if this information is private to you then you should also ensure the database is encrypted. -@node Org-roam Protocol -@chapter Org-roam Protocol - -Org-roam provides extensions for capturing content from external applications -such as the browser, via @code{org-protocol}. Org-roam extends @code{org-protocol} with 2 -protocols: the @code{roam-node} and @code{roam-ref} protocols. - -@menu -* Installation: Installation (1). -* The roam-node protocol:: -* The roam-ref protocol:: -@end menu - -@node Installation (1) -@section Installation - -To enable Org-roam's protocol extensions, simply add the following to your init -file: - -@lisp -(require 'org-roam-protocol) -@end lisp - -We also need to set up @code{org-protocol}: the instructions for setting up -@code{org-protocol} are reproduced here. - -On a high-level, external calls are passed to Emacs via @code{emacsclient}. -@code{org-protocol} intercepts these and runs custom actions based on the protocols -registered. Hence, to use @code{org-protocol}, once must: - -@itemize -@item -launch the @code{emacsclient} process - -@item -Register @code{org-protocol://} as a valid scheme-handler -@end itemize - -The instructions for the latter for each operating system is detailed below. - -@menu -* Linux:: -* Mac OS:: -* Windows:: -@end menu - -@node Linux -@subsection Linux - -For Linux users, create a desktop application in -@code{~/.local/share/applications/org-protocol.desktop}: - -@example -[Desktop Entry] -Name=Org-Protocol -Exec=emacsclient %u -Icon=emacs-icon -Type=Application -Terminal=false -MimeType=x-scheme-handler/org-protocol -@end example - -Associate @code{org-protocol://} links with the desktop application by -running in your shell: - -@example -xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol -@end example - -To disable the ``confirm'' prompt in Chrome, you can also make Chrome show a -checkbox to tick, so that the @code{Org-Protocol Client} app will be used without -confirmation. To do this, run in a shell: - -@example -sudo mkdir -p /etc/opt/chrome/policies/managed/ -sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF' -@{ - "ExternalProtocolDialogShowAlwaysOpenCheckbox": true -@} -EOF -sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json -@end example - -and then restart Chrome (for example, by navigating to ) to -make the new policy take effect. - -See @uref{https://www.chromium.org/administrators/linux-quick-start, here} for more info on the @code{/etc/opt/chrome/policies/managed} directory and -@uref{https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox, here} for information on the @code{ExternalProtocolDialogShowAlwaysOpenCheckbox} policy. - -@node Mac OS -@subsection Mac OS - -For Mac OS, we need to create our own application. - -@itemize -@item -Launch Script Editor - -@item -Use the following script, paying attention to the path to @code{emacsclient}: -@end itemize - -@lisp -on open location this_URL - set EC to "/usr/local/bin/emacsclient --no-wait " - set filePath to quoted form of this_URL - do shell script EC & filePath - tell application "Emacs" to activate -end open location -@end lisp - -@itemize -@item -Save the script in @code{/Applications/OrgProtocolClient.app}, changing the script type to -``Application'', rather than ``Script''. - -@item -Edit @code{/Applications/OrgProtocolClient.app/Contents/Info.plist}, adding the -following before the last @code{} tag: -@end itemize - -@example -CFBundleURLTypes - - - CFBundleURLName - org-protocol handler - CFBundleURLSchemes - - org-protocol - - - -@end example - -@itemize -@item -Save the file, and run the @code{OrgProtocolClient.app} to register the protocol. -@end itemize - -To disable the ``confirm'' prompt in Chrome, you can also make Chrome -show a checkbox to tick, so that the @code{OrgProtocol} app will be used -without confirmation. To do this, run in a shell: - -@example -defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true -@end example - -If you're using @uref{https://github.com/railwaycat/homebrew-emacsmacport, Emacs Mac Port}, it registered its `Emacs.app` as the default -handler for the URL scheme `org-protocol`. To make @code{OrgProtocol.app} -the default handler instead, run: - -@example -defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \ -'@{"LSHandlerPreferredVersions" = @{ "LSHandlerRoleAll" = "-"; @}; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";@}' -@end example - -Then restart your computer. - -@menu -* Testing org-protocol:: -@end menu - -@node Testing org-protocol -@unnumberedsubsubsec Testing org-protocol - -To test that you have the handler setup and registered properly from the command -line you can run: - -@example -open org-protocol://roam-ref\?template=r\&ref=test\&title=this -@end example - -If you get an error similar too this or the wrong handler is run: - -@quotation -No application knows how to open URL org-protocol://roam-ref?template=r&ref=test&title=this (Error Domain=NSOSStatusErrorDomain Code=-10814 ``kLSApplicationNotFoundErr: E.g. no application claims the file'' UserInfo=@{@math{_LSLine}=1489, _LSFunction=runEvaluator@}). - -@end quotation - -You may need to manually register your handler, like this: - -@example -/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/OrgProtocolClient.app -@end example - -Here is a link to the lsregister command that is really useful: @uref{https://eclecticlight.co/2019/03/25/lsregister-a-valuable-undocumented-command-for-launchservices/} - -@node Windows -@subsection Windows - -For Windows, create a temporary @code{org-protocol.reg} file: - -@example -REGEDIT4 - -[HKEY_CLASSES_ROOT\org-protocol] -@@="URL:Org Protocol" -"URL Protocol"="" -[HKEY_CLASSES_ROOT\org-protocol\shell] -[HKEY_CLASSES_ROOT\org-protocol\shell\open] -[HKEY_CLASSES_ROOT\org-protocol\shell\open\command] -@@="\"C:\\Windows\\System32\\wsl.exe\" emacsclient \"%1\"" -@end example - -The above will forward the protocol to WSL@. If you run Emacs natively on -Windows, replace the last line with: - -@example -@@="\"c:\\path\\to\\emacs\\bin\\emacsclientw.exe\" \"%1\"" -@end example - -After executing the .reg file, the protocol is registered and you can delete the -file. - -@node The roam-node protocol -@section The roam-node protocol - -The roam-node protocol opens the node with ID specified by the @code{node} key (e.g. -@code{org-protocol://roam-node?node=node-id}). @code{org-roam-graph} uses this to make the -graph navigable. - -@node The roam-ref protocol -@section The roam-ref protocol - -This protocol finds or creates a new note with a given @code{ROAM_REFS}: - -@image{images/roam-ref,,,,gif} - -To use this, create the following @uref{https://en.wikipedia.org/wiki/Bookmarklet, bookmarklet} in your browser: - -@example -javascript:location.href = - 'org-protocol://roam-ref?template=r&ref=' - + encodeURIComponent(location.href) - + '&title=' - + encodeURIComponent(document.title) - + '&body=' - + encodeURIComponent(window.getSelection()) -@end example - -or as a keybinding in @code{qutebrowser} in , using the @code{config.py} file (see -@uref{https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc, Configuring qutebrowser}): - -@example -config.bind("", "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)") -@end example - -where @code{template} is the template key for a template in -@code{org-roam-capture-ref-templates} (see @ref{The Templating System}). - @node The Templating System @chapter The Templating System @@ -1662,13 +1412,272 @@ One can check the list of available keys for nodes by inspecting the This makes @code{$@{file@}}, @code{$@{file-hash@}} etc. all valid substitutions. -@node Graphing -@chapter Graphing +@node Extensions +@chapter Extensions + +@menu +* org-roam-protocol:: +* org-roam-graph:: +* org-roam-dailies:: +* org-roam-export:: +@end menu + +@node org-roam-protocol +@section org-roam-protocol + +Org-roam provides extensions for capturing content from external applications +such as the browser, via @code{org-protocol}. Org-roam extends @code{org-protocol} with 2 +protocols: the @code{roam-node} and @code{roam-ref} protocols. + +@menu +* Installation: Installation (1). +* The roam-node protocol:: +* The roam-ref protocol:: +@end menu + +@node Installation (1) +@subsection Installation + +To enable Org-roam's protocol extensions, simply add the following to your init +file: + +@lisp +(require 'org-roam-protocol) +@end lisp + +We also need to set up @code{org-protocol}: the instructions for setting up +@code{org-protocol} are reproduced here. + +On a high-level, external calls are passed to Emacs via @code{emacsclient}. +@code{org-protocol} intercepts these and runs custom actions based on the protocols +registered. Hence, to use @code{org-protocol}, once must: + +@itemize +@item +launch the @code{emacsclient} process + +@item +Register @code{org-protocol://} as a valid scheme-handler +@end itemize + +The instructions for the latter for each operating system is detailed below. + +@menu +* Linux:: +* Mac OS:: +* Windows:: +@end menu + +@node Linux +@unnumberedsubsubsec Linux + +For Linux users, create a desktop application in +@code{~/.local/share/applications/org-protocol.desktop}: + +@example +[Desktop Entry] +Name=Org-Protocol +Exec=emacsclient %u +Icon=emacs-icon +Type=Application +Terminal=false +MimeType=x-scheme-handler/org-protocol +@end example + +Associate @code{org-protocol://} links with the desktop application by +running in your shell: + +@example +xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol +@end example + +To disable the ``confirm'' prompt in Chrome, you can also make Chrome show a +checkbox to tick, so that the @code{Org-Protocol Client} app will be used without +confirmation. To do this, run in a shell: + +@example +sudo mkdir -p /etc/opt/chrome/policies/managed/ +sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF' +@{ + "ExternalProtocolDialogShowAlwaysOpenCheckbox": true +@} +EOF +sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json +@end example + +and then restart Chrome (for example, by navigating to ) to +make the new policy take effect. + +See @uref{https://www.chromium.org/administrators/linux-quick-start, here} for more info on the @code{/etc/opt/chrome/policies/managed} directory and +@uref{https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox, here} for information on the @code{ExternalProtocolDialogShowAlwaysOpenCheckbox} policy. + +@node Mac OS +@unnumberedsubsubsec Mac OS + +For Mac OS, we need to create our own application. + +@itemize +@item +Launch Script Editor + +@item +Use the following script, paying attention to the path to @code{emacsclient}: +@end itemize + +@lisp +on open location this_URL + set EC to "/usr/local/bin/emacsclient --no-wait " + set filePath to quoted form of this_URL + do shell script EC & filePath + tell application "Emacs" to activate +end open location +@end lisp + +@itemize +@item +Save the script in @code{/Applications/OrgProtocolClient.app}, changing the script type to +``Application'', rather than ``Script''. + +@item +Edit @code{/Applications/OrgProtocolClient.app/Contents/Info.plist}, adding the +following before the last @code{} tag: +@end itemize + +@example +CFBundleURLTypes + + + CFBundleURLName + org-protocol handler + CFBundleURLSchemes + + org-protocol + + + +@end example + +@itemize +@item +Save the file, and run the @code{OrgProtocolClient.app} to register the protocol. +@end itemize + +To disable the ``confirm'' prompt in Chrome, you can also make Chrome +show a checkbox to tick, so that the @code{OrgProtocol} app will be used +without confirmation. To do this, run in a shell: + +@example +defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true +@end example + +If you're using @uref{https://github.com/railwaycat/homebrew-emacsmacport, Emacs Mac Port}, it registered its `Emacs.app` as the default +handler for the URL scheme `org-protocol`. To make @code{OrgProtocol.app} +the default handler instead, run: + +@example +defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \ +'@{"LSHandlerPreferredVersions" = @{ "LSHandlerRoleAll" = "-"; @}; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";@}' +@end example + +Then restart your computer. + +@itemize +@item +@anchor{Testing org-protocol}Testing org-protocol + + +To test that you have the handler setup and registered properly from the command +line you can run: + +@example +open org-protocol://roam-ref\?template=r\&ref=test\&title=this +@end example + +If you get an error similar too this or the wrong handler is run: + +@quotation +No application knows how to open URL org-protocol://roam-ref?template=r&ref=test&title=this (Error Domain=NSOSStatusErrorDomain Code=-10814 ``kLSApplicationNotFoundErr: E.g. no application claims the file'' UserInfo=@{@math{_LSLine}=1489, _LSFunction=runEvaluator@}). + +@end quotation + +You may need to manually register your handler, like this: + +@example +/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/OrgProtocolClient.app +@end example + +Here is a link to the lsregister command that is really useful: @uref{https://eclecticlight.co/2019/03/25/lsregister-a-valuable-undocumented-command-for-launchservices/} +@end itemize + +@node Windows +@unnumberedsubsubsec Windows + +For Windows, create a temporary @code{org-protocol.reg} file: + +@example +REGEDIT4 + +[HKEY_CLASSES_ROOT\org-protocol] +@@="URL:Org Protocol" +"URL Protocol"="" +[HKEY_CLASSES_ROOT\org-protocol\shell] +[HKEY_CLASSES_ROOT\org-protocol\shell\open] +[HKEY_CLASSES_ROOT\org-protocol\shell\open\command] +@@="\"C:\\Windows\\System32\\wsl.exe\" emacsclient \"%1\"" +@end example + +The above will forward the protocol to WSL@. If you run Emacs natively on +Windows, replace the last line with: + +@example +@@="\"c:\\path\\to\\emacs\\bin\\emacsclientw.exe\" \"%1\"" +@end example + +After executing the .reg file, the protocol is registered and you can delete the +file. + +@node The roam-node protocol +@subsection The roam-node protocol + +The roam-node protocol opens the node with ID specified by the @code{node} key (e.g. +@code{org-protocol://roam-node?node=node-id}). @code{org-roam-graph} uses this to make the +graph navigable. + +@node The roam-ref protocol +@subsection The roam-ref protocol + +This protocol finds or creates a new note with a given @code{ROAM_REFS}: + +@image{images/roam-ref,,,,gif} + +To use this, create the following @uref{https://en.wikipedia.org/wiki/Bookmarklet, bookmarklet} in your browser: + +@example +javascript:location.href = + 'org-protocol://roam-ref?template=r&ref=' + + encodeURIComponent(location.href) + + '&title=' + + encodeURIComponent(document.title) + + '&body=' + + encodeURIComponent(window.getSelection()) +@end example + +or as a keybinding in @code{qutebrowser} in , using the @code{config.py} file (see +@uref{https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc, Configuring qutebrowser}): + +@example +config.bind("", "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)") +@end example + +where @code{template} is the template key for a template in +@code{org-roam-capture-ref-templates} (see @ref{The Templating System}). + +@node org-roam-graph +@section org-roam-graph Org-roam provides basic graphing capabilities to explore interconnections between notes, in @code{org-roam-graph}. This is done by performing SQL queries and -generating images using @uref{https://graphviz.org/, Graphviz}. The graph can also be navigated: see @ref{Org-roam Protocol, , Roam -Protocol}. +generating images using @uref{https://graphviz.org/, Graphviz}. The graph can also be navigated: see @ref{org-roam-protocol}. The entry point to graph creation is @code{org-roam-graph}. @@ -1726,7 +1735,7 @@ the second option to set the browser and network file path: @end menu @node Graph Options -@section Graph Options +@subsection Graph Options Graphviz provides many options for customizing the graph output, and Org-roam supports some of them. See @uref{https://graphviz.gitlab.io/_pages/doc/info/attrs.html} @@ -1756,8 +1765,8 @@ Extra options for edges in the graphviz output (The ``E'' attributes). Example: @code{'(("dir" . "back"))} @end defopt -@node Org-roam Dailies -@chapter Org-roam Dailies +@node org-roam-dailies +@section org-roam-dailies Org-roam provides journaling capabilities akin to Org-journal with @code{org-roam-dailies}. @@ -1768,7 +1777,7 @@ Org-journal with @code{org-roam-dailies}. @end menu @node Configuration -@section Configuration +@subsection Configuration For @code{org-roam-dailies} to work, you need to define two variables: @@ -1797,7 +1806,7 @@ Here is a sane default configuration: See @ref{The Templating System} for creating new templates. @node Usage -@section Usage +@subsection Usage @code{org-roam-dailies} provides these interactive functions: @@ -1861,6 +1870,19 @@ When in an daily-note, find the previous one. When in an daily-note, find the next one. @end defun +@node org-roam-export +@section org-roam-export + +Because Org-roam files are plain org files, they can be exported easily using +@code{org-export} to a variety of formats, including @code{html} and @code{pdf}. However, +Org-roam relies heavily on ID links, which Org's html export has poor support +of. To fix this, Org-roam provides a bunch of overrides to better support +export. To use them, simply run: + +@lisp +(require 'org-roam-export) +@end lisp + @node Performance Optimization @chapter Performance Optimization @@ -1958,7 +1980,7 @@ The Deft interface can slow down quickly when the number of files get huge. @uref{https://github.com/bastibe/org-journal, Org-journal} provides journaling capabilities to Org-mode. A lot of its functionalities have been incorporated into Org-roam under the name -@ref{Org-roam Dailies, , @code{org-roam-dailies}}. It remains a good tool if you want to isolate your verbose +@ref{org-roam-dailies, , @code{org-roam-dailies}}. It remains a good tool if you want to isolate your verbose journal entries from the ideas you would write on a scratchpad. @lisp diff --git a/extensions/org-roam-export.el b/extensions/org-roam-export.el new file mode 100644 index 0000000..4c1e014 --- /dev/null +++ b/extensions/org-roam-export.el @@ -0,0 +1,75 @@ +;;; org-roam-export.el --- Org-roam org-export tweaks -*- coding: utf-8; lexical-binding: t; -*- + +;; Copyright © 2020-2022 Jethro Kuan + +;; Author: Jethro Kuan +;; URL: https://github.com/org-roam/org-roam +;; Keywords: org-mode, roam, convenience +;; Version: 2.2.1 +;; Package-Requires: ((emacs "26.1") (org "9.4") (org-roam "2.1")) + +;; This file is NOT part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; +;; This package provides the necessary changes required to make org-export work out-of-the-box. +;; +;; To enable it, run: +;; +;; (require 'org-roam-export) +;; +;; The key issue Org's export-to-html functionality has is that it does not respect the ID property, which +;; Org-roam relies heavily on. This patches the necessary function in ox-html to export ID links correctly, +;; pointing to the correct place. +;; +;;; Code: +(require 'ox-html) + +(defun org-roam-export--org-html--reference (datum info &optional named-only) + "Org-roam's patch for `org-html--reference' to support ID link export. +See `org-html--reference' for DATUM, INFO and NAMED-ONLY." + (let* ((type (org-element-type datum)) + (user-label + (org-element-property + (pcase type + ((or `headline `inlinetask) :CUSTOM_ID) + ((or `radio-target `target) :value) + (_ :name)) + datum)) + (user-label + (or user-label + (when-let ((path (org-element-property :ID datum))) + ;; see `org-html-link' for why we use "ID-" + ;; (search for "ID-" in ox-html.el) + (concat "ID-" path))))) + (cond + ((and user-label + (or (plist-get info :html-prefer-user-labels) + (memq type '(headline inlinetask)))) + user-label) + ((and named-only + (not (memq type '(headline inlinetask radio-target target))) + (not user-label)) + nil) + (t + (org-export-get-reference datum info))))) + +(advice-add 'org-html--reference :override #'org-roam-export--org-html--reference) + +(provide 'org-roam-export) +;;; org-roam-export.el ends here