From b032f091a1ec85583b25c4e0b6f19194b3d7fdba Mon Sep 17 00:00:00 2001 From: walker <13750528578@163.com> Date: Wed, 17 Jun 2026 13:40:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(theme):=20=E6=96=B0=E5=A2=9E=20red-editori?= =?UTF-8?q?al=20=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- README.zh-CN.md | 4 ++-- cmd/mark2note/main_test.go | 2 +- configs/config.example.yaml | 2 +- internal/deck/theme_registry.go | 29 ++++++++++++++++++++++++++++ internal/deck/theme_registry_test.go | 14 ++++++++++++++ 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f84fd44..0f5760f 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ The built-in providers are currently `bilibili`, `bangumi`, `anilist`, and `mydr ## Theme Notes -- Stable themes: `default`, `warm-paper`, `editorial-cool`, `tech-noir`, `plum-ink`, `sage-mist`, `fresh-green` +- Stable themes: `default`, `warm-paper`, `editorial-cool`, `tech-noir`, `plum-ink`, `red-editorial`, `sage-mist`, `fresh-green` - `deck.theme_mode: weekly` chooses a fixed theme from `deck.weekly_themes` by local weekday; `deck.theme` remains the fallback - `--theme` overrides fixed or weekly selection for one run - Unknown theme names fall back to `default` @@ -169,7 +169,7 @@ Key fields: - `output.dir`: default output root directory - `ai.command` / `ai.args`: AI CLI command and arguments used to generate deck JSON - `deck.theme_mode`: theme selection mode, supporting `fixed` and `weekly`; `weekly` reads `deck.weekly_themes` by local weekday -- `deck.theme`: default / fallback theme, supporting `default`, `warm-paper`, `editorial-cool`, `tech-noir`, `plum-ink`, `sage-mist`, and `fresh-green`; unknown names fall back to `default` +- `deck.theme`: default / fallback theme, supporting `default`, `warm-paper`, `editorial-cool`, `tech-noir`, `plum-ink`, `red-editorial`, `sage-mist`, and `fresh-green`; unknown names fall back to `default` - `deck.weekly_themes`: weekday-to-theme map for weekly mode, such as `mon` and `tue` - `deck.author`: default cover author value - `deck.watermark.enabled`: enables the page watermark, on by default diff --git a/README.zh-CN.md b/README.zh-CN.md index f92275e..91bf0ce 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -155,7 +155,7 @@ posters: ## 主题说明 -- 稳定主题支持 `default`、`warm-paper`、`editorial-cool`、`tech-noir`、`plum-ink`、`sage-mist`、`fresh-green` +- 稳定主题支持 `default`、`warm-paper`、`editorial-cool`、`tech-noir`、`plum-ink`、`red-editorial`、`sage-mist`、`fresh-green` - `deck.theme_mode: weekly` 会按本机星期从 `deck.weekly_themes` 选择固定主题;`deck.theme` 仍是兜底主题 - `--theme` 会单次覆盖 fixed 或 weekly 的主题选择 - 未知主题名会回落到 `default` @@ -169,7 +169,7 @@ posters: - `output.dir`:默认输出根目录 - `ai.command` / `ai.args`:用于生成 deck JSON 的 AI CLI 命令及参数 - `deck.theme_mode`:主题选择模式,支持 `fixed`、`weekly`;`weekly` 按本机星期读取 `deck.weekly_themes` -- `deck.theme`:默认 / 兜底主题,支持 `default`、`warm-paper`、`editorial-cool`、`tech-noir`、`plum-ink`、`sage-mist`、`fresh-green`;未知主题名会回落到 `default` +- `deck.theme`:默认 / 兜底主题,支持 `default`、`warm-paper`、`editorial-cool`、`tech-noir`、`plum-ink`、`red-editorial`、`sage-mist`、`fresh-green`;未知主题名会回落到 `default` - `deck.weekly_themes`:weekly 模式下的星期主题映射,如 `mon`、`tue` - `deck.author`:封面作者默认值 - `deck.watermark.enabled`:是否启用页内水印,默认启用 diff --git a/cmd/mark2note/main_test.go b/cmd/mark2note/main_test.go index cd486f6..e5e3cb8 100644 --- a/cmd/mark2note/main_test.go +++ b/cmd/mark2note/main_test.go @@ -123,7 +123,7 @@ func TestUsageTextMentionsAutoPublishXHSFlags(t *testing.T) { func TestUsageTextMentionsThemeAuthorAndAnimatedFlags(t *testing.T) { text := usageText() - for _, want := range []string{"--theme ", "--author ", "--animated", "--animated-format ", "--animated-duration ", "--animated-fps ", "--import-photos", "--import-album ", "--import-timeout ", "import generated PNG files into Apple Photos after export", "Apple Photos album name for imported PNG files", "--live", "--live-photo-format ", "--live-cover-frame ", "supported: first, middle, last", "--live-assemble", "--live-output-dir ", "--live-import-photos", "--live-import-album", "--live-import-timeout", "page animation timeline duration; also affects Live motion timing", "animation capture fps / sampling density; affects Animated WebP/MP4 output and Live frame sampling", "deck.theme_mode", "fixed / weekly", "deck.weekly_themes", "weekly mode chooses a theme by local weekday", "deck.theme", "fixed mode theme and weekly fallback", "deck.author", "plum-ink", "sage-mist", "default / warm-paper / editorial-cool / tech-noir / plum-ink / sage-mist / fresh-green", "one-off deck theme override", "one-off cover author input (blank falls back to deck.author)"} { + for _, want := range []string{"--theme ", "--author ", "--animated", "--animated-format ", "--animated-duration ", "--animated-fps ", "--import-photos", "--import-album ", "--import-timeout ", "import generated PNG files into Apple Photos after export", "Apple Photos album name for imported PNG files", "--live", "--live-photo-format ", "--live-cover-frame ", "supported: first, middle, last", "--live-assemble", "--live-output-dir ", "--live-import-photos", "--live-import-album", "--live-import-timeout", "page animation timeline duration; also affects Live motion timing", "animation capture fps / sampling density; affects Animated WebP/MP4 output and Live frame sampling", "deck.theme_mode", "fixed / weekly", "deck.weekly_themes", "weekly mode chooses a theme by local weekday", "deck.theme", "fixed mode theme and weekly fallback", "deck.author", "plum-ink", "sage-mist", "default / warm-paper / editorial-cool / tech-noir / plum-ink / red-editorial / sage-mist / fresh-green", "one-off deck theme override", "one-off cover author input (blank falls back to deck.author)"} { if !strings.Contains(text, want) { t.Fatalf("usageText() missing %q", want) } diff --git a/configs/config.example.yaml b/configs/config.example.yaml index dda1d7c..2381475 100644 --- a/configs/config.example.yaml +++ b/configs/config.example.yaml @@ -18,7 +18,7 @@ deck: # deck.theme_mode 可选值:fixed / weekly;weekly 会按本机星期选择 weekly_themes 中的固定主题。 theme_mode: weekly # deck.theme 是 fixed 模式的主题,也是 weekly 当天未配置时的兜底主题。 - # 可选值:default / warm-paper / editorial-cool / tech-noir / plum-ink / sage-mist / fresh-green + # 可选值:default / warm-paper / editorial-cool / tech-noir / plum-ink / red-editorial / sage-mist / fresh-green theme: default # 单次 deck 允许的最大页数,范围 3-18;默认 12。 max_pages: 12 diff --git a/internal/deck/theme_registry.go b/internal/deck/theme_registry.go index 9870cbc..8cf3b68 100644 --- a/internal/deck/theme_registry.go +++ b/internal/deck/theme_registry.go @@ -8,6 +8,7 @@ const ( ThemeEditorialCool = "editorial-cool" ThemeTechNoir = "tech-noir" ThemePlumInk = "plum-ink" + ThemeRedEditorial = "red-editorial" ThemeSageMist = "sage-mist" ThemeFreshGreen = "fresh-green" ) @@ -24,6 +25,7 @@ func RegisteredThemeKeys() []string { ThemeEditorialCool, ThemeTechNoir, ThemePlumInk, + ThemeRedEditorial, ThemeSageMist, ThemeFreshGreen, } @@ -170,6 +172,33 @@ func RegisteredThemes() map[string]Theme { AuthorSize: "24px", AuthorBottomOffset: "236px", }, + ThemeRedEditorial: { + Name: ThemeRedEditorial, + BG: "#FFF7F5", + Card: "#FFFFFF", + Text: "#2D2D2D", + Sub: "#767676", + Accent: "#D71A1B", + AccentSoft: "#FAE4E4", + Line: "#F0E0E0", + Panel: "#FFF5F5", + White: "#FFFFFF", + AccentForeground: "#FFFFFF", + InversePillColor: "#2D2D2D", + WatermarkColor: "rgba(45, 45, 45, 0.22)", + EmphasisColor: "#C86442", + NumberColor: "#D71A1B", + InlineCodeBG: "#FFF5F5", + InlineCodeBorder: "#F2B6B6", + InlineCodeColor: "#2D2D2D", + CodeBlockBG: "#FFFDFD", + CodeBlockBorder: "#F0E0E0", + CodeBlockColor: "#2D2D2D", + AuthorColor: "#9C5339", + AuthorWeight: "600", + AuthorSize: "24px", + AuthorBottomOffset: "236px", + }, ThemeSageMist: { Name: ThemeSageMist, BG: "#F2F5EF", diff --git a/internal/deck/theme_registry_test.go b/internal/deck/theme_registry_test.go index 9e99320..aa8e275 100644 --- a/internal/deck/theme_registry_test.go +++ b/internal/deck/theme_registry_test.go @@ -76,6 +76,20 @@ func TestRegisteredThemesPreserveRenamedTokenValues(t *testing.T) { } } +func TestRegisteredThemesIncludesRedEditorialPalette(t *testing.T) { + themes := RegisteredThemes() + theme, ok := themes["red-editorial"] + if !ok { + t.Fatal("RegisteredThemes missing red-editorial") + } + if theme.BG != "#FFF7F5" || theme.Card != "#FFFFFF" || theme.Text != "#2D2D2D" || theme.Accent != "#D71A1B" || theme.NumberColor != "#D71A1B" { + t.Fatalf("red-editorial tokens = %#v", theme) + } + if got := ResolveDeckTheme("red-editorial"); got != "red-editorial" { + t.Fatalf("ResolveDeckTheme(red-editorial) = %q", got) + } +} + func stableThemeKeys() []string { return RegisteredThemeKeys() }