Skip to content

Commit 541535e

Browse files
committed
add creation-date-key modification-date-key` configuration options
These two configuration options are used to change the way zk obtains the creation date and modification date from a file.
1 parent a10d80b commit 541535e

File tree

7 files changed

+113
-10
lines changed

7 files changed

+113
-10
lines changed

docs/notes/note-format.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ You can set up some features of `zk`'s Markdown parser from your
2323

2424
[1]: https://blog.bear.app/2017/11/bear-tips-how-to-create-multi-word-tags/
2525

26+
### `YAML` Frontmatter
27+
28+
The following configuration options are available for changing `zk`'s interactions with the
29+
frontmatter:
30+
31+
| Setting | Default | Description |
32+
| ----------------------- | --------- | --------------------------------------------------------------- |
33+
| `creation-date-key` | `"date"` | Yaml key used to store the creation date & time of the file |
34+
| `modification-date-key` | none [^2] | Yaml key used to store the modification date & time of the file |
35+
36+
[^2]: When this value is not set, the file's modification date is taken from the filesystem.
37+
2638
### Customizing the Markdown links generated by `zk`
2739

2840
By default, `zk` will generate regular Markdown links for internal links. If you

docs/notes/note-frontmatter.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ keywords: [writing, essay, practice]
2626
All metadata are indexed and can be printed in `zk list` output, using the
2727
template variable `{{metadata.<key>}}`, e.g. `{{metadata.description}}`. The
2828
keys are normalized to lower case.
29+
30+
Some of the keys above can be changed by the configuration file, see [`YAML`
31+
Frontmatter](note-format.md#yaml-frontmatter).

internal/core/config.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ func NewDefaultConfig() Config {
5757
LinkFormat: "markdown",
5858
LinkEncodePath: true,
5959
LinkDropExtension: true,
60+
Frontmatter: YamlFrontmatterConfig{
61+
CreationDate: "date",
62+
ModificationDate: opt.NullString,
63+
},
6064
},
6165
},
6266
LSP: LSPConfig{
@@ -161,6 +165,18 @@ type MarkdownConfig struct {
161165
LinkEncodePath bool
162166
// Indicates whether a link's path file extension will be removed.
163167
LinkDropExtension bool
168+
169+
// Frontmatter determines the keys used in the frontmatter
170+
Frontmatter YamlFrontmatterConfig
171+
}
172+
173+
// YamlFrontmatterConfig holds the configuration for Yaml frontmatter.
174+
type YamlFrontmatterConfig struct {
175+
// CreationDate indicates what name the key for the creation date has. Default is "date"
176+
CreationDate string
177+
// ModificationDate indicates what name the key for the modification date has. If not present,
178+
// the filesystems modification time is used.
179+
ModificationDate opt.String
164180
}
165181

166182
// ToolConfig holds the external tooling configuration.
@@ -391,6 +407,21 @@ func ParseConfig(content []byte, path string, parentConfig Config, isGlobal bool
391407
config.Format.Markdown.LinkDropExtension = *markdown.LinkDropExtension
392408
}
393409

410+
// Frontmatter
411+
frontmatter := markdown.Frontmatter
412+
if frontmatter.CreationDate != nil && *frontmatter.CreationDate == "" {
413+
*frontmatter.CreationDate = "date"
414+
}
415+
if frontmatter.CreationDate != nil {
416+
config.Format.Markdown.Frontmatter.CreationDate = *frontmatter.CreationDate
417+
}
418+
if frontmatter.ModificationDate != nil && *frontmatter.ModificationDate == "" {
419+
frontmatter.ModificationDate = nil
420+
}
421+
if frontmatter.ModificationDate != nil {
422+
config.Format.Markdown.Frontmatter.ModificationDate = opt.NewString(*frontmatter.ModificationDate)
423+
}
424+
394425
// Tool
395426
tool := tomlConf.Tool
396427
if tool.Editor != nil {
@@ -554,12 +585,18 @@ type tomlFormatConfig struct {
554585
}
555586

556587
type tomlMarkdownConfig struct {
557-
Hashtags *bool `toml:"hashtags"`
558-
ColonTags *bool `toml:"colon-tags"`
559-
MultiwordTags *bool `toml:"multiword-tags"`
560-
LinkFormat *string `toml:"link-format"`
561-
LinkEncodePath *bool `toml:"link-encode-path"`
562-
LinkDropExtension *bool `toml:"link-drop-extension"`
588+
Hashtags *bool `toml:"hashtags"`
589+
ColonTags *bool `toml:"colon-tags"`
590+
MultiwordTags *bool `toml:"multiword-tags"`
591+
LinkFormat *string `toml:"link-format"`
592+
LinkEncodePath *bool `toml:"link-encode-path"`
593+
LinkDropExtension *bool `toml:"link-drop-extension"`
594+
Frontmatter tomlYamlFrontmatterConfig `toml:"frontmatter"`
595+
}
596+
597+
type tomlYamlFrontmatterConfig struct {
598+
CreationDate *string `toml:"creation-date-key"`
599+
ModificationDate *string `toml:"modification-date-key"`
563600
}
564601

565602
type tomlToolConfig struct {

internal/core/config_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ func TestParseDefaultConfig(t *testing.T) {
3939
LinkFormat: "markdown",
4040
LinkEncodePath: true,
4141
LinkDropExtension: true,
42+
Frontmatter: YamlFrontmatterConfig{
43+
CreationDate: "date",
44+
ModificationDate: opt.NullString,
45+
},
4246
},
4347
},
4448
Tool: ToolConfig{
@@ -91,6 +95,10 @@ func TestParseComplete(t *testing.T) {
9195
link-encode-path = true
9296
link-drop-extension = false
9397
98+
[format.markdown.frontmatter]
99+
creation-date-key = "created"
100+
modification-date-key = "changed"
101+
94102
[tool]
95103
editor = "vim"
96104
shell = "/bin/bash"
@@ -235,6 +243,10 @@ func TestParseComplete(t *testing.T) {
235243
LinkFormat: "custom",
236244
LinkEncodePath: true,
237245
LinkDropExtension: false,
246+
Frontmatter: YamlFrontmatterConfig {
247+
CreationDate: "created",
248+
ModificationDate: opt.NewString("changed"),
249+
},
238250
},
239251
},
240252
Tool: ToolConfig{
@@ -421,6 +433,10 @@ func TestParseMergesGroupConfig(t *testing.T) {
421433
LinkFormat: "markdown",
422434
LinkEncodePath: true,
423435
LinkDropExtension: true,
436+
Frontmatter: YamlFrontmatterConfig{
437+
CreationDate: "date",
438+
ModificationDate: opt.NullString,
439+
},
424440
},
425441
},
426442
LSP: LSPConfig{

internal/core/note_parse.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,16 @@ func (n *Notebook) ParseNoteWithContent(absPath string, content []byte) (*Note,
9494

9595
times, err := times.Stat(absPath)
9696
if err == nil {
97-
note.Modified = times.ModTime().UTC()
98-
note.Created = creationDateFrom(note.Metadata, times)
97+
note.Modified = n.modificationDateFrom(note.Metadata, times)
98+
note.Created = n.creationDateFrom(note.Metadata, times)
9999
}
100100

101101
return &note, nil
102102
}
103103

104-
func creationDateFrom(metadata map[string]interface{}, times times.Timespec) time.Time {
104+
func (n *Notebook) creationDateFrom(metadata map[string]interface{}, times times.Timespec) time.Time {
105105
// Read the creation date from the YAML frontmatter `date` key.
106-
if dateVal, ok := metadata["date"]; ok {
106+
if dateVal, ok := metadata[n.Config.Format.Markdown.Frontmatter.CreationDate]; ok {
107107
if dateStr, ok := dateVal.(string); ok {
108108
if time, err := iso8601.ParseString(dateStr); err == nil {
109109
return time
@@ -124,3 +124,24 @@ func creationDateFrom(metadata map[string]interface{}, times times.Timespec) tim
124124

125125
return time.Now().UTC()
126126
}
127+
128+
func (n *Notebook) modificationDateFrom(metadata map[string]interface{}, times times.Timespec) time.Time {
129+
configKey := n.Config.Format.Markdown.Frontmatter.ModificationDate
130+
if !configKey.IsNull() {
131+
if dateVal, ok := metadata[configKey.Unwrap()]; ok {
132+
if dateStr, ok := dateVal.(string); ok {
133+
if time, err := iso8601.ParseString(dateStr); err == nil {
134+
return time
135+
}
136+
// Omitting the `T` is common
137+
if time, err := time.Parse("2006-01-02 15:04:05", dateStr); err == nil {
138+
return time
139+
}
140+
if time, err := time.Parse("2006-01-02 15:04", dateStr); err == nil {
141+
return time
142+
}
143+
}
144+
}
145+
}
146+
return times.ModTime().UTC()
147+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
$ cd blank
2+
3+
$ echo "[format.markdown.frontmatter] creation-date-key = \"created\"" > .zk/config.toml
4+
5+
$ echo "---\ncreated: 2025-03-27 01:18:43\n---\n\n# Note" > note.md
6+
$ zk list -qflink
7+
>{"filename":"note"}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
$ cd blank
2+
3+
$ echo "[format.markdown.frontmatter] modification-date-key = \"changed\"" > .zk/config.toml
4+
5+
$ echo "---\nchanged: 2025-03-27 01:18:43\n---\n\n# Note" > note.md
6+
$ zk list -qflink
7+
>{"filename":"note"}

0 commit comments

Comments
 (0)