This blog post shows how to set up Luhjmann's Zettelkasten with Tp-Note and how to work with it.

Lemon note

Introduction to Tp-Note's Zettelkasten

The term Zettelkasten (ZK, lit. “slip box”) refers to a knowledge management system, invented be the sociologist Niklas Luhman in 19811. In this blog post, I assume, that you are familiar with the Zettelkasten method allowing us to focus on how to implement it with the software Tp-Note. If you wish more background information about the method, I recommend this introductory video made by Darin Suthapong2.

The directory structure

The original Zettelkasten consists of paper index cards within boxes. Tp-Note models these index cards as files and the boxes as directories. The Zettelkasten system knows four kinds of notes, all stored in separate boxes:

  • Literature Notes
  • Permanent Notes
  • Hub Notes
  • Fleeting Notes

For our Zettelkasten we create the same structure:

mkdir Zettelkasten
cd Zettelkasten
mkdir 'Literature Note'
mkdir 'Permanent Note'
mkdir 'Hub Note'
mkdir 'Fleeting Note'

The document identifier “sort-tag”

Each Zettelkasten index card has a unique identifier. In Tp-Note parlance, we talk about a sort-tag, which appears at the beginning of each filename and optionally in the front matter of the file itself. Tp-Note knows two kinds of sort-tags:

  • Chronological sort-tags indicating the date, e,g. 20231114, and
  • Sequential sort-tags, e.g. 1b. These sort-tags are unique and form a “line of thinking”, e.g. 0, 1, 1a, 1a1, 1a2.

The line of thinking, is one of the core principles of Luhmann's Zettelkasten. While creating a new note, you assign it to exactly one existing note that inspired the current work the most. This “follow-up relation” (German: Folgezettel) is established by the new note's sequential sort-tag. For example, if you base your new note on the existing note 1b the sort-tag of the new note will be 1c. If 1c exists already, you branch this line of thinking and name your new note 1c1 instead3. This way, the line of thinking traces the path that led you to gain the current insight. Furthermore, inspecting a line of thinking later, leads your thoughts into a meta perspective, that might show up connection to other insights you have not thought of before. Keep in mind, that a line of thinking is not a hierarchical ordering scheme! Please check out Ĝabbo's excellent video 4 about the rationale behind this.

Luhmann's numbering system
Image source: https://zettelkasten.de

In Tp-Note's Zettelkasten filename scheme, the sort-tag is followed by a title, and keywords. For example, a Tp-Note about lemons stored in a file named 2b3--Lemon__fruit_round_sour taste.md, could look like this:

---
title:    Lemon
keywords:
          - fruit
          - round
          - sour taste
scheme:   zettel
sort_tag: 2b3
---

The [lemon] belongs to the Rutaceae family.
[lemon]: https://en.wikipedia.org/wiki/Lemon

It is to be observed that the filename reflects the note's header (front matter). Tp-Note takes care, that the note's filename and its front matter always stay synchronized. The synchronization process happens twice: once before Tp-Note opens your text editor application and then directly after you closed it.

The document life cycle

The document lifecycle of a Tp-Note file consists of creation, modification and archiving (more about this in a later section).

  • Document creation: invoke Tp-Note with a directory path (no path defaults to the current directory):

    cd 'Zettelkasten/Permanent Notes'
    tpnote
    

    or

    tpnote 'Zettelkasten/Permaent Notes'
    

    The above command triggers the following:

    1. Tp-Note creates a new note file with an internal (customizable) template.
    2. Tp-Note opens the new note file with you favorite (customizable) text editor.
    3. Tp-Note starts an internal Web-Server and exposes the rendered note.
    4. Tp-Note starts your Web-Browser, connect it to the Web-Server and displays the rendered note file (with live updates).

    Remember that Tp-Note behaves slightly different when your clipboard contains data. Read more in Tp-Note's documentation5.

  • Document modification: invoke Tp-Note with the file path to an existing document:

    tpnote 'Zettelkasten/Permanent Notes/2b3--Lemon__fruit_round_sour taste.md'
    

    Note: except the omitted step 1 the procedure is the same as above.

    That said, most users do not use the command line but the file manager (or File-Explorer) when working with Tp-Note 6.

Setting up a Zettelkasten

The rules on how the filename and front matter relate, are grouped in a set of configuration variables and templates referred to as a scheme. To activate the Zettelkasten scheme for our Zettelkasten, we place a Tp-Note configuration file Zettelkasten/.tpnote.toml in the root directory of our Zettelkasten with the content:

[arg_default]
scheme = "zettel"

[viewer]
displayed_tpnote_count_max = 50

[[scheme]]
name = "zettel"

[scheme.tmpl]
filter.get_lang = ["en", "de"]
filter.map_lang = [["en", "en-US"], ["de", "de-DE"]]

This configuration instructs Tp-Note to apply the zettel scheme for all new note files within the Zettelkasten directory. NB: the zettel scheme is compatible with the Emacs note-taking plugin Denote. There are some slight differences though: Denote uses an additional signature tag (which is not required with Tp-Note) and Tp-Note's zettel scheme allows spaces in titles and keywords7. For security reasons, the viewer displays only a limited number of documents per session. The displayed_tpnote_count_max variable assignment increases this number to 50. The filter settings overwrite the default language search list containing e.g. the French language. Tp-Note tries to guess the language from the words in the title: header field and stores the result in the lang: field. In the above setting example we restrict the search candidates to English (US) and German (DE) assuming we write our notes mainly in these languages. This reduces wrong automatic guesses.

Our Zettelkasten is now ready to be filled with notes.

Zettelkasten

Example workflows

Take a fleeting note

Luhmann used fleeting notes to record any random ideas that popped into his mind during the day. Fleeting are not meant to be kept for longer, but rather serve as input for permanent notes. Example:

cd 'Fletting Note'
tpnote

The zettel scheme generates the following empty note:

---
title:        Fleeting Note
keywords:
              - note
author:       Getreu
date:         2023-11-14
lang:         en-US
scheme:       zettel
sort_tag:     '20231114'
---

Now we complete the note file using our text editor:

---
title:        Fruits at the market
keywords:
              - observation
author:       Getreu
date:         2023-11-14
lang:         en-US
scheme:       zettel
sort_tag:     '20231114'
---

I found some inspiring fruits at the market square 
today: apples, bananas and pineapples.

After saving and closing the text editor, a new note file 20231114--Fruits at the market__observation.md is generated. Note, that the workflow automatically generated the current date as chronological sort-tag 20231114 which is just fine for fleeting notes.

Take permanent notes

I this section I follow a video showcase made by Ĝabbos about the Denote Emacs plugin 4. If you know Denote, you can then easily compare both applications.

For our practical task, we explore the topic “fruit”. So I start writing down what I know about “apple“, “banana“ and “pineapple“.

cd 'Permanent Note'
tpnote

Our text editor opens with the following:

---
title:        Permanent Note
keywords:
              - note
author:       Getreu
date:         2023-11-26
lang:         en-US
scheme:       zettel
sort_tag:     '20231126'
---
---
title:        Apples
keywords:
              - fruit
author:       Getreu
date:         2023-11-26
lang:         en-US
scheme:       zettel
sort_tag:     '01'
---

Lorem ipsum.

It is to be observed that we changed the sort-tag from 20231126 to 01. Following Luhmann's filing scheme, the directory Permantent Notes ggcontains exclusively notes with sequential sort-tags (cf. Tp-Note's manual page). After closing the text editor, the new note carries the filename 01--Apples__fruit.md.

To create a note about bananas we invoke Tp-Note again:

tpnote

Consider that, this time Tp-Note automatically suggests the sequential sort-tag 02. When creating a new note, Tp-Note searches for the latest existing note file in the same directory and reads its sort-tag. It case of a sequential sort-tag, it is incremented and inserted into the new note.

---
title:        Permanent Note
keywords:
              - note
author:       Getreu
date:         2023-11-26
lang:         en-US
scheme:       zettel
sort_tag:     '02'
---

Analogous to our first note about “Apples”, we create the following note files:

ls 
01--Apples__fruit.md
02--Bananas__fruit.md
03--Pineapples__fruit.md

Later, our research drives us back to apples. We find some aspects of its taste very interesting which conducts us to write a general note about taste. As at this point we focus on apples and its taste, it seems natural to link the new note to 01-Apples__fruit.md. We deliberately ignore that other things might have a taste too and create a new note with the sort-tag 01a and the title Taste. When we invoke Tp-Note with tpnote, it creates a new note suggesting the sort-tag 04. As we do not want to add other fruits, we just change the sort-tag to 01a. After closing the text editor our “Permanent Note” directory contains:

ls 
01--Apples__fruit.md
01a--Taste__note.md
02--Bananas__fruit.md
03--Pineapples__fruit.md

The next aspect we are interested in, is the shape of apples. This time Tp-Note suggests the sort-tag 01b because the latest created sort-tag 01a. We set the title to Shape and obtain:

ls 
01--Apples__fruit.md
01a--Taste__note.md
01b--Shape__note.md
02--Bananas__fruit.md
03--Pineapples__fruit.md

Continuing our research journey, we might end up with the following:

ls
01--Apples__fruit.md
01a--Taste__note.md
01b--Shape__note.md
01b1--Round things__note.md
01b1a--Oranges__fruit.md
01b1b--Wheels__note.md
01c--Colour__note.md
02--Bananas__fruit.md
03--Pineapples__fruit.md

Comparing the sort-tag 01 of apples and the sort-tag 01b1a of oranges, it becomes clear that Luhmann's filing scheme is deliberately not hierarchically organized. Instead, sort-tags reflect the author's line of thinking without forcing any preliminary categorization.

Linking notes and resources

We have seen in the previous section, that Luhmann's sort-tag scheme reflects the authors line of thinking allowing to introspect the cognitive process itself. But sort-tags, especially sequential sort-tags, have another function in Luhmann's Zettelkasten: as they are unique and invariable, they serve as a document ID allowing to link and reference notes thus constructing a network of knowledge.

Tp-Note supports Luhmann's hypertext scheme in two ways:

  1. Tp-Note's built-in viewer lets you easily browse between linked note files in your web browser.
  2. Tp-Note's so called ”shorthand autolink” syntax is a convenient way to insert hyperlinks.

What are shorthand links in Tp-Note? Instead of writing out the full link destination, e.g. [Taste](<01a--Taste__note.md>), you can shorten the link to [Taste](01a) indicating only the destination's sort-tag. Alternatively, the same shorthand link can be expressed as autolink as well: <http:01a?__>. All three variants produce the same result. Remark: you may have noticed the appended “format string” ?__ in the last example. Format strings determine how a link is displayed in the browser. In this case, the ?__ format string extracts only the title Taste from the target's filename and displays it as link text.

Tp-Note connects your web browser to its internal web server and renders note files on the fly while you browse them. This makes it very convenient to insert also absolute URLs in your notes. In general, the link syntax depends on the markup language used in the Tp-Note file. The following examples illustrate the different link types Tp-Note understands:

Link typeExample in Markdown notation
Absolute URL[blog](<https://blog.getreu.net>)
Relative URL (=local link)![Alt text](<images/my logo.png>)
Absolute local link![Alt text](</images/my logo.png>)
Relative local link![Alt text](<images/my logo.png>)
Relative local link[my doc](<./notes/31--My Apples.md>)
Absolute local autolink<tpnote:/notes/31--My%20Apples.md>
Relative local autolink<tpnote:./notes/31--My%20Apples.md>
Shorthand link[my doc](<./notes/31>)
Shorthand autolink<tpnote:./notes/31>
Formatted shorthand link<tpnote:./notes/31?__>)

Read more in the section Links to resources and other documents in Tp-Note's manual page.

Example

To illustrate the power of hyperlinks, we add some links to 01b--Shape__note.md:

---
title:        Shape
keywords:
              - note
author:       Getreu
date:         2023-11-07
lang:         en-US
scheme:       zettel
sort_tag:     01b
---

<tpnote:01?__>, <tpnote:02?__> and <tpnote:03?__> have a <tpnote:01b?__>.

See also 
* <tpnote:/Fleeting%20Note/20231114??:.>
* [Shape - Wikipedia](https://en.wikipedia.org/wiki/Shape)

The rendered note file displayed in the browser looks like this:

Shape

Observations:

  • Line 1: The format string ?__ displays only the title of the target note.
  • Line 3: As the base for absolute local autolinks is the location of the .tpnote.toml configuration file, the following is equivalent: <tpnote:../ Fleeting%20Note/20231114?:.>
  • Line 3: The Markdown specification requires for autolinks, that the space character is replaced with %20.
  • Line 3: The format string ??:. shows the whole filename without extension.
  • Line 4: Absolute URL

Retrieving notes

The present Zettelkasten implementation with Tp-Note each note is stored in a separate file with its filename reflecting the note's metadata. As a consequence metadata search in a Tp-Note Zettelkasten boils down to a simple filename search with standard operating system tools. For example the Linux file manager Thunar has a search bar that can be activated with the loupe icon in the upper right corner.

Search with Thunar1

To search notes with the word “fruit” the title and keyword fields, we enter fruit. It is also possilbe to restrict our search to the keyword fields by entring _fruits instead.

Search with Thunar2

The next screenshot shows the search results with the popular terminal based file manager “Midnight Commanader”:

Search with mc

As Tp-Note files are plain UTF-8 text files, full text search is as easy. Please consult your operating system documentation for the various full text search options.

Archiving

Archiving is the last stage in the document lifecycle. It consists of storing a snapshot of the whole Zettelkasten on some write once only media. As Tp-Note files are flat UTF-8 text files, your notes can still be searched with standard operating system tools, even after 20 years and more. Bear in mind that after such a long period of time our today's software might not exist anymore. However, our Zettelkasten is not concerned. The fact, that Tp-Note note files can be opened with any text editor and without any additional proprietary software, makes our Zettelkasten long-term future-proof.

Read more about Tp-Note

A good start is Tp-Note's project page or the introductory video. The source code is available on GitHub - getreu/tp-note and some binaries and packages for Linux, Windows and Mac can be found here. To fully profit of Tp-note, I recommend reading Tp-Note's user manual. If you like [Tp-Note], you probably soon want to customize it. How to do so, is explained in Tp-Note's manual page.

Last updated on 1.12.2023

1

Luhmann, Niklas (1981): Kommunikation mit Zettelkästen. Ein Erfahrungsbericht, in: Horst Baier / Hans Mathias Kepplinger / Kurt Reumann (eds.), Öffentliche Meinung und sozialer Wandel. Für Elisabeth Noelle-Neumann. Opladen, 222-228

3

Mathematical side note: the so organized note files form a labelled ordered rooted tree.

7

When you open a Denote file with Tp-Note, it automatically prepends a header to the file's content.