Take the article page color from the section banner SVG so the body cannot drift from the hero on current or future posts.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
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;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import path from "path";
|
||||
import matter from "gray-matter";
|
||||
import { validateBlogPost, sanitizeBlogPost } from "./validation";
|
||||
import type { BlogPostFrontmatter } from "./validation";
|
||||
import { resolveBlogPageBackgroundColor } from "./blogSectionBackground";
|
||||
import { logger } from "./logger";
|
||||
|
||||
/**
|
||||
@@ -104,6 +105,14 @@ export function parseBlogPost(filePath: string): BlogPost | null {
|
||||
|
||||
const sanitizedFrontmatter = sanitizeBlogPost(data);
|
||||
const slug = generateSlug(filePath.replace(/\.mdx?$/, ""));
|
||||
const pageBackground = resolveBlogPageBackgroundColor({
|
||||
slug,
|
||||
bannerFileName: sanitizedFrontmatter.banner?.horizontal,
|
||||
frontmatterColor: sanitizedFrontmatter.background?.color,
|
||||
});
|
||||
if (pageBackground) {
|
||||
sanitizedFrontmatter.background = { color: pageBackground };
|
||||
}
|
||||
|
||||
return {
|
||||
slug,
|
||||
|
||||
Reference in New Issue
Block a user