~subsetpark/erasmus

ref: 407cdb0b087a40146fbca6e7aacc898c949449be erasmus/priv/zk.pant -rw-r--r-- 3.1 KiB
407cdb0b — Zach Smith Escape backlinks also 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
module ZK.

// Notes on a note-taking system, inspired by Zettelkasten.

Line <= String.
Note <= [Line].

// The basic operation we're describing is *indexing*: taking all the notes in
// our set and updating them with references to other notes. That's all this
// system does; the notes themselves can be written and read with a standard
// text editor, and most text editors have a "go to file" procedure, so even
// the navigation from note to note can be done within the editor.

// The only thing it needs help with is finding the connections between notes.

index notes: [Note].
---

// Indexing does two things:

// 1. It updates each note, in place. All backlinks to each note are placed at
// the beginning of it, and all references contained within it are placed at
// the end.

all n: notes =>
        n' = backlinks n + body n + references n
        and name n' = name n.

// 2. It maintains an Index. Indices aren't notes - they aren't affected by
// indexing, in particular. They are simply a list of links to each note in the
// set, ordered by creation time.

some1 i: Index =>
        all n: notes' => ref_note n in i
        and all (n, m): notes' =>
                created_at n < created_at m -> i (ref_note n) < i (ref_note m).

;

Index <= [Line].

// A Reference is a line of text that's read and written by the system. Both
// backlinks and (forward) references are simply collections of References.

Reference <= Line.
backlinks n: Note => {Reference}.
references n: Note => [Reference].

name n: Note => String.
body n: Note => [Line].
created_at n: Note => Date.

ref s: String => Reference.
ref_note n: Note => Reference.
---

// To refer to a given name, we simply insert a line with a recognized string
// in front of it, followed by the name. For instance: "%ref:scifi\ authors".
// In particular, it's important to escape any delimiters in the name; this is
// to allow the "go to file under cursor" command to recognize the whole name
// rather than the first part, in the case of names with spaces.

ref s = "%ref:" + escape s + "\n".

// It follows then that a reference to a note is simply a reference to its
// filename.

ref_note n = ref (name n).

body n = [all line: n, ~(line in Reference) => line].

// As mentioned above, to *index* a note is to take the note body, prepend all
// of the backlinks to that note, and append all the references to other notes
// (or other potential notes) contained in the body. A backlink is a reference
// to any note that links to this one; a (forward) reference is a reference to
// any note which is linked to by this one.

backlinks n = {all m: Note, (bracketed (name n)) in m => ref_note m}.
references n = [all s: String, (bracketed s) in n => ref s].

// It's worth noting that references can be ordered as they appear in the note
// body; but backlinks have no defined order.

all (r, s): references n =>
        n (bracketed (name r)) < n (bracketed (name s)) -> references r < references s.

;

// To link to any name, simply enclose it in square brackets in the body of a note.

escape s: String => String.
bracketed s: String => String.
---

bracketed s = "[" + s + "]".