Add support for using the filename as the page title

This commit is contained in:
Dennis Verheijden 2025-08-29 14:37:59 +02:00 committed by Manuel Rüger
parent ae5347053a
commit 0f13d249f5
5 changed files with 38 additions and 18 deletions

View File

@ -811,6 +811,7 @@ GLOBAL OPTIONS:
--strip-linebreaks, -L remove linebreaks inside of tags, to accommodate non-standard Confluence behavior (default: false) [$MARK_STRIP_LINEBREAKS]
--title-from-h1 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_TITLE_FROM_H1]
--title-append-generated-hash appends a short hash generated from the path of the page (space, parents, and title) to the title (default: false) [$MARK_TITLE_APPEND_GENERATED_HASH]
--title-from-filename use the filename (without extension) as the Confluence page title if no explicit 'Title' header or H1 heading is found. (default: false) [$MARK_TITLE_FROM_FILENAME]
--minor-edit don't send notifications while updating Confluence page. (default: false) [$MARK_MINOR_EDIT]
--version-message string add a message to the page version, to explain the edit (default: "") [$MARK_VERSION_MESSAGE]
--color string display logs in color. Possible values: auto, never. (default: "auto") [$MARK_COLOR]

View File

@ -5,6 +5,7 @@ import (
"bytes"
"crypto/sha256"
"fmt"
"path/filepath"
"regexp"
"strings"
@ -48,7 +49,7 @@ var (
reHeaderPatternMacro = regexp.MustCompile(`<!-- Macro: .*`)
)
func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, parents []string, titleAppendGeneratedHash bool) (*Meta, []byte, error) {
func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, titleFromFilename bool, filename string, parents []string, titleAppendGeneratedHash bool) (*Meta, []byte, error) {
var (
meta *Meta
offset int
@ -141,7 +142,7 @@ func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, parents []s
}
}
if titleFromH1 || spaceFromCli != "" {
if titleFromH1 || spaceFromCli != "" || titleFromFilename {
if meta == nil {
meta = &Meta{}
}
@ -157,6 +158,10 @@ func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, parents []s
if titleFromH1 && meta.Title == "" {
meta.Title = ExtractDocumentLeadingH1(data)
}
if titleFromFilename && meta.Title == "" && filename != "" {
base := filepath.Base(filename)
meta.Title = strings.TrimSuffix(base, filepath.Ext(base))
}
if spaceFromCli != "" && meta.Space == "" {
meta.Space = spaceFromCli
}

View File

@ -33,6 +33,7 @@ func ResolveRelativeLinks(
base string,
spaceFromCli string,
titleFromH1 bool,
titleFromFilename bool,
parents []string,
titleAppendGeneratedHash bool,
) ([]LinkSubstitution, error) {
@ -47,7 +48,7 @@ func ResolveRelativeLinks(
match.filename,
match.hash,
)
resolved, err := resolveLink(api, base, match, spaceFromCli, titleFromH1, parents, titleAppendGeneratedHash)
resolved, err := resolveLink(api, base, match, spaceFromCli, titleFromH1, titleFromFilename, parents, titleAppendGeneratedHash)
if err != nil {
return nil, karma.Format(err, "resolve link: %q", match.full)
}
@ -71,6 +72,7 @@ func resolveLink(
link markdownLink,
spaceFromCli string,
titleFromH1 bool,
titleFromFilename bool,
parents []string,
titleAppendGeneratedHash bool,
) (string, error) {
@ -107,7 +109,7 @@ func resolveLink(
// This helps to determine if found link points to file that's
// not markdown or have mark required metadata
linkMeta, _, err := metadata.ExtractMeta(linkContents, spaceFromCli, titleFromH1, parents, titleAppendGeneratedHash)
linkMeta, _, err := metadata.ExtractMeta(linkContents, spaceFromCli, titleFromH1, titleFromFilename, filepath, parents, titleAppendGeneratedHash)
if err != nil {
log.Errorf(
err,

View File

@ -116,7 +116,7 @@ func processFile(
parents := strings.Split(cmd.String("parents"), cmd.String("parents-delimiter"))
meta, markdown, err := metadata.ExtractMeta(markdown, cmd.String("space"), cmd.Bool("title-from-h1"), parents, cmd.Bool("title-append-generated-hash"))
meta, markdown, err := metadata.ExtractMeta(markdown, cmd.String("space"), cmd.Bool("title-from-h1"), cmd.Bool("title-from-filename"), file, parents, cmd.Bool("title-append-generated-hash"))
if err != nil {
fatalErrorHandler.Handle(err, "unable to extract metadata from file %q", file)
return nil
@ -132,7 +132,10 @@ func processFile(
}
if pageID == "" && meta == nil {
fatalErrorHandler.Handle(nil, "specified file doesn't contain metadata and URL is not specified via command line or doesn't contain pageId GET-parameter")
fatalErrorHandler.Handle(
nil,
"specified file doesn't contain metadata and URL is not specified via command line or doesn't contain pageId GET-parameter",
)
return nil
}
@ -143,7 +146,10 @@ func processFile(
}
if meta.Title == "" {
fatalErrorHandler.Handle(nil, "page title is not set ('Title' header is not set and '--title-from-h1' option and 'h1-title' config is not set or there is no H1 in the file)")
fatalErrorHandler.Handle(
nil,
"page title is not set: use the 'Title' header, or the --title-from-h1 / --title-from-filename flags",
)
return nil
}
}
@ -196,7 +202,7 @@ func processFile(
}
}
links, err := page.ResolveRelativeLinks(api, meta, markdown, filepath.Dir(file), cmd.String("space"), cmd.Bool("title-from-h1"), parents, cmd.Bool("title-append-generated-hash"))
links, err := page.ResolveRelativeLinks(api, meta, markdown, filepath.Dir(file), cmd.String("space"), cmd.Bool("title-from-h1"), cmd.Bool("title-from-filename"), parents, cmd.Bool("title-append-generated-hash"))
if err != nil {
fatalErrorHandler.Handle(err, "unable to resolve relative links")
return nil
@ -220,11 +226,11 @@ func processFile(
}
cfg := types.MarkConfig{
MermaidScale: cmd.Float("mermaid-scale"),
D2Scale: cmd.Float("d2-scale"),
DropFirstH1: cmd.Bool("drop-h1"),
StripNewlines: cmd.Bool("strip-linebreaks"),
Features: cmd.StringSlice("features"),
MermaidScale: cmd.Float("mermaid-scale"),
D2Scale: cmd.Float("d2-scale"),
DropFirstH1: cmd.Bool("drop-h1"),
StripNewlines: cmd.Bool("strip-linebreaks"),
Features: cmd.StringSlice("features"),
}
html, _ := mark.CompileMarkdown(markdown, stdlib, file, cfg)
fmt.Println(html)
@ -299,11 +305,11 @@ func processFile(
)
}
cfg := types.MarkConfig{
MermaidScale: cmd.Float("mermaid-scale"),
D2Scale: cmd.Float("d2-scale"),
DropFirstH1: cmd.Bool("drop-h1"),
StripNewlines: cmd.Bool("strip-linebreaks"),
Features: cmd.StringSlice("features"),
MermaidScale: cmd.Float("mermaid-scale"),
D2Scale: cmd.Float("d2-scale"),
DropFirstH1: cmd.Bool("drop-h1"),
StripNewlines: cmd.Bool("strip-linebreaks"),
Features: cmd.StringSlice("features"),
}
html, inlineAttachments := mark.CompileMarkdown(markdown, stdlib, file, cfg)

View File

@ -61,6 +61,12 @@ var Flags = []cli.Flag{
Usage: "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.",
Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_FROM_H1"), altsrctoml.TOML("title-from-h1", altsrc.NewStringPtrSourcer(&filename))),
},
&cli.BoolFlag{
Name: "title-from-filename",
Value: false,
Usage: "use the filename (without extension) as the Confluence page title if no explicit 'Title' header or H1 heading is found.",
Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_FROM_FILENAME"), altsrctoml.TOML("title-from-filename", altsrc.NewStringPtrSourcer(&filename))),
},
&cli.BoolFlag{
Name: "title-append-generated-hash",
Value: false,