WEBVTT - EmacsConf 2022, Ramin Honary: "Build a Zettelkasten with the Hyperbole Rolodex" captioned by ramin 00:00:00.000 --> 00:00:06.759 Hello, attendees of EmacsConf 2022! 00:00:06.760 --> 00:00:08.839 The title of my talk is: 00:00:08.840 --> 00:00:16.159 "Build a Zettelkasten with the Hyperbole Rolodex." 00:00:16.160 --> 00:00:17.479 My name is Ramin Honary. 00:00:17.480 --> 00:00:19.279 I work as a software engineer 00:00:19.280 --> 00:00:22.839 writing apps for a small machine learning consultancy. 00:00:22.840 --> 00:00:24.839 I have been using Emacs since roughly 2018 00:00:24.840 --> 00:00:26.479 after having switched from a workflow 00:00:26.480 --> 00:00:29.439 using Vim together with Screen/Tmux for over a decade. 00:00:29.440 --> 00:00:31.439 Today I'd like to talk a bit about 00:00:31.440 --> 00:00:34.039 the Hyperbole package for Emacs. 00:00:34.040 --> 00:00:36.159 Others are presenting talks later today 00:00:36.160 --> 00:00:37.479 about Hyperbole as well, 00:00:37.480 --> 00:00:39.839 including some of the the authors and maintainers, 00:00:39.840 --> 00:00:41.879 so I won't go into too much detail 00:00:41.880 --> 00:00:43.559 about how Hyperbole works. 00:00:43.560 --> 00:00:45.039 Instead, I want to present 00:00:45.040 --> 00:00:46.839 a more concrete use case for Hyperbole, 00:00:46.840 --> 00:00:49.279 which is how to use it to facilitate 00:00:49.280 --> 00:00:51.919 the Zettelkasten method. 00:00:51.920 --> 00:00:53.759 Most Emacs users will probably be 00:00:53.760 --> 00:00:56.039 more familiar with Org Roam. 00:00:56.040 --> 00:00:58.679 Org Roam may even be the first thing that comes to mind 00:00:58.680 --> 00:01:00.399 when you hear the word "Zettelkasten." 00:01:00.400 --> 00:01:02.479 But personally, I use Hyperbole 00:01:02.480 --> 00:01:05.039 because I found it easier to get started with 00:01:05.040 --> 00:01:07.479 using it as an ideas database. 00:01:07.480 --> 00:01:09.599 All you need to do is install the Hyperbole package 00:01:09.600 --> 00:01:11.399 (which is available on GNU-ELPA) 00:01:11.400 --> 00:01:13.759 and then set a few customization options. 00:01:13.760 --> 00:01:15.399 There is nothing else you really need to do 00:01:15.400 --> 00:01:16.079 to get started. 00:01:16.080 --> 00:01:19.759 And also, Hyperbole works nicely with Org Mode. 00:01:19.760 --> 00:01:21.799 So Hyperbole's built-in functionality 00:01:21.800 --> 00:01:24.919 can be used as a nice, light-weight alternative 00:01:24.920 --> 00:01:28.199 to other Emacs Zettelkasten packages. 00:01:28.200 --> 00:01:30.599 This talk is for people who are curious about 00:01:30.600 --> 00:01:34.159 getting started with the Zettelkasten method, 00:01:34.160 --> 00:01:36.079 but are not ready to commit 00:01:36.080 --> 00:01:41.039 to a more purpose-built solution like Org Roam. 00:01:41.040 --> 00:01:42.719 So the thing I'd like people 00:01:42.720 --> 00:01:44.599 to take away from this presentation 00:01:44.600 --> 00:01:46.759 is that the Hyperbole Emacs package 00:01:46.760 --> 00:01:50.639 provides you with a flat-file database called "HyRolo" 00:01:50.640 --> 00:01:53.239 which you can use to store ideas. 00:01:53.240 --> 00:01:55.999 Then you can use what Hyperbole calls "buttons" 00:01:56.000 --> 00:01:57.239 (which are hyperlinks) 00:01:57.240 --> 00:02:00.519 to execute arbitrary Emacs commands 00:02:00.520 --> 00:02:03.159 and by inserting links into your database 00:02:03.160 --> 00:02:06.159 that execute queries against the database itself. 00:02:06.160 --> 00:02:08.959 These query-action links serve as 00:02:08.960 --> 00:02:10.319 a means to link ideas together, 00:02:10.320 --> 00:02:13.439 thus creating a functioning "Zettelkasten." 00:02:13.440 --> 00:02:15.479 If this doesn't make sense to you, 00:02:15.480 --> 00:02:19.839 I'll explain what all of this means presently. 00:02:19.840 --> 00:02:24.359 So just a quick overview of what "Zettelkasten" is. 00:02:24.360 --> 00:02:26.199 Note that most of what I say 00:02:26.200 --> 00:02:27.359 about the Zettelkasten method 00:02:27.360 --> 00:02:29.759 comes from a guy called Sascha Fast, 00:02:29.760 --> 00:02:33.119 and his website: zettelkasten.de . 00:02:33.120 --> 00:02:34.999 So a Zettelkasten is, in brief, 00:02:35.000 --> 00:02:38.199 a database containing many nodes of interconnected ideas, 00:02:38.200 --> 00:02:40.759 each idea being a single quantity of knowledge 00:02:40.760 --> 00:02:42.039 (about a paragraph) 00:02:42.040 --> 00:02:46.319 and linked to other related ideas. 00:02:46.320 --> 00:02:47.959 Also, let me quickly mention 00:02:47.960 --> 00:02:49.679 that there are actually many tools I use 00:02:49.680 --> 00:02:51.879 that assist me with the zettelkasten method: 00:02:51.880 --> 00:02:53.599 Hyperbole for hyperlinks; 00:02:53.600 --> 00:02:56.079 Embark for general text editing; 00:02:56.080 --> 00:02:57.279 Org Mode for markup; 00:02:57.280 --> 00:02:59.439 Dired for managing large sets of files; 00:02:59.440 --> 00:03:01.959 Consult, Vertico, Orderless, Marginalia; 00:03:01.960 --> 00:03:04.519 for interactive search through directories and documents; 00:03:04.520 --> 00:03:06.359 and Magit for revision control, 00:03:06.360 --> 00:03:08.159 and syncing my database of ideas 00:03:08.160 --> 00:03:10.199 across a few of my computers. 00:03:10.200 --> 00:03:12.959 Each of these tools provides some unique functionality, 00:03:12.960 --> 00:03:15.439 but today I will be focusing mostly on Hyperbole 00:03:15.440 --> 00:03:17.039 and how it is especially useful 00:03:17.040 --> 00:03:19.839 for the task of linking information together 00:03:19.840 --> 00:03:21.399 which is the most important aspect 00:03:21.400 --> 00:03:25.359 of the Zettelkasten methodology. 00:03:25.360 --> 00:03:28.399 And now I'll briefly go over what Hyperbole is. 00:03:28.400 --> 00:03:31.159 At it's core, Hyperbole is a simple markup language 00:03:31.160 --> 00:03:34.519 specifically designed to markup hyperlinks. 00:03:34.520 --> 00:03:38.439 Now, a hyperlink usually is only able to jump to 00:03:38.440 --> 00:03:40.959 ordinary URLs and file paths. 00:03:40.960 --> 00:03:44.319 Hyperbole extends the function of a hyperlink to provide 00:03:44.320 --> 00:03:45.999 a simple human-readable markup 00:03:46.000 --> 00:03:49.639 for executing Emacs commands (called "button actions") 00:03:49.640 --> 00:03:52.359 and then, on top of this core functionality, 00:03:52.360 --> 00:03:53.239 a few mini applications 00:03:53.240 --> 00:03:56.839 for example "HyRolo" and "Koutline", 00:03:56.840 --> 00:04:00.959 have been built to make Hyperbole more generally useful 00:04:00.960 --> 00:04:03.519 as a personal information management tool. 00:04:03.520 --> 00:04:07.959 "HyRolo" is the feature that I use as my Zettelkasten, 00:04:07.960 --> 00:04:10.999 and in particular, the HyRolo search feature 00:04:11.000 --> 00:04:12.319 in combination with 00:04:12.320 --> 00:04:16.719 the usual Hyperbole hyperlink markup language. 00:04:16.720 --> 00:04:19.199 So let me just quote the Hyperbole manual: 00:04:19.200 --> 00:04:24.759 "Hyperbole includes HyRolo for convenient management of 00:04:24.760 --> 00:04:27.439 hierarchical, record-oriented information. 00:04:27.440 --> 00:04:30.879 Most often, this is used for contact management 00:04:30.880 --> 00:04:33.519 but it can quickly be adapted to most any 00:04:33.520 --> 00:04:37.199 record-oriented lookup task requiring fast retrieval." 00:04:37.200 --> 00:04:38.839 So in other words, for example, 00:04:38.840 --> 00:04:41.399 it can be used to run search queries 00:04:41.400 --> 00:04:44.679 across the full set of nodes in a set of Org-Mode files. 00:04:44.680 --> 00:04:47.679 This means we can use an Org-Mode file 00:04:47.680 --> 00:04:49.639 as a flat-file database 00:04:49.640 --> 00:04:52.159 in which entries in the database can be linked together. 00:04:52.160 --> 00:04:55.239 This, in essence, is a what a Zettelkasten is. 00:04:55.240 --> 00:04:58.959 HyRolo needs almost no configuration, 00:04:58.960 --> 00:05:00.239 even if you are using it 00:05:00.240 --> 00:05:01.719 for the purpose of Zettelkasten, 00:05:01.720 --> 00:05:03.839 but you should at least make sure 00:05:03.840 --> 00:05:05.599 you set the location of the database 00:05:05.600 --> 00:05:08.159 in your Emacs config file, using the Customize system 00:05:08.160 --> 00:05:10.359 or however you prefer to configure your Emacs. 00:05:10.360 --> 00:05:13.799 I use "use-package", and on this slide I have here 00:05:13.800 --> 00:05:15.879 an abridged version of what my "init.el" file 00:05:15.880 --> 00:05:18.199 looks like for the Hyperbole package. 00:05:18.200 --> 00:05:21.159 A few relevant environment variables are set: 00:05:21.160 --> 00:05:23.879 the "hyrolo-file-list" variable 00:05:23.880 --> 00:05:26.919 selects where to find Rolo database files 00:05:26.920 --> 00:05:29.279 for the purpose of search. I have it set 00:05:29.280 --> 00:05:31.919 to just the Zettelkasten flat file database. 00:05:31.920 --> 00:05:35.199 And I also set "hyrolo-date-format" variable. 00:05:35.200 --> 00:05:37.879 Each database entry has a time stamp, and 00:05:37.880 --> 00:05:40.239 I use the time stamp as a unique ID 00:05:40.240 --> 00:05:43.279 for each entry (that is, each idea node) 00:05:43.280 --> 00:05:44.279 in the database. 00:05:44.280 --> 00:05:48.199 Finally, before I get into the actual demo, 00:05:48.200 --> 00:05:49.599 let me quickly explain 00:05:49.600 --> 00:05:51.559 the Hyperbole mini-buffer menu system. 00:05:51.560 --> 00:05:54.599 Mini-buffer menus in Hyperbole work just like 00:05:54.600 --> 00:05:55.559 in an ordinary GUI, 00:05:55.560 --> 00:05:58.759 except you typically enter into the mini-buffer menu 00:05:58.760 --> 00:06:01.159 with a key binding instead of a mouse click. 00:06:01.160 --> 00:06:03.319 To open the Hyperbole menu, 00:06:03.320 --> 00:06:06.479 you use the Hyperbole universal leader key 00:06:06.480 --> 00:06:09.519 that's C-h h, which by the way, 00:06:09.520 --> 00:06:13.239 this rebinds the "view-hello-file" command, 00:06:13.240 --> 00:06:15.759 which is a command that probably most people never use. 00:06:15.760 --> 00:06:20.919 So all Hyperbole menu key sequences begin with C-h h. 00:06:20.920 --> 00:06:23.239 Please remember this: 00:06:23.240 --> 00:06:25.159 as I explain how to do things, 00:06:25.160 --> 00:06:26.959 please don't worry too much 00:06:26.960 --> 00:06:28.679 about the key sequences I use 00:06:28.680 --> 00:06:30.319 to perform certain actions. 00:06:30.320 --> 00:06:32.319 Really, I am just navigating 00:06:32.320 --> 00:06:33.479 the Hyperbole mini-buffer menus. 00:06:33.480 --> 00:06:37.599 It is a very discoverable and fluid user interface. 00:06:37.600 --> 00:06:42.159 Anyway, now that we have configured our Rolo database, 00:06:42.160 --> 00:06:45.399 let's see how we enter new ideas into the database. 00:06:45.400 --> 00:06:48.879 And I will start with an empty database, 00:06:48.880 --> 00:06:53.639 then I'll switch over to a more complete database 00:06:53.640 --> 00:06:57.039 that I prepared for this demo. So... 00:06:57.040 --> 00:07:04.159 first we type the Hyperbole universal leader key C-h h, 00:07:04.160 --> 00:07:08.919 and then, you can see the menus down here 00:07:08.920 --> 00:07:15.279 we type "r" for "Rolo" and "a" for "add". 00:07:15.280 --> 00:07:19.479 That's C-h h r a to enter a new idea. 00:07:19.480 --> 00:07:23.319 And this command is available globally so, 00:07:23.320 --> 00:07:26.599 much like with the "org-capture" feature in Org-Mode, 00:07:26.600 --> 00:07:28.879 you can run this command at any time, 00:07:28.880 --> 00:07:32.479 at the very moment you want to enter an idea. 00:07:32.480 --> 00:07:36.159 First we are prompted for an entry title, 00:07:36.160 --> 00:07:38.799 and if you were using HyRolo as a contact list, 00:07:38.800 --> 00:07:40.959 this is where you would enter the person's name. 00:07:40.960 --> 00:07:43.199 I am using it as a Zettelkasten, 00:07:43.200 --> 00:07:45.439 so I instead enter a title for my idea. 00:07:45.440 --> 00:07:46.839 I'll just type in... 00:07:46.840 --> 00:07:53.159 and as soon as I press enter after this prompt, 00:07:53.160 --> 00:07:55.999 my Zettelkasten org file is opened, 00:07:56.000 --> 00:08:02.879 a new entry with the timestamp is created, 00:08:02.880 --> 00:08:06.319 and the cursor is placed at this entry 00:08:06.320 --> 00:08:09.079 ready for me to enter the body text of the idea. 00:08:09.080 --> 00:08:14.799 I'll type that in... 00:08:14.800 --> 00:08:18.039 Now I save the "idea" file (C-x C-s) 00:08:18.040 --> 00:08:20.879 and switch back to what I was working on before 00:08:20.880 --> 00:08:23.759 with the usual C-x 0 (delete-window) command. 00:08:23.760 --> 00:08:26.279 Next, I'd like to talk about 00:08:26.280 --> 00:08:28.719 the HyRolo database search feature, 00:08:28.720 --> 00:08:30.879 which is very useful. 00:08:30.880 --> 00:08:33.719 The HyRolo search feature uses 00:08:33.720 --> 00:08:35.319 only Emacs built-in functions 00:08:35.320 --> 00:08:36.599 and there is no indexing 00:08:36.600 --> 00:08:38.679 as with tools like "mlocate" or Org-Roam. 00:08:38.680 --> 00:08:41.439 So far, I have not had any trouble with efficiency. 00:08:41.440 --> 00:08:42.759 I don't know if at some point in the future, 00:08:42.760 --> 00:08:44.079 it will start slowing down. 00:08:44.080 --> 00:08:46.199 Emacs built-in search functionality 00:08:46.200 --> 00:08:47.679 is already pretty efficient as it is. 00:08:47.680 --> 00:08:50.839 It could also be that I am in the habit 00:08:50.840 --> 00:08:55.679 of storing larger bodies of text in separate files, 00:08:55.680 --> 00:08:57.559 and not in the flat file database. 00:08:57.560 --> 00:08:58.999 Anyway, you can search 00:08:59.000 --> 00:09:02.239 by regex, by string, or by words. 00:09:02.240 --> 00:09:03.799 I personally find the string search 00:09:03.800 --> 00:09:04.719 to be the most useful. 00:09:04.720 --> 00:09:07.479 The difference between word search and string search 00:09:07.480 --> 00:09:09.199 is that string search provides 00:09:09.200 --> 00:09:12.119 logical query operators like AND, OR, XOR, and NOT. 00:09:12.120 --> 00:09:14.199 Once you run a search query, 00:09:14.200 --> 00:09:16.479 a "*HyRolo*" buffer is opened 00:09:16.480 --> 00:09:18.159 with the query's results. 00:09:18.160 --> 00:09:20.439 And this is a read-only-mode buffer 00:09:20.440 --> 00:09:23.239 with a few useful single-key action bindings 00:09:23.240 --> 00:09:25.079 for navigating the list of results 00:09:25.080 --> 00:09:27.119 which I will now demonstrate. 00:09:27.120 --> 00:09:31.879 By the way, I have now switched over 00:09:31.880 --> 00:09:34.639 to a larger example Rolo database that I have created 00:09:34.640 --> 00:09:36.559 to demonstrate more of the HyRolo features. 00:09:36.560 --> 00:09:39.479 The HyRolo search is available 00:09:39.480 --> 00:09:40.679 in the Hyperbole mini-buffer menu 00:09:40.680 --> 00:09:42.239 so it is always available to you. 00:09:42.240 --> 00:09:46.959 Start with the Hyperbole universal leader key C-h h 00:09:46.960 --> 00:09:53.839 then "r" for Rolo and "s" for search. That is C-h h r s. 00:09:53.840 --> 00:09:56.039 Now we are prompted for a search string: 00:09:56.040 --> 00:10:02.519 I type in "Alice Abelton", and when I press enter, 00:10:02.520 --> 00:10:03.999 the search results pop up 00:10:04.000 --> 00:10:06.959 and the number of results is printed in the mini-buffer. 00:10:06.960 --> 00:10:09.599 We could also enter a search expression 00:10:09.600 --> 00:10:12.159 similar to a Lisp S-expression 00:10:12.160 --> 00:10:14.759 with logical operators like AND or NOT, 00:10:14.760 --> 00:10:19.279 but you would not need to quote the search terms. 00:10:19.280 --> 00:10:24.519 So, for example (C-h h r s), I could write 00:10:24.520 --> 00:10:30.279 "(and university character)" within parentheses 00:10:30.280 --> 00:10:31.959 and this would find entries 00:10:31.960 --> 00:10:33.799 that only contain both of the words 00:10:33.800 --> 00:10:35.759 "university" and "character". 00:10:35.760 --> 00:10:39.239 For the most part, I only really ever use 00:10:39.240 --> 00:10:41.719 the ordinary string search without logical operators. 00:10:41.720 --> 00:10:44.759 So as you can see, a search result buffer 00:10:44.760 --> 00:10:47.239 called "*HyRolo*" has popped up 00:10:47.240 --> 00:10:48.359 with all of the matching entries. 00:10:48.360 --> 00:10:51.319 And the search results buffer is a read-only buffer 00:10:51.320 --> 00:10:54.319 with several useful navigation key bindings: 00:10:54.320 --> 00:11:01.399 I can press "o" to switch to "overview" mode, 00:11:01.400 --> 00:11:03.959 which shows all of the headings, but no content. 00:11:03.960 --> 00:11:05.479 This would include subheadings 00:11:05.480 --> 00:11:07.959 with like 2 stars in front of it or 3 stars 00:11:07.960 --> 00:11:12.159 I can press "a" to switch to "show all mode" 00:11:12.160 --> 00:11:14.559 which shows all of the content under each heading. 00:11:14.560 --> 00:11:17.079 If I know I am looking for a keyword 00:11:17.080 --> 00:11:17.999 in a top-level heading, 00:11:18.000 --> 00:11:22.639 I can press "t" to switch to the "top-level" view mode 00:11:22.640 --> 00:11:25.439 which shows only the top-level headings. 00:11:25.440 --> 00:11:27.119 As is always the case 00:11:27.120 --> 00:11:28.879 with the Emacs default key bindings, 00:11:28.880 --> 00:11:32.359 "n" and "p" move the cursor down and up lines, 00:11:32.360 --> 00:11:34.519 so I can navigate the cursor downward 00:11:34.520 --> 00:11:37.599 to an entry that looks interesting. 00:11:37.600 --> 00:11:40.279 I can press "s" to show the content 00:11:40.280 --> 00:11:41.519 of that particular entry. 00:11:41.520 --> 00:11:44.799 I can press "h" to hide the entry again. 00:11:44.800 --> 00:11:49.479 And I can press "e" or M-RET on the entry heading 00:11:49.480 --> 00:11:53.279 to "edit" that heading (that entry), 00:11:53.280 --> 00:11:56.279 which will open the Org-Mode file, 00:11:56.280 --> 00:11:59.039 that is, the Zettelkasten database file 00:11:59.040 --> 00:12:01.759 with the cursor at this particular entry. 00:12:01.760 --> 00:12:07.639 Be warned that editing an entry creates a new timestamp, 00:12:07.640 --> 00:12:10.159 which I do not need, and there is currently 00:12:10.160 --> 00:12:12.039 no way to avoid this behavior. 00:12:12.040 --> 00:12:15.199 I work around this by simply using the undo command 00:12:15.200 --> 00:12:20.039 which removes the unwanted timestamp. 00:12:20.040 --> 00:12:25.559 And so that is how I use the HyRolo search functionality. 00:12:25.560 --> 00:12:31.999 Now... since the most important aspect of Zettelkasten 00:12:32.000 --> 00:12:33.839 is linking ideas in the database, 00:12:33.840 --> 00:12:37.039 how do we actually make this work in HyRolo? 00:12:37.040 --> 00:12:40.039 So this is the secret sauce of Hyperbole, 00:12:40.040 --> 00:12:41.119 and the key take-away 00:12:41.120 --> 00:12:43.279 for this presentation (as I said earlier). 00:12:43.280 --> 00:12:46.679 Hyperbole provides markup syntax 00:12:46.680 --> 00:12:50.079 for executing arbitrary Emacs commands 00:12:50.080 --> 00:12:53.759 so you can link HyRolo entries together 00:12:53.760 --> 00:12:56.039 using the HyRolo search function. 00:12:56.040 --> 00:12:58.279 Let me demonstrate this now. 00:12:58.280 --> 00:13:03.879 I am back in my example HyRolo database, 00:13:03.880 --> 00:13:06.239 and if you take a closer look 00:13:06.240 --> 00:13:11.399 you can see some of the hyperlinks 00:13:11.400 --> 00:13:13.119 that I already created 00:13:13.120 --> 00:13:15.839 with the angle-round bracket syntax. 00:13:15.840 --> 00:13:19.279 Now with the cursor inside of these brackets, 00:13:19.280 --> 00:13:23.439 I can press M-RET to "click" on this link. 00:13:23.440 --> 00:13:27.799 As you can see, the search query 00:13:27.800 --> 00:13:32.039 corresponding to this hyperlink here has executed 00:13:32.040 --> 00:13:34.919 and popped up the "*HyRolo*" search results buffer. 00:13:34.920 --> 00:13:38.719 There is only one linked entry, 00:13:38.720 --> 00:13:41.399 but the list of ideas that are produced 00:13:41.400 --> 00:13:43.759 by the search query in this buffer here 00:13:43.760 --> 00:13:45.639 are the list of all of the other ideas 00:13:45.640 --> 00:13:47.799 that are related to this hyperlink 00:13:47.800 --> 00:13:49.479 that we just clicked on here. 00:13:49.480 --> 00:13:52.199 (Let me get rid of the other window...) 00:13:52.200 --> 00:13:55.239 Now from within this "*HyRolo*" buffer, 00:13:55.240 --> 00:13:57.839 I can navigate to another hyperlink... 00:13:57.840 --> 00:14:03.759 and clicking on that updates the "*HyRolo*" buffer 00:14:03.760 --> 00:14:04.799 with new results again. 00:14:04.800 --> 00:14:10.119 I can just keep navigating through 00:14:10.120 --> 00:14:13.959 all the Zettelkasten entries in this way. 00:14:13.960 --> 00:14:18.639 And so this is it. 00:14:18.640 --> 00:14:22.719 This is my simple but effective Zettelkasten, 00:14:22.720 --> 00:14:25.119 constructed entirely with the functionality 00:14:25.120 --> 00:14:26.799 already built-in to Hyperbole. 00:14:26.800 --> 00:14:32.599 In the remaining time, 00:14:32.600 --> 00:14:36.999 I'd like to talk about how Hyperbole hyperlinks work, 00:14:37.000 --> 00:14:38.799 because it's slightly different 00:14:38.800 --> 00:14:40.759 from how hyperlinks work in Org Mode 00:14:40.760 --> 00:14:49.199 or with the Emacs clickable text properties. 00:14:49.200 --> 00:14:52.239 The easiest way to create a hyperlink button 00:14:52.240 --> 00:14:55.279 that runs an Emacs command 00:14:55.280 --> 00:14:59.479 is simply to type the Emacs command as an S-expression, 00:14:59.480 --> 00:15:03.399 but with angle brackets instead of parentheses. 00:15:03.400 --> 00:15:05.679 If you were looking closely, 00:15:05.680 --> 00:15:08.639 you probably already saw a hyperlink of this form, 00:15:08.640 --> 00:15:10.559 an angle-bracketed Emacs command. 00:15:10.560 --> 00:15:13.159 This hyperlink simply calls 00:15:13.160 --> 00:15:18.079 the "hyrolo-fgrep" function with this string argument. 00:15:18.080 --> 00:15:20.839 and so clicking on this button 00:15:20.840 --> 00:15:23.119 is equivalent to running a HyRolo search 00:15:23.120 --> 00:15:27.319 with the C-h h r s key sequence. 00:15:27.320 --> 00:15:31.399 As you can see, clicking on it 00:15:31.400 --> 00:15:32.919 produced the search results 00:15:32.920 --> 00:15:35.079 for entries associated with that string query. 00:15:35.080 --> 00:15:41.079 It's also possible to label an action 00:15:41.080 --> 00:15:43.599 with a so-called "implicit link", 00:15:43.600 --> 00:15:47.079 and that's this angle-and-square bracketed notation. 00:15:47.080 --> 00:15:51.999 If I click on this button, 00:15:52.000 --> 00:15:54.159 it will activate this action 00:15:54.160 --> 00:16:01.359 to the right of the colon separator, 00:16:01.360 --> 00:16:03.639 and there are the relevant search results 00:16:03.640 --> 00:16:04.679 from that string query. 00:16:04.680 --> 00:16:09.119 Finally, there are "explicit links", 00:16:09.120 --> 00:16:11.239 which I find to be especially useful 00:16:11.240 --> 00:16:12.599 for the Zettelkasten method. 00:16:12.600 --> 00:16:15.239 I've already shown an example 00:16:15.240 --> 00:16:17.079 of using an explicit link before. 00:16:17.080 --> 00:16:20.759 What makes explicit links so useful is, firstly, 00:16:20.760 --> 00:16:23.919 that the button works with just the label alone. 00:16:23.920 --> 00:16:26.599 There is no need to write an S-expression or anything. 00:16:26.600 --> 00:16:28.919 You can write the link label 00:16:28.920 --> 00:16:31.959 inline with the body text of the idea. 00:16:31.960 --> 00:16:34.879 (For example, like this.) 00:16:34.880 --> 00:16:38.999 Explicit links are identified by their label, 00:16:39.000 --> 00:16:40.839 so they are especially good for 00:16:40.840 --> 00:16:43.119 the names of people and places. 00:16:43.120 --> 00:16:46.399 By the way, this Zettelkasten database is for 00:16:46.400 --> 00:16:47.919 a fictional story I started writing 00:16:47.920 --> 00:16:50.079 for the purpose of demonstrating HyRolo 00:16:50.080 --> 00:16:52.879 in this presentation, and I had so much fun writing it 00:16:52.880 --> 00:16:54.999 that I may actually continue developing this story. 00:16:55.000 --> 00:16:58.639 Anyway, let's create a new explicit link 00:16:58.640 --> 00:17:01.679 and a new idea entry for a character in the story. 00:17:01.680 --> 00:17:10.239 So suppose I want to create a new idea node entry 00:17:10.240 --> 00:17:11.959 for this fictional character here, 00:17:11.960 --> 00:17:15.359 and I'll also want to link this entry to that node. 00:17:15.360 --> 00:17:17.839 Since hyperlinks are just string search, 00:17:17.840 --> 00:17:19.799 we don't actually need to have 00:17:19.800 --> 00:17:22.279 an entry in the database for this character. 00:17:22.280 --> 00:17:24.879 The worst that can happen is that the hyperlink 00:17:24.880 --> 00:17:27.319 executes a search that returns no results. 00:17:27.320 --> 00:17:29.079 So it's OK to create the hyperlink 00:17:29.080 --> 00:17:31.879 before we have an actual entry for this person. 00:17:31.880 --> 00:17:36.719 (I'll just M-w copy the name.) 00:17:36.720 --> 00:17:40.919 Now I use the universal Hyperbole leader key C-h h, 00:17:40.920 --> 00:17:44.519 and then "e" for "explicit links" 00:17:44.520 --> 00:17:49.359 and "c" for "create". That's C-h h e c. 00:17:49.360 --> 00:17:52.639 We are prompted for an entry label 00:17:52.640 --> 00:17:56.119 but it defaults to the text highlighted by the region, 00:17:56.120 --> 00:17:57.959 so I just press enter. 00:17:57.960 --> 00:18:00.479 Now it prompts for a button type, 00:18:00.480 --> 00:18:03.119 so I select "hyrolo-fgrep" 00:18:03.120 --> 00:18:06.479 (and there's Orderless helping me go faster), 00:18:06.480 --> 00:18:10.319 and since "hyrolo-fgrep" requires 00:18:10.320 --> 00:18:12.679 a string argument for the search query, 00:18:12.680 --> 00:18:14.479 I am prompted for the query string. 00:18:14.480 --> 00:18:21.839 I'll type in "character:", (yank "Kerri Katz's" name) 00:18:21.840 --> 00:18:26.839 and there we are, the link has been created, and 00:18:26.840 --> 00:18:31.159 (let me just get rid of the # character) 00:18:31.160 --> 00:18:32.719 I can try it out. 00:18:32.720 --> 00:18:36.199 There's no search results. That's fine. 00:18:36.200 --> 00:18:38.959 We haven't created an idea entry yet 00:18:38.960 --> 00:18:40.799 for this character now. 00:18:40.800 --> 00:18:43.399 So let's go ahead and do that now. 00:18:43.400 --> 00:18:45.679 If we remember how to create a new idea, 00:18:45.680 --> 00:18:52.359 it's C-h h r a, and then I type "character:" 00:18:52.360 --> 00:18:56.799 and then yank the name again. 00:18:56.800 --> 00:18:58.399 Now a new node has been created, 00:18:58.400 --> 00:19:04.359 and I can start describing this character. 00:19:04.360 --> 00:19:08.839 Notice that I like to precede my characters 00:19:08.840 --> 00:19:11.479 with the keyword "character:" colon. 00:19:11.480 --> 00:19:14.919 This technique helps me to create hyperlinks 00:19:14.920 --> 00:19:16.999 using more descriptive search queries 00:19:17.000 --> 00:19:19.879 that return fewer but more useful search results. 00:19:19.880 --> 00:19:23.839 And finally, I can create an explicit link 00:19:23.840 --> 00:19:26.039 from this character back to 00:19:26.040 --> 00:19:28.839 the other character (her boyfriend). 00:19:28.840 --> 00:19:31.159 I just type in "<(Bertrand Becket)>", 00:19:31.160 --> 00:19:37.039 and this explicit link has already been created 00:19:37.040 --> 00:19:39.679 so I don't need to create it again. It just works. 00:19:39.680 --> 00:19:41.879 Hyperbole identifies buttons by their label, 00:19:41.880 --> 00:19:44.719 so as long as an explicit link button with that label 00:19:44.720 --> 00:19:46.039 has been created before, 00:19:46.040 --> 00:19:51.079 I just can type in the button with markup by hand, 00:19:51.080 --> 00:19:53.279 and then I can just use it. 00:19:53.280 --> 00:19:57.839 Now I am back to the search results 00:19:57.840 --> 00:19:59.319 for the boyfriend character. 00:19:59.320 --> 00:20:04.159 I hope you can see how minimal but useful 00:20:04.160 --> 00:20:07.759 is this particular Zettelkasten technique I have 00:20:07.760 --> 00:20:10.559 that uses this "HyRolo". 00:20:10.560 --> 00:20:19.359 I should also make clear that Hyperbole explicit links 00:20:19.360 --> 00:20:22.279 are encoded in a separate file in the same directory 00:20:22.280 --> 00:20:24.279 as the Zettelkasten flat-file database. 00:20:24.280 --> 00:20:37.079 (So, let's go back to that and C-x C-f ".hypb"). 00:20:37.080 --> 00:20:41.239 You should not edit this file by hand, 00:20:41.240 --> 00:20:43.599 but it is human readable, 00:20:43.600 --> 00:20:45.399 so it works well with Git 00:20:45.400 --> 00:20:47.079 and other revision control systems. 00:20:47.080 --> 00:20:49.559 Whenever an explicit link is activated, 00:20:49.560 --> 00:20:52.559 it consults this file and runs the associated action, 00:20:52.560 --> 00:20:55.839 which, in the Zettelkasten use case, 00:20:55.840 --> 00:20:58.799 will always be to run a HyRolo search query. 00:20:58.800 --> 00:21:02.039 The advantage of keeping a separate table of links 00:21:02.040 --> 00:21:03.919 is that you can edit the link action 00:21:03.920 --> 00:21:06.999 (that is, the search query) in just one place, 00:21:07.000 --> 00:21:10.559 and the updated button action works everywhere 00:21:10.560 --> 00:21:12.479 without having to change any other files. 00:21:12.480 --> 00:21:18.399 So, that is all for today. 00:21:18.400 --> 00:21:20.519 Thank you so much for listening to my talk. 00:21:20.520 --> 00:21:23.079 I'll be available for questions 00:21:23.080 --> 00:21:24.919 for the next 20 minutes or so. 00:21:24.920 --> 00:21:27.959 If there are any questions that I cannot answer, 00:21:27.960 --> 00:21:29.439 you will have a chance to ask 00:21:29.440 --> 00:21:31.799 the author of Hyperbole himself, Bob Weiner, 00:21:31.800 --> 00:21:34.239 later today after his presentation. 00:21:34.240 --> 00:21:43.920 Thanks for your attention!