zettels 0.3.0

Zettels is a command line tool implementing Niklas Luhmann's system of a Zettelkasten. It is designed for people who want to use their favourite text editor to edit their notes.
# 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
```