2024-05-20 20:34:11 +03:00
|
|
|
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"
|
|
|
|
|
|
|
|
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 {
|
2024-05-24 12:43:55 +03:00
|
|
|
str, ok := tengo.ToString(arg)
|
2024-05-20 20:34:11 +03:00
|
|
|
if !ok {
|
|
|
|
return nil, tengo.ErrInvalidArgumentType{
|
2024-05-24 12:43:55 +03:00
|
|
|
Name: "v",
|
|
|
|
Expected: "stringer",
|
|
|
|
Found: arg.TypeName(),
|
2024-05-20 20:34:11 +03:00
|
|
|
}
|
|
|
|
}
|
2024-05-24 12:43:55 +03:00
|
|
|
b.Write([]byte(str))
|
2024-05-20 20:34:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|