diff --git a/kernel/model/blockial.go b/kernel/model/blockial.go index d5f3db007..603af84d5 100644 --- a/kernel/model/blockial.go +++ b/kernel/model/blockial.go @@ -232,7 +232,7 @@ func setNodeAttrs0(node *ast.Node, nameValues map[string]string) (oldAttrs map[s } for name, value := range nameValues { - value = util.RemoveInvalid(value) + value = util.RemoveInvalidRetainCtrl(value) value = strings.TrimSpace(value) value = strings.TrimSuffix(value, ",") if "" == value { diff --git a/kernel/model/blockinfo.go b/kernel/model/blockinfo.go index f0e291fea..dc0b1f48d 100644 --- a/kernel/model/blockinfo.go +++ b/kernel/model/blockinfo.go @@ -240,7 +240,7 @@ func GetBlockRefText(id string) string { func GetDOMText(dom string) (ret string) { luteEngine := NewLute() tree := luteEngine.BlockDOM2Tree(dom) - ret = renderBlockText(tree.Root.FirstChild, nil) + ret = renderBlockText(tree.Root.FirstChild, nil, true) return } @@ -265,7 +265,7 @@ func getNodeRefText(node *ast.Node) string { ret = util.EscapeHTML(ret) return ret } - return getNodeRefText0(node, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + return getNodeRefText0(node, Conf.Editor.BlockRefDynamicAnchorTextMaxLen, true) } func getNodeAvBlockText(node *ast.Node) (icon, content string) { @@ -279,7 +279,7 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) { name = util.EscapeHTML(name) content = name } else { - content = getNodeRefText0(node, 1024) + content = getNodeRefText0(node, 1024, false) } content = strings.TrimSpace(content) @@ -290,7 +290,7 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) { return } -func getNodeRefText0(node *ast.Node, maxLen int) string { +func getNodeRefText0(node *ast.Node, maxLen int, removeLineBreak bool) string { switch node.Type { case ast.NodeBlockQueryEmbed: return "Query Embed Block..." @@ -313,7 +313,7 @@ func getNodeRefText0(node *ast.Node, maxLen int) string { if ast.NodeDocument != node.Type && node.IsContainerBlock() { node = treenode.FirstLeafBlock(node) } - ret := renderBlockText(node, nil) + ret := renderBlockText(node, nil, removeLineBreak) if maxLen < utf8.RuneCountInString(ret) { ret = gulu.Str.SubStr(ret, maxLen) + "..." } @@ -481,9 +481,9 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo } else { if "" == name { if ast.NodeListItem == parent.Type || ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type { - name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen) } else { - name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes, true), maxNameLen) } } if ast.NodeHeading == parent.Type { @@ -504,7 +504,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo } if ast.NodeListItem == parent.Type { if "" == name { - name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen) } } @@ -542,7 +542,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo continue } - name = gulu.Str.SubStr(renderBlockText(b, excludeTypes), maxNameLen) + name = gulu.Str.SubStr(renderBlockText(b, excludeTypes, true), maxNameLen) name = util.EscapeHTML(name) ret = append([]*BlockPath{{ ID: b.ID, diff --git a/kernel/model/heading.go b/kernel/model/heading.go index 0da46a492..b9749d0f3 100644 --- a/kernel/model/heading.go +++ b/kernel/model/heading.go @@ -296,7 +296,7 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath, previousPath string) (sr } box := Conf.Box(targetBoxID) - headingText := getNodeRefText0(headingNode, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + headingText := getNodeRefText0(headingNode, Conf.Editor.BlockRefDynamicAnchorTextMaxLen, true) if strings.Contains(headingText, "/") { headingText = strings.ReplaceAll(headingText, "/", "_") util.PushMsg(Conf.language(246), 7000) diff --git a/kernel/model/render.go b/kernel/model/render.go index 5fcace663..82d459e20 100644 --- a/kernel/model/render.go +++ b/kernel/model/render.go @@ -103,14 +103,16 @@ func renderOutline(heading *ast.Node, luteEngine *lute.Lute) (ret string) { return } -func renderBlockText(node *ast.Node, excludeTypes []string) (ret string) { +func renderBlockText(node *ast.Node, excludeTypes []string, removeLineBreak bool) (ret string) { if nil == node { return } ret = sql.NodeStaticContent(node, excludeTypes, false, false, false) ret = strings.TrimSpace(ret) - ret = strings.ReplaceAll(ret, "\n", "") + if removeLineBreak { + ret = strings.ReplaceAll(ret, "\n", "") + } ret = util.UnescapeHTML(ret) ret = util.EscapeHTML(ret) ret = strings.TrimSpace(ret) diff --git a/kernel/util/rune.go b/kernel/util/rune.go index 3e385d5ae..c6b3593a0 100644 --- a/kernel/util/rune.go +++ b/kernel/util/rune.go @@ -20,6 +20,7 @@ import ( "os" "path/filepath" "regexp" + "strings" "unicode" "github.com/88250/gulu" @@ -69,6 +70,13 @@ func RemoveInvalid(text string) (ret string) { return } +func RemoveInvalidRetainCtrl(text string) (ret string) { + ret = strings.ReplaceAll(text, "\u00A0", " ") // NBSP 转换为普通空格 + ret = gulu.Str.RemoveZeroWidthCharacters(ret) + ret = gulu.Str.RemovePUA(ret) + return +} + var NativeEmojiChars = map[string]bool{} func InitEmojiChars() {