tpl/strings: Add findRESubmatch - hugo - [fork] hugo port for 9front
 (HTM) git clone git@git.drkhsh.at/hugo.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 2fb40ece5df38c3d6565cfd69ae194dbe0126f53
 (DIR) parent c6b3887696162335d806ff25e9b9db27d73611de
 (HTM) Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Tue, 17 Jan 2023 09:35:16 +0100
       
       tpl/strings: Add findRESubmatch
       
       Fixes #10594
       
       Diffstat:
         M tpl/internal/templatefuncsRegistry… |       5 +++++
         M tpl/strings/init.go                 |      12 +++++++++++-
         M tpl/strings/regexp.go               |      25 +++++++++++++++++++++++++
         M tpl/strings/regexp_test.go          |      33 +++++++++++++++++++++++++++++++
       
       4 files changed, 74 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/tpl/internal/templatefuncsRegistry.go b/tpl/internal/templatefuncsRegistry.go
       @@ -66,6 +66,11 @@ func (t *TemplateFuncsNamespace) AddMethodMapping(m any, aliases []string, examp
        
                name := methodToName(m)
        
       +        // Rewrite §§ to ` in example commands.
       +        for i, e := range examples {
       +                examples[i][0] = strings.ReplaceAll(e[0], "§§", "`")
       +        }
       +
                // sanity check
                for _, e := range examples {
                        if e[0] == "" {
 (DIR) diff --git a/tpl/strings/init.go b/tpl/strings/init.go
       @@ -78,12 +78,22 @@ func init() {
                                []string{"findRE"},
                                [][2]string{
                                        {
       -                                        `{{ findRE "[G|g]o" "Hugo is a static side generator written in Go." "1" }}`,
       +                                        `{{ findRE "[G|g]o" "Hugo is a static side generator written in Go." 1 }}`,
                                                `[go]`,
                                        },
                                },
                        )
        
       +                ns.AddMethodMapping(ctx.FindRESubmatch,
       +                        []string{"findRESubmatch"},
       +                        [][2]string{
       +                                {
       +                                        `{{ findRESubmatch §§<a\s*href="(.+?)">(.+?)</a>§§ §§<li><a href="#foo">Foo</a></li> <li><a href="#bar">Bar</a></li>§§ | print | safeHTML }}`,
       +                                        "[[<a href=\"#foo\">Foo</a> #foo Foo] [<a href=\"#bar\">Bar</a> #bar Bar]]",
       +                                },
       +                        },
       +                )
       +
                        ns.AddMethodMapping(ctx.HasPrefix,
                                []string{"hasPrefix"},
                                [][2]string{
 (DIR) diff --git a/tpl/strings/regexp.go b/tpl/strings/regexp.go
       @@ -45,6 +45,31 @@ func (ns *Namespace) FindRE(expr string, content any, limit ...any) ([]string, e
                return re.FindAllString(conv, lim), nil
        }
        
       +// FindRESubmatch returns returns a slice of strings holding the text of the leftmost match of the regular expression in s and the matches, if any, of its subexpressions.
       +//
       +// By default all matches will be included. The number of matches can be limited with the optional limit parameter. A return value of nil indicates no match.
       +func (ns *Namespace) FindRESubmatch(expr string, content any, limit ...any) ([][]string, error) {
       +        re, err := reCache.Get(expr)
       +        if err != nil {
       +                return nil, err
       +        }
       +
       +        conv, err := cast.ToStringE(content)
       +        if err != nil {
       +                return nil, err
       +        }
       +        n := -1
       +        if len(limit) > 0 {
       +                n, err = cast.ToIntE(limit[0])
       +                if err != nil {
       +                        return nil, err
       +                }
       +        }
       +
       +        return re.FindAllStringSubmatch(conv, n), nil
       +
       +}
       +
        // ReplaceRE returns a copy of s, replacing all matches of the regular
        // expression pattern with the replacement text repl. The number of replacements
        // can be limited with an optional fourth parameter.
 (DIR) diff --git a/tpl/strings/regexp_test.go b/tpl/strings/regexp_test.go
       @@ -50,6 +50,39 @@ func TestFindRE(t *testing.T) {
                }
        }
        
       +func TestFindRESubmatch(t *testing.T) {
       +        t.Parallel()
       +        c := qt.New(t)
       +
       +        for _, test := range []struct {
       +                expr    string
       +                content any
       +                limit   any
       +                expect  any
       +        }{
       +                {`<a\s*href="(.+?)">(.+?)</a>`, `<li><a href="#foo">Foo</a></li><li><a href="#bar">Bar</a></li>`, -1, [][]string{
       +                        {"<a href=\"#foo\">Foo</a>", "#foo", "Foo"},
       +                        {"<a href=\"#bar\">Bar</a>", "#bar", "Bar"},
       +                }},
       +                // Some simple cases.
       +                {"([G|g]o)", "Hugo is a static site generator written in Go.", -1, [][]string{{"go", "go"}, {"Go", "Go"}}},
       +                {"([G|g]o)", "Hugo is a static site generator written in Go.", 1, [][]string{{"go", "go"}}},
       +
       +                // errors
       +                {"([G|go", "Hugo is a static site generator written in Go.", nil, false},
       +                {"([G|g]o)", t, nil, false},
       +        } {
       +                result, err := ns.FindRESubmatch(test.expr, test.content, test.limit)
       +
       +                if b, ok := test.expect.(bool); ok && !b {
       +                        c.Assert(err, qt.Not(qt.IsNil))
       +                        continue
       +                }
       +
       +                c.Assert(err, qt.IsNil)
       +                c.Check(result, qt.DeepEquals, test.expect)
       +        }
       +}
        func TestReplaceRE(t *testing.T) {
                t.Parallel()
                c := qt.New(t)