hugo version)?$ hugo version Hugo Static Site Generator v0.75.0-FEF924BA windows/amd64 BuildDate: 2020-09-14T09:19:16Z
Not tested.
Looking at this page of the documentation:
https://gohugo.io/functions/substr/
It says: "To extract characters from the end of the string, use a negative start number."
I was expecting this to happen, like the substr PHP function:
{{substr "BatMan" -3}} → "Man"
{{substr "BatMan" -2}} → "an"
Yet, I got errors
{{substr "BatMan" -3}}
execute of template failed: template: partials/test.html:1:3: executing "partials/test.html" at <substr "BatMan" -3>: error calling substr: runtime error: slice bounds out of range **[-2:]**
{{substr "BatMan" -2}}
execute of template failed: template: partials/test.html:1:3: executing "partials/test.html" at <substr "BatMan" -3>: error calling substr: runtime error: slice bounds out of range **[-1:]**
This one is working and returning the full string
{{substr "BatMan" -1}} → "BatMan"
{{ substr "BatMan" -1 3 }} → "Man"
{{ substr "BatMan" -2 3 }} → "tMa"
{{ substr "BatMan" -3 3 }} → "atM"
With a negative start number you're saying, "Start this many characters from the end, and go backwards this many characters."
This is not coherent with any other programming languages.
How one can know that -1 means the end of the string and -2 means 1 char from the end. Because if I follow your logic, then -1 should mean start 1 character from the end.
At least an example should be added to the doc
I agree. I expected {{ substr "BatMan" -2 }} to yield an.
OK, so the documentation now shows the current behavior, but I'm not sure if the current behavior is correct for this example:
{{ substr "BatMan" -3 3 }} → "atM"
Shouldn't this be "Man" instead? There's a test for this in strings_test.go, but I think the test is wrong:
{"abcdef", -3, 3, "bcd"},
Shouldn't this be "def" instead?
We're extracting backward instead of forward when the start number is negative, but I think we should always be extracting forward (left to right).
EDIT: I think Python goes right to left with a negative start number. Perhaps we're modeling that behavior.
@moorereason,
Thank you for addressing this. There is one remaining problem.
Statement|Expected Return|Actual Return
--|--|--
substr "abcdef" 0 0|empty string|abcdef
substr "abcdef" 1 0|empty string|bcdef
substr "abcdef" -1 0|empty string|f
If length is zero, you should always get an empty string. This matches PHP substr behavior.
Thanks, @jmooring. I've submitted a new PR to fix that case.
Most helpful comment
Thanks, @jmooring. I've submitted a new PR to fix that case.