fix sync bug with signature
This commit is contained in:
parent
2eb9e3511c
commit
77a1db71e3
22
README.md
22
README.md
|
|
@ -116,6 +116,28 @@ You may change this by changing `ftype` in main.go.
|
|||
|
||||
This program supports encrypted notes by integrating with [acme-crypt](https://github.com/lneely/acme-crypt). Set up the [plumbing rules](./PLUMBING.md) to read encrypted notes, and use `CryptPut` to write them.
|
||||
|
||||
## Signature Support
|
||||
|
||||
Denote supports an optional signature component in filenames: `ID==SIGNATURE--TITLE__TAGS.ext`. Signatures are useful for sequential numbering, context markers, or priorities.
|
||||
|
||||
**Plumbing Configuration:**
|
||||
|
||||
To plumb files with signatures, you must add `=` to the file pattern character classes in your plumbing rules. Update these three patterns:
|
||||
|
||||
**Original patterns:**
|
||||
```
|
||||
data matches '([.a-zA-Z<>-\uffff0-9_/\-@]*[a-zA-Z<>-\uffff0-9_/\-])':$twocolonaddr,$twocolonaddr
|
||||
data matches '([.a-zA-Z<>-\uffff0-9_/\-@]*[a-zA-Z<>-\uffff0-9_/\-])':$twocolonaddr
|
||||
data matches '([.a-zA-Z<>-\uffff0-9_/\-@]*[a-zA-Z<>-\uffff0-9_/\-])('$addr')?'
|
||||
```
|
||||
|
||||
**Modified patterns (add `=` to character classes):**
|
||||
```
|
||||
data matches '([.a-zA-Z<>-\uffff0-9_/\-@=]*[a-zA-Z<>-\uffff0-9_/\-=])':$twocolonaddr,$twocolonaddr
|
||||
data matches '([.a-zA-Z<>-\uffff0-9_/\-@=]*[a-zA-Z<>-\uffff0-9_/\-=])':$twocolonaddr
|
||||
data matches '([.a-zA-Z<>-\uffff0-9_/\-@=]*[a-zA-Z<>-\uffff0-9_/\-=])('$addr')?'
|
||||
```
|
||||
|
||||
## Extensions
|
||||
|
||||
Some extensions have also been ported. While these extensions, like the main program, try to stay as true as possible to the original program and be as feature-complete as possible, they are intentionally *not* exact replicas.
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ func HandleRenameEvent(f *client.Fsys, identifier, denoteDir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Find old file on disk.
|
||||
pattern := filepath.Join(denoteDir, identifier+"--*")
|
||||
// Find old file on disk (matches with or without signature).
|
||||
pattern := filepath.Join(denoteDir, identifier+"*")
|
||||
matches, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find file: %w", err)
|
||||
|
|
@ -165,7 +165,7 @@ func HandleDeleteEvent(f *client.Fsys, identifier, denoteDir string) error {
|
|||
dir = denoteDir
|
||||
}
|
||||
|
||||
pattern := filepath.Join(dir, identifier+"--*")
|
||||
pattern := filepath.Join(dir, identifier+"*")
|
||||
matches, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find file: %w", err)
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ func SyncAll() error {
|
|||
// Path in metadata doesn't exist - search for actual file on disk
|
||||
// Use the directory from the metadata path (handles subdirs like journal/)
|
||||
dir := filepath.Dir(path)
|
||||
pattern := filepath.Join(dir, identifier+"--*")
|
||||
pattern := filepath.Join(dir, identifier+"*")
|
||||
matches, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
log.Printf("sync: failed to glob for %s: %v", identifier, err)
|
||||
|
|
|
|||
|
|
@ -88,16 +88,16 @@ func ParseFrontMatter(content string, ext string) (*FrontMatter, error) {
|
|||
switch ext {
|
||||
case ".org":
|
||||
fm.FileType = "org"
|
||||
if m := regexp.MustCompile(`(?m)^#\+title:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^#\+title:[ \t]*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Title = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^#\+filetags:\s*:(.+):$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^#\+filetags:[ \t]*:(.+):$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Tags = strings.Split(m[1], ":")
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^#\+identifier:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^#\+identifier:[ \t]*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Identifier = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^#\+signature:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^#\+signature:[ \t]*(.*)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Signature = strings.TrimSpace(m[1])
|
||||
}
|
||||
|
||||
|
|
@ -107,20 +107,20 @@ func ParseFrontMatter(content string, ext string) (*FrontMatter, error) {
|
|||
if m := yamlRe.FindStringSubmatch(text); m != nil {
|
||||
fm.FileType = "md-yaml"
|
||||
yamlContent := m[1]
|
||||
if m := regexp.MustCompile(`(?m)^title:\s*["']?(.+?)["']?$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^title:[ \t]*["']?(.+?)["']?$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
fm.Title = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^tags:\s*\[(.+?)\]$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^tags:[ \t]*\[(.+?)\]$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
tags := strings.Split(m[1], ",")
|
||||
for i, t := range tags {
|
||||
tags[i] = strings.TrimSpace(t)
|
||||
}
|
||||
fm.Tags = tags
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^identifier:\s*["']?(.+?)["']?$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^identifier:[ \t]*["']?(.+?)["']?$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
fm.Identifier = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^signature:\s*["']?(.+?)["']?$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^signature:[ \t]*["']?(.*)["']?$`).FindStringSubmatch(yamlContent); m != nil {
|
||||
fm.Signature = strings.TrimSpace(m[1])
|
||||
}
|
||||
} else {
|
||||
|
|
@ -129,20 +129,20 @@ func ParseFrontMatter(content string, ext string) (*FrontMatter, error) {
|
|||
if m := tomlRe.FindStringSubmatch(text); m != nil {
|
||||
fm.FileType = "md-toml"
|
||||
tomlContent := m[1]
|
||||
if m := regexp.MustCompile(`(?m)^title\s*=\s*["']?(.+?)["']?$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^title[ \t]*=[ \t]*["']?(.+?)["']?$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
fm.Title = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^tags\s*=\s*\[(.+?)\]$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^tags[ \t]*=[ \t]*\[(.+?)\]$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
tags := strings.Split(m[1], ",")
|
||||
for i, t := range tags {
|
||||
tags[i] = strings.TrimSpace(t)
|
||||
}
|
||||
fm.Tags = tags
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^identifier\s*=\s*["']?(.+?)["']?$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^identifier[ \t]*=[ \t]*["']?(.+?)["']?$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
fm.Identifier = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^signature\s*=\s*["']?(.+?)["']?$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^signature[ \t]*=[ \t]*["']?(.*)["']?$`).FindStringSubmatch(tomlContent); m != nil {
|
||||
fm.Signature = strings.TrimSpace(m[1])
|
||||
}
|
||||
}
|
||||
|
|
@ -150,16 +150,16 @@ func ParseFrontMatter(content string, ext string) (*FrontMatter, error) {
|
|||
|
||||
case ".txt":
|
||||
fm.FileType = "txt"
|
||||
if m := regexp.MustCompile(`(?m)^title:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^title:[ \t]*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Title = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^tags:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^tags:[ \t]*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Tags = strings.Fields(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^identifier:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^identifier:[ \t]*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Identifier = strings.TrimSpace(m[1])
|
||||
}
|
||||
if m := regexp.MustCompile(`(?m)^signature:\s*(.+)$`).FindStringSubmatch(text); m != nil {
|
||||
if m := regexp.MustCompile(`(?m)^signature:[ \t]*(.*)$`).FindStringSubmatch(text); m != nil {
|
||||
fm.Signature = strings.TrimSpace(m[1])
|
||||
}
|
||||
}
|
||||
|
|
@ -206,8 +206,8 @@ func UpdateFrontMatter(originalContent string, fm *FrontMatter) (string, error)
|
|||
}
|
||||
|
||||
case "md-yaml":
|
||||
// Replace YAML front matter
|
||||
re := regexp.MustCompile(`(?s)^---\n.*?\n---\n`)
|
||||
// Replace YAML front matter (match trailing blank lines to avoid duplication)
|
||||
re := regexp.MustCompile(`(?s)^---\n.*?\n---\n\n*`)
|
||||
if re.MatchString(text) {
|
||||
newText = re.ReplaceAllString(text, newFrontMatter)
|
||||
} else {
|
||||
|
|
@ -215,8 +215,8 @@ func UpdateFrontMatter(originalContent string, fm *FrontMatter) (string, error)
|
|||
}
|
||||
|
||||
case "md-toml":
|
||||
// Replace TOML front matter
|
||||
re := regexp.MustCompile(`(?s)^\+\+\+\n.*?\n\+\+\+\n`)
|
||||
// Replace TOML front matter (match trailing blank lines to avoid duplication)
|
||||
re := regexp.MustCompile(`(?s)^\+\+\+\n.*?\n\+\+\+\n\n*`)
|
||||
if re.MatchString(text) {
|
||||
newText = re.ReplaceAllString(text, newFrontMatter)
|
||||
} else {
|
||||
|
|
@ -224,8 +224,8 @@ func UpdateFrontMatter(originalContent string, fm *FrontMatter) (string, error)
|
|||
}
|
||||
|
||||
case "txt":
|
||||
// Replace text front matter
|
||||
re := regexp.MustCompile(`(?s)^title:.*?\n-+\n`)
|
||||
// Replace text front matter (match trailing blank lines to avoid duplication)
|
||||
re := regexp.MustCompile(`(?s)^title:.*?\n-+\n\n*`)
|
||||
if re.MatchString(text) {
|
||||
newText = re.ReplaceAllString(text, newFrontMatter)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue