Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2025-12-06 16:46:14 +08:00
parent 362f6ffa05
commit 980f6dd0b8
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
9 changed files with 26 additions and 12 deletions

View file

@ -72,6 +72,7 @@ type TypeFilter struct {
ListItem bool `json:"listItem"`
Blockquote bool `json:"blockquote"`
Super bool `json:"super"`
Callout bool `json:"callout"`
}
type D3 struct {

View file

@ -532,7 +532,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
name, _ = av.GetAttributeViewName(parent.AttributeViewID)
} else {
if "" == name {
if ast.NodeListItem == parent.Type || ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type {
if ast.NodeListItem == parent.Type || ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type || ast.NodeCallout == parent.Type {
name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen)
} else {
name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes, true), maxNameLen)
@ -544,7 +544,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
}
add := true
if ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type {
if ast.NodeList == parent.Type || ast.NodeSuperBlock == parent.Type || ast.NodeBlockquote == parent.Type || ast.NodeCallout == parent.Type {
add = false
if parent == node {
// https://github.com/siyuan-note/siyuan/issues/13141#issuecomment-2476789553

View file

@ -539,7 +539,7 @@ func normalizeTree(tree *parse.Tree) (yfmRootID, yfmTitle, yfmUpdated string) {
if "" == n.IALAttr("id") && (ast.NodeParagraph == n.Type || ast.NodeList == n.Type || ast.NodeListItem == n.Type || ast.NodeBlockquote == n.Type ||
ast.NodeMathBlock == n.Type || ast.NodeCodeBlock == n.Type || ast.NodeHeading == n.Type || ast.NodeTable == n.Type || ast.NodeThematicBreak == n.Type ||
ast.NodeYamlFrontMatter == n.Type || ast.NodeBlockQueryEmbed == n.Type || ast.NodeSuperBlock == n.Type || ast.NodeAttributeView == n.Type ||
ast.NodeHTMLBlock == n.Type || ast.NodeIFrame == n.Type || ast.NodeWidget == n.Type || ast.NodeAudio == n.Type || ast.NodeVideo == n.Type) {
ast.NodeHTMLBlock == n.Type || ast.NodeIFrame == n.Type || ast.NodeWidget == n.Type || ast.NodeAudio == n.Type || ast.NodeVideo == n.Type || ast.NodeCallout == n.Type) {
n.ID = ast.NewNodeID()
n.KramdownIAL = [][]string{{"id", n.ID}}
n.InsertAfter(&ast.Node{Type: ast.NodeKramdownBlockIAL, Tokens: []byte("{: id=\"" + n.ID + "\"}")})

View file

@ -905,7 +905,7 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
var headings []*ast.Node
if pdf { // 导出 PDF 需要标记目录书签
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) {
if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) && !n.ParentIs(ast.NodeCallout) {
headings = append(headings, n)
return ast.WalkSkipChildren
}
@ -1128,7 +1128,7 @@ func ProcessPDF(id, p string, merge, removeAssets, watermark bool) (err error) {
return ast.WalkContinue
}
if ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) {
if ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) && !n.ParentIs(ast.NodeCallout) {
headings = append(headings, n)
return ast.WalkSkipChildren
}
@ -3557,14 +3557,14 @@ func adjustHeadingLevel(bt *treenode.BlockTree, tree *parse.Tree) {
var firstHeading *ast.Node
if !Conf.Export.AddTitle {
for n := tree.Root.FirstChild; nil != n; n = n.Next {
if ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) {
if ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) && !n.ParentIs(ast.NodeCallout) {
firstHeading = n
break
}
}
} else {
for n := tree.Root.FirstChild.Next; nil != n; n = n.Next {
if ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) {
if ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) && !n.ParentIs(ast.NodeCallout) {
firstHeading = n
break
}

View file

@ -596,6 +596,14 @@ func graphTypeFilter(local bool) string {
inList = append(inList, "'s'")
}
callout := Conf.Graph.Local.Callout
if !local {
callout = Conf.Graph.Global.Callout
}
if callout {
inList = append(inList, "'callout'")
}
inList = append(inList, "'d'")
return " AND ref.type IN (" + strings.Join(inList, ",") + ")"
}

View file

@ -54,7 +54,7 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) {
headings := []*ast.Node{}
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) {
if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) && !n.ParentIs(ast.NodeCallout) {
headings = append(headings, n)
}
return ast.WalkContinue
@ -305,7 +305,7 @@ func outline(tree *parse.Tree) (ret []*Path) {
luteEngine := NewLute()
var headings []*Block
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) {
if entering && ast.NodeHeading == n.Type && !n.ParentIs(ast.NodeBlockquote) && !n.ParentIs(ast.NodeCallout) {
n.Box, n.Path = tree.Box, tree.Path
block := &Block{
RootID: tree.Root.ID,

View file

@ -373,7 +373,8 @@ func RenderTemplate(p, id string, preview bool) (tree *parse.Tree, dom string, e
if (ast.NodeListItem == n.Type && (nil == n.FirstChild ||
(3 == n.ListData.Typ && (nil == n.FirstChild.Next || ast.NodeKramdownBlockIAL == n.FirstChild.Next.Type)))) ||
(ast.NodeBlockquote == n.Type && nil != n.FirstChild && nil != n.FirstChild.Next && ast.NodeKramdownBlockIAL == n.FirstChild.Next.Type) {
(ast.NodeBlockquote == n.Type && nil != n.FirstChild && nil != n.FirstChild.Next && ast.NodeKramdownBlockIAL == n.FirstChild.Next.Type) ||
(ast.NodeCallout == n.Type && nil != n.FirstChild && ast.NodeKramdownBlockIAL == n.FirstChild.Next.Type) {
nodesNeedAppendChild = append(nodesNeedAppendChild, n)
}

View file

@ -1433,7 +1433,6 @@ func execStmtTx(tx *sql.Tx, stmt string, args ...interface{}) (err error) {
func nSort(n *ast.Node) int {
switch n.Type {
// 以下为块级元素
case ast.NodeHeading:
return 5
case ast.NodeParagraph:
@ -1452,6 +1451,8 @@ func nSort(n *ast.Node) int {
return 20
case ast.NodeBlockquote:
return 20
case ast.NodeCallout:
return 20
case ast.NodeSuperBlock:
return 30
case ast.NodeAttributeView:

View file

@ -224,7 +224,7 @@ func FirstLeafBlock(node *ast.Node) (ret *ast.Node) {
func CountBlockNodes(node *ast.Node) (ret int) {
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || !n.IsBlock() || ast.NodeList == n.Type || ast.NodeBlockquote == n.Type || ast.NodeSuperBlock == n.Type {
if !entering || !n.IsBlock() || ast.NodeList == n.Type || ast.NodeBlockquote == n.Type || ast.NodeSuperBlock == n.Type || ast.NodeCallout == n.Type {
return ast.WalkContinue
}
@ -403,6 +403,7 @@ var typeAbbrMap = map[string]string{
"NodeThematicBreak": "tb",
"NodeVideo": "video",
"NodeAudio": "audio",
"NodeCallout": "callout",
// 行级元素
"NodeText": "text",
"NodeImage": "img",
@ -458,6 +459,8 @@ func SubTypeAbbr(n *ast.Node) string {
if 6 == n.HeadingLevel {
return "h6"
}
case ast.NodeCallout:
return n.CalloutType
}
return ""
}