Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ae364aa
ListItem Render Hook
alexanderhansen Apr 26, 2022
acc3263
Update Tests
alexanderhansen May 2, 2022
4a659ee
Merge branch 'gohugoio:master' into listitem-render-hook
alexanderhansen May 2, 2022
106caac
ListItem Render Hook
alexanderhansen Apr 26, 2022
e751003
Update Tests
alexanderhansen May 2, 2022
b143fa6
Merge branch 'listitem-render-hook' of https://github.com/alexanderha…
alexanderhansen May 2, 2022
5e0eba9
List Render Hook
alexanderhansen May 2, 2022
5130a3d
With ordered parameter
alexanderhansen May 2, 2022
c025e3f
ListItem has no attributes
alexanderhansen May 2, 2022
156e671
Test for attributes
alexanderhansen May 2, 2022
5757d1d
First and Last sibling check for listitems
alexanderhansen May 5, 2022
1c954b9
Borrowed from Goldmark
alexanderhansen May 5, 2022
0de16a5
ListItem Render Hook
alexanderhansen Apr 26, 2022
b04f772
Update Tests
alexanderhansen May 2, 2022
595c696
List Render Hook
alexanderhansen May 2, 2022
9d3616a
With ordered parameter
alexanderhansen May 2, 2022
5e38325
ListItem has no attributes
alexanderhansen May 2, 2022
6ccad18
Test for attributes
alexanderhansen May 2, 2022
433d9cf
First and Last sibling check for listitems
alexanderhansen May 5, 2022
600e5a5
Borrowed from Goldmark
alexanderhansen May 5, 2022
4266674
Merge branch 'listitem-render-hook' of https://github.com/alexanderha…
alexanderhansen May 5, 2022
9199981
docs
alexanderhansen May 5, 2022
db2a4ca
Delete devcontainer.json
alexanderhansen May 5, 2022
3cb278b
Merge branch 'gohugoio:master' into listitem-render-hook
alexanderhansen Aug 3, 2022
c85708b
Merge branch 'gohugoio:master' into listitem-render-hook
alexanderhansen Dec 8, 2022
398be2d
Merge branch 'gohugoio:master' into listitem-render-hook
alexanderhansen Apr 6, 2023
3b2b6b1
Add Context to Renderer
alexanderhansen Apr 6, 2023
967447f
Merge branch 'gohugoio:master' into listitem-render-hook
alexanderhansen Apr 14, 2023
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
ListItem Render Hook
  • Loading branch information
alexanderhansen committed Apr 26, 2022
commit ae364aa929e9e74703de361d22127cd4837b5b82
15 changes: 13 additions & 2 deletions hugolib/content_render_hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Inner Block: {{ .Inner | .Page.RenderString (dict "display" "block" ) }}
b.WithTemplatesAdded("_default/_markup/render-image.html", `IMAGE: {{ .Page.Title }}||{{ .Destination | safeURL }}|Title: {{ .Title | safeHTML }}|Text: {{ .Text | safeHTML }}|END`)
b.WithTemplatesAdded("_default/_markup/render-heading.html", `HEADING: {{ .Page.Title }}||Level: {{ .Level }}|Anchor: {{ .Anchor | safeURL }}|Text: {{ .Text | safeHTML }}|Attributes: {{ .Attributes }}|END`)
b.WithTemplatesAdded("docs/_markup/render-heading.html", `Docs Level: {{ .Level }}|END`)

b.WithTemplatesAdded("_default/_markup/render-listitem.html", `LISTITEM: {{ .Text | safeHTML }} {{ .Attributes }} {{ .FirstChild }} {{ .Parent }}`)
b.WithContent("customview/p1.md", `---
title: Custom View
---
Expand Down Expand Up @@ -196,6 +196,13 @@ title: Doc With Heading

# Docs lvl 1

`, "blog/p9.md", `---
title: With List Items
---
- Dog
- Cat
- Mouse
- Bird{ parrot=true }
`,
)

Expand All @@ -210,7 +217,7 @@ title: No Template
}
counters := &testCounters{}
b.Build(BuildCfg{testCounters: counters})
b.Assert(int(counters.contentRenderCounter), qt.Equals, 45)
b.Assert(int(counters.contentRenderCounter), qt.Equals, 46)

b.AssertFileContent("public/blog/p1/index.html", `
Cool Page|https://www.google.com|Title: Google's Homepage|Text: First Link|END
Expand Down Expand Up @@ -265,6 +272,10 @@ SHORT3|

// https://github.com/gohugoio/hugo/issues/7349
b.AssertFileContent("public/docs/p8/index.html", "Docs Level: 1")

b.AssertFileContent("public/blog/p9/index.html", "LISTITEM: Dog")
b.AssertFileContent("public/blog/p9/index.html", "LISTITEM: Cat")
b.AssertFileContent("public/blog/p9/index.html", "LISTITEM: Mouse")
}

func TestRenderHooksDeleteTemplate(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions hugolib/page__per_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ func (p *pageContentOutput) initRenderHooks() error {
layoutDescriptor.KindVariants = lang
}
}
case hooks.ListItemRendererType:
layoutDescriptor.Kind = "render-listitem"
}

getHookTemplate := func(f output.Format) (tpl.Template, bool) {
Expand Down
4 changes: 4 additions & 0 deletions hugolib/site.go
Original file line number Diff line number Diff line change
Expand Up @@ -1804,6 +1804,10 @@ func (hr hookRendererTemplate) RenderCodeblock(w hugio.FlexiWriter, ctx hooks.Co
return hr.templateHandler.Execute(hr.templ, w, ctx)
}

func (hr hookRendererTemplate) RenderListItem(w io.Writer, ctx hooks.ListItemContext) error {
return hr.templateHandler.Execute(hr.templ, w, ctx)
}

func (hr hookRendererTemplate) ResolvePosition(ctx any) text.Position {
return hr.resolvePosition(ctx)
}
Expand Down
17 changes: 17 additions & 0 deletions markup/converter/hooks/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ type HeadingRenderer interface {
identity.Provider
}

type ListItemContext interface {
Page() interface{}
Text() hstring.RenderedString
PlainText() string
Offset() int
FirstChild() interface{}
Parent() interface{}

AttributesProvider
}

type ListItemRenderer interface {
RenderListItem(w io.Writer, ctx ListItemContext) error
identity.Provider
}

// ElementPositionResolver provides a way to resolve the start Position
// of a markdown element in the original source document.
// This may be both slow and approximate, so should only be
Expand All @@ -106,6 +122,7 @@ const (
ImageRendererType
HeadingRendererType
CodeBlockRendererType
ListItemRendererType
)

type GetRendererFunc func(t RendererType, id any) any
96 changes: 96 additions & 0 deletions markup/goldmark/render_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,40 @@ func (ctx headingContext) PlainText() string {
return ctx.plainText
}

type listItemContext struct {
page interface{}
text hstring.RenderedString
plainText string
offset int
firstChild interface{}
parent interface{}
*attributes.AttributesHolder
}

func (ctx listItemContext) Page() interface{} {
return ctx.page
}

func (ctx listItemContext) Text() hstring.RenderedString {
return ctx.text
}

func (ctx listItemContext) PlainText() string {
return ctx.plainText
}

func (ctx listItemContext) Offset() int {
return ctx.offset
}

func (ctx listItemContext) FirstChild() interface{} {
return ctx.firstChild
}

func (ctx listItemContext) Parent() interface{} {
return ctx.parent
}

type hookedRenderer struct {
linkifyProtocol []byte
html.Config
Expand All @@ -122,6 +156,7 @@ func (r *hookedRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer)
reg.Register(ast.KindAutoLink, r.renderAutoLink)
reg.Register(ast.KindImage, r.renderImage)
reg.Register(ast.KindHeading, r.renderHeading)
reg.Register(ast.KindListItem, r.renderListItem)
}

func (r *hookedRenderer) renderImage(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
Expand Down Expand Up @@ -410,6 +445,67 @@ func (r *hookedRenderer) renderHeadingDefault(w util.BufWriter, source []byte, n
return ast.WalkContinue, nil
}

func (r *hookedRenderer) renderListItem(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*ast.ListItem)
n.FirstChild()
var hli hooks.ListItemRenderer

ctx, ok := w.(*render.Context)
if ok {
h := ctx.RenderContext().GetRenderer(hooks.ListItemRendererType, nil)
ok = h != nil
if ok {
hli = h.(hooks.ListItemRenderer)
}
}

if !ok {
return r.renderListItemDefault(w, source, node, entering)
}

if entering {
// Store the current pos so we can capture the rendered text.
ctx.PushPos(ctx.Buffer.Len())
return ast.WalkContinue, nil
}

pos := ctx.PopPos()
text := ctx.Buffer.Bytes()[pos:]
ctx.Buffer.Truncate(pos)

err := hli.RenderListItem(
w,
listItemContext{
page: ctx.DocumentContext().Document,
text: hstring.RenderedString(text),
plainText: string(n.Text(source)),
offset: int(n.Offset),
firstChild: n.FirstChild(),
parent: n.Parent(),
AttributesHolder: attributes.New(n.Attributes(), attributes.AttributesOwnerGeneral),
},
)

ctx.AddIdentity(hli)

return ast.WalkContinue, err
}

func (r *hookedRenderer) renderListItemDefault(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
if entering {
_, _ = w.WriteString("<li>")
fc := n.FirstChild()
if fc != nil {
if _, ok := fc.(*ast.TextBlock); !ok {
_ = w.WriteByte('\n')
}
}
} else {
_, _ = w.WriteString("</li>\n")
}
return ast.WalkContinue, nil
}

type links struct {
cfg goldmark_config.Config
}
Expand Down