Pi66

Home | Repos | About | Blog | Gaza

merodi
A markdown-based static site generator.
git clone https://git.pi66.xyz/merodi

About | Files | Commits | Refs | License


refactor: replace merodi.extensions with enable/disable API

Author: pi66
Date: 2026-09-10 21:19
commit: 4f4d542f

merodi.extensions.X relied on bare field access as a statement,
which is invalid Lua and only appeared to work accidentally.

Replace the extensions table with callable enable/disable APIs:
merodi.enable.X() and merodi.disable.X(). Add ParsersOption to
Lua so enable can handle parser options and inline/block parsers,
not just Goldmark extensions.

Remove registerExtensions/extensions.go and its example.

Stat

M src/core/build/compile/main.go 10 +6 -4
A src/core/lua/disable.go 70 +70 -0
A src/core/lua/enable.go 100 +100 -0
D src/core/lua/extensions.go 38 +0 -38
M src/core/lua/main.go 16 +10 -6

Diff

diff --git a/src/core/build/compile/main.go b/src/core/build/compile/main.go
index 41b062b..75cf061 100644
--- a/src/core/build/compile/main.go
+++ b/src/core/build/compile/main.go
@@ -2,16 +2,15 @@ package compile

import ( "bytes" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" "merodi/src/config" "merodi/src/core/state" "merodi/src/utils" "os" "path/filepath" "strings" - - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/renderer/html" ...

Show all

diff --git a/src/core/build/compile/main.go b/src/core/build/compile/main.go
index 41b062b..75cf061 100644
--- a/src/core/build/compile/main.go
+++ b/src/core/build/compile/main.go
@@ -2,16 +2,15 @@ package compile

import ( "bytes" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" "merodi/src/config" "merodi/src/core/state" "merodi/src/utils" "os" "path/filepath" "strings" - - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/renderer/html" - "github.com/yuin/goldmark/text" )

type Compile struct { @@ -34,10 +33,13 @@ func (self *Compile) ReadMD(mdfile string) error { func (self *Compile) MdToHtml(md string) error { var raw_html bytes.Buffer mdBytes := []byte(md) + gm := goldmark.New( + goldmark.WithParserOptions(self.State.Lua.ParsersOption...), goldmark.WithExtensions(self.State.Lua.Extensions...), goldmark.WithRendererOptions(html.WithUnsafe()), ) + doc := gm.Parser().Parse(text.NewReader(mdBytes)) doc = self.Jinja.CleanJinja(mdBytes, doc) err := gm.Renderer().Render(&raw_html, mdBytes, doc) diff --git a/src/core/lua/disable.go b/src/core/lua/disable.go new file mode 100644 index 0000000..242fbd5 --- /dev/null +++ b/src/core/lua/disable.go @@ -0,0 +1,70 @@ +package lua + +import ( + "github.com/yuin/goldmark/renderer/html" + glua "github.com/yuin/gopher-lua" +) + +var disableMap = map[string]func(){ + "GlobalAttribute": func() { + html.GlobalAttributeFilter = nil + }, + "HeadingAttribute": func() { + html.HeadingAttributeFilter = nil + }, + "BlockquoteAttribute": func() { + html.BlockquoteAttributeFilter = nil + }, + "CodeAttribute": func() { + html.CodeAttributeFilter = nil + }, + "EmphasisAttribute": func() { + html.EmphasisAttributeFilter = nil + }, + "ImageAttribute": func() { + html.ImageAttributeFilter = nil + }, + "LinkAttribute": func() { + html.LinkAttributeFilter = nil + }, + "ListAttribute": func() { + html.ListAttributeFilter = nil + }, + "ListItemAttribute": func() { + html.ListItemAttributeFilter = nil + }, + "ParagraphAttribute": func() { + html.ParagraphAttributeFilter = nil + }, + "ThematicAttribute": func() { + html.ThematicAttributeFilter = nil + }, +} + +func (self *Lua) registerDisable() { + disableTable := self.Context.NewTable() + meta := self.Context.NewTable() + + self.Context.SetField(meta, "__index", self.Context.NewFunction( + func(L *glua.LState) int { + name := L.CheckString(2) + + disable, ok := disableMap[name] + if !ok { + L.RaiseError("unknown filter: %s", name) + return 0 + } + + fn := self.Context.NewFunction(func(L *glua.LState) int { + disable() + return 0 + }) + + L.Push(fn) + return 1 + }, + )) + + disableTable.Metatable = meta + self.Merodi.RawSetString("disable", disableTable) +} diff --git a/src/core/lua/enable.go b/src/core/lua/enable.go new file mode 100644 index 0000000..f737f17 --- /dev/null +++ b/src/core/lua/enable.go @@ -0,0 +1,100 @@ +package lua + +import ( + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/util" + glua "github.com/yuin/gopher-lua" +) + +var extensionsMap = map[string]goldmark.Extender{ + "Table": extension.Table, + "Strikethrough": extension.Strikethrough, + "Linkify": extension.Linkify, + "TaskList": extension.TaskList, + "GFM": extension.GFM, + "DefinitionList": extension.DefinitionList, + "Footnote": extension.Footnote, + "Typographer": extension.Typographer, + "CJK": extension.CJK, +} + +var parsersMap = map[string]parser.Option{ + "HtmlAttr": parser.WithAttribute(), + "AutoHeadingID": parser.WithAutoHeadingID(), + "EscapedSpace": parser.WithEscapedSpace(), +} + +var blockParsersMap = map[string]parser.BlockParser{ + "SetextHeading": parser.NewSetextHeadingParser(), + "ThematicBreak": parser.NewThematicBreakParser(), + "List": parser.NewListParser(), + "ListItem": parser.NewListItemParser(), + "CodeBlock": parser.NewCodeBlockParser(), + "ATXHeading": parser.NewATXHeadingParser(), + "FencedCodeBlock": parser.NewFencedCodeBlockParser(), + "Blockquote": parser.NewBlockquoteParser(), + "HTMLBlock": parser.NewHTMLBlockParser(), + "Paragraph": parser.NewParagraphParser(), +} + +var inlineParsersMap = map[string]parser.InlineParser{ + "CodeSpan": parser.NewCodeSpanParser(), + "Link": parser.NewLinkParser(), + "AutoLink": parser.NewAutoLinkParser(), + "RawHTML": parser.NewRawHTMLParser(), + "Emphasis": parser.NewEmphasisParser(), +} + +func (self *Lua) registerEnable() { + enableTable := self.Context.NewTable() + meta := self.Context.NewTable() + + self.Context.SetField(meta, "__index", self.Context.NewFunction( + func(L *glua.LState) int { + name := L.CheckString(2) + + fn := self.Context.NewFunction(func(L *glua.LState) int { + if ext, ok := extensionsMap[name]; ok { + self.Extensions = append(self.Extensions, ext) + return 0 + } + + if option, ok := parsersMap[name]; ok { + self.ParsersOption = append(self.ParsersOption, option) + return 0 + } + + if p, ok := inlineParsersMap[name]; ok { + self.ParsersOption = append( + self.ParsersOption, + parser.WithInlineParsers( + util.Prioritized(p, 100), + ), + ) + return 0 + } + + if p, ok := blockParsersMap[name]; ok { + self.ParsersOption = append( + self.ParsersOption, + parser.WithBlockParsers( + util.Prioritized(p, 100), + ), + ) + return 0 + } + + L.RaiseError("unknown parser or extension: %s", name) + return 0 + }) + + L.Push(fn) + return 1 + }, + )) + + enableTable.Metatable = meta + self.Merodi.RawSetString("enable", enableTable) +} diff --git a/src/core/lua/extensions.go b/src/core/lua/extensions.go deleted file mode 100644 index d96833b..0000000 --- a/src/core/lua/extensions.go +++ /dev/null @@ -1,38 +0,0 @@ -package lua - -import ( - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/extension" - glua "github.com/yuin/gopher-lua" -) - -var extensionsMap = map[string]goldmark.Extender{ - "Table": extension.Table, - "Strikethrough": extension.Strikethrough, - "Linkify": extension.Linkify, - "TaskList": extension.TaskList, - "GFM": extension.GFM, - "DefinitionList": extension.DefinitionList, - "Footnote": extension.Footnote, - "Typographer": extension.Typographer, - "CJK": extension.CJK, -} - -func (self *Lua) registerExtensions() { - extensionTable := self.Context.NewTable() - meta := self.Context.NewTable() - self.Context.SetField(meta, "__index", self.Context.NewFunction( - func(L *glua.LState) int { - name := L.CheckString(2) - ext, ok := extensionsMap[name] - if !ok { - L.RaiseError("unknown extension: %s", name) - return 0 - } - self.Extensions = append(self.Extensions, ext) - return 0 - }, - )) - extensionTable.Metatable = meta - self.Merodi.RawSetString("extensions", extensionTable) -} diff --git a/src/core/lua/main.go b/src/core/lua/main.go index d505464..bba2707 100644 --- a/src/core/lua/main.go +++ b/src/core/lua/main.go @@ -5,6 +5,7 @@ import ( "path/filepath"

"github.com/yuin/goldmark"

+ "github.com/yuin/goldmark/parser" glua "github.com/yuin/gopher-lua" )

@@ -12,11 +13,13 @@ type Lua struct { Context *glua.LState Config *config.Data

- Hooks map[string]*glua.LFunction - Jinja map[string]any - Build *Build - Http *Http - Extensions []goldmark.Extender + Hooks map[string]*glua.LFunction + Jinja map[string]any + Build *Build + Http *Http + + Extensions []goldmark.Extender + ParsersOption []parser.Option

Merodi  *glua.LTable
Aborted bool

@@ -60,7 +63,8 @@ func (self *Lua) registerMerodi() { self.registerJinja() self.registerBuild() self.registerHttp() - self.registerExtensions() + self.registerEnable() + self.registerDisable() self.registerLog() self.Context.SetGlobal("merodi", self.Merodi) }

// Created by Pi66

// Copyright ©Pi66 2026