mirror of
https://github.com/kovetskiy/mark.git
synced 2026-03-14 06:07:36 +08:00
feat: add support for --content-appearance
This commit is contained in:
parent
d2717f031d
commit
9516939c7d
@ -838,6 +838,7 @@ GLOBAL OPTIONS:
|
||||
--space string use specified space key. If the space key is not specified, it must be set in the page metadata. [$MARK_SPACE]
|
||||
--parents string A list containing the parents of the document separated by parents-delimiter (default: '/'). These will be prepended to the ones defined in the document itself. [$MARK_PARENTS]
|
||||
--parents-delimiter string The delimiter used for the parents list (default: "/") [$MARK_PARENTS_DELIMITER]
|
||||
--content-appearance string default content appearance for pages without a Content-Appearance header. Possible values: full-width, fixed. [$MARK_CONTENT_APPEARANCE]
|
||||
--mermaid-scale float defines the scaling factor for mermaid renderings. (default: 1) [$MARK_MERMAID_SCALE]
|
||||
--include-path string Path for shared includes, used as a fallback if the include doesn't exist in the current directory. [$MARK_INCLUDE_PATH]
|
||||
--changes-only Avoids re-uploading pages that haven't changed since the last run. [$MARK_CHANGES_ONLY]
|
||||
|
||||
2
main.go
2
main.go
@ -29,7 +29,7 @@ func main() {
|
||||
Flags: util.Flags,
|
||||
EnableShellCompletion: true,
|
||||
HideHelpCommand: true,
|
||||
Before: util.CheckMutuallyExclusiveTitleFlags,
|
||||
Before: util.CheckFlags,
|
||||
Action: util.RunMark,
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ var (
|
||||
reHeaderPatternMacro = regexp.MustCompile(`<!-- Macro: .*`)
|
||||
)
|
||||
|
||||
func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, titleFromFilename bool, filename string, parents []string, titleAppendGeneratedHash bool) (*Meta, []byte, error) {
|
||||
func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, titleFromFilename bool, filename string, parents []string, titleAppendGeneratedHash bool, defaultContentAppearance string) (*Meta, []byte, error) {
|
||||
var (
|
||||
meta *Meta
|
||||
offset int
|
||||
@ -81,7 +81,6 @@ func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, titleFromFi
|
||||
if meta == nil {
|
||||
meta = &Meta{}
|
||||
meta.Type = "page" // Default if not specified
|
||||
meta.ContentAppearance = FullWidthContentAppearance // Default to full-width for backwards compatibility
|
||||
}
|
||||
|
||||
header := cases.Title(language.English).String(matches[1])
|
||||
@ -152,10 +151,6 @@ func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, titleFromFi
|
||||
meta.Type = "page"
|
||||
}
|
||||
|
||||
if meta.ContentAppearance == "" {
|
||||
meta.ContentAppearance = FullWidthContentAppearance // Default to full-width for backwards compatibility
|
||||
}
|
||||
|
||||
if titleFromH1 && meta.Title == "" {
|
||||
meta.Title = ExtractDocumentLeadingH1(data)
|
||||
}
|
||||
@ -167,6 +162,17 @@ func ExtractMeta(data []byte, spaceFromCli string, titleFromH1 bool, titleFromFi
|
||||
}
|
||||
}
|
||||
|
||||
// Use the global content appearance flag if the header is not set in the document
|
||||
if meta != nil && defaultContentAppearance != "" && meta.ContentAppearance == "" {
|
||||
if strings.TrimSpace(defaultContentAppearance) == FixedContentAppearance {
|
||||
meta.ContentAppearance = FixedContentAppearance
|
||||
} else {
|
||||
meta.ContentAppearance = FullWidthContentAppearance
|
||||
}
|
||||
} else if meta != nil && meta.ContentAppearance == "" {
|
||||
meta.ContentAppearance = FullWidthContentAppearance // Default to full-width if nothing else is set for backwards compatibility
|
||||
}
|
||||
|
||||
if meta == nil {
|
||||
return nil, data, nil
|
||||
}
|
||||
|
||||
@ -60,3 +60,32 @@ func TestSetTitleFromFilename(t *testing.T) {
|
||||
assert.Equal(t, "Already Title Cased", meta.Title)
|
||||
})
|
||||
}
|
||||
|
||||
func TestExtractMetaContentAppearance(t *testing.T) {
|
||||
t.Run("default fills missing content appearance", func(t *testing.T) {
|
||||
data := []byte("<!-- Space: DOC -->\n<!-- Title: Example -->\n\nbody\n")
|
||||
|
||||
meta, _, err := ExtractMeta(data, "", false, false, "", nil, false, FixedContentAppearance)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, meta)
|
||||
assert.Equal(t, FixedContentAppearance, meta.ContentAppearance)
|
||||
})
|
||||
|
||||
t.Run("header takes precedence over default", func(t *testing.T) {
|
||||
data := []byte("<!-- Space: DOC -->\n<!-- Title: Example -->\n<!-- Content-Appearance: full-width -->\n\nbody\n")
|
||||
|
||||
meta, _, err := ExtractMeta(data, "", false, false, "", nil, false, FixedContentAppearance)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, meta)
|
||||
assert.Equal(t, FullWidthContentAppearance, meta.ContentAppearance)
|
||||
})
|
||||
|
||||
t.Run("falls back to full-width when default isn't set", func(t *testing.T) {
|
||||
data := []byte("<!-- Space: DOC -->\n<!-- Title: Example -->\n\nbody\n")
|
||||
|
||||
meta, _, err := ExtractMeta(data, "", false, false, "", nil, false, "")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, meta)
|
||||
assert.Equal(t, FullWidthContentAppearance, meta.ContentAppearance)
|
||||
})
|
||||
}
|
||||
|
||||
@ -122,7 +122,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, spaceForLinks, titleFromH1, titleFromFilename, filepath, parents, titleAppendGeneratedHash)
|
||||
linkMeta, _, err := metadata.ExtractMeta(linkContents, spaceForLinks, titleFromH1, titleFromFilename, filepath, parents, titleAppendGeneratedHash, "")
|
||||
if err != nil {
|
||||
log.Errorf(
|
||||
err,
|
||||
|
||||
@ -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"), cmd.Bool("title-from-filename"), file, 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"), cmd.String("content-appearance"))
|
||||
if err != nil {
|
||||
fatalErrorHandler.Handle(err, "unable to extract metadata from file %q", file)
|
||||
return nil
|
||||
|
||||
@ -12,8 +12,9 @@ func runWithArgs(args []string) error {
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{Name: "title-from-h1"},
|
||||
&cli.BoolFlag{Name: "title-from-filename"},
|
||||
&cli.StringFlag{Name: "content-appearance"},
|
||||
},
|
||||
Before: CheckMutuallyExclusiveTitleFlags,
|
||||
Before: CheckFlags,
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
return nil
|
||||
},
|
||||
@ -50,3 +51,26 @@ func TestCheckMutuallyExclusiveTitleFlags(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestContentAppearanceFlagValidation(t *testing.T) {
|
||||
t.Run("fixed is accepted", func(t *testing.T) {
|
||||
err := runWithArgs([]string{"cmd", "--content-appearance", "fixed"})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("full-width is accepted", func(t *testing.T) {
|
||||
err := runWithArgs([]string{"cmd", "--content-appearance", "full-width"})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid value is rejected", func(t *testing.T) {
|
||||
err := runWithArgs([]string{"cmd", "--content-appearance", "nope"})
|
||||
if err == nil {
|
||||
t.Errorf("expected error, got nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package util
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
altsrc "github.com/urfave/cli-altsrc/v3"
|
||||
altsrctoml "github.com/urfave/cli-altsrc/v3/toml"
|
||||
@ -164,6 +165,15 @@ var Flags = []cli.Flag{
|
||||
Usage: "The delimiter used for the parents list",
|
||||
Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_PARENTS_DELIMITER"), altsrctoml.TOML("parents-delimiter", altsrc.NewStringPtrSourcer(&filename))),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "content-appearance",
|
||||
Value: "",
|
||||
Usage: "default content appearance for pages without a Content-Appearance header. Possible values: full-width, fixed.",
|
||||
Sources: cli.NewValueSourceChain(
|
||||
cli.EnvVar("MARK_CONTENT_APPEARANCE"),
|
||||
altsrctoml.TOML("content-appearance", altsrc.NewStringPtrSourcer(&filename)),
|
||||
),
|
||||
},
|
||||
&cli.FloatFlag{
|
||||
Name: "mermaid-scale",
|
||||
Value: 1.0,
|
||||
@ -204,10 +214,24 @@ var Flags = []cli.Flag{
|
||||
},
|
||||
}
|
||||
|
||||
// CheckMutuallyExclusiveTitleFlags checks if both title-from-h1 and title-from-filename are set
|
||||
func CheckMutuallyExclusiveTitleFlags(context context.Context, command *cli.Command) (context.Context, error) {
|
||||
// CheckFlags validates combinations and values of global flags.
|
||||
func CheckFlags(context context.Context, command *cli.Command) (context.Context, error) {
|
||||
if command.Bool("title-from-h1") && command.Bool("title-from-filename") {
|
||||
return context, errors.New("flags --title-from-h1 and --title-from-filename are mutually exclusive. Please specify only one")
|
||||
}
|
||||
|
||||
contentAppearance := command.String("content-appearance")
|
||||
if contentAppearance != "" {
|
||||
switch contentAppearance {
|
||||
case "full-width", "fixed":
|
||||
// ok
|
||||
default:
|
||||
return context, fmt.Errorf(
|
||||
"invalid value for --content-appearance: %q (expected: full-width or fixed)",
|
||||
contentAppearance,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return context, nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user