summaryrefslogtreecommitdiffstats
path: root/hugolib/shortcode.go
diff options
context:
space:
mode:
Diffstat (limited to 'hugolib/shortcode.go')
-rw-r--r--hugolib/shortcode.go58
1 files changed, 42 insertions, 16 deletions
diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go
index 77c5b4e7e..c5125f717 100644
--- a/hugolib/shortcode.go
+++ b/hugolib/shortcode.go
@@ -28,6 +28,7 @@ import (
"sync"
"github.com/gohugoio/hugo/common/herrors"
+ "github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/parser/pageparser"
"github.com/gohugoio/hugo/resources/page"
@@ -43,7 +44,7 @@ import (
var (
_ urls.RefLinker = (*ShortcodeWithPage)(nil)
- _ pageWrapper = (*ShortcodeWithPage)(nil)
+ _ types.Unwrapper = (*ShortcodeWithPage)(nil)
_ text.Positioner = (*ShortcodeWithPage)(nil)
)
@@ -175,15 +176,16 @@ func (scp *ShortcodeWithPage) Get(key any) any {
return x.Interface()
}
-func (scp *ShortcodeWithPage) page() page.Page {
+// For internal use only.
+func (scp *ShortcodeWithPage) Unwrapv() any {
return scp.Page
}
// Note - this value must not contain any markup syntax
const shortcodePlaceholderPrefix = "HAHAHUGOSHORTCODE"
-func createShortcodePlaceholder(sid string, id, ordinal int) string {
- return shortcodePlaceholderPrefix + strconv.Itoa(id) + sid + strconv.Itoa(ordinal) + "HBHB"
+func createShortcodePlaceholder(sid string, id uint64, ordinal int) string {
+ return shortcodePlaceholderPrefix + strconv.FormatUint(id, 10) + sid + strconv.Itoa(ordinal) + "HBHB"
}
type shortcode struct {
@@ -193,7 +195,6 @@ type shortcode struct {
inner []any // string or nested shortcode
params any // map or array
ordinal int
- err error
indentation string // indentation from source.
@@ -271,9 +272,8 @@ func (sc shortcode) String() string {
}
type shortcodeHandler struct {
- p *pageState
-
- s *Site
+ filename string
+ s *Site
// Ordered list of shortcodes for a page.
shortcodes []*shortcode
@@ -286,9 +286,9 @@ type shortcodeHandler struct {
enableInlineShortcodes bool
}
-func newShortcodeHandler(p *pageState, s *Site) *shortcodeHandler {
+func newShortcodeHandler(filename string, s *Site) *shortcodeHandler {
sh := &shortcodeHandler{
- p: p,
+ filename: filename,
s: s,
enableInlineShortcodes: s.ExecHelper.Sec().EnableInlineShortcodes,
shortcodes: make([]*shortcode, 0, 4),
@@ -312,14 +312,16 @@ func prepareShortcode(
sc *shortcode,
parent *ShortcodeWithPage,
p *pageState,
+ isRenderString bool,
) (shortcodeRenderer, error) {
toParseErr := func(err error) error {
- return p.parseError(fmt.Errorf("failed to render shortcode %q: %w", sc.name, err), p.source.parsed.Input(), sc.pos)
+ source := p.content.mustSource()
+ return p.parseError(fmt.Errorf("failed to render shortcode %q: %w", sc.name, err), source, sc.pos)
}
// Allow the caller to delay the rendering of the shortcode if needed.
var fn shortcodeRenderFunc = func(ctx context.Context) ([]byte, bool, error) {
- r, err := doRenderShortcode(ctx, level, s, tplVariants, sc, parent, p)
+ r, err := doRenderShortcode(ctx, level, s, tplVariants, sc, parent, p, isRenderString)
if err != nil {
return nil, false, toParseErr(err)
}
@@ -341,6 +343,7 @@ func doRenderShortcode(
sc *shortcode,
parent *ShortcodeWithPage,
p *pageState,
+ isRenderString bool,
) (shortcodeRenderer, error) {
var tmpl tpl.Template
@@ -354,13 +357,16 @@ func doRenderShortcode(
if !p.s.ExecHelper.Sec().EnableInlineShortcodes {
return zeroShortcode, nil
}
- templName := path.Join("_inline_shortcode", p.File().Path(), sc.name)
+ templName := path.Join("_inline_shortcode", p.Path(), sc.name)
if sc.isClosing {
templStr := sc.innerString()
var err error
tmpl, err = s.TextTmpl().Parse(templName, templStr)
if err != nil {
+ if isRenderString {
+ return zeroShortcode, p.wrapError(err)
+ }
fe := herrors.NewFileErrorFromName(err, p.File().Filename())
pos := fe.Position()
pos.LineNumber += p.posOffset(sc.pos).LineNumber
@@ -376,6 +382,7 @@ func doRenderShortcode(
return zeroShortcode, fmt.Errorf("no earlier definition of shortcode %q found", sc.name)
}
}
+ tmpl = tpl.AddIdentity(tmpl)
} else {
var found, more bool
tmpl, found, more = s.Tmpl().LookupVariant(sc.name, tplVariants)
@@ -398,7 +405,7 @@ func doRenderShortcode(
case string:
inner += innerData
case *shortcode:
- s, err := prepareShortcode(ctx, level+1, s, tplVariants, innerData, data, p)
+ s, err := prepareShortcode(ctx, level+1, s, tplVariants, innerData, data, p, isRenderString)
if err != nil {
return zeroShortcode, err
}
@@ -505,7 +512,7 @@ func (s *shortcodeHandler) hasName(name string) bool {
return ok
}
-func (s *shortcodeHandler) prepareShortcodesForPage(ctx context.Context, p *pageState, f output.Format) (map[string]shortcodeRenderer, error) {
+func (s *shortcodeHandler) prepareShortcodesForPage(ctx context.Context, p *pageState, f output.Format, isRenderString bool) (map[string]shortcodeRenderer, error) {
rendered := make(map[string]shortcodeRenderer)
tplVariants := tpl.TemplateVariants{
@@ -514,7 +521,7 @@ func (s *shortcodeHandler) prepareShortcodesForPage(ctx context.Context, p *page
}
for _, v := range s.shortcodes {
- s, err := prepareShortcode(ctx, 0, s.s, tplVariants, v, nil, p)
+ s, err := prepareShortcode(ctx, 0, s.s, tplVariants, v, nil, p, isRenderString)
if err != nil {
return nil, err
}
@@ -525,6 +532,25 @@ func (s *shortcodeHandler) prepareShortcodesForPage(ctx context.Context, p *page
return rendered, nil
}
+func posFromInput(filename string, input []byte, offset int) text.Position {
+ if offset < 0 {
+ return text.Position{
+ Filename: filename,
+ }
+ }
+ lf := []byte("\n")
+ input = input[:offset]
+ lineNumber := bytes.Count(input, lf) + 1
+ endOfLastLine := bytes.LastIndex(input, lf)
+
+ return text.Position{
+ Filename: filename,
+ LineNumber: lineNumber,
+ ColumnNumber: offset - endOfLastLine,
+ Offset: offset,
+ }
+}
+
// pageTokens state:
// - before: positioned just before the shortcode start
// - after: shortcode(s) consumed (plural when they are nested)