feat: articles format option with markdown new default
This commit is contained in:
1 parent
68401d66e0
commit
7e9bd9ba30
61 files changed
+2269
-243
No files matched your search
@@ -0,0 +1,111 @@
|
||||
package markdown
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type jsonMark struct {
|
||||
Type string `json:"type"`
|
||||
Href string `json:"href,omitempty"`
|
||||
}
|
||||
|
||||
type jsonText struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text"`
|
||||
Marks []jsonMark `json:"marks"`
|
||||
}
|
||||
|
||||
type jsonHeading struct {
|
||||
Type string `json:"type"`
|
||||
Level int `json:"level"`
|
||||
Align string `json:"align,omitempty"`
|
||||
Children []jsonText `json:"children"`
|
||||
}
|
||||
|
||||
type jsonParagraph struct {
|
||||
Type string `json:"type"`
|
||||
Align string `json:"align,omitempty"`
|
||||
Children []jsonText `json:"children"`
|
||||
}
|
||||
|
||||
type jsonList struct {
|
||||
Type string `json:"type"`
|
||||
Ordered bool `json:"ordered"`
|
||||
Items [][]any `json:"items"`
|
||||
}
|
||||
|
||||
type jsonBlockquote struct {
|
||||
Type string `json:"type"`
|
||||
Children []any `json:"children"`
|
||||
}
|
||||
|
||||
type jsonCode struct {
|
||||
Type string `json:"type"`
|
||||
Language string `json:"language"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type jsonRule struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type jsonImage struct {
|
||||
Type string `json:"type"`
|
||||
Src string `json:"src"`
|
||||
Alt string `json:"alt"`
|
||||
}
|
||||
|
||||
func renderJSON(blocks []block) (string, error) {
|
||||
var buffer bytes.Buffer
|
||||
encoder := json.NewEncoder(&buffer)
|
||||
encoder.SetEscapeHTML(false)
|
||||
if err := encoder.Encode(toJSONBlocks(blocks)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSuffix(buffer.String(), "\n"), nil
|
||||
}
|
||||
|
||||
func toJSONBlocks(blocks []block) []any {
|
||||
result := make([]any, 0, len(blocks))
|
||||
for _, b := range blocks {
|
||||
result = append(result, toJSONBlock(b))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toJSONBlock(b block) any {
|
||||
switch b.kind {
|
||||
case kindHeading:
|
||||
return jsonHeading{Type: "heading", Level: b.level, Align: b.align, Children: toJSONTexts(b.inlines)}
|
||||
case kindParagraph:
|
||||
return jsonParagraph{Type: "paragraph", Align: b.align, Children: toJSONTexts(b.inlines)}
|
||||
case kindList:
|
||||
items := make([][]any, 0, len(b.items))
|
||||
for _, item := range b.items {
|
||||
items = append(items, toJSONBlocks(item))
|
||||
}
|
||||
return jsonList{Type: "list", Ordered: b.ordered, Items: items}
|
||||
case kindBlockquote:
|
||||
return jsonBlockquote{Type: "blockquote", Children: toJSONBlocks(b.children)}
|
||||
case kindCode:
|
||||
return jsonCode{Type: "code", Language: b.language, Text: b.text}
|
||||
case kindImage:
|
||||
return jsonImage{Type: "image", Src: b.src, Alt: b.alt}
|
||||
}
|
||||
return jsonRule{Type: "hr"}
|
||||
}
|
||||
|
||||
func toJSONTexts(inlines []inline) []jsonText {
|
||||
plain := withoutCodeMarks(inlines)
|
||||
texts := make([]jsonText, 0, len(plain))
|
||||
for _, item := range plain {
|
||||
marks := make([]jsonMark, 0, len(item.marks))
|
||||
for _, m := range item.marks {
|
||||
marks = append(marks, jsonMark{Type: m.kind, Href: m.href})
|
||||
}
|
||||
texts = append(texts, jsonText{Type: "text", Text: item.text, Marks: marks})
|
||||
}
|
||||
return texts
|
||||
}
|
||||
Reference in new issue
Block a user