mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-09-22 00:20:47 +02:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
d8bb794437
8 changed files with 164 additions and 134 deletions
|
@ -128,7 +128,7 @@ func listDocTree(c *gin.Context) {
|
|||
doctree = append(doctree, parent)
|
||||
|
||||
subPath := filepath.Join(root, entry.Name())
|
||||
if err = walkDocTree(subPath, parent, &ids); err != nil {
|
||||
if err = walkDocTree(subPath, parent, ids); err != nil {
|
||||
ret.Code = -1
|
||||
ret.Msg = err.Error()
|
||||
return
|
||||
|
@ -152,7 +152,7 @@ type DocFile struct {
|
|||
Children []*DocFile `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
|
||||
func walkDocTree(p string, docFile *DocFile, ids map[string]bool) (err error) {
|
||||
dir, err := os.ReadDir(p)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -169,7 +169,7 @@ func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
|
|||
}
|
||||
|
||||
parent := &DocFile{ID: entry.Name()}
|
||||
(*ids)[parent.ID] = true
|
||||
ids[parent.ID] = true
|
||||
docFile.Children = append(docFile.Children, parent)
|
||||
|
||||
subPath := filepath.Join(p, entry.Name())
|
||||
|
@ -178,10 +178,10 @@ func walkDocTree(p string, docFile *DocFile, ids *map[string]bool) (err error) {
|
|||
}
|
||||
} else {
|
||||
doc := &DocFile{ID: strings.TrimSuffix(entry.Name(), ".sy")}
|
||||
if !(*ids)[doc.ID] {
|
||||
if !ids[doc.ID] {
|
||||
docFile.Children = append(docFile.Children, doc)
|
||||
}
|
||||
(*ids)[doc.ID] = true
|
||||
ids[doc.ID] = true
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
|
@ -27,7 +27,8 @@ import (
|
|||
// ViewFilter 描述了视图过滤规则的结构。
|
||||
type ViewFilter struct {
|
||||
Column string `json:"column"` // 列(字段)ID
|
||||
Operator FilterOperator `json:"operator"` // 过滤操作符
|
||||
Qualifier FilterQuantifier `json:"quantifier,omitempty"` // 量词
|
||||
Operator FilterOperator `json:"operator"` // 操作符
|
||||
Value *Value `json:"value"` // 过滤值
|
||||
RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间
|
||||
RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween
|
||||
|
@ -76,7 +77,16 @@ const (
|
|||
FilterOperatorIsFalse FilterOperator = "Is false"
|
||||
)
|
||||
|
||||
func Filter(viewable Viewable, attrView *AttributeView) {
|
||||
type FilterQuantifier string
|
||||
|
||||
const (
|
||||
FilterQuantifierUndefined FilterQuantifier = ""
|
||||
FilterQuantifierAny FilterQuantifier = "Any"
|
||||
FilterQuantifierAll FilterQuantifier = "All"
|
||||
FilterQuantifierNone FilterQuantifier = "None"
|
||||
)
|
||||
|
||||
func Filter(viewable Viewable, attrView *AttributeView, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) {
|
||||
collection := viewable.(Collection)
|
||||
filters := collection.GetFilters()
|
||||
if 1 > len(filters) {
|
||||
|
@ -94,8 +104,6 @@ func Filter(viewable Viewable, attrView *AttributeView) {
|
|||
}
|
||||
|
||||
var items []Item
|
||||
attrViewCache := map[string]*AttributeView{}
|
||||
attrViewCache[attrView.ID] = attrView
|
||||
for _, item := range collection.GetItems() {
|
||||
pass := true
|
||||
values := item.GetValues()
|
||||
|
@ -116,7 +124,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
|
|||
break
|
||||
}
|
||||
|
||||
if !values[index].Filter(filters[j], attrView, item.GetID(), &attrViewCache) {
|
||||
if !values[index].Filter(filters[j], attrView, item.GetID(), rollupFurtherCollections, cachedAttrViews) {
|
||||
pass = false
|
||||
break
|
||||
}
|
||||
|
@ -128,7 +136,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
|
|||
collection.SetItems(items)
|
||||
}
|
||||
|
||||
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID string, attrViewCache *map[string]*AttributeView) bool {
|
||||
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, itemID string, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) bool {
|
||||
if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) {
|
||||
return true
|
||||
}
|
||||
|
@ -149,7 +157,6 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
|||
nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) {
|
||||
// 单独处理汇总类型的比较
|
||||
|
||||
// 处理值比较
|
||||
key, _ := attrView.GetKey(value.KeyID)
|
||||
if nil == key {
|
||||
return false
|
||||
|
@ -160,16 +167,16 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
|||
return false
|
||||
}
|
||||
|
||||
relVal := attrView.GetValue(relKey.ID, rowID)
|
||||
relVal := attrView.GetValue(relKey.ID, itemID)
|
||||
if nil == relVal || nil == relVal.Relation {
|
||||
return false
|
||||
}
|
||||
|
||||
destAv := (*attrViewCache)[relKey.Relation.AvID]
|
||||
destAv := cachedAttrViews[relKey.Relation.AvID]
|
||||
if nil == destAv {
|
||||
destAv, _ = ParseAttributeView(relKey.Relation.AvID)
|
||||
if nil != destAv {
|
||||
(*attrViewCache)[relKey.Relation.AvID] = destAv
|
||||
cachedAttrViews[relKey.Relation.AvID] = destAv
|
||||
}
|
||||
}
|
||||
if nil == destAv {
|
||||
|
@ -181,7 +188,10 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
|||
return false
|
||||
}
|
||||
|
||||
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, nil)
|
||||
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, rollupFurtherCollections[key.ID])
|
||||
|
||||
switch filter.Qualifier {
|
||||
case FilterQuantifierUndefined, FilterQuantifierAny:
|
||||
for _, content := range value.Rollup.Contents {
|
||||
switch filter.Operator {
|
||||
case FilterOperatorContains:
|
||||
|
@ -189,8 +199,7 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
|||
return true
|
||||
}
|
||||
case FilterOperatorDoesNotContain:
|
||||
ret := content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator)
|
||||
if !ret {
|
||||
if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
|
@ -199,16 +208,22 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch filter.Operator {
|
||||
case FilterOperatorContains:
|
||||
case FilterQuantifierAll:
|
||||
for _, content := range value.Rollup.Contents {
|
||||
if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||||
return false
|
||||
case FilterOperatorDoesNotContain:
|
||||
}
|
||||
}
|
||||
return true
|
||||
default:
|
||||
case FilterQuantifierNone:
|
||||
for _, content := range value.Rollup.Contents {
|
||||
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if nil != value.Relation && KeyTypeRelation == value.Type && nil != filter.Value && KeyTypeRelation == filter.Value.Type &&
|
||||
nil != filter.Value.Relation && 0 < len(filter.Value.Relation.BlockIDs) {
|
||||
|
@ -523,17 +538,17 @@ func filterRelativeTime(valueMills int64, valueIsNotEmpty bool, operator FilterO
|
|||
|
||||
switch operator {
|
||||
case FilterOperatorIsEqual:
|
||||
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && valueTime.Before(otherValueEnd)
|
||||
return (valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)) && (valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd))
|
||||
case FilterOperatorIsNotEqual:
|
||||
return valueTime.Before(otherValueStart) || valueTime.After(otherValueEnd)
|
||||
case FilterOperatorIsGreater:
|
||||
return valueTime.After(otherValueStart)
|
||||
return valueTime.After(otherValueEnd)
|
||||
case FilterOperatorIsGreaterOrEqual:
|
||||
return valueTime.After(otherValueStart) || valueTime.Equal(otherValueStart)
|
||||
case FilterOperatorIsLess:
|
||||
return valueTime.Before(otherValueStart)
|
||||
case FilterOperatorIsLessOrEqual:
|
||||
return valueTime.Before(otherValueStart) || valueTime.Equal(otherValueStart)
|
||||
return valueTime.Before(otherValueEnd) || valueTime.Equal(otherValueEnd)
|
||||
case FilterOperatorIsBetween:
|
||||
if RelativeDateDirectionBefore == direction {
|
||||
if RelativeDateDirectionBefore == direction2 {
|
||||
|
|
|
@ -1465,16 +1465,16 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
|||
return
|
||||
}
|
||||
|
||||
attrViewCache := map[string]*av.AttributeView{}
|
||||
cachedAttrViews := map[string]*av.AttributeView{}
|
||||
avIDs := strings.Split(avs, ",")
|
||||
for _, avID := range avIDs {
|
||||
attrView := attrViewCache[avID]
|
||||
attrView := cachedAttrViews[avID]
|
||||
if nil == attrView {
|
||||
attrView, _ = av.ParseAttributeView(avID)
|
||||
if nil == attrView {
|
||||
return
|
||||
}
|
||||
attrViewCache[avID] = attrView
|
||||
cachedAttrViews[avID] = attrView
|
||||
}
|
||||
|
||||
if !attrView.ExistBoundBlock(nodeID) {
|
||||
|
@ -1572,42 +1572,7 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
|||
|
||||
// 再渲染关联和汇总
|
||||
|
||||
rollupFurtherCollections := map[string]av.Collection{}
|
||||
for _, kv := range keyValues {
|
||||
if av.KeyTypeRollup != kv.Key.Type {
|
||||
continue
|
||||
}
|
||||
|
||||
relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
|
||||
if nil == relKey {
|
||||
continue
|
||||
}
|
||||
|
||||
destAv := attrViewCache[relKey.Relation.AvID]
|
||||
if nil == destAv {
|
||||
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
|
||||
if nil == destAv {
|
||||
continue
|
||||
}
|
||||
attrViewCache[relKey.Relation.AvID] = destAv
|
||||
}
|
||||
|
||||
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
isSameAv := destAv.ID == attrView.ID
|
||||
|
||||
var furtherCollection av.Collection
|
||||
if av.KeyTypeTemplate == destKey.Type || (!isSameAv && (av.KeyTypeUpdated == destKey.Type || av.KeyTypeCreated == destKey.Type)) {
|
||||
viewable := sql.RenderView(destAv, destAv.Views[0], "")
|
||||
if nil != viewable {
|
||||
furtherCollection = viewable.(av.Collection)
|
||||
}
|
||||
}
|
||||
rollupFurtherCollections[kv.Key.ID] = furtherCollection
|
||||
}
|
||||
|
||||
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
|
||||
for _, kv := range keyValues {
|
||||
switch kv.Key.Type {
|
||||
case av.KeyTypeRollup:
|
||||
|
@ -1622,13 +1587,13 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
|||
|
||||
relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID)
|
||||
if nil != relVal && nil != relVal.Relation {
|
||||
destAv := attrViewCache[relKey.Relation.AvID]
|
||||
destAv := cachedAttrViews[relKey.Relation.AvID]
|
||||
if nil == destAv {
|
||||
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
|
||||
if nil == destAv {
|
||||
break
|
||||
}
|
||||
attrViewCache[relKey.Relation.AvID] = destAv
|
||||
cachedAttrViews[relKey.Relation.AvID] = destAv
|
||||
}
|
||||
|
||||
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
|
||||
|
@ -1642,14 +1607,14 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
|
|||
break
|
||||
}
|
||||
|
||||
destAv := attrViewCache[kv.Key.Relation.AvID]
|
||||
destAv := cachedAttrViews[kv.Key.Relation.AvID]
|
||||
if nil == destAv {
|
||||
destAv, _ = av.ParseAttributeView(kv.Key.Relation.AvID)
|
||||
if nil == destAv {
|
||||
break
|
||||
}
|
||||
|
||||
attrViewCache[kv.Key.Relation.AvID] = destAv
|
||||
cachedAttrViews[kv.Key.Relation.AvID] = destAv
|
||||
}
|
||||
|
||||
blocks := map[string]*av.Value{}
|
||||
|
@ -2070,8 +2035,10 @@ func GetCurrentAttributeViewImages(avID, viewID, query string) (ret []string, er
|
|||
view = attrView.GetView(attrView.ViewID)
|
||||
}
|
||||
|
||||
cachedAttrViews := map[string]*av.AttributeView{}
|
||||
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
|
||||
table := getAttrViewTable(attrView, view, query)
|
||||
av.Filter(table, attrView)
|
||||
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
|
||||
av.Sort(table, attrView)
|
||||
|
||||
ids := map[string]bool{}
|
||||
|
@ -2566,6 +2533,7 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr
|
|||
for _, filter := range masterView.Filters {
|
||||
view.Filters = append(view.Filters, &av.ViewFilter{
|
||||
Column: filter.Column,
|
||||
Qualifier: filter.Qualifier,
|
||||
Operator: filter.Operator,
|
||||
Value: filter.Value,
|
||||
RelativeDate: filter.RelativeDate,
|
||||
|
@ -3284,8 +3252,10 @@ func getNewValueByNearItem(nearItem av.Item, key *av.Key, addingBlockID string)
|
|||
}
|
||||
|
||||
func getNearItem(attrView *av.AttributeView, view, groupView *av.View, previousItemID string) (ret av.Item) {
|
||||
cachedAttrViews := map[string]*av.AttributeView{}
|
||||
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
|
||||
viewable := sql.RenderGroupView(attrView, view, groupView, "")
|
||||
av.Filter(viewable, attrView)
|
||||
av.Filter(viewable, attrView, rollupFurtherCollections, cachedAttrViews)
|
||||
av.Sort(viewable, attrView)
|
||||
items := viewable.(av.Collection).GetItems()
|
||||
if 0 < len(items) {
|
||||
|
|
|
@ -377,7 +377,9 @@ func renderViewableInstance(viewable av.Viewable, view *av.View, attrView *av.At
|
|||
return
|
||||
}
|
||||
|
||||
av.Filter(viewable, attrView)
|
||||
cachedAttrViews := map[string]*av.AttributeView{}
|
||||
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
|
||||
av.Filter(viewable, attrView, rollupFurtherCollections, cachedAttrViews)
|
||||
av.Sort(viewable, attrView)
|
||||
av.Calc(viewable, attrView)
|
||||
|
||||
|
|
|
@ -83,7 +83,9 @@ func ExportAv2CSV(avID, blockID string) (zipPath string, err error) {
|
|||
table := getAttrViewTable(attrView, view, "")
|
||||
|
||||
// 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474
|
||||
av.Filter(table, attrView)
|
||||
cachedAttrViews := map[string]*av.AttributeView{}
|
||||
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
|
||||
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
|
||||
av.Sort(table, attrView)
|
||||
|
||||
exportFolder := filepath.Join(util.TempDir, "export", "csv", name)
|
||||
|
@ -273,7 +275,7 @@ func Export2Liandi(id string) (err error) {
|
|||
".md", 3, 1, 1,
|
||||
"#", "#",
|
||||
"", "",
|
||||
false, false, nil, true, false, &map[string]*parse.Tree{})
|
||||
false, false, nil, true, false, map[string]*parse.Tree{})
|
||||
result := gulu.Ret.NewResult()
|
||||
request := httpclient.NewCloudRequest30s()
|
||||
request = request.
|
||||
|
@ -584,7 +586,7 @@ func Preview(id string, fillCSSVar bool) (retStdHTML string) {
|
|||
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
|
||||
"#", "#", // 这里固定使用 # 包裹标签,否则无法正确解析标签 https://github.com/siyuan-note/siyuan/issues/13857
|
||||
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, &map[string]*parse.Tree{})
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, map[string]*parse.Tree{})
|
||||
luteEngine := NewLute()
|
||||
enableLuteInlineSyntax(luteEngine)
|
||||
luteEngine.SetFootnotes(true)
|
||||
|
@ -722,7 +724,7 @@ func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string
|
|||
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
|
||||
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
|
||||
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, &map[string]*parse.Tree{})
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, map[string]*parse.Tree{})
|
||||
name = path.Base(tree.HPath)
|
||||
name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614
|
||||
savePath = strings.TrimSpace(savePath)
|
||||
|
@ -884,7 +886,7 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
|
|||
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
|
||||
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
|
||||
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, &map[string]*parse.Tree{})
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, true, true, map[string]*parse.Tree{})
|
||||
adjustHeadingLevel(bt, tree)
|
||||
name = path.Base(tree.HPath)
|
||||
name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614
|
||||
|
@ -1518,7 +1520,7 @@ func ExportStdMarkdown(id string, assetsDestSpace2Underscore, fillCSSVar, adjust
|
|||
".md", Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
|
||||
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
|
||||
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, defBlockIDs, true, fillCSSVar, &map[string]*parse.Tree{})
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, defBlockIDs, true, fillCSSVar, map[string]*parse.Tree{})
|
||||
}
|
||||
|
||||
func ExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) {
|
||||
|
@ -1684,7 +1686,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
|||
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(70), fmt.Sprintf("%d/%d %s", count, len(docPaths), tree.Root.IALAttr("title"))))
|
||||
|
||||
refs := map[string]*parse.Tree{}
|
||||
exportRefTrees(tree, &[]string{}, &refs, &treeCache)
|
||||
exportRefTrees(tree, &[]string{}, refs, treeCache)
|
||||
for refTreeID, refTree := range refs {
|
||||
if nil == trees[refTreeID] {
|
||||
refTrees[refTreeID] = refTree
|
||||
|
@ -2012,7 +2014,7 @@ func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar
|
|||
".md", refMode, embedMode, Conf.Export.FileAnnotationRefMode,
|
||||
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
|
||||
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, nil, true, fillCSSVar, &map[string]*parse.Tree{})
|
||||
Conf.Export.AddTitle, Conf.Export.InlineMemo, nil, true, fillCSSVar, map[string]*parse.Tree{})
|
||||
docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
|
||||
if addYfm {
|
||||
exportedMd = yfm(docIAL) + exportedMd
|
||||
|
@ -2020,7 +2022,7 @@ func ExportMarkdownContent(id string, refMode, embedMode int, addYfm, fillCSSVar
|
|||
return
|
||||
}
|
||||
|
||||
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache *map[string]*parse.Tree) (tree *parse.Tree, exportedMd string, isEmpty bool) {
|
||||
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache map[string]*parse.Tree) (tree *parse.Tree, exportedMd string, isEmpty bool) {
|
||||
tree, err := loadTreeWithCache(id, treeCache)
|
||||
if err != nil {
|
||||
logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
|
||||
|
@ -2055,7 +2057,7 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
|
|||
func exportMarkdownContent0(id string, tree *parse.Tree, cloudAssetsBase string, assetsDestSpace2Underscore, adjustHeadingLv, imgTag bool,
|
||||
ext string, blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
|
||||
tagOpenMarker, tagCloseMarker string, blockRefTextLeft, blockRefTextRight string,
|
||||
addTitle, inlineMemo bool, defBlockIDs []string, singleFile, fillCSSVar bool, treeCache *map[string]*parse.Tree) (ret string) {
|
||||
addTitle, inlineMemo bool, defBlockIDs []string, singleFile, fillCSSVar bool, treeCache map[string]*parse.Tree) (ret string) {
|
||||
tree = exportTree(tree, false, false, false,
|
||||
blockRefMode, blockEmbedMode, fileAnnotationRefMode,
|
||||
tagOpenMarker, tagCloseMarker,
|
||||
|
@ -2182,11 +2184,11 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
|
|||
blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
|
||||
tagOpenMarker, tagCloseMarker string,
|
||||
blockRefTextLeft, blockRefTextRight string,
|
||||
addTitle, inlineMemo, addDocAnchorSpan, singleFile bool, treeCache *map[string]*parse.Tree) (ret *parse.Tree) {
|
||||
addTitle, inlineMemo, addDocAnchorSpan, singleFile bool, treeCache map[string]*parse.Tree) (ret *parse.Tree) {
|
||||
luteEngine := NewLute()
|
||||
ret = tree
|
||||
id := tree.Root.ID
|
||||
(*treeCache)[tree.ID] = tree
|
||||
treeCache[tree.ID] = tree
|
||||
|
||||
// 解析查询嵌入节点
|
||||
depth := 0
|
||||
|
@ -2544,7 +2546,9 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
|
|||
table := getAttrViewTable(attrView, view, "")
|
||||
|
||||
// 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474
|
||||
av.Filter(table, attrView)
|
||||
cachedAttrViews := map[string]*av.AttributeView{}
|
||||
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
|
||||
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
|
||||
av.Sort(table, attrView)
|
||||
|
||||
var aligns []int
|
||||
|
@ -2821,7 +2825,7 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
|
|||
return ret
|
||||
}
|
||||
|
||||
func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tree, currentTreeNodeIDs map[string]bool, blockRefTextLeft, blockRefTextRight string, treeCache *map[string]*parse.Tree) (footnotesDefBlock *ast.Node) {
|
||||
func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tree, currentTreeNodeIDs map[string]bool, blockRefTextLeft, blockRefTextRight string, treeCache map[string]*parse.Tree) (footnotesDefBlock *ast.Node) {
|
||||
if 1 > len(*refFootnotes) {
|
||||
return nil
|
||||
}
|
||||
|
@ -2955,7 +2959,7 @@ func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, currentTree *parse.Tr
|
|||
return
|
||||
}
|
||||
|
||||
func blockLink2Ref(currentTree *parse.Tree, id string, treeCache *map[string]*parse.Tree, depth *int) {
|
||||
func blockLink2Ref(currentTree *parse.Tree, id string, treeCache map[string]*parse.Tree, depth *int) {
|
||||
*depth++
|
||||
if 4096 < *depth {
|
||||
return
|
||||
|
@ -2985,7 +2989,7 @@ func blockLink2Ref(currentTree *parse.Tree, id string, treeCache *map[string]*pa
|
|||
return
|
||||
}
|
||||
|
||||
func blockLink2Ref0(currentTree *parse.Tree, node *ast.Node, treeCache *map[string]*parse.Tree, depth *int) {
|
||||
func blockLink2Ref0(currentTree *parse.Tree, node *ast.Node, treeCache map[string]*parse.Tree, depth *int) {
|
||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering {
|
||||
return ast.WalkContinue
|
||||
|
@ -3006,7 +3010,7 @@ func blockLink2Ref0(currentTree *parse.Tree, node *ast.Node, treeCache *map[stri
|
|||
})
|
||||
}
|
||||
|
||||
func collectFootnotesDefs(currentTree *parse.Tree, id string, refFootnotes *[]*refAsFootnotes, treeCache *map[string]*parse.Tree, depth *int) {
|
||||
func collectFootnotesDefs(currentTree *parse.Tree, id string, refFootnotes *[]*refAsFootnotes, treeCache map[string]*parse.Tree, depth *int) {
|
||||
*depth++
|
||||
if 4096 < *depth {
|
||||
return
|
||||
|
@ -3035,7 +3039,7 @@ func collectFootnotesDefs(currentTree *parse.Tree, id string, refFootnotes *[]*r
|
|||
return
|
||||
}
|
||||
|
||||
func collectFootnotesDefs0(currentTree *parse.Tree, node *ast.Node, refFootnotes *[]*refAsFootnotes, treeCache *map[string]*parse.Tree, depth *int) {
|
||||
func collectFootnotesDefs0(currentTree *parse.Tree, node *ast.Node, refFootnotes *[]*refAsFootnotes, treeCache map[string]*parse.Tree, depth *int) {
|
||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering {
|
||||
return ast.WalkContinue
|
||||
|
@ -3143,7 +3147,7 @@ func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode i
|
|||
}
|
||||
|
||||
func exportPandocConvertZip(baseFolderName string, docPaths, defBlockIDs []string,
|
||||
pandocFrom, pandocTo, ext string, treeCache *map[string]*parse.Tree) (zipPath string) {
|
||||
pandocFrom, pandocTo, ext string, treeCache map[string]*parse.Tree) (zipPath string) {
|
||||
defer util.ClearPushProgress(100)
|
||||
|
||||
dir, name := path.Split(baseFolderName)
|
||||
|
@ -3296,9 +3300,9 @@ func getExportBlockRefLinkText(blockRef *ast.Node, blockRefTextLeft, blockRefTex
|
|||
return
|
||||
}
|
||||
|
||||
func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees *map[string]*parse.Tree, relatedDocPaths []string) {
|
||||
trees = &map[string]*parse.Tree{}
|
||||
treeCache := &map[string]*parse.Tree{}
|
||||
func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees map[string]*parse.Tree, relatedDocPaths []string) {
|
||||
trees = map[string]*parse.Tree{}
|
||||
treeCache := map[string]*parse.Tree{}
|
||||
defBlockIDs = []string{}
|
||||
for i, p := range docPaths {
|
||||
rootID := strings.TrimSuffix(path.Base(p), ".sy")
|
||||
|
@ -3315,18 +3319,18 @@ func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees *map[str
|
|||
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(70), fmt.Sprintf("%d/%d %s", i+1, len(docPaths), tree.Root.IALAttr("title"))))
|
||||
}
|
||||
|
||||
for _, tree := range *trees {
|
||||
for _, tree := range trees {
|
||||
relatedDocPaths = append(relatedDocPaths, tree.Path)
|
||||
}
|
||||
relatedDocPaths = gulu.Str.RemoveDuplicatedElem(relatedDocPaths)
|
||||
return
|
||||
}
|
||||
|
||||
func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache *map[string]*parse.Tree) {
|
||||
if nil != (*retTrees)[tree.ID] {
|
||||
func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache map[string]*parse.Tree) {
|
||||
if nil != retTrees[tree.ID] {
|
||||
return
|
||||
}
|
||||
(*retTrees)[tree.ID] = tree
|
||||
retTrees[tree.ID] = tree
|
||||
|
||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering {
|
||||
|
@ -3345,14 +3349,14 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
|
|||
|
||||
var defTree *parse.Tree
|
||||
var err error
|
||||
if (*treeCache)[defBlock.RootID] != nil {
|
||||
defTree = (*treeCache)[defBlock.RootID]
|
||||
if treeCache[defBlock.RootID] != nil {
|
||||
defTree = treeCache[defBlock.RootID]
|
||||
} else {
|
||||
defTree, err = loadTreeWithCache(defBlock.RootID, treeCache)
|
||||
if err != nil {
|
||||
return ast.WalkSkipChildren
|
||||
}
|
||||
(*treeCache)[defBlock.RootID] = defTree
|
||||
treeCache[defBlock.RootID] = defTree
|
||||
}
|
||||
*defBlockIDs = append(*defBlockIDs, defID)
|
||||
|
||||
|
@ -3369,14 +3373,14 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
|
|||
|
||||
var defTree *parse.Tree
|
||||
var err error
|
||||
if (*treeCache)[defBlock.RootID] != nil {
|
||||
defTree = (*treeCache)[defBlock.RootID]
|
||||
if treeCache[defBlock.RootID] != nil {
|
||||
defTree = treeCache[defBlock.RootID]
|
||||
} else {
|
||||
defTree, err = loadTreeWithCache(defBlock.RootID, treeCache)
|
||||
if err != nil {
|
||||
return ast.WalkSkipChildren
|
||||
}
|
||||
(*treeCache)[defBlock.RootID] = defTree
|
||||
treeCache[defBlock.RootID] = defTree
|
||||
}
|
||||
*defBlockIDs = append(*defBlockIDs, defID)
|
||||
|
||||
|
@ -3412,14 +3416,14 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
|
|||
|
||||
var defTree *parse.Tree
|
||||
var err error
|
||||
if (*treeCache)[defBlock.RootID] != nil {
|
||||
defTree = (*treeCache)[defBlock.RootID]
|
||||
if treeCache[defBlock.RootID] != nil {
|
||||
defTree = treeCache[defBlock.RootID]
|
||||
} else {
|
||||
defTree, err = loadTreeWithCache(defBlock.RootID, treeCache)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
(*treeCache)[defBlock.RootID] = defTree
|
||||
treeCache[defBlock.RootID] = defTree
|
||||
}
|
||||
*defBlockIDs = append(*defBlockIDs, val.BlockID)
|
||||
|
||||
|
@ -3432,13 +3436,13 @@ func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache
|
|||
*defBlockIDs = gulu.Str.RemoveDuplicatedElem(*defBlockIDs)
|
||||
}
|
||||
|
||||
func loadTreeWithCache(id string, treeCache *map[string]*parse.Tree) (tree *parse.Tree, err error) {
|
||||
if tree = (*treeCache)[id]; nil != tree {
|
||||
func loadTreeWithCache(id string, treeCache map[string]*parse.Tree) (tree *parse.Tree, err error) {
|
||||
if tree = treeCache[id]; nil != tree {
|
||||
return
|
||||
}
|
||||
tree, err = LoadTreeByBlockID(id)
|
||||
if nil == err && nil != tree {
|
||||
(*treeCache)[id] = tree
|
||||
treeCache[id] = tree
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -280,10 +280,10 @@ func generateAttrViewItems(attrView *av.AttributeView, view *av.View) (ret map[s
|
|||
return
|
||||
}
|
||||
|
||||
func filterNotFoundAttrViewItems(keyValuesMap *map[string][]*av.KeyValues) {
|
||||
func filterNotFoundAttrViewItems(keyValuesMap map[string][]*av.KeyValues) {
|
||||
var notFound []string
|
||||
var toCheckBlockIDs []string
|
||||
for blockID, keyValues := range *keyValuesMap {
|
||||
for blockID, keyValues := range keyValuesMap {
|
||||
blockValue := getBlockValue(keyValues)
|
||||
if nil == blockValue || nil == blockValue.Block {
|
||||
notFound = append(notFound, blockID)
|
||||
|
@ -308,7 +308,7 @@ func filterNotFoundAttrViewItems(keyValuesMap *map[string][]*av.KeyValues) {
|
|||
}
|
||||
}
|
||||
for _, blockID := range notFound {
|
||||
delete(*keyValuesMap, blockID)
|
||||
delete(keyValuesMap, blockID)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,6 +518,45 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection
|
|||
}
|
||||
}
|
||||
|
||||
func GetFurtherCollections(attrView *av.AttributeView, cachedAttrViews map[string]*av.AttributeView) (ret map[string]av.Collection) {
|
||||
ret = map[string]av.Collection{}
|
||||
for _, kv := range attrView.KeyValues {
|
||||
if av.KeyTypeRollup != kv.Key.Type {
|
||||
continue
|
||||
}
|
||||
|
||||
relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
|
||||
if nil == relKey {
|
||||
continue
|
||||
}
|
||||
|
||||
destAv := cachedAttrViews[relKey.Relation.AvID]
|
||||
if nil == destAv {
|
||||
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
|
||||
if nil == destAv {
|
||||
continue
|
||||
}
|
||||
cachedAttrViews[relKey.Relation.AvID] = destAv
|
||||
}
|
||||
|
||||
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
|
||||
if nil == destKey {
|
||||
continue
|
||||
}
|
||||
isSameAv := destAv.ID == attrView.ID
|
||||
|
||||
var furtherCollection av.Collection
|
||||
if av.KeyTypeTemplate == destKey.Type || (!isSameAv && (av.KeyTypeUpdated == destKey.Type || av.KeyTypeCreated == destKey.Type)) {
|
||||
viewable := RenderView(destAv, destAv.Views[0], "")
|
||||
if nil != viewable {
|
||||
furtherCollection = viewable.(av.Collection)
|
||||
}
|
||||
}
|
||||
ret[kv.Key.ID] = furtherCollection
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func fillAttributeViewTemplateValues(attrView *av.AttributeView, view *av.View, collection av.Collection, ials map[string]map[string]string) (err error) {
|
||||
items := generateAttrViewItems(attrView, view)
|
||||
existTemplateField := false
|
||||
|
|
|
@ -62,7 +62,7 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
|
|||
}
|
||||
|
||||
cardsValues := generateAttrViewItems(attrView, view) // 生成卡片
|
||||
filterNotFoundAttrViewItems(&cardsValues) // 过滤掉不存在的卡片
|
||||
filterNotFoundAttrViewItems(cardsValues) // 过滤掉不存在的卡片
|
||||
|
||||
// 批量加载绑定块对应的树
|
||||
var ialIDs []string
|
||||
|
|
|
@ -62,7 +62,7 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s
|
|||
}
|
||||
|
||||
rowsValues := generateAttrViewItems(attrView, view) // 生成行
|
||||
filterNotFoundAttrViewItems(&rowsValues) // 过滤掉不存在的行
|
||||
filterNotFoundAttrViewItems(rowsValues) // 过滤掉不存在的行
|
||||
|
||||
// 生成行单元格
|
||||
for rowID, rowValues := range rowsValues {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue