2024-06-09 15:16:38 +03:00
|
|
|
package mdx
|
|
|
|
import "github.com/gomarkdown/markdown"
|
|
|
|
import "github.com/gomarkdown/markdown/html"
|
|
|
|
import "github.com/gomarkdown/markdown/parser"
|
2024-08-02 18:30:32 +03:00
|
|
|
import "surdeus.su/core/xgo/v2"
|
2024-06-09 15:16:38 +03:00
|
|
|
import "bytes"
|
|
|
|
|
2024-08-02 18:30:32 +03:00
|
|
|
func GetModule() xgo.Importable {
|
|
|
|
return &xgo.BuiltinModule{Attrs:map[string]xgo.Object{
|
|
|
|
"new": &xgo.BuiltinFunction{
|
2024-06-18 15:34:12 +03:00
|
|
|
Name: "new",
|
|
|
|
Value: func(
|
2024-08-02 18:30:32 +03:00
|
|
|
args ...xgo.Object,
|
|
|
|
) (xgo.Object, error){
|
2024-06-18 15:34:12 +03:00
|
|
|
return MakeDefaultMarkdown(), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
2024-06-09 15:16:38 +03:00
|
|
|
type Markdown struct {
|
2024-08-02 18:30:32 +03:00
|
|
|
xgo.ObjectImpl
|
2024-06-09 15:16:38 +03:00
|
|
|
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(
|
2024-08-02 18:30:32 +03:00
|
|
|
args ...xgo.Object,
|
|
|
|
) (xgo.Object, error) {
|
2024-06-09 15:16:38 +03:00
|
|
|
var b bytes.Buffer
|
|
|
|
for _, arg := range args {
|
2024-08-02 18:30:32 +03:00
|
|
|
str, ok := xgo.ToString(arg)
|
2024-06-09 15:16:38 +03:00
|
|
|
if !ok {
|
2024-08-02 18:30:32 +03:00
|
|
|
return nil, xgo.ErrInvalidArgumentType{
|
2024-06-09 15:16:38 +03:00
|
|
|
Name: "v",
|
|
|
|
Expected: "stringer",
|
|
|
|
Found: arg.TypeName(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
b.Write([]byte(str))
|
|
|
|
}
|
|
|
|
|
|
|
|
rendered, err := md.Render(b.Bytes())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-08-02 18:30:32 +03:00
|
|
|
return xgo.FromInterface(rendered)
|
2024-06-09 15:16:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|