mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
tpl: Add findRE template func
This commit is contained in:
parent
54750b0780
commit
5bfe16ef8d
3 changed files with 73 additions and 0 deletions
|
@ -474,6 +474,36 @@ Pluralize the given word with a set of common English pluralization rules.
|
||||||
|
|
||||||
e.g. `{{ "cat" | pluralize }}` → "cats"
|
e.g. `{{ "cat" | pluralize }}` → "cats"
|
||||||
|
|
||||||
|
### findRE
|
||||||
|
Returns a list of strings that match the regular expression. By default all matches will be included. The number of matches can be limitted with an optional third parameter.
|
||||||
|
|
||||||
|
The example below returns a list of all second level headers (`<h2>`) in the content:
|
||||||
|
|
||||||
|
{{ findRE "<h2.*?>(.|\n)*?</h2>" .Content }}
|
||||||
|
|
||||||
|
We can limit the number of matches in that list with a third parameter. Let's say we want to have at most one match (or none if no substring matched):
|
||||||
|
|
||||||
|
{{ findRE "<h2.*?>(.|\n)*?</h2>" .Content 1 }}
|
||||||
|
<!-- returns ["<h2 id="#foo">Foo</h2>"] -->
|
||||||
|
|
||||||
|
`findRe` allows us to build an automatically generated table of contents that could be used for a simple scrollspy:
|
||||||
|
|
||||||
|
{{ $headers := findRE "<h2.*?>(.|\n)*?</h2>" .Content }}
|
||||||
|
|
||||||
|
{{ if ge (len $headers) 1 }}
|
||||||
|
<ul>
|
||||||
|
{{ range $headers }}
|
||||||
|
<li>
|
||||||
|
<a href="#{{ . | plainify | urlize }}">
|
||||||
|
{{ . | plainify }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
First, we try to find all second-level headers and generate a list if at least one header was found. `plainify` strips the HTML and `urlize` converts the header into an a valid URL.
|
||||||
|
|
||||||
### replace
|
### replace
|
||||||
Replaces all occurrences of the search string with the replacement string.
|
Replaces all occurrences of the search string with the replacement string.
|
||||||
|
|
||||||
|
|
|
@ -437,6 +437,22 @@ func first(limit interface{}, seq interface{}) (interface{}, error) {
|
||||||
return seqv.Slice(0, limitv).Interface(), nil
|
return seqv.Slice(0, limitv).Interface(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// findRE returns a list of strings that match the regular expression. By default all matches
|
||||||
|
// will be included. The number of matches can be limitted with an optional third parameter.
|
||||||
|
func findRE(expr string, content interface{}, limit ...int) ([]string, error) {
|
||||||
|
re, err := reCache.Get(expr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
conv := cast.ToString(content)
|
||||||
|
if len(limit) > 0 {
|
||||||
|
return re.FindAllString(conv, limit[0]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return re.FindAllString(conv, -1), nil
|
||||||
|
}
|
||||||
|
|
||||||
// last returns the last N items in a rangeable list.
|
// last returns the last N items in a rangeable list.
|
||||||
func last(limit interface{}, seq interface{}) (interface{}, error) {
|
func last(limit interface{}, seq interface{}) (interface{}, error) {
|
||||||
if limit == nil || seq == nil {
|
if limit == nil || seq == nil {
|
||||||
|
@ -1729,6 +1745,7 @@ func init() {
|
||||||
"echoParam": returnWhenSet,
|
"echoParam": returnWhenSet,
|
||||||
"emojify": emojify,
|
"emojify": emojify,
|
||||||
"eq": eq,
|
"eq": eq,
|
||||||
|
"findRE": findRE,
|
||||||
"first": first,
|
"first": first,
|
||||||
"ge": ge,
|
"ge": ge,
|
||||||
"getCSV": getCSV,
|
"getCSV": getCSV,
|
||||||
|
|
|
@ -89,6 +89,7 @@ delimit: {{ delimit (slice "A" "B" "C") ", " " and " }}
|
||||||
div: {{div 6 3}}
|
div: {{div 6 3}}
|
||||||
emojify: {{ "I :heart: Hugo" | emojify }}
|
emojify: {{ "I :heart: Hugo" | emojify }}
|
||||||
eq: {{ if eq .Section "blog" }}current{{ end }}
|
eq: {{ if eq .Section "blog" }}current{{ end }}
|
||||||
|
findRE: {{ findRE "[G|g]o" "Hugo is a static side generator written in Go." 1 }}
|
||||||
hasPrefix 1: {{ hasPrefix "Hugo" "Hu" }}
|
hasPrefix 1: {{ hasPrefix "Hugo" "Hu" }}
|
||||||
hasPrefix 2: {{ hasPrefix "Hugo" "Fu" }}
|
hasPrefix 2: {{ hasPrefix "Hugo" "Fu" }}
|
||||||
in: {{ if in "this string contains a substring" "substring" }}Substring found!{{ end }}
|
in: {{ if in "this string contains a substring" "substring" }}Substring found!{{ end }}
|
||||||
|
@ -138,6 +139,7 @@ delimit: A, B and C
|
||||||
div: 2
|
div: 2
|
||||||
emojify: I ❤️ Hugo
|
emojify: I ❤️ Hugo
|
||||||
eq: current
|
eq: current
|
||||||
|
findRE: [go]
|
||||||
hasPrefix 1: true
|
hasPrefix 1: true
|
||||||
hasPrefix 2: false
|
hasPrefix 2: false
|
||||||
in: Substring found!
|
in: Substring found!
|
||||||
|
@ -1801,6 +1803,30 @@ func TestReplaceRE(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindRE(t *testing.T) {
|
||||||
|
for i, this := range []struct {
|
||||||
|
expr string
|
||||||
|
content string
|
||||||
|
limit int
|
||||||
|
expect []string
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{"[G|g]o", "Hugo is a static side generator written in Go.", 2, []string{"go", "Go"}, true},
|
||||||
|
{"[G|g]o", "Hugo is a static side generator written in Go.", -1, []string{"go", "Go"}, true},
|
||||||
|
{"[G|g]o", "Hugo is a static side generator written in Go.", 1, []string{"go"}, true},
|
||||||
|
{"[G|g]o", "Hugo is a static side generator written in Go.", 0, []string(nil), true},
|
||||||
|
{"[G|go", "Hugo is a static side generator written in Go.", 0, []string(nil), false},
|
||||||
|
} {
|
||||||
|
res, err := findRE(this.expr, this.content, this.limit)
|
||||||
|
|
||||||
|
if err != nil && this.ok {
|
||||||
|
t.Errorf("[%d] returned an unexpected error: %s", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, this.expect, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTrim(t *testing.T) {
|
func TestTrim(t *testing.T) {
|
||||||
|
|
||||||
for i, this := range []struct {
|
for i, this := range []struct {
|
||||||
|
|
Loading…
Reference in a new issue