mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-12 13:59:47 +08:00
856e8e5205
Split monolithic render.ts into cli, constants, extend-config, html-builder, renderer, themes, and types modules. Bundle highlight.js code theme CSS files locally instead of CDN loading.
164 lines
5.7 KiB
TypeScript
164 lines
5.7 KiB
TypeScript
import type { CliOptions, ThemeName } from "./types.js";
|
|
import {
|
|
FONT_FAMILY_MAP,
|
|
FONT_SIZE_OPTIONS,
|
|
COLOR_PRESETS,
|
|
CODE_BLOCK_THEMES,
|
|
} from "./constants.js";
|
|
import { THEME_NAMES } from "./themes.js";
|
|
import { loadExtendConfig } from "./extend-config.js";
|
|
|
|
export function printUsage(): void {
|
|
console.error(
|
|
[
|
|
"Usage:",
|
|
" npx tsx src/md/render.ts <markdown_file> [options]",
|
|
"",
|
|
"Options:",
|
|
` --theme <name> Theme (${THEME_NAMES.join(", ")})`,
|
|
` --color <name|hex> Primary color: ${Object.keys(COLOR_PRESETS).join(", ")}, or hex`,
|
|
` --font-family <name> Font: ${Object.keys(FONT_FAMILY_MAP).join(", ")}, or CSS value`,
|
|
` --font-size <N> Font size: ${FONT_SIZE_OPTIONS.join(", ")} (default: 16px)`,
|
|
` --code-theme <name> Code highlight theme (default: github)`,
|
|
` --mac-code-block Show Mac-style code block header`,
|
|
` --line-number Show line numbers in code blocks`,
|
|
` --cite Enable footnote citations`,
|
|
` --count Show reading time / word count`,
|
|
` --legend <value> Image caption: title-alt, alt-title, title, alt, none`,
|
|
` --keep-title Keep the first heading in output`,
|
|
].join("\n")
|
|
);
|
|
}
|
|
|
|
function parseArgValue(argv: string[], i: number, flag: string): string | null {
|
|
const arg = argv[i]!;
|
|
if (arg.includes("=")) {
|
|
return arg.slice(flag.length + 1);
|
|
}
|
|
const next = argv[i + 1];
|
|
return next ?? null;
|
|
}
|
|
|
|
function resolveFontFamily(value: string): string {
|
|
return FONT_FAMILY_MAP[value] ?? value;
|
|
}
|
|
|
|
function resolveColor(value: string): string {
|
|
return COLOR_PRESETS[value] ?? value;
|
|
}
|
|
|
|
export function parseArgs(argv: string[]): CliOptions | null {
|
|
const ext = loadExtendConfig();
|
|
|
|
let inputPath = "";
|
|
let theme: ThemeName = ext.default_theme ?? "default";
|
|
let keepTitle = ext.keep_title ?? false;
|
|
let primaryColor: string | undefined = ext.default_color ? resolveColor(ext.default_color) : undefined;
|
|
let fontFamily: string | undefined = ext.default_font_family ? resolveFontFamily(ext.default_font_family) : undefined;
|
|
let fontSize: string | undefined = ext.default_font_size ?? undefined;
|
|
let codeTheme = ext.default_code_theme ?? "github";
|
|
let isMacCodeBlock = ext.mac_code_block ?? true;
|
|
let isShowLineNumber = ext.show_line_number ?? false;
|
|
let citeStatus = ext.cite ?? false;
|
|
let countStatus = ext.count ?? false;
|
|
let legend = ext.legend ?? "alt";
|
|
|
|
for (let i = 0; i < argv.length; i += 1) {
|
|
const arg = argv[i]!;
|
|
|
|
if (!arg.startsWith("--") && !inputPath) {
|
|
inputPath = arg;
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--help" || arg === "-h") {
|
|
return null;
|
|
}
|
|
|
|
if (arg === "--keep-title") { keepTitle = true; continue; }
|
|
if (arg === "--mac-code-block") { isMacCodeBlock = true; continue; }
|
|
if (arg === "--no-mac-code-block") { isMacCodeBlock = false; continue; }
|
|
if (arg === "--line-number") { isShowLineNumber = true; continue; }
|
|
if (arg === "--cite") { citeStatus = true; continue; }
|
|
if (arg === "--count") { countStatus = true; continue; }
|
|
|
|
if (arg === "--theme" || arg.startsWith("--theme=")) {
|
|
const val = parseArgValue(argv, i, "--theme");
|
|
if (!val) { console.error("Missing value for --theme"); return null; }
|
|
theme = val as ThemeName;
|
|
if (!arg.includes("=")) i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--color" || arg.startsWith("--color=")) {
|
|
const val = parseArgValue(argv, i, "--color");
|
|
if (!val) { console.error("Missing value for --color"); return null; }
|
|
primaryColor = resolveColor(val);
|
|
if (!arg.includes("=")) i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--font-family" || arg.startsWith("--font-family=")) {
|
|
const val = parseArgValue(argv, i, "--font-family");
|
|
if (!val) { console.error("Missing value for --font-family"); return null; }
|
|
fontFamily = resolveFontFamily(val);
|
|
if (!arg.includes("=")) i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--font-size" || arg.startsWith("--font-size=")) {
|
|
const val = parseArgValue(argv, i, "--font-size");
|
|
if (!val) { console.error("Missing value for --font-size"); return null; }
|
|
fontSize = val.endsWith("px") ? val : `${val}px`;
|
|
if (!FONT_SIZE_OPTIONS.includes(fontSize)) {
|
|
console.error(`Invalid font size: ${fontSize}. Valid: ${FONT_SIZE_OPTIONS.join(", ")}`);
|
|
return null;
|
|
}
|
|
if (!arg.includes("=")) i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--code-theme" || arg.startsWith("--code-theme=")) {
|
|
const val = parseArgValue(argv, i, "--code-theme");
|
|
if (!val) { console.error("Missing value for --code-theme"); return null; }
|
|
codeTheme = val;
|
|
if (!CODE_BLOCK_THEMES.includes(codeTheme)) {
|
|
console.error(`Unknown code theme: ${codeTheme}`);
|
|
return null;
|
|
}
|
|
if (!arg.includes("=")) i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (arg === "--legend" || arg.startsWith("--legend=")) {
|
|
const val = parseArgValue(argv, i, "--legend");
|
|
if (!val) { console.error("Missing value for --legend"); return null; }
|
|
const valid = ["title-alt", "alt-title", "title", "alt", "none"];
|
|
if (!valid.includes(val)) {
|
|
console.error(`Invalid legend: ${val}. Valid: ${valid.join(", ")}`);
|
|
return null;
|
|
}
|
|
legend = val;
|
|
if (!arg.includes("=")) i += 1;
|
|
continue;
|
|
}
|
|
|
|
console.error(`Unknown argument: ${arg}`);
|
|
return null;
|
|
}
|
|
|
|
if (!inputPath) {
|
|
return null;
|
|
}
|
|
|
|
if (!THEME_NAMES.includes(theme)) {
|
|
console.error(`Unknown theme: ${theme}`);
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
inputPath, theme, keepTitle, primaryColor, fontFamily, fontSize,
|
|
codeTheme, isMacCodeBlock, isShowLineNumber, citeStatus, countStatus, legend,
|
|
};
|
|
}
|