mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 07:00:12 +01:00
✨ Callout block https://github.com/siyuan-note/siyuan/issues/16051
Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
parent
362f6ffa05
commit
980f6dd0b8
9 changed files with 26 additions and 12 deletions
|
|
@ -72,6 +72,7 @@ type TypeFilter struct {
|
||||||
ListItem bool `json:"listItem"`
|
ListItem bool `json:"listItem"`
|
||||||
Blockquote bool `json:"blockquote"`
|
Blockquote bool `json:"blockquote"`
|
||||||
Super bool `json:"super"`
|
Super bool `json:"super"`
|
||||||
|
Callout bool `json:"callout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type D3 struct {
|
type D3 struct {
|
||||||
|
|
|
||||||
|
|
@ -532,7 +532,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
|
||||||
name, _ = av.GetAttributeViewName(parent.AttributeViewID)
|
name, _ = av.GetAttributeViewName(parent.AttributeViewID)
|
||||||
} else {
|
} else {
|
||||||
if "" == name {
|
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)
|
name = gulu.Str.SubStr(renderBlockText(fc, excludeTypes, true), maxNameLen)
|
||||||
} else {
|
} else {
|
||||||
name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes, true), maxNameLen)
|
name = gulu.Str.SubStr(renderBlockText(parent, excludeTypes, true), maxNameLen)
|
||||||
|
|
@ -544,7 +544,7 @@ func buildBlockBreadcrumb(node *ast.Node, excludeTypes []string, isEmbedBlock bo
|
||||||
}
|
}
|
||||||
|
|
||||||
add := true
|
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
|
add = false
|
||||||
if parent == node {
|
if parent == node {
|
||||||
// https://github.com/siyuan-note/siyuan/issues/13141#issuecomment-2476789553
|
// https://github.com/siyuan-note/siyuan/issues/13141#issuecomment-2476789553
|
||||||
|
|
|
||||||
|
|
@ -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 ||
|
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.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.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.ID = ast.NewNodeID()
|
||||||
n.KramdownIAL = [][]string{{"id", n.ID}}
|
n.KramdownIAL = [][]string{{"id", n.ID}}
|
||||||
n.InsertAfter(&ast.Node{Type: ast.NodeKramdownBlockIAL, Tokens: []byte("{: id=\"" + n.ID + "\"}")})
|
n.InsertAfter(&ast.Node{Type: ast.NodeKramdownBlockIAL, Tokens: []byte("{: id=\"" + n.ID + "\"}")})
|
||||||
|
|
|
||||||
|
|
@ -905,7 +905,7 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
|
||||||
var headings []*ast.Node
|
var headings []*ast.Node
|
||||||
if pdf { // 导出 PDF 需要标记目录书签
|
if pdf { // 导出 PDF 需要标记目录书签
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
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)
|
headings = append(headings, n)
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
|
@ -1128,7 +1128,7 @@ func ProcessPDF(id, p string, merge, removeAssets, watermark bool) (err error) {
|
||||||
return ast.WalkContinue
|
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)
|
headings = append(headings, n)
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
|
@ -3557,14 +3557,14 @@ func adjustHeadingLevel(bt *treenode.BlockTree, tree *parse.Tree) {
|
||||||
var firstHeading *ast.Node
|
var firstHeading *ast.Node
|
||||||
if !Conf.Export.AddTitle {
|
if !Conf.Export.AddTitle {
|
||||||
for n := tree.Root.FirstChild; nil != n; n = n.Next {
|
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
|
firstHeading = n
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for n := tree.Root.FirstChild.Next; nil != n; n = n.Next {
|
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
|
firstHeading = n
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -596,6 +596,14 @@ func graphTypeFilter(local bool) string {
|
||||||
inList = append(inList, "'s'")
|
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'")
|
inList = append(inList, "'d'")
|
||||||
return " AND ref.type IN (" + strings.Join(inList, ",") + ")"
|
return " AND ref.type IN (" + strings.Join(inList, ",") + ")"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ func (tx *Transaction) doMoveOutlineHeading(operation *Operation) (ret *TxErr) {
|
||||||
|
|
||||||
headings := []*ast.Node{}
|
headings := []*ast.Node{}
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
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)
|
headings = append(headings, n)
|
||||||
}
|
}
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
|
|
@ -305,7 +305,7 @@ func outline(tree *parse.Tree) (ret []*Path) {
|
||||||
luteEngine := NewLute()
|
luteEngine := NewLute()
|
||||||
var headings []*Block
|
var headings []*Block
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
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
|
n.Box, n.Path = tree.Box, tree.Path
|
||||||
block := &Block{
|
block := &Block{
|
||||||
RootID: tree.Root.ID,
|
RootID: tree.Root.ID,
|
||||||
|
|
|
||||||
|
|
@ -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 ||
|
if (ast.NodeListItem == n.Type && (nil == n.FirstChild ||
|
||||||
(3 == n.ListData.Typ && (nil == n.FirstChild.Next || ast.NodeKramdownBlockIAL == n.FirstChild.Next.Type)))) ||
|
(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)
|
nodesNeedAppendChild = append(nodesNeedAppendChild, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1433,7 +1433,6 @@ func execStmtTx(tx *sql.Tx, stmt string, args ...interface{}) (err error) {
|
||||||
|
|
||||||
func nSort(n *ast.Node) int {
|
func nSort(n *ast.Node) int {
|
||||||
switch n.Type {
|
switch n.Type {
|
||||||
// 以下为块级元素
|
|
||||||
case ast.NodeHeading:
|
case ast.NodeHeading:
|
||||||
return 5
|
return 5
|
||||||
case ast.NodeParagraph:
|
case ast.NodeParagraph:
|
||||||
|
|
@ -1452,6 +1451,8 @@ func nSort(n *ast.Node) int {
|
||||||
return 20
|
return 20
|
||||||
case ast.NodeBlockquote:
|
case ast.NodeBlockquote:
|
||||||
return 20
|
return 20
|
||||||
|
case ast.NodeCallout:
|
||||||
|
return 20
|
||||||
case ast.NodeSuperBlock:
|
case ast.NodeSuperBlock:
|
||||||
return 30
|
return 30
|
||||||
case ast.NodeAttributeView:
|
case ast.NodeAttributeView:
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ func FirstLeafBlock(node *ast.Node) (ret *ast.Node) {
|
||||||
|
|
||||||
func CountBlockNodes(node *ast.Node) (ret int) {
|
func CountBlockNodes(node *ast.Node) (ret int) {
|
||||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
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
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,6 +403,7 @@ var typeAbbrMap = map[string]string{
|
||||||
"NodeThematicBreak": "tb",
|
"NodeThematicBreak": "tb",
|
||||||
"NodeVideo": "video",
|
"NodeVideo": "video",
|
||||||
"NodeAudio": "audio",
|
"NodeAudio": "audio",
|
||||||
|
"NodeCallout": "callout",
|
||||||
// 行级元素
|
// 行级元素
|
||||||
"NodeText": "text",
|
"NodeText": "text",
|
||||||
"NodeImage": "img",
|
"NodeImage": "img",
|
||||||
|
|
@ -458,6 +459,8 @@ func SubTypeAbbr(n *ast.Node) string {
|
||||||
if 6 == n.HeadingLevel {
|
if 6 == n.HeadingLevel {
|
||||||
return "h6"
|
return "h6"
|
||||||
}
|
}
|
||||||
|
case ast.NodeCallout:
|
||||||
|
return n.CalloutType
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue