mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-07 01:08:49 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
07f3de1c50
3 changed files with 59 additions and 38 deletions
|
|
@ -216,15 +216,6 @@ const (
|
|||
NumberFormatFranc NumberFormat = "franc"
|
||||
)
|
||||
|
||||
func NewValueNumber(content float64) *ValueNumber {
|
||||
return &ValueNumber{
|
||||
Content: content,
|
||||
IsNotEmpty: true,
|
||||
Format: NumberFormatNone,
|
||||
FormattedContent: fmt.Sprintf("%f", content),
|
||||
}
|
||||
}
|
||||
|
||||
func NewFormattedValueNumber(content float64, format NumberFormat) (ret *ValueNumber) {
|
||||
ret = &ValueNumber{
|
||||
Content: content,
|
||||
|
|
@ -483,9 +474,9 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
switch calc.Operator {
|
||||
case CalcOperatorNone:
|
||||
case CalcOperatorCountAll:
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(len(r.Contents)))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorCountValues:
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(len(r.Contents)))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorCountUniqueValues:
|
||||
countUniqueValues := 0
|
||||
uniqueValues := map[string]bool{}
|
||||
|
|
@ -495,7 +486,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
countUniqueValues++
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countUniqueValues))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorCountEmpty:
|
||||
countEmpty := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -503,7 +494,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
countEmpty++
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countEmpty))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorCountNotEmpty:
|
||||
countNonEmpty := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -511,7 +502,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
countNonEmpty++
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countNonEmpty))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorPercentEmpty:
|
||||
countEmpty := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -519,7 +510,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
countEmpty++
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countEmpty * 100 / len(r.Contents)))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(countEmpty*100/len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorPercentNotEmpty:
|
||||
countNonEmpty := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -527,7 +518,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
countNonEmpty++
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countNonEmpty * 100 / len(r.Contents)))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(countNonEmpty*100/len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorSum:
|
||||
sum := 0.0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -560,39 +551,39 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(numbers[len(numbers)/2], destKey.NumberFormat)}}
|
||||
}
|
||||
case CalcOperatorMin:
|
||||
min := math.MaxFloat64
|
||||
minVal := math.MaxFloat64
|
||||
for _, v := range r.Contents {
|
||||
if nil != v.Number {
|
||||
if v.Number.Content < min {
|
||||
min = v.Number.Content
|
||||
if v.Number.Content < minVal {
|
||||
minVal = v.Number.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(min, destKey.NumberFormat)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(minVal, destKey.NumberFormat)}}
|
||||
case CalcOperatorMax:
|
||||
max := -math.MaxFloat64
|
||||
maxVal := -math.MaxFloat64
|
||||
for _, v := range r.Contents {
|
||||
if nil != v.Number {
|
||||
if v.Number.Content > max {
|
||||
max = v.Number.Content
|
||||
if v.Number.Content > maxVal {
|
||||
maxVal = v.Number.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(max, destKey.NumberFormat)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(maxVal, destKey.NumberFormat)}}
|
||||
case CalcOperatorRange:
|
||||
min := math.MaxFloat64
|
||||
max := -math.MaxFloat64
|
||||
minVal := math.MaxFloat64
|
||||
maxVal := -math.MaxFloat64
|
||||
for _, v := range r.Contents {
|
||||
if nil != v.Number {
|
||||
if v.Number.Content < min {
|
||||
min = v.Number.Content
|
||||
if v.Number.Content < minVal {
|
||||
minVal = v.Number.Content
|
||||
}
|
||||
if v.Number.Content > max {
|
||||
max = v.Number.Content
|
||||
if v.Number.Content > maxVal {
|
||||
maxVal = v.Number.Content
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(max-min, destKey.NumberFormat)}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(maxVal-minVal, destKey.NumberFormat)}}
|
||||
case CalcOperatorChecked:
|
||||
countChecked := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -602,7 +593,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countChecked))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(countChecked), NumberFormatNone)}}
|
||||
case CalcOperatorUnchecked:
|
||||
countUnchecked := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -612,7 +603,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countUnchecked))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(countUnchecked), NumberFormatNone)}}
|
||||
case CalcOperatorPercentChecked:
|
||||
countChecked := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -622,7 +613,7 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countChecked * 100 / len(r.Contents)))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(countChecked*100/len(r.Contents)), NumberFormatNone)}}
|
||||
case CalcOperatorPercentUnchecked:
|
||||
countUnchecked := 0
|
||||
for _, v := range r.Contents {
|
||||
|
|
@ -632,6 +623,6 @@ func (r *ValueRollup) RenderContents(calc *RollupCalc, destKey *Key) {
|
|||
}
|
||||
}
|
||||
}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewValueNumber(float64(countUnchecked * 100 / len(r.Contents)))}}
|
||||
r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(float64(countUnchecked*100/len(r.Contents)), NumberFormatNone)}}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,6 +314,8 @@ func (tx *Transaction) doMove(operation *Operation) (ret *TxErr) {
|
|||
headingChildren = treenode.GetHeadingFold(headingChildren)
|
||||
}
|
||||
|
||||
refreshHeadingChildrenUpdated(srcNode, time.Now().Format("20060102150405"))
|
||||
|
||||
var srcEmptyList *ast.Node
|
||||
if ast.NodeListItem == srcNode.Type && srcNode.Parent.FirstChild == srcNode && srcNode.Parent.LastChild == srcNode {
|
||||
// 列表中唯一的列表项被移除后,该列表就为空了
|
||||
|
|
@ -366,6 +368,8 @@ func (tx *Transaction) doMove(operation *Operation) (ret *TxErr) {
|
|||
srcEmptyList.Unlink()
|
||||
}
|
||||
|
||||
refreshHeadingChildrenUpdated(srcNode, time.Now().Format("20060102150405"))
|
||||
|
||||
refreshUpdated(srcNode)
|
||||
refreshUpdated(srcTree.Root)
|
||||
if err = tx.writeTree(srcTree); nil != err {
|
||||
|
|
@ -444,6 +448,8 @@ func (tx *Transaction) doMove(operation *Operation) (ret *TxErr) {
|
|||
}
|
||||
}
|
||||
|
||||
refreshHeadingChildrenUpdated(srcNode, time.Now().Format("20060102150405"))
|
||||
|
||||
refreshUpdated(srcNode)
|
||||
refreshUpdated(srcTree.Root)
|
||||
if err = tx.writeTree(srcTree); nil != err {
|
||||
|
|
@ -752,6 +758,9 @@ func (tx *Transaction) doDelete(operation *Operation) (ret *TxErr) {
|
|||
// 列表块撤销状态异常 https://github.com/siyuan-note/siyuan/issues/3985
|
||||
node.Next.Unlink()
|
||||
}
|
||||
|
||||
refreshHeadingChildrenUpdated(node, time.Now().Format("20060102150405"))
|
||||
|
||||
node.Unlink()
|
||||
if nil != parent && ast.NodeListItem == parent.Type && nil == parent.FirstChild {
|
||||
// 保持空列表项
|
||||
|
|
@ -961,6 +970,8 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
|
|||
}
|
||||
}
|
||||
|
||||
refreshHeadingChildrenUpdated(insertedNode, time.Now().Format("20060102150405"))
|
||||
|
||||
createdUpdated(insertedNode)
|
||||
tx.nodes[insertedNode.ID] = insertedNode
|
||||
if err = tx.writeTree(tree); nil != err {
|
||||
|
|
@ -1048,6 +1059,8 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
|
|||
treenode.MoveFoldHeading(updatedNode, oldNode)
|
||||
}
|
||||
|
||||
refreshHeadingChildrenUpdated(oldNode, time.Now().Format("20060102150405"))
|
||||
|
||||
cache.PutBlockIAL(updatedNode.ID, parse.IAL2Map(updatedNode.KramdownIAL))
|
||||
|
||||
// 替换为新节点
|
||||
|
|
@ -1055,6 +1068,8 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
|
|||
oldNode.Unlink()
|
||||
|
||||
createdUpdated(updatedNode)
|
||||
refreshHeadingChildrenUpdated(updatedNode, updatedNode.IALAttr("updated"))
|
||||
|
||||
tx.nodes[updatedNode.ID] = updatedNode
|
||||
if err = tx.writeTree(tree); nil != err {
|
||||
return &TxErr{code: TxErrCodeWriteTree, msg: err.Error(), id: id}
|
||||
|
|
@ -1066,6 +1081,19 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
|
|||
return
|
||||
}
|
||||
|
||||
func refreshHeadingChildrenUpdated(heading *ast.Node, updated string) {
|
||||
if nil == heading || ast.NodeHeading != heading.Type {
|
||||
return
|
||||
}
|
||||
|
||||
// 将非标题块更新为标题块时需要更新下方块的 parent id
|
||||
// The parent block field of the blocks under the heading block is calculated incorrectly https://github.com/siyuan-note/siyuan/issues/9869
|
||||
children := treenode.HeadingChildren(heading)
|
||||
for _, child := range children {
|
||||
child.SetIALAttr("updated", updated)
|
||||
}
|
||||
}
|
||||
|
||||
func upsertAvBlockRel(node *ast.Node) {
|
||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering {
|
||||
|
|
|
|||
|
|
@ -810,8 +810,7 @@ func buildBlockFromNode(n *ast.Node, tree *parse.Tree) (block *Block, attributes
|
|||
fcontent = treenode.NodeStaticContent(fc, nil, true, false, true)
|
||||
|
||||
parentID = n.Parent.ID
|
||||
// 将标题块作为父节点
|
||||
if h := heading(n); nil != h {
|
||||
if h := heading(n); nil != h { // 如果在标题块下方,则将标题块作为父节点
|
||||
parentID = h.ID
|
||||
}
|
||||
length = utf8.RuneCountInString(fcontent)
|
||||
|
|
@ -823,7 +822,6 @@ func buildBlockFromNode(n *ast.Node, tree *parse.Tree) (block *Block, attributes
|
|||
content = treenode.NodeStaticContent(n, nil, true, indexAssetPath, true)
|
||||
|
||||
parentID = n.Parent.ID
|
||||
// 将标题块作为父节点
|
||||
if h := heading(n); nil != h {
|
||||
parentID = h.ID
|
||||
}
|
||||
|
|
@ -909,6 +907,10 @@ func tagFromNode(node *ast.Node) (ret string) {
|
|||
}
|
||||
|
||||
func heading(node *ast.Node) *ast.Node {
|
||||
if nil == node {
|
||||
return nil
|
||||
}
|
||||
|
||||
currentLevel := 16
|
||||
if ast.NodeHeading == node.Type {
|
||||
currentLevel = node.HeadingLevel
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue