Add doc pages

pull/6/head
Mickaël Menu 3 years ago
parent 0e447f749e
commit 6ce25e0ed6
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

1
.gitignore vendored

@ -14,4 +14,3 @@
# Dependency directories (remove the comment below to include it)
# vendor/
.zk

@ -1,2 +1,19 @@
# zk
A plain-text note-taking assistant
# `zk` a plain text note-taking assistant
Looking for a quick usage example? [Let's get started](http://mickael-menu.github.io/zk/getting-started).
`zk` is a command-line tool helping you to maintain a plain text [Zettelkasten](https://zettelkasten.de/introduction/) or [personal wiki](https://en.wikipedia.org/wiki/Personal_wiki).
It is primarily focused on:
* [keeping your notebook future-proof](http://mickael-menu.github.io/zk/future-proof), by relying on plain text
* [creating notes from templates](http://mickael-menu.github.io/zk/note-creation)
* performing [advanced search queries](http://mickael-menu.github.io/zk/note-filtering)
* being a hub for everything related to your notes, thanks to [command aliases](http://mickael-menu.github.io/zk/config-alias) and [automation](http://mickael-menu.github.io/zk/automation).
* [notebook housekeeping](http://mickael-menu.github.io/zk/notebook-housekeeping)
What `zk` is not:
* a note editor
* a tool to serve your notes on the web for this, you may be interested in [Neuron](http://mickael-menu.github.io/zk/neuron) or [Gollum](https://github.com/gollum/gollum).

@ -0,0 +1,10 @@
[note]
template = "default.md"
[tool]
editor = "vim"
[alias]
neuron = 'neuron gen $@'
wc = "zk list --format '{{word-count}}\t{{title}}' --sort word-count -x log $@"

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:41e8b104003fba2e5076276d9b4929912391bbd163edd97d6598f654039c82e8
size 331776

@ -0,0 +1,18 @@
# `zk` a plain text note-taking assistant
Looking for a quick usage example? [Let's get started](getting-started.md).
`zk` is a command-line tool helping you to maintain a plain text [Zettelkasten](https://zettelkasten.de/introduction/) or [personal wiki](https://en.wikipedia.org/wiki/Personal_wiki).
It is primarily focused on:
* [keeping your notebook future-proof](future-proof.md), by relying on plain text
* [creating notes from templates](note-creation.md)
* performing [advanced search queries](note-filtering.md)
* being a hub for everything related to your notes, thanks to [command aliases](config-alias.md) and [automation](automation.md).
* [notebook housekeeping](notebook-housekeeping.md)
What `zk` is not:
* a note editor
* a tool to serve your notes on the web for this, you may be interested in [Neuron](neuron.md) or [Gollum](https://github.com/gollum/gollum).

@ -0,0 +1,2 @@
permalink: /:title
theme: jekyll-theme-modernist

@ -0,0 +1,57 @@
<!doctype html>
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
{% seo %}
<link rel="stylesheet" href="{{ '/assets/css/style.css?v=' | append: site.github.build_revision | relative_url }}">
<script src="{{ '/assets/js/scale.fix.js' | relative_url }}"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header {% unless site.description or site.github.project_tagline %} class="without-description" {% endunless %}>
<h1><a href="https://mickael-menu.github.io/zk/">{{ site.title | default: site.github.repository_name }}</a></h1>
{% if site.description or site.github.project_tagline %}
<p>{{ site.description | default: site.github.project_tagline }}</p>
{% endif %}
<p class="view"><a href="{{ site.github.repository_url }}">View the Project on GitHub <small>{{ github_name }}</small></a></p>
<ul>
{% if site.show_downloads %}
<li><a href="{{ site.github.zip_url }}">Download <strong>ZIP File</strong></a></li>
<li><a href="{{ site.github.tar_url }}">Download <strong>TAR Ball</strong></a></li>
{% endif %}
<li><a href="{{ site.github.repository_url }}">View On <strong>GitHub</strong></a></li>
</ul>
</header>
<section>
{{ content }}
</section>
</div>
<footer>
{% if site.github.is_project_page %}
<p>Project maintained by <a href="{{ site.github.owner_url }}">{{ site.github.owner_name }}</a></p>
{% endif %}
</footer>
<!--[if !IE]><script>fixScale(document);</script><![endif]-->
{% if site.google_analytics %}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '{{ site.google_analytics }}', 'auto');
ga('send', 'pageview');
</script>
{% endif %}
</body>
</html>

@ -0,0 +1,9 @@
---
---
@import "{{ site.theme }}";
code, pre {
font-size: inherit;
}

@ -0,0 +1,10 @@
# Automating frequent tasks
`zk` was designed with automation in mind and strive to be [a good Unix citizen](https://en.wikipedia.org/wiki/Unix_philosophy). As such, it offers a number of ways to interface with other programs:
* [write command aliases](config-alias.md) for repeated complex commands
* [call `zk` from other programs](external-call.md)
* [send notes for processing by other programs](external-processing.md)
* [create a note with initial content](note-creation.md) from a standard input pipe
If you find out that `zk` does not behave as expected or could communicate better with other programs, [please post an issue](https://github.com/mickael-menu/zk/issues).

@ -0,0 +1,193 @@
# Command aliases
A command alias is a custom `zk` command which can run another `zk` command or an external program.
Declaring your own aliases is a great way to make your experience with `zk` easier and more familiar. With aliases, `zk` becomes a hub capable of launching all the programs you need to manage your [notebook](notebook.md).
## Configuring aliases
Command aliases are declared in your [configuration file](config.md), under the `[alias]` section. They are executed with `$SHELL -c`, which allows you to:
* expand arguments with `$@` or `$*`
* expand environment variables
* run several commands with `&&`
* pipe several commands with `|`
An alias can call other aliases but cannot call itself. This enables you to override the default options of native commands, for example:
```toml
[alias]
edit = "zk edit --interactive $@"
```
When running an alias, the `ZK_PATH` environment variable is set to the absolute path of the current notebook. You can use it to run commands working no matter the location of the working directory.
```toml
journal = 'zk new "$ZK_PATH/journal"'
```
If you need to surround the path with quotes, make sure you use double quotes, otherwise environment variables will not be expanded.
### `xargs` formula
Calling an external program with a list of note paths using `xargs` is such a common use case that we can extract a reusable alias pattern.
```toml
alias = "zk list --quiet --format path --delimiter0 $@ | xargs -0 <EXTERNAL COMMAND>"
```
Find more details about these options in [Send notes for processing by other programs](external-processing.md).
## Collection of useful aliases
Here are a few aliases to get you started writing your own.
### Shortcuts for native commands
```toml
ls = "zk list $@"
ed = "zk edit $@"
n = "zk new $@"
```
### Edit the last modified note
Suffixing the `modified` sort criterion with `-` orders the notes by *descendent* modification date.
```toml
edlast = "zk edit --limit 1 --sort modified- $@"
```
### Edit the notes created during the last two weeks
This command uses `--interactive` to let the user select which notes to actually edit among the recent ones. Note the use of human friendly language for `--created-after`'s argument.
In this case, additional arguments do not necessarily make sense, so we omit the trailing `$@`.
```toml
recent = "zk edit --sort created- --created-after 'last two weeks' --interactive"
```
### Edit the configuration file
Here's a concrete example using environment variables, in particular `ZK_PATH`. Note the double quotes around the path.
```toml
conf = '$EDITOR "$ZK_PATH/.zk/config.toml"'
```
### List paths in a command-line friendly fashion
Use this alias to send a list of space-separated file paths matching the given [filtering criteria](note-filtering.md) to another program. See [send notes for processing by other programs](external-processing.md) for more details.
```toml
paths = "zk list --quiet --format \"'{{path}}'\" --delimiter ' ' $@"
```
### List paths to be used in a parent `zk` command
Similarly, use this alias to expand filtered note paths inside a parent `zk` command taking a comma-separated paths list.
```toml
inline = "zk list --quiet --format {{path}} --delimiter , $@"
```
Examples of use:
```sh
# List the notes which have at least one link pointing to them (i.e. not orphans).
$ zk list --exclude "`zk inline --orphan`"
# List the notes which are linked by at least one note from the journal/ directory.
$ zk list --linked-by "`zk inline journal`"
```
### Print a random note
Increasing serendipity while using your notebook is important to spark new ideas. The `random` sort criterion is the key to this alias.
```toml
lucky = "zk list --quiet --format full --sort random --limit 1"
```
### Create a note from a free title
If you often create notes with `zk new --title "An interesting concept"`, you will like this alias. Using `"$*"`, you do not need to quote the arguments anymore.
```toml
nt = 'zk new --title "$*"'
```
Usage: `zk nt An interesting concept`
No more forgotten quotes!
### Create a note and save its path into the clipboard (macOS)
Build upon the previous alias, but instead of editing the created note it will copy the created note's path into the macOS clipboard.
```toml
ntc = 'zk new --print-path --title "$*" | pbcopy'
```
### Print and sort the word count of selected notes
This will list the notes and their word count sorted by increasing word count. It is useful to spot flimsy notes that you could flesh out.
```toml
wc = "zk list --format '{{word-count}}\t{{title}}' --sort word-count $@"
```
Usage:
```sh
$ zk wc
4 Integration with fzf
5 Searching and filtering notes
63 Setting your default editor
86 Anatomy of a notebook
...
```
### Print the backlinks of a note
This is such a useful command, that an alias might be helpful.
```toml
bl = "zk list --linking-to $@"
```
### Browse the Git history of selected notes
This example showcases the "`xargs` formula" with a concrete example.
```toml
log = "zk list --quiet --format path --delimiter0 $@ | xargs -0 git log --patch --"
```
### Saving the changes in the Git repository
This alias does not call `zk` at all! This shows how you can use `zk` as a hub for everything related to your notes.
```toml
save = 'git add . && git commit -m "$*"'
```
Usage: `zk save Expand the note on command aliases`
### Copy/backup selected notes
A more complex example backing up the notes matching the given filtering criteria in a target directory. It creates intermediate directories if needed.
`$1` and `${@:2}` are used to split the arguments between the first one which will be the destination directory, and the remaining arguments which will be used as filtering options.
```toml
# macOS
cp = 'zk list --quiet --format path --delimiter0 ${@:2} | xargs -t -0 -I % ditto "%" "$1/%"'
# Linux
cp = 'mkdir -p "$1" && zk list --quiet --format path --delimiter0 ${@:2} | xargs -t -0 -I % cp --parents "%" "$1"'
```
Usage: `zk cp output/ --created-after 'last two weeks'`

@ -0,0 +1,43 @@
# Extra user variables
`zk` is opened for template context extension which can be useful when [creating new notes](note-creation.md), for example:
* expanding custom metadata (author, subject, etc.)
* modifying a [template](template.md)'s output dynamically depending on the value of an extra variable
## Static extra variables
You can declare static extra variables in the [configuration file](config.md)'s `[extra]` section. Each [note group](config-group.md) can have its own `[extra]` section, which may override values from the root section.
```toml
[extra]
visibility = "public"
author = "Mickaël"
[group.journal.extra]
visibility = "private" # overrides
```
## Dynamic extra variables
Maybe more useful, you can provide additional extra variables dynamically to `zk new` from the command-line with `--extra`. Multiple variables must be separated by a semicolon `;`, in which case quoting the argument is required.
```sh
$ zk new --extra author=Thomas
$ zk new --extra "show-header=1;author=Thomas"
```
## Using extra variables in templates
After declaring extra variables, you can expand them inside the [template used when creating new notes](template-creation.md), using the usual [Handlebars syntax](template.md).
```markdown
# {{title}}
Written by {{extra.author}}.
{{#if extra.show-header}}
Behold, the mighty dynamic header!
{{/if}}
```

@ -0,0 +1,50 @@
# Note group
A *group* is a named [configuration section](config.md) used to override [note creation rules](config-note.md) for specific directories. This allows you to use your [notebook](notebook.md) very differently depending on the type of note created. For a practical example, take a look at [maintaining a daily journal](daily-journal.md).
## Declaring a new group
To add a new group to your configuration file, declare a new `[group.<name>]` section. It takes a single optional property `paths`, which is the list of directories belonging to this group.
```toml
[group.journal]
paths = [
"journal/daily",
"journal/weekly"
]
```
You can also use [glob patterns](https://en.wikipedia.org/wiki/Glob_\(programming\)) in `paths`.
```toml
[group.journal]
paths = ["journal/*"]
```
If you omit `paths`, the directory named after the group will be inferred. Note the double quotes when using spaces or slashes for subdirectories.
```toml
# This will automatically apply to the `citations/web` directory
[group."citations/web"]
```
## Overriding note configuration and extra variables
You can override the global [note configuration](config-note.md) and [extra user variables](config-extra.md) for a given group.
```toml
[group.journal.note]
filename = "{{date now}}"
template = "journal.md"
[group.journal.extra]
author = "Mickaël"
```
## Choose a group dynamically
If you prefer to keep multiple groups in a single directory, you can specify which group to use when creating a new note explicitly.
```sh
$ zk new --group journal
```

@ -0,0 +1,55 @@
# Note configuration
The `[note]` section from the [configuration file](config.md) is used to set the [note creation rules](note-creation.md). The following properties are customizable:
* `language` (string)
* Two-letters code of the language used when writing notes, e.g. `en`.
* This is used to generate slugs or with date formats. For now, only English is fully supported.
* `default-title` (string)
* The default title used for new notes when no `--title` option is provided.
* `filename` (string)
* [Template](template.md) used to generate the note filename, without its file extension.
* `extension` (string)
* File extension for the generated note. By default, `md` (Markdown) is used.
* `template` (string)
* Path to the [template](template.md) used to generate the note content.
* Either an absolute path, or relative to `.zk/templates/`.
* `id-charset` (string)
* Characters set used to [generate random IDs](note-id.md).
* You can use:
* `letters` for characters from `a` to `z`
* `numbers` for characters from `0` to `9`
* `alphanum` for `letters` + `numbers`
* `hex` for characters from `a` to `f` and `0` to `9`
* a free string for custom characters
* `id-length` (integer)
* Length of the generated random IDs.
* `id-case` (enum)
* Letter case for the generated random IDs.
* Possible values are `lower`, `upper` or `mixed`.
## Common filename templates
Here are some common filename patterns you may want to use:
* `{{id}}` e.g. `i2hn8.md`
* Just a [random ID](note-id.md), simple and elegant.
* To use [Neuron](neuron.md)'s ID format, set:
```toml
[note]
id-charset = "hex"
id-length = 8
id-case = "lower"
```
* `{{slug title}}` e.g. `an-interesting-concept.md`
* A [slugified](template.md) version of the title given with `--title`.
* Readable and practical for web servers, but fragile in case of renaming.
* `{{id}}-{{slug title}}` e.g. `i2hn8-an-interesting-concept.md`
* The best of both worlds? Readable but if you link only with the prefix ID, you can rename without breaking links.
* `{{date now 'timestamp'}}` e.g. `200911172034.md`
* Verbose, but sortable by creation date and stable.
* `{{date now 'timestamp'}} {{title}}` e.g. `200911172034 An interesting concept.md`
* The format of [The Archive](https://zettelkasten.de/the-archive/) and [sirupsen's zk](https://github.com/sirupsen/zk).
* `{{date now '%Y-%m-%d'}}` e.g. `2009-11-17.md`
* Sortable, human-friendly format for a daily journal.
* i.e. [Maintaining a daily journal](daily-journal.md).

@ -0,0 +1,89 @@
# Configuration file
Each [notebook](notebook.md) contains a configuration file used to customize your experience with `zk`. This file is located at `.zk/config.toml` and uses the [TOML format](https://github.com/toml-lang/toml). It is composed of several optional sections:
* `[note]` sets the [note creation rules](config-note.md)
* `[extra]` contains free [user variables](config-extra.md) which can be expanded in templates
* `[group]` defines [note groups](config-group.md) with custom rules
* `[tool]` customizes interaction with external programs such as:
* [your default editor](tool-editor.md)
* [your default pager](tool-pager.md)
* [`fzf`](tool-fzf.md)
* `[alias]` holds your [command aliases](config-alias.md)
## Complete example
Here's an example of a complete configuration file:
```toml
# NOTE SETTINGS
[note]
# Language used when writing notes.
# This is used to generate slugs or with date formats.
language = "en"
# The default title used for new note, if no `--title` flag is provided.
default-title = "Untitled"
# Template used to generate a note's filename, without extension.
filename = "{{id}}-{{slug title}}"
# The file extension used for the notes.
extension = "md"
# Template used to generate a note's content.
# If not an absolute path, it is relative to .zk/templates/
template = "default.md"
# Configure random ID generation.
# The charset used for random IDs.
id-charset = "alphanum"
# Length of the generated IDs.
id-length = 4
# Letter case for the random IDs.
id-case = "lower"
# EXTRA VARIABLES
[extra]
author = "Mickaël"
# GROUP OVERRIDES
[dir.journal]
paths = ["journal/weekly", "journal/daily"]
[dir.journal.note]
filename = "{{date now}}"
# EXTERNAL TOOLS
[tool]
# Default editor used to open notes.
editor = "nvim"
# Pager used to scroll through long output.
pager = "less -FIRX"
# Command used to preview a note during interactive fzf mode.
fzf-preview = "bat -p --color always {-1}"
# COMMAND ALIASES
[alias]
# Edit the last modified note.
edlast = "zk edit --limit 1 --sort modified- $@"
# Edit the notes selected interactively among the notes created the last two weeks.
recent = "zk edit --sort created- --created-after 'last two weeks' --interactive"
# Show a random note.
lucky = "zk list --quiet --format full --sort random --limit 1"
```

@ -0,0 +1,48 @@
# Maintaining a daily journal
<!--{% raw %}-->
Let's assume you want to write daily notes named like `2021-02-16.md` in a `journal/daily` sub-directory. This common use case is a good fit for creating a [note group](config-group.md) overriding the default [note creation](note-creation.md) settings.
First, create a `group` entry in the [configuration file](config.md) to set the note settings for this directory. Refer to the [template syntax reference](template.md) to understand how to use the `{{date}}` helper.
```toml
[group.daily]
# Directories listed here will automatically use this group when creating notes.
paths = ["journal/daily"]
[group.daily.note]
# %Y-%m-%d is actually the default format, so you could use {{date now}} instead.
filename = "{{date now '%Y-%m-%d'}}"
extension = "md"
template = "daily.md"
```
Next, create a template file under `.zk/templates/daily.md` to render the note content. Here we used the date again to generate a title like "February 16, 2021".
```markdown
# {{date now "long"}}
What did I do today?
```
We are now ready to write today's note! We don't need to set `--title` since the note's title is entirely generated by the template.
```sh
$ zk new journal/daily
```
That is a bit of a mouthful for a command called every day. Would it not be better to just write `zk daily`? We can, by defining a [command alias](config-alias.md) in the [configuration file](config.md).
```toml
[alias]
daily = 'zk new --no-input "$ZK_PATH/journal/daily"'
```
Let's unpack this alias:
* `zk new` will refuse to overwrite notes. If you already created today's note, it will instead ask you if you wish to edit it. Using `--no-input` skips the prompt and edit the existing note right away.
* `$ZK_PATH` is set to the absolute path of the current [notebook](notebook.md) when running an alias. Using it allows you to run `zk daily` no matter where you are in the notebook folder hierarchy.
* We need to use double quotes around `$ZK_PATH`, otherwise it will not be expanded.
<!--{% endraw %}-->

@ -0,0 +1,15 @@
# Call `zk` from other programs
Calling `zk` from other programs can be useful in a number of situations, such as:
* creating notes from your text editor using a custom shortcut
* creating a reference note from the text selected in your web browser
* automating periodical maintenance tasks on your [notebook](notebook.md)
* displaying the backlinks of a note in a GUI wrapper around `zk`
The following options can be useful to make sure `zk` behaves properly in a background context:
<!-- TODO: --color=none, --json -->
* `--no-input` disables all user prompts and ignores `--interactive`
* `--quiet` reduces unnecessary output

@ -0,0 +1,62 @@
# Send notes for processing by other programs
<!--{% raw %}-->
<!-- TODO: --color=none -->
A great way to expand `zk` feature set is to explore a wealth of command-line tools available. You can use `zk`'s powerful [searching and filtering](note-filtering.md) capabilities to select notes before delegating further processing to other programs.
## Process file paths
Many programs expect file paths for input. You can interface with such program using the `path` list format and a space delimiter.
```sh
$ zk list --format path --delimiter " "
```
If the file paths can contain spaces, you may want to quote manually the paths, using the `{{path}}` [template variable](template-format.md) instead:
```sh
$ zk list --format "'{{path}}'" --delimiter " "
```
As always, this is such a useful [command alias](config-alias.md) to have:
```toml
paths = "zk list --format \"'{{path}}'\" --quiet --delimiter ' ' $@"
```
Some programs such as `xargs` work better when file paths are separated by the ASCII NUL character (`\0`). In this case, you can use the `--delimiter0` (or `-0`) option.
For example, this command prints the full Git history of the notes:
```sh
$ zk list --format path --delimiter0 | xargs -0 git log --patch --
```
### Feeding `zk` to itself
Some `zk` options such as `--exclude` also take file paths for parameters. Let's increase their flexibility by nesting `zk` calls. In this case, the delimiter will be `,`.
For example, this command lists the notes which are linked by at least one other note so the notes which are *not* orphans.
```sh
$ zk list --exclude "`zk list -q -f path -d "," --orphan`"
```
And this one finds the notes which are linked by at least one note in `journal/`.
```sh
$ zk list --linked-by "`zk list -q -f path -d "," journal`"
```
## Process the content of a note
If you want to directly transform the content instead, you may use the `raw-content` template variable, which will print the full content of the note file.
In this particular case, we usually want to process only one note at a time. You can make sure that `zk list` will print only the first note from the result with `--limit 1` (or `-n1`).
```sh
$ zk list --format {{raw-content}} --limit 1
```
<!--{% endraw %}-->

@ -0,0 +1,5 @@
# A future-proof notebook
`zk` is designed to be future-proof and rely on simple plain text formats such as Markdown.
The shape of your [notebook](notebook.md) is entirely up to you, making `zk` flexible enough to be used in a variety of contexts. However, `zk` shines in a Zettelkasten-style notebook with many small interlinked notes.

@ -0,0 +1,49 @@
# Getting started with `zk`
A short introduction showing how to use `zk`.
## Create a new notebook
Create a [notebook](notebook.md) to host your notes. You are free to organize your notebook as you want, adding subdirectories if needed.
```sh
$ zk init my-notes
Initialized a notebook in my-notes
$ cd my-notes
```
## Edit the configuration file
To customize your experience with `zk`, you may want to edit the [user configuration file](config.md).
```sh
$ vim .zk/config.toml
```
## Create your first notes
Now you are ready to write your very first note. Pick a subject, [create a new note](note-creation.md) and write on!
```sh
$ zk new --title "An interesting concept"
```
## Edit existing notes
After some time, hopefully you will have enough notes to be lost in it. Use `zk`'s powerful [filtering capabilities](note-filtering.md) to find what you need.
```sh
$ zk edit --interactive --match "recipe pizza -pineapple"
# or with short flags
$ zk edit -i -m "recipe pizza -pineapple"
```
## List existing notes
If you do not need to edit a note, use `zk list` instead to print context-sensitive results.
```sh
$ zk list -m "recipe pizza -pineapple"
```

@ -0,0 +1,29 @@
# Neuron
[Neuron](https://neuron.zettel.page/) is a command-line app for managing a plain-text [Zettelkasten](https://zettelkasten.de/introduction/).
While there is some overlap with `zk`'s features, both tools are actually useful when paired together:
* `zk` has powerful [filtering](note-filtering.md) and [note generation](note-creation.md) capabilities
* Neuron shines with its static website generation
Close integration with Neuron was thought through from the start when designing `zk`. For example, Neuron's [Folgezettel](https://neuron.zettel.page/folgezettel.html) syntax is supported: `[[[link]]]`, `#[[link]]` and `[[link]]#`.
<!-- TODO: They automatically add a `from` or `to` link relation when used. -->
But you can make your [notebook](notebook.md) even more tightly integrated with Neuron by:
* using the [same settings as Neuron](https://neuron.zettel.page/id.html) to generate the [note IDs](note-id.md) in the [note configuration](config-note.md)
```toml
[note]
filename = "{{id}}"
id-charset = "hex"
id-length = 8
id-case = "lower"
```
* adding [command aliases](config-alias.md) for your frequently used `neuron` commands
```toml
[alias]
serve = "neuron gen -wS"
gen = "neuron gen -o public"
```

@ -0,0 +1,28 @@
# Creating a new note
<!--{% raw %}-->
You can add a new note to a [notebook](notebook.md) using `zk new --title "An interesting concept" [<directory>]`.
`zk` automatically generates a filename and initial content according to rules set in your [configuration file](config.md). These settings can be customized per [group of notes](config-group.md) in your notebook, as illustrated in [Maintaining a daily journal](daily-journal.md).
By default, `zk new` will start [your editor](tool-editor.md) after creating the note. You can choose instead to print the absolute path to the note with `--print-path`, which is more useful for [automation](automation.md).
## Search or create with a single command
If you are not sure whether a note already exists for a particular subject, the "search or create" mode might be more appropriate than `zk new`. It is inspired by [Notational Velocity](https://notational.net/) and enables searching for an existing note or creating a new one in a single action.
This option is available when running `zk edit --interactive`, which spawns [`fzf`](tool-fzf.md) to filter selected notes. From `fzf`, press `Ctrl-N` to create a new note using the current search query as title.
## Create a note with initial content
Initial content can be fed to the template through a standard input pipe, which will be expandable with the `{{content}}` [template variable](template-creation.md).
For example, to use the content of the macOS clipboard as the initial content you can run:
```sh
$ pbpaste | zk new
```
<!--{% endraw %}-->

@ -0,0 +1,198 @@
# Searching and filtering notes
A few commands are built upon `zk`'s powerful note filtering capabilities, such as `edit` and `list`. They accept any option described here.
## Filter by path
All filtering commands take for unique positional argument a list of paths. When set, only the notes matching the given paths will be returned.
You can use it to find all the notes in a directory.
```sh
$ zk list journal/daily journal/weekly
```
Or specific notes.
```sh
$ zk edit 200911172034-an-interesting-concept.md
```
It works fine with only a path prefix as well. This is useful when you have a [note ID](note-id.md) prefix, but not the full file path.
```sh
$ zk edit 200911172034
```
These rules apply to all the following options, when they expect a `<path>` parameter.
```sh
$ zk list --linking-to 200911172034
```
You can also use a nested `zk` command to pre-filter paths to feed to an option with a `<path>` argument. [See the `inline` command alias example](config-alias.md) for more explanation.
```sh
# List the notes which have at least one link pointing to them (i.e. not orphans).
$ zk list --exclude "`zk inline --orphan`"
# List the notes which are linked by at least one note from the journal/ directory.
$ zk list --linked-by "`zk inline journal`"
```
## Search the title or body
Use `--match <query>` (or `-m`) to search through the title and body of notes.
The search is powered by a [full-text search](https://en.wikipedia.org/wiki/Full-text_search) database enabling near-instant results. Queries are not case-sensitive and terms are tokenized, which means that searching for `create` will also match `created` and `creating`.
A syntax similar to Google Search is available for advanced search queries.
### Combining terms
By default, the search engine will find the notes containing all the terms in the query, in any order.
```
"tesla edison"
```
If you want to find the notes containing any or both of the terms, put `OR` (all caps) or a pipe `|` between them.
```
"tesla OR edison"
"tesla | edison"
```
Search for an exact phrase by surrounding it with double quotes. In this case, you will need to single quote the full query if you do not want to escape the double quotes.
```
'tesla "alternating current"'
```
To construct more complex queries, you can group sub-queries with parentheses.
```
"current (tesla OR edison)"
```
Finally, you can filter out results by excluding a term with `NOT` (all caps) or a `-` prefix.
```
"tesla NOT car"
"tesla -car"
```
### Search in specific fields
If you want to search only in the title or body of notes, prefix a query with `title:` or `body:`.
```
"title: tesla"
"body: (tesla OR edison)"
```
### Prefix terms
Match any term beginning with the given prefix with a wildcard `*`.
```
"edi*"
```
Prefixing a query with `^` will match notes whose title or body start with the following term.
```
"title: ^journal"
```
## Filter by creation or modification date
To find notes created or modified on a specific day, use `--created <date>` and `--modified <date>`. They accept a human-friendly date for argument.
```
--created yesterday
--created "last tuesday"
--modified "Feb 3"
```
You can filter by range instead, using `--created-before`, `--created-after`, `--modified-before` and `--modified-after`.
```
--created-before 10am
--modified-after 2021
--created-after "last monday" --created-before yesterday
```
## Explore links
You can use the following options to explore the web of links spanning your [notebook](notebook.md).
`--linked-by <path>` (or `-l`) finds the notes linked by the given one, while `--linking-to <path>` (or `-L`) searches the notes having a link to it (also known as *backlinks*).
```
--linked-by 200911172034
--linking-to 200911172034
```
These options stop at the first level by default. But you can explore the whole web by adding the `--recursive` (or `-r`) option to find all the notes leading to (or from) a given note. If you feel overwhelmed, limit the distance between two notes with `--max-distance <count>`.
```
--linked-by 200911172034 --recursive --max-distance 3
```
Finally, it can be useful to see which notes have no links pointing to them at all. You can use the `--orphan` option for this.
## Find related notes
Part of writing a great notebook is to establish links between related notes. The `--related <path>` option can help by listing results having a linked note in common, but not yet connected to the note.
```
--related 200911172034
```
## Exclude notes from the results
To prevent certain notes from polluting the results, you can explicitly exclude them with `--exclude <path>` (or `-x`). This is particularly useful when you have a whole directory of notes to be ignored.
```
-x journal
```
## Limit the number of results
If you are only interested into the first few notes, limit the number of results with `--limit <count>` (or `-n`).
```
--limit 20
```
Using `-n1` is particularly common when you are expecting only a single result.
## Interactive filtering
A common search flow is to reduce the search scope using `zk`'s filtering options, before selecting manually the notes to process among them. This is especially useful with `zk edit` to avoid opening many unwanted notes with your editor.
Use `--interactive` (or `-i`) to select filtered notes manually. The interactive selection is handled by [`fzf`](tool-fzf.md) which brings a powerful fuzzy matching search into the mix.
## Sort the results
After finding matching notes, it might be useful to sort them before processing. The `--sort <criteria>` (or `-s`) option is made for that.
You can add a `+` (ascending) or `-` (descending) suffix to a sort criterion to customize the order. Each criterion has a sensible intrinsic order by default.
```
--sort path
--sort created+
-st- (eq. --sort title-)
```
| Criterion | Shortcut | Order | Description |
|--------------|----------|-------|------------------------------------|
| `created` | `c` | `-` | Creation date |
| `modified` | `m` | `-` | Modification date |
| `path` | `p` | `+` | File path relative to the notebook |
| `title` | `t` | `+` | Note title |
| `random` | `r` | `+` | Order notes randomly |
| `word-count` | `wc` | `+` | Word count in the note |

@ -0,0 +1,20 @@
# Note ID
Each note is uniquely identified by its path relative to the [notebook](notebook.md)'s root. However, in some cases it is more convenient to refer to a "note ID", which is the unique part of its filename. For example, the note ID of the file `200911172034 An interesting concept.md` is `200911172034`. You could have several notes named "An interesting concept", but only one with the ID `200911172034`.
The purpose of using a unique identifier in your note filenames is to create stable links between your notes, which will not break even if you change the title of the linked note. [See this reference for more information](https://zettelkasten.de/introduction/#the-unique-identifier).
There are several flavors of note IDs and `zk` supports most of them. You can set it up in the [note configuration](config-note.md).
## Random ID
A random ID enables short and memorable unique identifiers. By default, `zk` is configured to generate random IDs of four alphanumeric characters. I found this to be the sweet spot between an easily memorable and usable ID and enough candidates. This default setting can generate 1 679 616 unique IDs.
## Timestamp
Another common ID is a timestamp in the `YYYYMMDDHHMM` shape. This is less readable than a short random ID, but has the added advantage of being sortable by creation date. However, I find this not so useful in practice.
## Sequential IDs
Sequential (incremented) IDs are currently not supported by `zk`. They get ugly very quickly when deleting outdated notes and have an irregular shape.

@ -0,0 +1,26 @@
# Notebook housekeeping
Tending to your notes does not only mean writing. You need to keep your [notebook](notebook.md) in great shape to make good use of it. For many maintenance tasks, `zk` can help!
## Find related notes
To surf your notebook with ease, make sure to link all related notes together. You can list notes which could be good candidates for a new link with the `--related` [filtering option](note-filtering.md).
```sh
$ zk list --related note.md
```
This returns notes which are not connected to the given note, but with at least one linked note in common.
## Find flimsy notes
To find flimsy notes needing to be fleshed out, you can list the first few notes with the smallest word count from your notebook with the following command:
```sh
$ zk list --format '{{word-count}}\t{{title}}' --sort word-count --limit 20
4 Integration with fzf
5 Searching and filtering notes
63 Setting your default editor
86 Anatomy of a notebook
...
```

@ -0,0 +1,15 @@
# Notebook
A *notebook* is a directory containing a collection of notes managed by `zk`. Notebooks cannot be nested, but you are free to organize your notes in subdirectories.
To create a new notebook, simply run `zk init [<directory>]`.
Most `zk` commands are operating "Git-style" on the notebook containing the current working directory (or one of its parents).
## Anatomy of a notebook
Similarly to Git, a notebook is identified by the presence of a `.zk` directory at its root. This directory contains the only `zk`-specific files in your notebook:
* `.zk/config.toml` is the user [configuration file](config.md)
* `.zk/templates/` contains [user templates](template.md) used when [creating new notes](note-creation.md)
* `.zk/notebook.db` is the SQLite database enabling [powerful search features](note-filtering.md).

@ -0,0 +1,32 @@
# Styling
<!--{% raw %}-->
<!-- TODO: semantic rules -->
`zk` supports a `{{style}}` [template helper](template.md) to format its output with colors and font decorations.
Usage: `{{style "<rules>" "<text>"}}`
Multiple rules can be provided, separated by spaces.
Examples:
```
Inline: {{style "red bold" "One is never alone with a rubber duck."}}
Block:
{{#style "underline"}}
For a moment, nothing happened. Then, after a second
or so, nothing continued to happen.
{{/style}}
```
## Styling rules
* Decorations: `bold`, `italic`, `faint`, `underline`, `strikethrough`, `blink`, `reverse`, `hidden`
* Text color: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`
* Text color (bright): `bright-black`, `bright-red`, `bright-green`, `bright-yellow`, `bright-blue`, `bright-magenta`, `bright-cyan`, `bright-white`
* Background color: `black-bg`, `red-bg`, `green-bg`, `yellow-bg`, `blue-bg`, `magenta-bg`, `cyan-bg`, `white-bg`
* Background color (bright): `bright-black-bg`, `bright-red-bg`, `bright-green-bg`, `bright-yellow-bg`, `bright-blue-bg`, `bright-magenta-bg`, `bright-cyan-bg`, `bright-white-bg`
<!--{% endraw %}-->

@ -0,0 +1,23 @@
# Template context when creating notes
<!--{% raw %}-->
The following variables are available in the templates used when [creating new notes](note-creation.md) both for the filename and the note content.
| Variable | Type | Description |
|---------------|--------|---------------------------------------------------------------------------------------|
| `id` | string | Random ID generated for this note |
| `title` | string | Note title given to `--title` |
| `content` | string | Any text piped through the standard input |
| `dir` | string | Parent directory in the notebook |
| `extra.<key>` | string | [Additional variables](config-extra.md) provided through the config file or `--extra` |
| `now` | date | Current date and time, useful when paired with [`{{date now}}`](template.md) |
These additional variables are available only to the note content template, once the filename is generated.
| Variable | Type | Description |
|-----------------|--------|----------------------------------------------------------------|
| `filename` | string | Filename generated for this note, including the file extension |
| `filename-stem` | string | Filename without the file extension |
<!--{% endraw %}-->

@ -0,0 +1,17 @@
# Template context when formatting a note
The following variables are available in the templates used when formatting notes, for example with `zk list --format <template>`.
| Variable | Type | Description |
|---------------|----------|-----------------------------------------------------------|
| `path` | string | File path to the note, relative to the current directory |
| `title` | string | Note title |
| `lead` | string | First paragraph extracted from the note content |
| `body` | string | All of the note content, minus the heading |
| `snippets` | [string] | List of context-sensitive relevant excerpts from the note |
| `raw-content` | string | The full raw content of the note file |
| `word-count` | int | Number of words in the note |
| `created` | date | Date of creation of the note |
| `modified` | date | Last date of modification of the note |
| `checksum` | string | SHA-256 checksum of the note file |

@ -0,0 +1,89 @@
# Template syntax
<!--{% raw %}-->
`zk` uses the [Handlebars template syntax](https://handlebarsjs.com/guide) for its templates. The list of variables available depends of the running command:
* [Template context when creating notes](template-creation.md) (i.e. `zk new`)
* [Template context when formatting a note](template-format.md) (i.e. `zk list --format <template>`)
## Additional helpers
Besides the default Handlebars helpers, `zk` ships with additional helpers which you might find useful. They are available to all templates.
### Date helper
The `{{date}}` helper formats the given date for display.
Template contexts usually provide a `now` variable which can be used to print the current date.
The default format output by `{{date <variable>}}` looks like `2009-11-17`, but you can choose a different format by providing a second argument, e.g. `{{date now "medium"}}`.
| Format | Output | Notes |
|------------------|----------------------------|--------------------------------------------------|
| `short` | 11/17/2009 | |
| `medium` | Nov 17, 2009 | |
| `long` | November 17, 2009 | |
| `full` | Tuesday, November 17, 2009 | |
| `year` | 2009 | |
| `time` | 20:34 | |
| `timestamp` | 200911172034 | Useful for sortable filenames |
| `timestamp-unix` | 1258490098 | Number of seconds since January 1, 1970 |
| `elapsed` | 12 years ago | Time elapsed since then in human-friendly format |
If none of the provided formats suit you, you can use a custom format using `strftime`-style placeholders, e.g. `{{date now "%m-%d-%Y"}}`. See `man strftime` for a list of placeholders.
### Slug helper
The `{{slug}}` helper generates a URL friendly version of a text. For example, `{{slug "This will be slugified!"}}` becomes `this-will-be-slugified`.
This is mostly useful to generate a safe filename containing the title passed to `zk new --title "An interesting note"`. With the [`filename`](config-note.md) template `{{slug title}}`, it becomes `an-interesting-note.md`.
### Prepend helper
The `{{prepend}}` helper adds a prefix to every line of the given text or block. You can use it to generate a Markdown quote, for example:
```
{{prepend "> " "A quote"}}
{{#prepend "> "}}
A multiline
quote.
{{/prepend}}
```
### Shell helper
The `{{sh}}` helper will call the given shell command and insert its output in the template. Your imagination is the limit!
```
Get today's events from your calendar:
{{sh "icalBuddy -b '* ' -nc eventsToday"}}
Insert a random quote:
{{prepend '> ' (sh 'fortune')}}
Download today's weather:
{{sh 'curl http://wttr.in/?0'}}
```
When used as a block helper, the block content will be passed to the command through a standard input pipe.
```
Will output "HELLO, WORLD!":
{{#sh "tr '[a-z]' '[A-Z]'"}}
Hello, world!
{{/sh}}
```
### Style helper
The `{{style}}` helper is mostly useful when formatting content for the command-line. See the [styling rules](style.md) for more information.
```
{{style 'red bold' 'A text'}}
{{#style 'underline'}}Another text{{/style}}
```
<!--{% endraw %}-->

@ -0,0 +1,14 @@
# Setting your default editor
`zk` is not a text editor. Instead, it is designed to interface with your favorite editor to write your notes.
You can customize which editor to use either from the [configuration file](config.md) or environment variables. In order of precedence, `zk` will use:
1. `ZK_EDITOR` environment variable
2. `editor` configuration property
```toml
[tool]
editor = "vim"
```
3. `VISUAL` environment variable
4. `EDITOR` environment variable

@ -0,0 +1,25 @@
# Integration with `fzf`
[`fzf`](https://github.com/junegunn/fzf) is an awesome and versatile fuzzy finder powering `zk`'s [interactive filtering mode](note-filtering.md).
Besides the standard [`fzf` configuration options](https://github.com/junegunn/fzf) documented on its website, `zk` offers additional options you can set in the `[tool]` [configuration section](config.md).
If you wish to customize more of `fzf` behavior, [please post a feature request](https://github.com/mickael-menu/zk/issues).
## Preview command
You can customize the command used to preview a note with `fzf-preview`. The special placeholder `{-1}` will be expanded to the note file path.
By default, `zk` uses `cat` for preview, which is a bit boring. A much better option would be to use [`bat`](https://github.com/sharkdp/bat) which supports syntax highlighting.
```toml
[tool]
fzf-preview = "bat -p --color always {-1}"
```
Or, if you prefer to preview more metadata, you can use a nested `zk` command.
```toml
[tool]
fzf-preview = "zk list --quiet --format full --limit 1 {-1}"
```

@ -0,0 +1,18 @@
# Setting your default pager
When `zk`'s output exceeds a certain limit, it is automatically paginated by your system pager. By default, `less` is used but you may set up your own pager in the [configuration file](config.md) or environment variables. In order of precedence, `zk` will use:
1. `ZK_PAGER` environment variable
2. `pager` configuration property
```toml
[tool]
pager = "less -FIRX"
```
3. `PAGER` environment variable
## Disable the pager
If you need to disable paging, you can either:
* use `--no-pager`
* set the `pager` configuration property to an empty string `""`
Loading…
Cancel
Save