diff --git a/kernel/api/workspace.go b/kernel/api/workspace.go index 35a0bc9f8..6663ba5da 100644 --- a/kernel/api/workspace.go +++ b/kernel/api/workspace.go @@ -238,18 +238,13 @@ func getWorkspaces(c *gin.Context) { model.RoleAdministrator, }) { ret.Data = []*Workspace{} - logging.LogInfof("non-admin user tried to get workspaces") return } - logging.LogInfof("workspace paths [%+v]", workspacePaths) - var workspaces, openedWorkspaces, closedWorkspaces []*Workspace for _, p := range workspacePaths { - logging.LogInfof("get workspace [%s]", p) closed := !util.IsWorkspaceLocked(p) if closed { - logging.LogInfof("workspace [%s] is closed", p) closedWorkspaces = append(closedWorkspaces, &Workspace{Path: p, Closed: closed}) } else { openedWorkspaces = append(openedWorkspaces, &Workspace{Path: p, Closed: closed}) diff --git a/kernel/model/conf.go b/kernel/model/conf.go index 89630aaa8..29ef45f38 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -750,7 +750,7 @@ func Close(force, setCurrentWorkspace bool, execInstallPkg int) (exitCode int) { } util.HttpServing = false - if util.ContainerAndroid == util.Container || util.ContainerIOS == util.Container { + if util.ContainerAndroid == util.Container || util.ContainerIOS == util.Container || util.ContainerHarmony == util.Container { return } diff --git a/kernel/model/render.go b/kernel/model/render.go index 26a4abdbc..62e3324c6 100644 --- a/kernel/model/render.go +++ b/kernel/model/render.go @@ -256,165 +256,168 @@ func resolveEmbedR(n *ast.Node, blockEmbedMode int, luteEngine *lute.Lute, resol return ast.WalkContinue } - if ast.NodeBlockQueryEmbed == n.Type { - if gulu.Str.Contains(n.ID, *resolved) { - return ast.WalkContinue + if ast.NodeBlockQueryEmbed != n.Type { + return ast.WalkContinue + } + + if gulu.Str.Contains(n.ID, *resolved) { + return ast.WalkContinue + } + *resolved = append(*resolved, n.ID) + + stmt := n.ChildByType(ast.NodeBlockQueryEmbedScript).TokensStr() + stmt = html.UnescapeString(stmt) + stmt = strings.ReplaceAll(stmt, editor.IALValEscNewLine, "\n") + sqlBlocks := sql.SelectBlocksRawStmt(stmt, 1, Conf.Search.Limit) + for _, sqlBlock := range sqlBlocks { + if "query_embed" == sqlBlock.Type { + continue } - *resolved = append(*resolved, n.ID) - stmt := n.ChildByType(ast.NodeBlockQueryEmbedScript).TokensStr() - stmt = html.UnescapeString(stmt) - stmt = strings.ReplaceAll(stmt, editor.IALValEscNewLine, "\n") - sqlBlocks := sql.SelectBlocksRawStmt(stmt, 1, Conf.Search.Limit) - for _, sqlBlock := range sqlBlocks { - if "query_embed" == sqlBlock.Type { - continue - } + subTree, _ := LoadTreeByBlockID(sqlBlock.ID) + if nil == subTree { + continue + } - subTree, _ := LoadTreeByBlockID(sqlBlock.ID) - if nil == subTree { - continue - } - - var md string - if "d" == sqlBlock.Type { - if 0 == blockEmbedMode { - // 嵌入块中出现了大于等于上方非嵌入块的标题时需要降低嵌入块中的标题级别 - // Improve export of heading levels in embedded blocks https://github.com/siyuan-note/siyuan/issues/12233 https://github.com/siyuan-note/siyuan/issues/12741 - embedTopLevel := 0 - ast.Walk(subTree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { - if !entering || ast.NodeHeading != n.Type { - return ast.WalkContinue - } - - embedTopLevel = n.HeadingLevel - if parentHeadingLevel >= embedTopLevel { - n.HeadingLevel += parentHeadingLevel - embedTopLevel + 1 - if 6 < n.HeadingLevel { - n.HeadingLevel = 6 - } - } + var md string + if "d" == sqlBlock.Type { + if 0 == blockEmbedMode { + // 嵌入块中出现了大于等于上方非嵌入块的标题时需要降低嵌入块中的标题级别 + // Improve export of heading levels in embedded blocks https://github.com/siyuan-note/siyuan/issues/12233 https://github.com/siyuan-note/siyuan/issues/12741 + embedTopLevel := 0 + ast.Walk(subTree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { + if !entering || ast.NodeHeading != n.Type { return ast.WalkContinue - }) - } - - md, _ = lute.FormatNodeSync(subTree.Root, luteEngine.ParseOptions, luteEngine.RenderOptions) - } else if "h" == sqlBlock.Type { - h := treenode.GetNodeInTree(subTree, sqlBlock.ID) - var hChildren []*ast.Node - - // 从嵌入块的 IAL 属性中解析 custom-heading-mode,使用全局配置作为默认值 - blockHeadingMode := Conf.Editor.HeadingEmbedMode - if customHeadingMode := n.IALAttr("custom-heading-mode"); "" != customHeadingMode { - if mode, err := strconv.Atoi(customHeadingMode); nil == err && (mode == 0 || mode == 1 || mode == 2) { - blockHeadingMode = mode } - } - // 根据 blockHeadingMode 处理标题块的显示 - // blockHeadingMode: 0=显示标题与下方的块,1=仅显示标题,2=仅显示标题下方的块 - if 1 == blockHeadingMode { - // 仅显示标题 - hChildren = append(hChildren, h) - } else if 2 == blockHeadingMode { - // 仅显示标题下方的块(默认行为) - if "1" != h.IALAttr("fold") { - children := treenode.HeadingChildren(h) - for _, c := range children { - if "1" == c.IALAttr("heading-fold") { - // 嵌入块包含折叠标题时不应该显示其下方块 https://github.com/siyuan-note/siyuan/issues/4765 - continue - } - hChildren = append(hChildren, c) + embedTopLevel = n.HeadingLevel + if parentHeadingLevel >= embedTopLevel { + n.HeadingLevel += parentHeadingLevel - embedTopLevel + 1 + if 6 < n.HeadingLevel { + n.HeadingLevel = 6 } } - } else { - // 0: 显示标题与下方的块 - hChildren = append(hChildren, h) - hChildren = append(hChildren, treenode.HeadingChildren(h)...) + return ast.WalkContinue + }) + } + + md, _ = lute.FormatNodeSync(subTree.Root, luteEngine.ParseOptions, luteEngine.RenderOptions) + } else if "h" == sqlBlock.Type { + h := treenode.GetNodeInTree(subTree, sqlBlock.ID) + var hChildren []*ast.Node + + // 从嵌入块的 IAL 属性中解析 custom-heading-mode,使用全局配置作为默认值 + blockHeadingMode := Conf.Editor.HeadingEmbedMode + if customHeadingMode := n.IALAttr("custom-heading-mode"); "" != customHeadingMode { + if mode, err := strconv.Atoi(customHeadingMode); nil == err && (mode == 0 || mode == 1 || mode == 2) { + blockHeadingMode = mode } - if 0 == blockEmbedMode { - embedTopLevel := 0 + } + + // 根据 blockHeadingMode 处理标题块的显示 + // blockHeadingMode: 0=显示标题与下方的块,1=仅显示标题,2=仅显示标题下方的块 + if 1 == blockHeadingMode { + // 仅显示标题 + hChildren = append(hChildren, h) + } else if 2 == blockHeadingMode { + // 仅显示标题下方的块(默认行为) + if "1" != h.IALAttr("fold") { + children := treenode.HeadingChildren(h) + for _, c := range children { + if "1" == c.IALAttr("heading-fold") { + // 嵌入块包含折叠标题时不应该显示其下方块 https://github.com/siyuan-note/siyuan/issues/4765 + continue + } + hChildren = append(hChildren, c) + } + } + } else { + // 0: 显示标题与下方的块 + hChildren = append(hChildren, h) + hChildren = append(hChildren, treenode.HeadingChildren(h)...) + } + if 0 == blockEmbedMode { + embedTopLevel := 0 + for _, hChild := range hChildren { + if ast.NodeHeading == hChild.Type { + embedTopLevel = hChild.HeadingLevel + break + } + } + if parentHeadingLevel >= embedTopLevel { for _, hChild := range hChildren { if ast.NodeHeading == hChild.Type { - embedTopLevel = hChild.HeadingLevel - break - } - } - if parentHeadingLevel >= embedTopLevel { - for _, hChild := range hChildren { - if ast.NodeHeading == hChild.Type { - hChild.HeadingLevel += parentHeadingLevel - embedTopLevel + 1 - if 6 < hChild.HeadingLevel { - hChild.HeadingLevel = 6 - } + hChild.HeadingLevel += parentHeadingLevel - embedTopLevel + 1 + if 6 < hChild.HeadingLevel { + hChild.HeadingLevel = 6 } } } } - - mdBuf := &bytes.Buffer{} - for _, hChild := range hChildren { - md, _ = lute.FormatNodeSync(hChild, luteEngine.ParseOptions, luteEngine.RenderOptions) - mdBuf.WriteString(md) - mdBuf.WriteString("\n\n") - } - md = mdBuf.String() - } else { - node := treenode.GetNodeInTree(subTree, sqlBlock.ID) - md, _ = lute.FormatNodeSync(node, luteEngine.ParseOptions, luteEngine.RenderOptions) } - buf := &bytes.Buffer{} - lines := strings.Split(md, "\n") - for i, line := range lines { - if 0 == blockEmbedMode { // 使用原始文本 - buf.WriteString(line) - } else { // 使用引述块 - buf.WriteString("> " + line) - } - if i < len(lines)-1 { - buf.WriteString("\n") - } + mdBuf := &bytes.Buffer{} + for _, hChild := range hChildren { + md, _ = lute.FormatNodeSync(hChild, luteEngine.ParseOptions, luteEngine.RenderOptions) + mdBuf.WriteString(md) + mdBuf.WriteString("\n\n") } - buf.WriteString("\n\n") + md = mdBuf.String() + } else { + node := treenode.GetNodeInTree(subTree, sqlBlock.ID) + md, _ = lute.FormatNodeSync(node, luteEngine.ParseOptions, luteEngine.RenderOptions) + } - subTree = parse.Parse("", buf.Bytes(), luteEngine.ParseOptions) - var inserts []*ast.Node - for subNode := subTree.Root.FirstChild; nil != subNode; subNode = subNode.Next { - if ast.NodeKramdownBlockIAL != subNode.Type { - inserts = append(inserts, subNode) - } + buf := &bytes.Buffer{} + lines := strings.Split(md, "\n") + for i, line := range lines { + if 0 == blockEmbedMode { // 使用原始文本 + buf.WriteString(line) + } else { // 使用引述块 + buf.WriteString("> " + line) } - if 2 < len(n.KramdownIAL) && 0 < len(inserts) { - if bookmark := n.IALAttr("bookmark"); "" != bookmark { - inserts[0].SetIALAttr("bookmark", bookmark) - } - if name := n.IALAttr("name"); "" != name { - inserts[0].SetIALAttr("name", name) - } - if alias := n.IALAttr("alias"); "" != alias { - inserts[0].SetIALAttr("alias", alias) - } - if memo := n.IALAttr("memo"); "" != memo { - inserts[0].SetIALAttr("memo", memo) - } - } - for _, insert := range inserts { - n.InsertBefore(insert) - - if gulu.Str.Contains(sqlBlock.ID, *resolved) { - return ast.WalkContinue - } - - resolveEmbedR(insert, blockEmbedMode, luteEngine, resolved, depth) + if i < len(lines)-1 { + buf.WriteString("\n") } } - unlinks = append(unlinks, n) - return ast.WalkSkipChildren + buf.WriteString("\n\n") + + subTree = parse.Parse("", buf.Bytes(), luteEngine.ParseOptions) + var inserts []*ast.Node + for subNode := subTree.Root.FirstChild; nil != subNode; subNode = subNode.Next { + if ast.NodeKramdownBlockIAL != subNode.Type { + inserts = append(inserts, subNode) + } + } + if 2 < len(n.KramdownIAL) && 0 < len(inserts) { + if bookmark := n.IALAttr("bookmark"); "" != bookmark { + inserts[0].SetIALAttr("bookmark", bookmark) + } + if name := n.IALAttr("name"); "" != name { + inserts[0].SetIALAttr("name", name) + } + if alias := n.IALAttr("alias"); "" != alias { + inserts[0].SetIALAttr("alias", alias) + } + if memo := n.IALAttr("memo"); "" != memo { + inserts[0].SetIALAttr("memo", memo) + } + } + for _, insert := range inserts { + n.InsertBefore(insert) + + if gulu.Str.Contains(sqlBlock.ID, *resolved) { + return ast.WalkContinue + } + + resolveEmbedR(insert, blockEmbedMode, luteEngine, resolved, depth) + *depth-- + } } - return ast.WalkContinue + unlinks = append(unlinks, n) + return ast.WalkSkipChildren }) + for _, unlink := range unlinks { unlink.Unlink() } diff --git a/kernel/util/working_mobile.go b/kernel/util/working_mobile.go index f7fc0b942..9d8fb3cea 100644 --- a/kernel/util/working_mobile.go +++ b/kernel/util/working_mobile.go @@ -21,6 +21,7 @@ import ( "os" "path/filepath" "runtime" + "strings" "time" "github.com/88250/gulu" @@ -117,6 +118,7 @@ func initWorkspaceDirMobile(workspaceBaseDir string) { var workspacePaths []string if !gulu.File.IsExist(workspaceConf) { + logging.LogInfof("workspace conf [%s] not exist, use the default workspace [%s]", workspaceConf, defaultWorkspaceDir) WorkspaceDir = defaultWorkspaceDir if !gulu.File.IsDir(WorkspaceDir) { logging.LogWarnf("use the default workspace [%s] since the specified workspace [%s] is not a dir", WorkspaceDir, defaultWorkspaceDir) @@ -125,6 +127,8 @@ func initWorkspaceDirMobile(workspaceBaseDir string) { workspacePaths = append(workspacePaths, WorkspaceDir) } else { workspacePaths, _ = ReadWorkspacePaths() + logging.LogInfof("1 read workspace paths [%s]", strings.Join(workspacePaths, ",")) + if 0 < len(workspacePaths) { WorkspaceDir = workspacePaths[len(workspacePaths)-1] if !gulu.File.IsDir(WorkspaceDir) { @@ -136,8 +140,12 @@ func initWorkspaceDirMobile(workspaceBaseDir string) { WorkspaceDir = defaultWorkspaceDir workspacePaths = append(workspacePaths, WorkspaceDir) } + + logging.LogInfof("2 read workspace paths [%s]", strings.Join(workspacePaths, ",")) } + logging.LogInfof("3 read workspace paths [%s]", strings.Join(workspacePaths, ",")) + if err := WriteWorkspacePaths(workspacePaths); err != nil { logging.LogErrorf("write workspace conf [%s] failed: %s", workspaceConf, err) os.Exit(logging.ExitCodeInitWorkspaceErr)