52 lines
1.2 KiB
TypeScript
52 lines
1.2 KiB
TypeScript
import fs from "fs";
|
||
import path from "path";
|
||
|
||
const SECTION_RECT =
|
||
/<rect\b[^>]*\bwidth="1920"[^>]*\bheight="672"[^>]*\bfill="(#[0-9A-Fa-f]{3,8})"/i;
|
||
|
||
/**
|
||
* First 1920×672 rect fill in a Figma Section banner SVG.
|
||
* Clip-path rects with fill="white" come later and are ignored.
|
||
*/
|
||
export function extractSectionBannerFill(svg: string): string | null {
|
||
const match = svg.match(SECTION_RECT);
|
||
return match?.[1] ?? null;
|
||
}
|
||
|
||
function sectionBannerDiskPath(slug: string, bannerFileName?: string): string {
|
||
return path.join(
|
||
process.cwd(),
|
||
"public/content/blog",
|
||
bannerFileName ?? `${slug}-section.svg`,
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Page background for an article: section banner fill when that SVG exists,
|
||
* otherwise the markdown `background.color`.
|
||
*/
|
||
export function resolveBlogPageBackgroundColor({
|
||
slug,
|
||
bannerFileName,
|
||
frontmatterColor,
|
||
}: {
|
||
slug: string;
|
||
bannerFileName?: string;
|
||
frontmatterColor?: string;
|
||
}): string | undefined {
|
||
try {
|
||
const svg = fs.readFileSync(
|
||
sectionBannerDiskPath(slug, bannerFileName),
|
||
"utf8",
|
||
);
|
||
const fill = extractSectionBannerFill(svg);
|
||
if (fill) {
|
||
return fill;
|
||
}
|
||
} catch {
|
||
// No section SVG yet — fall through to frontmatter.
|
||
}
|
||
|
||
return frontmatterColor;
|
||
}
|