mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-02 02:36:24 -07:00
Add function to lua for setting custom bbcode tags
This commit is contained in:
parent
30c1c1c037
commit
5bc47e003d
6 changed files with 137 additions and 13 deletions
5
examples/plugins/bbcode.lua
Normal file
5
examples/plugins/bbcode.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
local bbcode = require("bbcode")
|
||||
|
||||
bbcode.set_tag("rcv", function(node)
|
||||
return {name="span", attrs={class="rcv"}}
|
||||
end)
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/gochan-org/gochan/pkg/gctemplates"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
"github.com/gochan-org/gochan/pkg/manage"
|
||||
"github.com/gochan-org/gochan/pkg/posting"
|
||||
"github.com/gochan-org/gochan/pkg/posting/geoip"
|
||||
"github.com/gochan-org/gochan/pkg/posting/uploads"
|
||||
"github.com/gochan-org/gochan/pkg/server/serverutil"
|
||||
|
@ -106,6 +107,7 @@ func preloadLua() {
|
|||
lState.PreloadModule("manage", manage.PreloadModule)
|
||||
lState.PreloadModule("uploads", uploads.PreloadModule)
|
||||
lState.PreloadModule("serverutil", serverutil.PreloadModule)
|
||||
lState.PreloadModule("bbcode", posting.PreloadBBCodeModule)
|
||||
|
||||
lState.SetGlobal("_GOCHAN_VERSION", lua.LString(config.GetVersion().String()))
|
||||
}
|
||||
|
|
|
@ -14,14 +14,13 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
msgfmtr *MessageFormatter
|
||||
msgfmtr MessageFormatter
|
||||
urlRE = regexp.MustCompile(`https?://(\S+)`)
|
||||
unsetBBcodeTags = []string{"center", "color", "img", "quote", "size"}
|
||||
)
|
||||
|
||||
// InitPosting prepares the formatter and the temp post pruner
|
||||
func InitPosting() {
|
||||
msgfmtr = new(MessageFormatter)
|
||||
msgfmtr.Init()
|
||||
go tempCleaner()
|
||||
}
|
||||
|
|
|
@ -5,20 +5,17 @@ import (
|
|||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
const (
|
||||
versionStr = "4.0.0"
|
||||
bbcodeMsgPreRender = `[b]Bold[/b]
|
||||
[i]Italics[/i]
|
||||
[u]Underline[/u]
|
||||
[url=https://gochan.org]URL[/url]
|
||||
[code]Code[/code]`
|
||||
bbcodeMsgExpected = `<b>Bold</b><br>` +
|
||||
`<i>Italics</i><br>` +
|
||||
`<u>Underline</u><br>` +
|
||||
`<a href="https://gochan.org">URL</a><br>` +
|
||||
`<pre>Code</pre>`
|
||||
bbcodeMsgPreRender = `[b]Bold[/b] [i]Italics[/i] [u]Underline[/u] [url=https://gochan.org]URL[/url] [?]Spoiler[/?]
|
||||
[code]Code[/code]
|
||||
[hide]Hidden[/hide]`
|
||||
bbcodeMsgExpected = `<b>Bold</b> <i>Italics</i> <u>Underline</u> <a href="https://gochan.org">URL</a> <span class="spoiler">Spoiler</span><br>` +
|
||||
`<pre>Code</pre><br>` +
|
||||
`<div class="hideblock hidden">Hidden</div>`
|
||||
|
||||
linkTestPreRender = `gochan.org: https://gochan.org
|
||||
gochan.org with path: https://gochan.org/a
|
||||
|
@ -29,6 +26,12 @@ gochan.org with bad link: https://gochan.org/a">:)</a>`
|
|||
|
||||
doubleTagPreRender = `[url=https://gochan.org]Gochan[/url] [url]https://gochan.org[/url]`
|
||||
doubleTagExpected = `<a href="https://gochan.org">Gochan</a> <a href="https://gochan.org">https://gochan.org</a>`
|
||||
luaBBCodeTest = `local bbcode = require("bbcode")
|
||||
local msg = "[lua]Lua test[/lua]"
|
||||
bbcode.set_tag("lua", function(node)
|
||||
return {name="span", attrs={class="lua"}}
|
||||
end)`
|
||||
luaBBCodeTestExpected = `<span class="lua">Lua test</span>`
|
||||
)
|
||||
|
||||
func TestBBCode(t *testing.T) {
|
||||
|
@ -50,9 +53,22 @@ func TestLinks(t *testing.T) {
|
|||
|
||||
func TestNoDoubleTags(t *testing.T) {
|
||||
config.SetVersion(versionStr)
|
||||
msgfmtr = new(MessageFormatter)
|
||||
msgfmtr.Init()
|
||||
rendered, err := FormatMessage(doubleTagPreRender, "")
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, doubleTagExpected, rendered)
|
||||
}
|
||||
|
||||
func TestLuaBBCode(t *testing.T) {
|
||||
config.SetVersion(versionStr)
|
||||
msgfmtr.Init()
|
||||
l := lua.NewState()
|
||||
defer l.Close()
|
||||
l.PreloadModule("bbcode", PreloadBBCodeModule)
|
||||
assert.NoError(t, l.DoString(luaBBCodeTest))
|
||||
compiled := msgfmtr.bbCompiler.Compile("[lua]Lua test[/lua]")
|
||||
assert.Equal(t, luaBBCodeTestExpected, compiled)
|
||||
assert.NoError(t, l.DoString(`require("bbcode").set_tag("b", nil)`))
|
||||
assert.Equal(t, "[b]Lua test[/b]", msgfmtr.bbCompiler.Compile("[b]Lua test[/b]"))
|
||||
assert.Error(t, l.DoString(`bbcode.set_tag("lua", 1)`))
|
||||
}
|
||||
|
|
97
pkg/posting/lua.go
Normal file
97
pkg/posting/lua.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
package posting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/frustra/bbcode"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
func luaTableToHTMLTag(l *lua.LState, table *lua.LTable) (*bbcode.HTMLTag, error) {
|
||||
tag := &bbcode.HTMLTag{
|
||||
Name: table.RawGetString("name").String(),
|
||||
}
|
||||
value := table.RawGetString("value")
|
||||
if value.Type() != lua.LTNil {
|
||||
tag.Value = value.String()
|
||||
}
|
||||
attrsLV := table.RawGetString("attrs")
|
||||
switch attrsLV.Type() {
|
||||
case lua.LTTable:
|
||||
attrsLT := attrsLV.(*lua.LTable)
|
||||
fmt.Println("attrs size:", attrsLT.Len())
|
||||
attrsLT.ForEach(func(key, val lua.LValue) {
|
||||
if tag.Attrs == nil {
|
||||
tag.Attrs = make(map[string]string)
|
||||
}
|
||||
tag.Attrs[key.String()] = val.String()
|
||||
})
|
||||
case lua.LTNil:
|
||||
default:
|
||||
return nil, fmt.Errorf("expected table or nil for attrs value, got %s", attrsLV.Type().String())
|
||||
}
|
||||
childrenLV := table.RawGetString("children")
|
||||
switch childrenLV.Type() {
|
||||
case lua.LTTable:
|
||||
childrenT := childrenLV.(*lua.LTable)
|
||||
if childrenT.Len() > 0 {
|
||||
tag.Children = make([]*bbcode.HTMLTag, childrenT.Len())
|
||||
childrenT.ForEach(func(iLV, childLV lua.LValue) {
|
||||
childT, err := luaTableToHTMLTag(l, childLV.(*lua.LTable))
|
||||
if err != nil {
|
||||
l.RaiseError("Error converting child table to HTMLTag: %v", err)
|
||||
return
|
||||
}
|
||||
tag.Children[int(iLV.(lua.LNumber)-1)] = childT
|
||||
})
|
||||
}
|
||||
case lua.LTNil:
|
||||
default:
|
||||
return nil, fmt.Errorf("expected table or nil for children value, got %s", childrenLV.Type().String())
|
||||
}
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
func PreloadBBCodeModule(l *lua.LState) int {
|
||||
t := l.NewTable()
|
||||
l.SetFuncs(t, map[string]lua.LGFunction{
|
||||
"set_tag": func(l *lua.LState) int {
|
||||
bbcodeTag := l.CheckString(1)
|
||||
bbCodeLV := l.CheckAny(2)
|
||||
if bbCodeLV.Type() == lua.LTNil {
|
||||
msgfmtr.bbCompiler.SetTag(bbcodeTag, nil)
|
||||
return 0
|
||||
}
|
||||
bbcodeFunc := l.CheckFunction(2)
|
||||
msgfmtr.bbCompiler.SetTag(bbcodeTag, func(node *bbcode.BBCodeNode) (*bbcode.HTMLTag, bool) {
|
||||
err := l.CallByParam(lua.P{
|
||||
Fn: bbcodeFunc,
|
||||
NRet: 2,
|
||||
}, luar.New(l, node))
|
||||
if err != nil {
|
||||
gcutil.LogError(err).Caller().Msg("Error calling bbcode function")
|
||||
l.RaiseError("Error calling bbcode function: %v", err)
|
||||
return nil, false
|
||||
}
|
||||
tagRet := l.CheckAny(-2)
|
||||
if tagRet.Type() != lua.LTTable {
|
||||
l.RaiseError("Invalid return value from bbcode function (expected table)")
|
||||
return nil, false
|
||||
}
|
||||
tagTable := tagRet.(*lua.LTable)
|
||||
tag, err := luaTableToHTMLTag(l, tagTable)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).Caller().Msg("Error converting table to HTMLTag")
|
||||
l.RaiseError("Error converting table to HTMLTag: %v", err)
|
||||
return nil, false
|
||||
}
|
||||
return tag, true
|
||||
})
|
||||
return 0
|
||||
},
|
||||
})
|
||||
l.Push(t)
|
||||
return 1
|
||||
}
|
|
@ -9,6 +9,11 @@ The following are modules that can be loaded via `require("modulename")`. See [.
|
|||
- [filepath](https://pkg.go.dev/github.com/vadv/gopher-lua-libs@v0.5.0/filepath)
|
||||
- [json](https://pkg.go.dev/layeh.com/gopher-json@v0.0.0-20201124131017-552bb3c4c3bf)
|
||||
- [strings](https://pkg.go.dev/github.com/vadv/gopher-lua-libs@v0.5.0/strings)
|
||||
|
||||
## bbcode
|
||||
- **set_tag(tag string, handler [bbcode.TagCompilerFunc](https://pkg.go.dev/github.com/frustra/bbcode@v0.0.0-20201127003707-6ef347fbe1c8#TagCompilerFunc)))**
|
||||
- Registers a new BBCode function to handle the given tag. Struct-table fields are expected to use snake case (e.g., name instead of Name)
|
||||
|
||||
## config
|
||||
- **config.system_critical_config()**
|
||||
- Returns the [SystemCriticalConfig](https://pkg.go.dev/github.com/gochan-org/gochan/pkg/config#SystemCriticalConfig)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue