main.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package mdx
  2. import "github.com/gomarkdown/markdown"
  3. import "github.com/gomarkdown/markdown/html"
  4. import "github.com/gomarkdown/markdown/parser"
  5. import "surdeus.su/core/xgo/v2"
  6. import "bytes"
  7. func GetModule() xgo.Importable {
  8. return &xgo.BuiltinModule{Attrs:map[string]xgo.Object{
  9. "new": &xgo.BuiltinFunction{
  10. Name: "new",
  11. Value: func(
  12. args ...xgo.Object,
  13. ) (xgo.Object, error){
  14. return MakeDefaultMarkdown(), nil
  15. },
  16. },
  17. }}
  18. }
  19. type Markdown struct {
  20. xgo.ObjectImpl
  21. MakeParser func() *parser.Parser
  22. MakeRenderer func() *html.Renderer
  23. }
  24. func MakeDefaultMarkdown() *Markdown {
  25. return &Markdown{
  26. MakeParser: MakeDefaultParser,
  27. MakeRenderer: MakeDefaultRenderer,
  28. }
  29. }
  30. func (md *Markdown) TypeName() string {
  31. return "*Markdown"
  32. }
  33. func (md *Markdown) String() string {
  34. if md == nil {
  35. return "<nil>"
  36. }
  37. return "&Markdown{...}"
  38. }
  39. func (md *Markdown) Render(
  40. data []byte,
  41. ) ([]byte, error) {
  42. doc := md.MakeParser().Parse(data)
  43. rendered := markdown.Render(doc, md.MakeRenderer())
  44. return rendered, nil
  45. }
  46. func (md *Markdown) CanCall() bool {
  47. return md != nil
  48. }
  49. func (md *Markdown) Call(
  50. args ...xgo.Object,
  51. ) (xgo.Object, error) {
  52. var b bytes.Buffer
  53. for _, arg := range args {
  54. str, ok := xgo.ToString(arg)
  55. if !ok {
  56. return nil, xgo.ErrInvalidArgumentType{
  57. Name: "v",
  58. Expected: "stringer",
  59. Found: arg.TypeName(),
  60. }
  61. }
  62. b.Write([]byte(str))
  63. }
  64. rendered, err := md.Render(b.Bytes())
  65. if err != nil {
  66. return nil, err
  67. }
  68. return xgo.FromInterface(rendered)
  69. }
  70. func MakeDefaultParser() *parser.Parser {
  71. return parser.NewWithExtensions(
  72. parser.CommonExtensions | parser.AutoHeadingIDs |
  73. parser.NoEmptyLineBeforeBlock | parser.Attributes |
  74. parser.Tables,
  75. )
  76. }
  77. func MakeDefaultRenderer() *html.Renderer {
  78. return html.NewRenderer(
  79. html.RendererOptions{
  80. Flags: html.CommonFlags | html.HrefTargetBlank,
  81. },
  82. )
  83. }