# Zettels Zettels is a command line tool which implements Niklas Luhmann's system of a "Zettelkasten". It is designed for people who want to use their favourite text editor to edit their notes. It uses [libzettels](https://gitlab.com/sthesing/libzettels) as a backend. If you have no idea what a Zettelkasten is, read below at "What the heck is a Zettelkasten?" ## Code and crate Zettels is written in Rust. Find code and crate here: - [Gitlab repository](https://gitlab.com/sthesing/zettels) - [crates.io](https://crates.io/crates/zettels) Zettels is still in alpha stage and probably buggy. ## Installation ### 1. Binary packages See the [Releases](https://gitlab.com/sthesing/zettels/-/releases) page. There are binary packages available for - 64 bit GNU/Linux - 32 bit GNU/Linux - 64 bit Windows Also, there are *.deb packages for Debian-based GNU/Linux distros (e.g. Ubuntu). ### 2. via Cargo Rust's package manager [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) offers a really easy installation method: `cargo install zettels` ### 3. From source Checkout the repository or download the source code from [Releases](https://gitlab.com/sthesing/zettels/-/releases). If you choose this way, I assume you know what you're doing. # What does Zettels do? It's intended to be used for a "Zettelkasten" like Niklas Luhmann used it. Zettels is a tool to index markdown files (your zettels). It takes a directory (your Zettelkasten's root directory) containing [Markdown](https://daringfireball.net/projects/markdown/syntax) files (which may be in sub-directories) with a YAML metadata block (as defined by [pandoc](https://pandoc.org/MANUAL.html#extension-yaml_metadata_block)). Zettels bundles the information about the relations between these files (your zettels) in a queryable index. To populate this index, Zettels does two things: 1. It inspects the fields `title`, `keywords` and `followups` of the YAML metadata block. ```{.yaml} --- title: 'Example Zettel' keywords: [example, question] followups: [file.md, subdir/anotherfile.md, ../yetanotherfile.md] foo: 'Potentially more data ignored by libzettels.' ... ``` 2. It parses the inline-style links (like `[example](afile.md)`) of the markdown document body and extracts the targets of these links. The resulting index contains the metadata and the targets of the hyperlinks. ## Example files If you want to look at some example files to get a better idea, zettels has a subcommand that will generate some for you: 1. Just example zettels. Probably most useful to users, to just see how zettel files look like. ``` zettels examples --bare ``` 2. Example zettels and a config file, probably only useful for developers ``` zettels examples --with_config ``` 3. Example zettels complete with config file and an index ``` zettels examples --with_index ``` You can run that configuration by running zettels with the option `-c` and supplying it with the path to the generated config file. # What the heck is a Zettelkasten? "Zettel" is German for "note" or "slip of paper". "Kasten" is German for "box". Think of old style library catalogues. Obviously, this piece of software is not a box of paper sheets. However, [Niklas Luhmann](https://en.wikipedia.org/wiki/Niklas_Luhmann) used such a box in a very specific way for his academic work. A wonderful introduction in Luhmann's system of a Zettelkasten are the slides of a talk by Daniel Lüdecke: [Introduction to Luhmann's Zettelkasten-Thinking](https://strengejacke.wordpress.com/2015/10/07/introduction-to-luhmanns-zettelkasten-thinking-and-its-technical-implementation/) In Luhmann's own words: [Communicating with Slip Boxes](http://luhmann.surge.sh/communicating-with-slip-boxes) (translation of "Kommunikation mit Zettelkästen"). If you speak German, there's more: - Luhmann, Niklas (1981): Kommunikation mit Zettelkästen. Ein Erfahrungsbericht. in: H. Baier / H.M. Kepplinger / K. Reumann (Eds.), Öffentliche Meinung und sozialer Wandel. Opladen: Westdeutscher Verlag. pp. 22-28 - Daniel Lüdecke: [Luhmanns Arbeitsweise im elektronischen Zettelkasten](https://strengejacke.wordpress.com/2015/09/08/luhmanns-arbeitsweise-im-elektronischen-zettelkasten/) - Thomas Schlesinger: [Wissen konservieren und kuratieren mit dem Zettelkasten nach Niklas Luhmann](http://www.schlesisblog.de/2016/09/wissen-konservieren-und-kuratieren-mit.html) - Universität Bielefeld: Video - [Einblicke in das System der Zettel - Geheimnis um Niklas Luhmanns Zettelkasten](https://youtu.be/4veq2i3teVk) ## Alternatives If you're looking for a GUI, all-in-one approach to implementing Luhmann's idea into software, I can recommend Daniel Lüdecke's [Zettelkasten](http://zettelkasten.danielluedecke.de/) (sjPlot/Zettelkasten). # Zettel format Zettels doesn't require your markdown files to have a metadata block. But to be really effective parts of your Zettelkasten, a YAML metadata block containing an entry for `title`, `keywords` and `followups` is necessary. ```{.yaml} --- title: 'Example Zettel' keywords: [example, question] followups: [file.md, subdir/anotherfile.md, ../yetanotherfile.md] ... ``` If no such metadata is present, Zettels will replace it with appropriate "empty" values in the index: - `title`: "untitled" - `keywords`: "[]" - `followups`: "[]" Instead of finishing the metadata block with `...` you can also use `---`. ```{.yaml} --- title: 'Example Zettel' keywords: [example, question] followups: [file.md, subdir/anotherfile.md, ../yetanotherfile.md] --- ``` In fact, a zettel file may contain several YAML-blocks. However, Zettels will only parse the first one. The metadata block may contain a variety of other entries (e.g. `author`, `date`) – maybe for other tools, like pandoc – but those other entries are ignored by Zettels and do not become part of Zettels' index. To manually link between zettels, use the "inline syntax" for markdown hyperlinks: ```[.markdown] [link text](url) ``` Links between zettel files should be relative links. The same is true for entries in `followups`. # Usage ## tl;dr 1. run `zettels setup` for config 2. run `zettels -h` to see usage info ## Search and inspect There are two main ways of querying the Zettelkasten. ### 1. Search Searching is a means to find an entry into the Zettelkasten. Zettels implements searching the `title` and `keywords` fields of the zettel. Just for the sake of completeness: searching the contents of the zettel is not a functionality of zettels. For that there are specialized tools like `grep` oder `ripgrep` out there. Search for keywords `-k`, `--keywords`: ``` zettels -k foo ``` Search for title `-t`, `--title` or `-e`, `--exacttitle`: ``` zettels -t foo ``` Both can be combined: ``` zettels -k foo -t bar ``` Results can be limited to zettels that match all queries: `-a`, `--all` ``` zettels -k foo -t bar -a ``` And of course, that applies to mor than one search term, too. ``` zettels -k foo bar -a ``` ### 2. Inspect Inspecting the relations between zettels is the second way of querying the zettelkasten. Inspection requires a "scope", meaning a list of zettels to inspect. This scope is either specified by the user, or it's the result of search or it's the whole zettelkasten. For inspecting the "followup" relation, a key concept are "sequences". When a zettel designates another as a followup, they form a sequence. Further followups extend that sequence or might branch into subsequences. ![Example Sequence](resources/zettel-sequence.png) Show to which sequences zettels specified by SCOPE belong `-s`, `--sequences`: ``` zettels -s file1.md ``` Show all zettels of the sequences specified by SCOPE `-z`, `--zettels`: ``` zettels -z file1.md ``` Show zettels that belong to the sequence(s) specified by SCOPE, plus all ancestors of SCOPE `-f`, `--family`: ``` zettels -f file1.md ``` Show zettels that belong to the sequence(s) specified by SCOPE, plus all ancestors of SCOPE, plus all descendants of those ancestors `-w`, `--wholefamily`: ``` zettels -w file1.md ``` For inspecting the "link" relation, we can inspect SCOPE's outgoing links `-l`, `--links`: ``` zettels -l file1.md ``` or incoming links `-i`, `--incoming`: ``` zettels -i file1.md ``` ### Both As mentioned before, the result of a search can be used as SCOPE for inspection. So this will show all outgoing links of zettels that have the word "foo" in their titles: ``` zettels -t foo -l ```