Skip to content
Ian Cornelius edited this page Sep 24, 2022 · 2 revisions

Summary

ZettelGeist performs two basic operations: writing note cards and retrieving them. The tool for writing cards is zettel. Since cards are stored as yaml and markdown, zettel is essentially a command-line tool for writing new yaml documents and editing existing ones. The functionality of this tool will be illustrated first. We will turn then to zimport and zfind, the tools for collecting cards into a database and running queries on it.

Prerequisites

This manual assumes that you have installed ZettelGeist and confirmed its tools are available in a Python virtual environment. See the Installing the Tools page for instructions. You must source the virtual environment to use ZettelGeist. We will assume that your virtual environment is named zenv.

Writing cards with zettel

Synopsis

zettel [--file INPUT-FILE] [OPTIONS]

If no input file is specified, input is read from the options. Output goes by default to standard output. For output to a new file, use --save (to write the filename yourself) or --name (to have zettel write the filename for you). To overwrite the input file, use the option --in-place.

Getting help

(zenv) $ zettel --help

Most options have a regular verb-object syntax and instruct zettel to do a specified action (set, append, prompt, load or delete) on a field-value. Examples will be given below.

Create and save a simple zettel

(zenv) $ zettel --set-title "Hello, World!"

This results in the following output:

title: Hello, World!

To write this output to a file, invoke the --save option:

(zenv) $ zettel --set-title "Hello, World!" --save template.yaml

A basic ZettelGeist workflow consists in writing a template-card to be invoked and edited in subsequent iterations. Here is an example:

(zenv) $ zettel --file template.yaml --set-note "A Zettel with a note" --name timestamp

This command reads two input sources, merges them, and saves output to a new file with the following content:

title: Hello, World!
note: A Zettel with a note

Writing long strings in command line arguments is inconvenient, so ZettelGeist provides two alternatives. The option --prompt-<FIELD> divides card-writing into steps. When this option is invoked, zettel will request input for the specified field before creating a new card. Text is entered within the terminal. Newlines and blank lines are permitted. Type ctrl+d to complete input.

(zenv) $ zettel --file template.yaml --prompt-note --name timestamp

The option --load-<FIELD> reads input for the specified field from a text file:

(zenv) $ zettel --file template.yaml --load-note some.txt --name timestamp

The timestamp value ensures that no two cards will have the same file name, but it masks file content. The --id option feeds a descriptive string into the file name:

(zenv) $ zettel --file template.yaml --id tutorial --name id timestamp

To serialize cards rather assigning a timestamp to them, use the --counter option:

(zenv) $ zettel --file template.yaml --id tutorial --counter tutorial --name id counter

This command initiates a count of cards with the id "tutorial". The count is maintained in a new binary file .counter.dat. The default number of digits is four and the count starts at 0000. The values id, counter, and timestamp may be combined in any order.

ZettelGeist fields

The preceding section introduced the fields title and note. In this section we provide a full list of ZettelGeist fields and the operations that may be performed on them.

For fields with a string value, the option --set-<FIELD> inputs a value for that field, as we saw in the previous section. For fields with a list value, use the --append-<FIELD> and place each value within quotes. Examples will be provided below for the relevant fields.

All fields are user-defined. We provide suggestions based on our own workflows.

  • bibkey (String.) A unique identifier for the source from which you have extracted this note. Users of the Better BibTex extension for Zotero may want to enter the Better BibTeX Citation Key in this field.

  • bibtex A BibTeX citation. This field is redundant if you manage your bibliography with Zotero and tie note-cards to Zotero items with Better BibTeX Citation Keys in the field bibkey. Alternatively, you could manage your bibliography within ZettelGeist itself, with some zetteln that record BibTeX citations and others that record notes on those sources, using the bibkey field to link note-card and citation-cards.

  • cite This field has two child fields, bibkey and page. Values must be supplied for both child fields and placed in quotes. For instance: --set-cite "FoucaultArchaeologyKnowledgeDiscourse1982" "pp. 103-4". When creating a template card, enter a dummy value for page: --set-cite "FoucaultArchaeologyKnowledgeDiscourse1982" "p.". When calling a template card with the --file option, the following syntax will update cite values: --set-cite "" "pp. 103-4". This argument retains the bibkey value in the input file but replaces the previous page value with "pp. 103-4".

  • comment (String.) Any comment you want to make about the zettel in general.

  • dates A year (string) and era (string) as a nested dictionary. Syntax follows cite.

  • mentions (List.) One or more mentions. Use the option --append-mentions and put each within quotes. For instance: --append-mentions "Sievers, Eduard" "Lachmann, Karl".

  • note (String.) This is the core element of the note card. Usually it is a quotation extracted from the source and page identified in the cite field. If you need greater versatility, a fuller range of characters, and more formatting options, leave the note field undefined and use the markdown document element instead.

  • summary (String.) A concise summary of the note (by convention).

  • tags (List.) One or more keywords. Use the option --append-tags and put each keyword within quotes. For instance: --append-tags "Charles Babbage" "Ada Lovelace" "Victorian Era".

  • title (String.) A human-readable label for a sequence of note cards. We set this label in the template card for a source and retain it in all note cards on that source.

  • url (String.) Useful for bookmarking websites.

Retrieving cards

We now describe tools for selectively retrieving cards. zimport populates a database with note cards. zfind runs queries on the database and returns matching cards.

After the synopsis, this section presents two tutorials. The first illustrates basic functions. The second shows how output from the database can be fed back into zettel to revise and update notes.

Synopsis

For usage, run zimport -h and zfind -h. This prints the full set of options recognized by each command.

zimport

zimport --database DATABASE --dir PATH/TO/ZETTELS [--fullpath] [--validate] [--create]

The --create flag takes over the operation formerly performed by the command zcreate.

zfind

A common form of this command is

zfind --database DATABASE  --query-string 'FIELD:"VALUE"...' [--count] [--show-FIELD...]

Multiple FIELD:VALUE pairs are combined with the operators & | ! (respectively AND, OR, NOT).

In this first form of the zfind command, at least one optional argument is required, telling zfind what action to perform on matches. The argument --count returns the number of zetteln that match the search criteria. The argument --show-FIELD prints the specified field to standard output. To see all YAML fields, use --show-all. This prints the value of every YAML field used in any zettel that match the search criteria. To see the markdown element for matching zetteln, use --show-document.

A second form of the zfind command is

zfind --database index.db [--get-all-tags | --get-all-mentions]

This form of the command writes all tags (or all mentions) to standard output.

Tutorial 1: baseball

To illustrate the function of these tools, we use sample zettels published at https://github.com/ZettelGeist/zg-tutorial.git. Download the repository with git clone:

$ git clone https://github.com/ZettelGeist/zg-tutorial.git

This creates a new directory zg-tutorial. Enter zg-tutorial/zettels/baseball and list its contents:

$ cd zg-tutorial/zettels/baseball
$ ls

Use cat to take a look at one of the cards.

title: MLB Teams
summary: Arizona Diamondbacks
note: |
  The Arizona Diamondbacks, often shortened as the D-backs, are an American professional
  baseball franchise based in Phoenix, Arizona. The club competes in Major League
  Baseball (MLB) as a member of the National League (NL) West division. Since the
  team's inception in 1998, the franchise has played home games at Chase Field, formerly
  known as Bank One Ballpark. The Diamondbacks have won one World Series championship
  (in 2001), becoming the fastest expansion team in the Major Leagues to win a championship,
  doing it in only the fourth season since the franchise's inception in the 1998 Major
  League Baseball season.
tags:
- MLB
- National League
- NL West
cite:
  bibkey: arizona-diamondbacks-wikipedia
  page: web page

Create and populate a database

We will now import the cards into a database.

(zenv) $ zimport --database mlb.db --dir . --create --fullpath

This command

  1. creates a new database mlb.db (first deleting any existing database with that name)
  2. populates that database with all zetteln in the working directory (including child-directories)
  3. records the full path of each input file

We are now ready to run queries on the database and selectively retrieve cards from it.

Run queries

Searching is done with the zfind tool. The option --query-string tells zfind what to look for. The options --count and --show-<FIELD> tell zfind what to do with matches:

  • --count counts the cards matching the search criteria and prints that number to standard output.
  • --show-<FIELD> prints the specified field to standard output.

These output options may be combined. --show-<FIELD> may be repeated with different fields.

The basic syntax of --query-string is 'KEY:"VALUE"'. This syntax is illustrated in the following examples:

  1. To find how many cards mention Chicago in the summary field
(zenv) $ zfind --database mlb.db --query-string 'summary:"Chicago"' --count
2 Zettels matched search
  1. To print the matching summaries and filenames
(zenv) $ zfind --database mlb.db --query-string 'summary:"Chicago"' --show-filename --show-summary
summary: Chicago White Sox

filename:
/path/to/chicago-grey-sox.yaml

---

summary: Chicago Cubs

filename:
/path/to/chicago-cubs.yaml

---
  1. To find the phrase "Central division" in the note field and print the summary fields
(zenv) $ zfind --database mlb.db --query-string 'note:"Central division"' --show-summary
summary: Minnesota Twins

---

summary: Pittsburgh Pirates

---

summary: Cincinnati Reds

---

summary: Detroit Tigers

---

summary: Cleveland Indians

---

summary: St. Louis Cardinals

---

summary: Chicago Cubs

---

summary: Kansas City Royals

---
  1. To find all cards with Cubs mentioned in the note field and print that field
(zenv) $ zfind --database mlb.db --query-string 'note:"Cubs"' --show-note
note: |
  The Chicago Cubs are an American professional baseball team based in Chicago, Illinois. The Cubs
  compete in Major League Baseball (MLB) as a member club of the National League (NL) Central
  division, where they are the defending World Series champions. The team plays its home games at
  Wrigley Field, located on the city\'s North Side. The Cubs are one of two major league teams in
  Chicago; the other, the Chicago White Sox, is a member of the American League (AL) Central
  division. The Cubs, first known as the White Stockings, was a founding member of the NL in 1876,
  becoming the Chicago Cubs in 1903.[2] The Cubs have appeared in a total of eleven World Series.
  The 1906 Cubs won 116 games, finishing 116–36 and posting a modern-era record winning percentage
  of .763, before losing the World Series to the Chicago White Sox by four games to two. The Cubs
  won back-to-back World Series championships in 1907 and 1908, becoming the first major league
  team to play in three consecutive World Series, and the first to win it twice. Most recently,
  the Cubs won the 2016 National League Championship Series and 2016 World Series, which ended a
  71-year National League pennant drought and a 108-year World Series championship drought,

To save this output, redirect standard output to a file with > or >>:

(zenv) $ zfind --database mlb.db --query-string 'note:"Cubs"' --show-note > new-file.txt

Tutorial 2: research notes

In this second tutorial we will use the zettels in zg-tutorial/zettels/rheingold-examples. Enter that directory and create a database from its zettels, as described in tutorial 1. We will assume that the database is named index.db.

To query this database, we need some idea of its contents. For instance, what tags are used?

(zenv) $ zfind --database index.db --get-all-tags | less

This will output the entire list of tags in your database.

The list of tags is unique, but please keep in mind that the list is case sensitive, even though ZettelGeist itself does not distinguish tags by case. You can pipe the output to the Unix sort and uniq -i to see only the unique tags as follows:

(zenv) $ zfind --database index.db --get-all-tags | sort | uniq -i | less

To keep an incremental record of the tags used in your database, redirect this output to a new file in a git repository (perhaps the same repository that holds your zettels).

The incremental record will allow you to check new tags against the existing set and spot errors and redundancies.

Let's now select a tag to investigate:

$ zfind --database index.db --query-string 'tags:"Turing"' --count

The output reports 66 matching zettels. Narrow the search to cards that mention the Enigma machine in the note field and browse the results with less:

$ zfind --database index.db --query-string 'tags:"Turing" & note:"Enigma"' --show-note --show-tags --count | less

Now suppose that we want to add the tag crypoanalysis to the four cards that match this search. Revisions can always be made to individual cards with a text editor. When just four cards are involved, it is no hardship to add a new tag manually. To identify the files to be revised, add the option --show-filename to the command above.

Suppose, however, that we want to add a new tag to all 66 cards with the tag "Turning". For this, we want automation.

Adding tags to multiple zettels

To a get list of filenames from search results, use grep:

$ zfind --database index.db --query-string 'tags:"Turing" & note:"Enigma"' --show-filename | grep zg-tutorial

Any portion of the file path should work in the pattern fed to grep. The command above uses zg-tutorial. The output gives the absolute path to each of the matching zettels.

To add the tag crypoanalysis to each of the files, use this shell loop:

$ for filename in $(zfind --database index.db --query-string 'tags:"Turing" & note:"Enigma"' --show-filename | grep zg-tutorial) \
do \
   zettel --file $filename --append-tags "crypoanalysis" --in-place \
done

To view the results, run git status and git diff. Notice that the --in-place option creates backups of the overwritten files. This is a safety check. Delete the backups once you are satisfied with the results of the for loop.