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
Show less
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"
...
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)
}