From 3990586a85e91923c0a3ae1a1f0f61420db555ac Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 14 Sep 2026 23:34:51 +0200 Subject: captures keep the name's diacritics --- internal/cond/eval.go | 30 +++++++++++++++++++++++------- internal/cond/eval_test.go | 17 +++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'internal/cond') diff --git a/internal/cond/eval.go b/internal/cond/eval.go index b0ee828..f241504 100644 --- a/internal/cond/eval.go +++ b/internal/cond/eval.go @@ -164,17 +164,33 @@ func (c *Cond) evalLeaf(n *node, f Facts) (ok bool, reason, warn string, caps [] subj = f.Rel() word = "path" } - subj = norm.Name(subj, c.opt.Fold) + if n.kind == kPath { + subj = norm.Name(subj, c.opt.Fold) + for _, p := range n.patterns { + if p.re.MatchString(subj) { + return true, word + ` "` + p.src + `"`, "", nil + } + } + return false, "", "", nil + } + // A name test matches the folded name, but its captures are read + // back from the original, so {1} keeps the name's diacritics. + folded := norm.Folded{Text: subj} + if c.opt.Fold { + folded = norm.FoldMapped(subj) + } for _, p := range n.patterns { - m := p.re.FindStringSubmatch(subj) - if m == nil { + loc := p.re.FindStringSubmatchIndex(folded.Text) + if loc == nil { continue } - reason = word + ` "` + p.src + `"` - if n.kind == kName { - return true, reason, "", m + caps := make([]string, len(loc)/2) + for g := range caps { + if loc[2*g] >= 0 { + caps[g] = folded.Source(loc[2*g], loc[2*g+1]) + } } - return true, reason, "", nil + return true, word + ` "` + p.src + `"`, "", caps } return false, "", "", nil diff --git a/internal/cond/eval_test.go b/internal/cond/eval_test.go index 88612ac..2e8bcfd 100644 --- a/internal/cond/eval_test.go +++ b/internal/cond/eval_test.go @@ -240,3 +240,20 @@ func TestEvalReportsUnreadableContent(t *testing.T) { t.Errorf("not reached: Match %v Unreadable %v; want true, false", r.Match, r.Unreadable) } } + +// TestCapturesKeepDiacritics: a name test matches the folded name, but its +// captures are the original name's characters, so {1} keeps "Łódź". +func TestCapturesKeepDiacritics(t *testing.T) { + f := &fake{name: "Łódź-Faktura.pdf"} + r := eval(t, `(name "^(.+)-faktura")`, Options{IgnoreCase: true, Fold: true}, f) + if !r.Match { + t.Fatal("no match") + } + if want := []string{"Łódź-Faktura", "Łódź"}; !reflect.DeepEqual(r.Captures, want) { + t.Errorf("captures = %q, want %q", r.Captures, want) + } + r = eval(t, `(name "^(lodz)?(x)?-")`, Options{IgnoreCase: true, Fold: true}, f) + if want := []string{"Łódź-", "Łódź", ""}; !reflect.DeepEqual(r.Captures, want) { + t.Errorf("captures with a group that did not take part = %q, want %q", r.Captures, want) + } +} -- cgit v1.3