kyra/mdx/main.go

96 lines
1.9 KiB
Go

package mdx
import "github.com/gomarkdown/markdown"
import "github.com/gomarkdown/markdown/html"
import "github.com/gomarkdown/markdown/parser"
import "github.com/d5/tengo/v2"
import "bytes"
func GetModule() tengo.Importable {
return &tengo.BuiltinModule{Attrs:map[string]tengo.Object{
"new": &tengo.BuiltinFunction{
Name: "new",
Value: func(
args ...tengo.Object,
) (tengo.Object, error){
return MakeDefaultMarkdown(), nil
},
},
}}
}
type Markdown struct {
tengo.ObjectImpl
MakeParser func() *parser.Parser
MakeRenderer func() *html.Renderer
}
func MakeDefaultMarkdown() *Markdown {
return &Markdown{
MakeParser: MakeDefaultParser,
MakeRenderer: MakeDefaultRenderer,
}
}
func (md *Markdown) TypeName() string {
return "*Markdown"
}
func (md *Markdown) String() string {
if md == nil {
return "<nil>"
}
return "&Markdown{...}"
}
func (md *Markdown) Render(
data []byte,
) ([]byte, error) {
doc := md.MakeParser().Parse(data)
rendered := markdown.Render(doc, md.MakeRenderer())
return rendered, nil
}
func (md *Markdown) CanCall() bool {
return md != nil
}
func (md *Markdown) Call(
args ...tengo.Object,
) (tengo.Object, error) {
var b bytes.Buffer
for _, arg := range args {
str, ok := tengo.ToString(arg)
if !ok {
return nil, tengo.ErrInvalidArgumentType{
Name: "v",
Expected: "stringer",
Found: arg.TypeName(),
}
}
b.Write([]byte(str))
}
rendered, err := md.Render(b.Bytes())
if err != nil {
return nil, err
}
return tengo.FromInterface(rendered)
}
func MakeDefaultParser() *parser.Parser {
return parser.NewWithExtensions(
parser.CommonExtensions | parser.AutoHeadingIDs |
parser.NoEmptyLineBeforeBlock | parser.Attributes |
parser.Tables,
)
}
func MakeDefaultRenderer() *html.Renderer {
return html.NewRenderer(
html.RendererOptions{
Flags: html.CommonFlags | html.HrefTargetBlank,
},
)
}