Move drop-h1 to the renderer

This is more reliable than a regular expression.
This commit is contained in:
Manuel Rüger 2023-05-19 18:47:55 +02:00
parent 5602297459
commit 484f988f32
4 changed files with 42 additions and 23 deletions

View File

@ -667,7 +667,7 @@ GLOBAL OPTIONS:
--compile-only show resulting HTML and don't update Confluence page content. (default: false) [$MARK_COMPILE_ONLY]
--dry-run resolve page and ancestry, show resulting HTML and exit. (default: false) [$MARK_DRY_RUN]
--edit-lock, -k lock page editing to current user only to prevent accidental manual edits over Confluence Web UI. (default: false) [$MARK_EDIT_LOCK]
--drop-h1, --h1_drop don't include H1 headings in Confluence output. (default: false) [$MARK_H1_DROP]
--drop-h1, --h1_drop don't include the first H1 heading in Confluence output. (default: false) [$MARK_H1_DROP]
--title-from-h1, --h1_title extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata. (default: false) [$MARK_H1_TITLE]
--minor-edit don't send notifications while updating Confluence page. (default: false) [$MARK_MINOR_EDIT]
--color value display logs in color. Possible values: auto, never. (default: "auto") [$MARK_COLOR]

View File

@ -58,7 +58,7 @@ var flags = []cli.Flag{
Name: "drop-h1",
Value: false,
Aliases: []string{"h1_drop"},
Usage: "don't include H1 headings in Confluence output.",
Usage: "don't include the first H1 heading in Confluence output.",
EnvVars: []string{"MARK_H1_DROP"},
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
@ -361,10 +361,9 @@ func processFile(
log.Info(
"the leading H1 heading will be excluded from the Confluence output",
)
markdown = mark.DropDocumentLeadingH1(markdown)
}
html, _ := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"))
html, _ := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"), cCtx.Bool("drop-h1"))
fmt.Println(html)
os.Exit(0)
}
@ -438,10 +437,9 @@ func processFile(
log.Info(
"the leading H1 heading will be excluded from the Confluence output",
)
markdown = mark.DropDocumentLeadingH1(markdown)
}
html, inlineAttachments := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"))
html, inlineAttachments := mark.CompileMarkdown(markdown, stdlib, file, cCtx.String("mermaid-provider"), cCtx.Bool("drop-h1"))
// Resolve attachements detected from markdown
_, err = mark.ResolveAttachments(

View File

@ -53,17 +53,19 @@ type ConfluenceRenderer struct {
Stdlib *stdlib.Lib
Path string
MermaidProvider string
DropFirstH1 bool
LevelMap BlockQuoteLevelMap
Attachments []Attachment
}
// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
func NewConfluenceRenderer(stdlib *stdlib.Lib, path string, mermaidProvider string, opts ...html.Option) renderer.NodeRenderer {
func NewConfluenceRenderer(stdlib *stdlib.Lib, path string, mermaidProvider string, dropFirstH1 bool, opts ...html.Option) renderer.NodeRenderer {
return &ConfluenceRenderer{
Config: html.NewConfig(),
Stdlib: stdlib,
Path: path,
MermaidProvider: mermaidProvider,
DropFirstH1: dropFirstH1,
LevelMap: nil,
Attachments: []Attachment{},
}
@ -73,7 +75,7 @@ func NewConfluenceRenderer(stdlib *stdlib.Lib, path string, mermaidProvider stri
func (r *ConfluenceRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
// blocks
// reg.Register(ast.KindDocument, r.renderNode)
// reg.Register(ast.KindHeading, r.renderNode)
reg.Register(ast.KindHeading, r.renderHeading)
reg.Register(ast.KindBlockquote, r.renderBlockQuote)
reg.Register(ast.KindCodeBlock, r.renderCodeBlock)
reg.Register(ast.KindFencedCodeBlock, r.renderFencedCodeBlock)
@ -95,6 +97,37 @@ func (r *ConfluenceRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegister
// reg.Register(ast.KindString, r.renderNode)
}
func (r *ConfluenceRenderer) renderHeading(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*ast.Heading)
// If this is the first h1 heading of the document and we want to drop it, let's not render it at all.
if n.Level == 1 && r.DropFirstH1 {
if !entering {
r.DropFirstH1 = false
}
return ast.WalkSkipChildren, nil
}
return r.goldmarkRenderHeading(w, source, node, entering)
}
func (r *ConfluenceRenderer) goldmarkRenderHeading(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*ast.Heading)
if entering {
_, _ = w.WriteString("<h")
_ = w.WriteByte("0123456"[n.Level])
if n.Attributes() != nil {
html.RenderAttributes(w, node, html.HeadingAttributeFilter)
}
_ = w.WriteByte('>')
} else {
_, _ = w.WriteString("</h")
_ = w.WriteByte("0123456"[n.Level])
_, _ = w.WriteString(">\n")
}
return ast.WalkContinue, nil
}
func ParseLanguage(lang string) string {
// lang takes the following form: language? "collapse"? ("title"? <any string>*)?
// let's split it by spaces
@ -612,10 +645,10 @@ func (r *ConfluenceRenderer) goldmarkRenderHTMLBlock(w util.BufWriter, source []
return ast.WalkContinue, nil
}
func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidProvider string) (string, []Attachment) {
func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidProvider string, dropFirstH1 bool) (string, []Attachment) {
log.Tracef(nil, "rendering markdown:\n%s", string(markdown))
confluenceRenderer := NewConfluenceRenderer(stdlib, path, mermaidProvider)
confluenceRenderer := NewConfluenceRenderer(stdlib, path, mermaidProvider, dropFirstH1)
converter := goldmark.New(
goldmark.WithExtensions(
@ -657,18 +690,6 @@ func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidPr
}
// DropDocumentLeadingH1 will drop leading H1 headings to prevent
// duplication of or visual conflict with page titles.
// NOTE: This is intended only to operate on the whole markdown document.
// Operating on individual lines will clear them if the begin with `#`.
func DropDocumentLeadingH1(
markdown []byte,
) []byte {
h1 := regexp.MustCompile(`^#[^#].*\n`)
markdown = h1.ReplaceAll(markdown, []byte(""))
return markdown
}
// ExtractDocumentLeadingH1 will extract leading H1 heading
func ExtractDocumentLeadingH1(markdown []byte) string {
h1 := regexp.MustCompile(`#[^#]\s*(.*)\s*\n`)

View File

@ -36,7 +36,7 @@ func TestCompileMarkdown(t *testing.T) {
if err != nil {
panic(err)
}
actual, _ := CompileMarkdown(markdown, lib, filename, "")
actual, _ := CompileMarkdown(markdown, lib, filename, "", false)
test.EqualValues(string(html), actual, filename+" vs "+htmlname)
}
}