diff --git a/API.md b/API.md index 04c663326..19d5744c6 100644 --- a/API.md +++ b/API.md @@ -27,6 +27,7 @@ * [Append blocks](#Append-blocks) * [Update a block](#Update-a-block) * [Delete a block](#Delete-a-block) + * [Get a block kramdown](#Get-a-block-kramdown) * [Attributes](#Attributes) * [Set block attributes](#Set-block-attributes) * [Get block attributes](#Get-block-attributes) @@ -696,6 +697,31 @@ View API token in Settings - About, request header: `Authorization: T } ``` +### Get a block kramdown + +* `/api/block/getBlockKramdown` +* Parameters + + ```json + { + "id": "20201225220954-dlgzk1o" + } + ``` + + * `id`: ID of the block to be got +* Return value + + ```json + { + "code": 0, + "msg": "", + "data": { + "id": "20201225220954-dlgzk1o", + "kramdown": "* {: id=\"20201225220954-e913snx\"}Create a new notebook, create a new document under the notebook\n {: id=\"20210131161940-kfs31q6\"}\n* {: id=\"20201225220954-ygz217h\"}Enter / in the editor to trigger the function menu\n {: id=\"20210131161940-eo0riwq\"}\n* {: id=\"20201225220954-875yybt\"}((20200924101200-gss5vee \"Navigate in the content block\")) and ((20200924100906-0u4zfq3 \"Window and tab\"))\n {: id=\"20210131161940-b5uow2h\"}" + } + } + ``` + ## Attributes ### Set block attributes diff --git a/API_zh_CN.md b/API_zh_CN.md index bbe29299b..9d10defb6 100644 --- a/API_zh_CN.md +++ b/API_zh_CN.md @@ -27,6 +27,7 @@ * [插入后置子块](#插入后置子块) * [更新块](#更新块) * [删除块](#删除块) + * [获取块 kramdown 源码](#获取块-kramdown-源码) * [属性](#属性) * [设置块属性](#设置块属性) * [获取块属性](#获取块属性) @@ -691,6 +692,31 @@ } ``` +### 获取块 kramdown 源码 + +* `/api/block/getBlockKramdown` +* 参数 + + ```json + { + "id": "20201225220955-l154bn4" + } + ``` + + * `id`:待获取块的 ID +* 返回值 + + ```json + { + "code": 0, + "msg": "", + "data": { + "id": "20201225220955-l154bn4", + "kramdown": "* {: id=\"20201225220955-2nn1mns\"}新建笔记本,在笔记本下新建文档\n {: id=\"20210131155408-3t627wc\"}\n* {: id=\"20201225220955-uwhqnug\"}在编辑器中输入 / 触发功能菜单\n {: id=\"20210131155408-btnfw88\"}\n* {: id=\"20201225220955-04ymi2j\"}((20200813131152-0wk5akh \"在内容块中遨游\"))、((20200822191536-rm6hwid \"窗口和页签\"))\n {: id=\"20210131155408-hh1z442\"}" + } + } + ``` + ## 属性 ### 设置块属性 diff --git a/kernel/api/block.go b/kernel/api/block.go index 9a0967f13..a82b15c74 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -319,3 +319,20 @@ func getBlockDOM(c *gin.Context) { "dom": dom, } } + +func getBlockKramdown(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + id := arg["id"].(string) + kramdown := model.GetBlockKramdown(id) + ret.Data = map[string]string{ + "id": id, + "kramdown": kramdown, + } +} diff --git a/kernel/api/router.go b/kernel/api/router.go index b7c967c03..e9b23502a 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -125,6 +125,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/getBlockInfo", model.CheckAuth, getBlockInfo) ginServer.Handle("POST", "/api/block/getBlockDOM", model.CheckAuth, getBlockDOM) + ginServer.Handle("POST", "/api/block/getBlockKramdown", model.CheckAuth, getBlockKramdown) ginServer.Handle("POST", "/api/block/getBlockBreadcrumb", model.CheckAuth, getBlockBreadcrumb) ginServer.Handle("POST", "/api/block/getRefIDs", model.CheckAuth, getRefIDs) ginServer.Handle("POST", "/api/block/getRefIDsByFileAnnotationID", model.CheckAuth, getRefIDsByFileAnnotationID) diff --git a/kernel/model/block.go b/kernel/model/block.go index 825e476b6..ad3000f9c 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -100,6 +100,23 @@ func GetBlockDOM(id string) (ret string) { return } +func GetBlockKramdown(id string) (ret string) { + if "" == id { + return + } + + tree, err := loadTreeByBlockID(id) + if nil != err { + return + } + + addBlockIALNodes(tree) + node := treenode.GetNodeInTree(tree, id) + luteEngine := NewLute() + ret, _ = lute.FormatNodeSync(node, luteEngine.ParseOptions, luteEngine.RenderOptions) + return +} + func GetBlock(id string) (ret *Block, err error) { ret, err = getBlock(id) return diff --git a/kernel/model/template.go b/kernel/model/template.go index b13265698..6e7fd67a3 100644 --- a/kernel/model/template.go +++ b/kernel/model/template.go @@ -95,37 +95,8 @@ func DocSaveAsTemplate(id string, overwrite bool) (code int, err error) { return } - var blocks []*ast.Node // 添加 block ial,后面格式化渲染需要 - ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { - if !entering || !n.IsBlock() { - return ast.WalkContinue - } - - if ast.NodeBlockQueryEmbed == n.Type { - if script := n.ChildByType(ast.NodeBlockQueryEmbedScript); nil != script { - script.Tokens = bytes.ReplaceAll(script.Tokens, []byte("\n"), []byte(" ")) - } - } else if ast.NodeHTMLBlock == n.Type { - n.Tokens = bytes.TrimSpace(n.Tokens) - // 使用
包裹,否则后续解析模板时会识别为行级 HTML https://github.com/siyuan-note/siyuan/issues/4244 - if !bytes.HasPrefix(n.Tokens, []byte("
")) { - n.Tokens = append([]byte("
\n"), n.Tokens...) - } - if !bytes.HasSuffix(n.Tokens, []byte("
")) { - n.Tokens = append(n.Tokens, []byte("\n
")...) - } - } - - n.RemoveIALAttr("updated") - if 0 < len(n.KramdownIAL) { - blocks = append(blocks, n) - } - return ast.WalkContinue - }) - for _, block := range blocks { - block.InsertAfter(&ast.Node{Type: ast.NodeKramdownBlockIAL, Tokens: parse.IAL2Tokens(block.KramdownIAL)}) - } + addBlockIALNodes(tree) luteEngine := NewLute() formatRenderer := render.NewFormatRenderer(tree, luteEngine.RenderOptions) @@ -287,3 +258,36 @@ func appendRefTextRenderResultForBlockRef(blockRef *ast.Node) { } blockRef.AppendChild(&ast.Node{Type: ast.NodeBlockRefDynamicText, Tokens: gulu.Str.ToBytes(text)}) } + +func addBlockIALNodes(tree *parse.Tree) { + var blocks []*ast.Node + ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { + if !entering || !n.IsBlock() { + return ast.WalkContinue + } + + if ast.NodeBlockQueryEmbed == n.Type { + if script := n.ChildByType(ast.NodeBlockQueryEmbedScript); nil != script { + script.Tokens = bytes.ReplaceAll(script.Tokens, []byte("\n"), []byte(" ")) + } + } else if ast.NodeHTMLBlock == n.Type { + n.Tokens = bytes.TrimSpace(n.Tokens) + // 使用
包裹,否则后续解析模板时会识别为行级 HTML https://github.com/siyuan-note/siyuan/issues/4244 + if !bytes.HasPrefix(n.Tokens, []byte("
")) { + n.Tokens = append([]byte("
\n"), n.Tokens...) + } + if !bytes.HasSuffix(n.Tokens, []byte("
")) { + n.Tokens = append(n.Tokens, []byte("\n
")...) + } + } + + n.RemoveIALAttr("updated") + if 0 < len(n.KramdownIAL) { + blocks = append(blocks, n) + } + return ast.WalkContinue + }) + for _, block := range blocks { + block.InsertAfter(&ast.Node{Type: ast.NodeKramdownBlockIAL, Tokens: parse.IAL2Tokens(block.KramdownIAL)}) + } +}