Skip to content

Commit

Permalink
resources/page: Adjust the permalinks colon implementation a little
Browse files Browse the repository at this point in the history
Mostly to get back to an attribute regexp that's reasonably simle to read/understand.

Updates #12918
  • Loading branch information
bep committed Oct 15, 2024
1 parent 56734c4 commit d068ddc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 22 deletions.
54 changes: 32 additions & 22 deletions resources/page/permalinks.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,44 +107,42 @@ func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]ma
return p, nil
}

func (l PermalinkExpander) normalizeEscapeSequences(result string) string {
return strings.ReplaceAll(result, "\\:", ":")
// Escape sequence for colons in permalink patterns.
const escapePlaceholderColon = "\x00"

func (l PermalinkExpander) normalizeEscapeSequencesIn(s string) (string, bool) {
s2 := strings.ReplaceAll(s, "\\:", escapePlaceholderColon)
return s2, s2 != s
}

func (l PermalinkExpander) normalizeEscapeSequencesOut(result string) string {
return strings.ReplaceAll(result, escapePlaceholderColon, ":")
}

// ExpandPattern expands the path in p with the specified expand pattern.
func (l PermalinkExpander) ExpandPattern(pattern string, p Page) (string, error) {
expander, err := l.getOrParsePattern(pattern)
expand, err := l.getOrParsePattern(pattern)
if err != nil {
return "", err
}

result, err := expander(p)
if err != nil {
return "", err
}
return l.normalizeEscapeSequences(result), nil
return expand(p)
}

// Expand expands the path in p according to the rules defined for the given key.
// If no rules are found for the given key, an empty string is returned.
func (l PermalinkExpander) Expand(key string, p Page) (string, error) {
expanders, found := l.expanders[p.Kind()]

if !found {
return "", nil
}

expand, found := expanders[key]

if !found {
return "", nil
}

result, err := expand(p)
if err != nil {
return "", err
}
return l.normalizeEscapeSequences(result), nil
return expand(p)
}

// Allow " " and / to represent the root section.
Expand All @@ -161,12 +159,24 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
if !l.validate(pattern) {
return nil, &permalinkExpandError{pattern: pattern, err: errPermalinkIllFormed}
}
var normalized bool
pattern, normalized = l.normalizeEscapeSequencesIn(pattern)

matches := attributeRegexp.FindAllStringSubmatch(pattern, -1)
if matches == nil {
result := pattern
if normalized {
result = l.normalizeEscapeSequencesOut(result)
}
return func(p Page) (string, error) {
return result, nil
}, nil
}

callbacks := make([]pageToPermaAttribute, len(matches))
replacements := make([]string, len(matches))
for i, m := range matches {
replacement := m[1]
replacement := m[0]
attr := replacement[1:]
replacements[i] = replacement
callback, ok := l.callback(attr)
Expand All @@ -179,10 +189,6 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
}

return func(p Page) (string, error) {
if matches == nil {
return pattern, nil
}

newField := pattern

for i, replacement := range replacements {
Expand All @@ -196,6 +202,10 @@ func (l PermalinkExpander) getOrParsePattern(pattern string) (func(Page) (string
newField = strings.Replace(newField, replacement, newAttr, 1)
}

if normalized {
newField = l.normalizeEscapeSequencesOut(newField)
}

return newField, nil
}, nil
})
Expand All @@ -222,7 +232,7 @@ func (l PermalinkExpander) parse(patterns map[string]string) (map[string]func(Pa
// can return a string to go in that position in the page (or an error)
type pageToPermaAttribute func(Page, string) (string, error)

var attributeRegexp = regexp.MustCompile(`(?:^|[^\\])(:\w+(?:\[.+?])?)`)
var attributeRegexp = regexp.MustCompile(`:\w+(\[.+?\])?`)

// validate determines if a PathPattern is well-formed
func (l PermalinkExpander) validate(pp string) bool {
Expand All @@ -246,7 +256,7 @@ func (l PermalinkExpander) validate(pp string) bool {
}

for _, match := range matches {
k := match[1][1:]
k := match[0][1:]
if _, ok := l.callback(k); !ok {
return false
}
Expand Down
4 changes: 4 additions & 0 deletions resources/page/permalinks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ func TestPermalinkExpansion(t *testing.T) {
expanded, err := expander.Expand("posts", page)
c.Assert(err, qt.IsNil)
c.Assert(expanded, qt.Equals, item.expandsTo)

expanded, err = expander.ExpandPattern(item.spec, page)
c.Assert(err, qt.IsNil)
c.Assert(expanded, qt.Equals, item.expandsTo)
})

}
Expand Down

0 comments on commit d068ddc

Please sign in to comment.