# 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.

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
```