Skip to content

Commit

Permalink
support ? or ! admonition
Browse files Browse the repository at this point in the history
  • Loading branch information
zizdlp committed Oct 11, 2024
1 parent c0f93b7 commit 4f5a6a1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 33 deletions.
51 changes: 30 additions & 21 deletions zbook_backend/markdown/admonition/extend.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,49 @@ import (
"github.com/yuin/goldmark/util"
)

// This extender allows you to use admonitions in markdown
// Extender allows you to use admonitions in markdown with different triggers.
//
// Admonitions are a markdown extension that allows you to style markdown as
// nice boxes with a title. This is done by way of wrapping other elements in
// divs with classes starting with "adm-"
// Admonitions are a markdown extension that styles markdown as
// boxes with titles, triggered by characters like '!' or '?'
//
// !!!note This is the title {.some-additional-class}
// This is the admonition
// This is the admonition content
//
// ## with a header
// Example with a different trigger:
// ???note Another type of admonition
//
// !!!danger Nesting is possible!
// ```R
// X <- as.data.table(iris)
// X[Species != "virginica", mean(Sepal.Length), Species]
// ```
// !!!
// !!!
// You can now pass multiple trigger characters to support different
// types of admonitions.
type Extender struct {
priority int // optional int != 0. the priority value for parser and renderer. Defaults to 100.
priority int // optional int != 0. the priority value for parser and renderer. Defaults to 100.
triggerChars []byte // list of trigger characters (e.g., '!', '?')
}

// This implements the Extend method for goldmark-admonitions.Extender
// NewExtender creates an Extender with specified trigger characters and priority.
func NewExtender(priority int, triggerChars []byte) *Extender {
return &Extender{
priority: priority,
triggerChars: triggerChars,
}
}

// Extend adds block parsers and node renderers to the markdown instance.
func (e *Extender) Extend(md goldmark.Markdown) {
priority := 100

if e.priority != 0 {
priority = e.priority
}
md.Parser().AddOptions(
parser.WithBlockParsers(
util.Prioritized(&admonitionParser{}, priority),
),
)

// Add a parser for each trigger character
for _, char := range e.triggerChars {
md.Parser().AddOptions(
parser.WithBlockParsers(
util.Prioritized(NewAdmonitionParser(char), priority),
),
)
}

// Add the renderer
md.Renderer().AddOptions(
renderer.WithNodeRenderers(
util.Prioritized(&Renderer{}, priority),
Expand Down
26 changes: 16 additions & 10 deletions zbook_backend/markdown/admonition/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ import (
)

type admonitionParser struct {
triggerChar byte // The character that triggers the admonition, e.g., '!' or '?'
}

var defaultAdmonitionParser = &admonitionParser{}

// NewAdmonitionParser returns a new BlockParser that
// parses admonition blocks.
func NewAdmonitionParser() parser.BlockParser {
return defaultAdmonitionParser
// NewAdmonitionParser creates a new admonition parser with a specified trigger character.
func NewAdmonitionParser(char byte) parser.BlockParser {
return &admonitionParser{
triggerChar: char,
}
}

type admonitionData struct {
ID string // The ID of the admonition. This enables nested admonitions with indentation
char byte // Currently, this is always "!"
char byte // Trigger character, e.g., '!' or '?'
indent int // The indentation of the opening (and closing) tags (!!!{})
length int // The length of the admonition, e.g. is it !!! or !!!!?
length int // The length of the admonition, e.g. is it !!! or ???
node ast.Node // The node of the admonition
contentIndent int // The indentation of the content relative to the previous admonition block. The first line of the content is taken as its indentation. If you want an admonition with just a code block you need to use backticks
contentHasStarted bool // Only used as an indicator if contentIndent has been set already
Expand All @@ -34,13 +34,13 @@ type admonitionData struct {
var admonitionInfoKey = parser.NewContextKey()

func (b *admonitionParser) Trigger() []byte {
return []byte{'!'}
return []byte{b.triggerChar}
}

func (b *admonitionParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State) {
line, _ := reader.PeekLine()
pos := pc.BlockOffset()
if pos < 0 || line[pos] != '!' {
if pos < 0 || line[pos] != b.triggerChar {
return nil, parser.NoChildren
}
findent := pos
Expand Down Expand Up @@ -108,6 +108,12 @@ func (b *admonitionParser) Open(parent ast.Node, reader text.Reader, pc parser.C
if close, _ := hasClosingTag(line, w, pos, fdata); w < fdata.indent || close {
return node, parser.NoChildren
}
indentClose :=
!util.IsBlank(line) &&
(w < fdata.indent || (w == fdata.indent && w <= fdata.contentIndent)) // mydebug:warning,这里w < fdata.contentIndent 修改添加=
if indentClose {
return node, parser.NoChildren
}
return node, parser.HasChildren
}

Expand Down
3 changes: 1 addition & 2 deletions zbook_backend/markdown/render/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package render

import (
// admonitions "github.com/stefanfritsch/goldmark-admonitions"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
Expand All @@ -23,7 +22,7 @@ func GetMarkdownConfig() goldmark.Markdown {
),
goldmark.WithExtensions(extension.GFM),
goldmark.WithExtensions(
&admonitions.Extender{},
admonitions.NewExtender(100, []byte{'!', '?'}),
),
goldmark.WithExtensions(extension.NewCJK(extension.WithEastAsianLineBreaks(), extension.WithEscapedSpace())),
goldmark.WithExtensions(
Expand Down

0 comments on commit 4f5a6a1

Please sign in to comment.