diff --git a/kernel/av/av.go b/kernel/av/av.go index 204b341e1..095492b80 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -606,8 +606,9 @@ var ( ) const ( - NodeAttrNameAvs = "custom-avs" // 用于标记块所属的属性视图,逗号分隔 av id - NodeAttrView = "custom-sy-av-view" // 用于标记块所属的属性视图视图 view id Database block support specified view https://github.com/siyuan-note/siyuan/issues/10443 + NodeAttrNameAvs = "custom-avs" // 用于标记块所属的属性视图,逗号分隔 av id + NodeAttrView = "custom-sy-av-view" // 用于标记块所属的属性视图视图 view id Database block support specified view https://github.com/siyuan-note/siyuan/issues/10443 + NodeAttrViewStaticText = "custom-sy-av-s-text" // 用于标记块所属的属性视图静态文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049 NodeAttrViewNames = "av-names" // 用于临时标记块所属的属性视图名称,空格分隔 ) diff --git a/kernel/model/appearance.go b/kernel/model/appearance.go index cd08f0248..dca1f2b09 100644 --- a/kernel/model/appearance.go +++ b/kernel/model/appearance.go @@ -65,6 +65,8 @@ func InitAppearance() { } Conf.Save() + + util.InitEmojiChars() } func containTheme(name string, themes []*conf.AppearanceTheme) bool { diff --git a/kernel/model/assets.go b/kernel/model/assets.go index 160b10fb4..179c71f6f 100644 --- a/kernel/model/assets.go +++ b/kernel/model/assets.go @@ -962,7 +962,7 @@ func MissingAssets() (ret []string) { func emojisInTree(tree *parse.Tree) (ret []string) { if icon := tree.Root.IALAttr("icon"); "" != icon { - if !strings.Contains(icon, "://") && !strings.HasPrefix(icon, "api/icon/") { + if !strings.Contains(icon, "://") && !strings.HasPrefix(icon, "api/icon/") && !util.NativeEmojiChars[icon] { ret = append(ret, "/emojis/"+icon) } } diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index cb829e53c..9899d58fb 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -560,6 +560,13 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) { // 先处理关联列、汇总列、创建时间列和更新时间列 for _, kv := range keyValues { switch kv.Key.Type { + case av.KeyTypeBlock: // 对于主键可能需要填充静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049 + if nil != kv.Values[0].Block { + ial := sql.GetBlockAttrs(blockID) + if v := ial[av.NodeAttrViewStaticText+"-"+attrView.ID]; "" != v { + kv.Values[0].Block.Content = v + } + } case av.KeyTypeRollup: if nil == kv.Key.Rollup { break @@ -3099,8 +3106,13 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID string, valueDa unbindBlockAv(tx, avID, oldBoundBlockID) bindBlockAv(tx, avID, val.BlockID) } else { // 之前绑定的块和现在绑定的块一样 - // 直接返回,因为锚文本不允许更改 - return + // 设置静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049 + node, tree, getErr := getNodeByBlockID(tx, val.BlockID) + if nil != getErr || nil == node { + return + } + + updateBlockValueStaticText(node, tree, avID, strings.TrimSpace(val.Block.Content)) } } } @@ -3269,6 +3281,21 @@ func bindBlockAv0(tx *Transaction, avID string, node *ast.Node, tree *parse.Tree return } +func updateBlockValueStaticText(node *ast.Node, tree *parse.Tree, avID, text string) { + attrs := parse.IAL2Map(node.KramdownIAL) + attrs[av.NodeAttrViewStaticText+"-"+avID] = text + var err error + if nil != tree { + err = setNodeAttrsWithTx(nil, node, tree, attrs) + } else { + err = setNodeAttrs(node, nil, attrs) + } + if err != nil { + logging.LogWarnf("set node [%s] attrs failed: %s", node.ID, err) + return + } +} + func getNodeByBlockID(tx *Transaction, blockID string) (node *ast.Node, tree *parse.Tree, err error) { if nil != tx { tree, err = tx.loadTree(blockID) diff --git a/kernel/model/export.go b/kernel/model/export.go index 9b59e5edd..1b2dbffba 100644 --- a/kernel/model/export.go +++ b/kernel/model/export.go @@ -610,6 +610,7 @@ func ExportDocx(id, savePath string, removeAssets, merge bool) (fullPath string, } defer os.Remove(tmpDir) name, content := ExportMarkdownHTML(id, tmpDir, true, merge) + content = strings.ReplaceAll(content, " \n", "
\n") tmpDocxPath := filepath.Join(tmpDir, name+".docx") args := []string{ // pandoc -f html --resource-path=请从这里开始 请从这里开始\index.html -o test.docx @@ -752,7 +753,6 @@ func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string to := filepath.Join(savePath, emoji) if err := filelock.Copy(from, to); err != nil { logging.LogErrorf("copy emojis from [%s] to [%s] failed: %s", from, to, err) - return } } @@ -910,7 +910,6 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do to := filepath.Join(savePath, emoji) if err := filelock.Copy(from, to); err != nil { logging.LogErrorf("copy emojis from [%s] to [%s] failed: %s", from, to, err) - return } } } diff --git a/kernel/sql/av.go b/kernel/sql/av.go index 16f1846fc..97adf803f 100644 --- a/kernel/sql/av.go +++ b/kernel/sql/av.go @@ -195,6 +195,15 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s for _, row := range ret.Rows { for _, cell := range row.Cells { switch cell.ValueType { + case av.KeyTypeBlock: // 对于主键可能需要填充静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049 + if nil != cell.Value.Block { + for k, v := range ials[row.ID] { + if k == av.NodeAttrViewStaticText+"-"+attrView.ID { + cell.Value.Block.Content = v + break + } + } + } case av.KeyTypeRollup: // 渲染汇总列 rollupKey, _ := attrView.GetKey(cell.Value.KeyID) if nil == rollupKey || nil == rollupKey.Rollup { diff --git a/kernel/util/rune.go b/kernel/util/rune.go index 77de77a07..3e385d5ae 100644 --- a/kernel/util/rune.go +++ b/kernel/util/rune.go @@ -17,10 +17,13 @@ package util import ( + "os" + "path/filepath" "regexp" "unicode" "github.com/88250/gulu" + "github.com/siyuan-note/logging" ) func ContainsCJK(text string) bool { @@ -65,3 +68,29 @@ func RemoveInvalid(text string) (ret string) { ret = gulu.Str.RemovePUA(ret) return } + +var NativeEmojiChars = map[string]bool{} + +func InitEmojiChars() { + builtConfPath := filepath.Join(AppearancePath, "emojis", "conf.json") + data, err := os.ReadFile(builtConfPath) + if err != nil { + logging.LogErrorf("read emojis conf.json failed: %s", err) + return + } + + var conf []map[string]interface{} + if err = gulu.JSON.UnmarshalJSON(data, &conf); err != nil { + logging.LogErrorf("unmarshal emojis conf.json failed: %s", err) + return + } + + for _, emoji := range conf { + items := emoji["items"].([]interface{}) + for _, item := range items { + e := item.(map[string]interface{}) + NativeEmojiChars[e["unicode"].(string)] = true + } + } + return +}