diff --git a/packages/baoyu-md/src/document.test.ts b/packages/baoyu-md/src/document.test.ts index c188acc..bfa6533 100644 --- a/packages/baoyu-md/src/document.test.ts +++ b/packages/baoyu-md/src/document.test.ts @@ -9,12 +9,26 @@ import { COLOR_PRESETS, FONT_FAMILY_MAP } from "./constants.ts"; import { buildMarkdownDocumentMeta, formatTimestamp, + renderMarkdownDocument, resolveColorToken, resolveFontFamilyToken, resolveMarkdownStyle, resolveRenderOptions, } from "./document.ts"; +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, `\\$&`); +} + +function findInlineStyle(html: string, tagName: string, text: string): string { + const pattern = new RegExp( + `<${tagName}[^>]*style="([^"]*)"[^>]*>${escapeRegExp(text)}${tagName}>`, + ); + const match = html.match(pattern); + assert.ok(match, `Expected inline style for <${tagName}>${text}${tagName}>`); + return match![1]!; +} + function useCwd(t: TestContext, cwd: string): void { const previous = process.cwd(); process.chdir(cwd); @@ -138,3 +152,23 @@ keep_title: true assert.equal(explicit.fontSize, "18px"); assert.equal(explicit.keepTitle, false); }); + +test("renderMarkdownDocument layers default rules into grace theme before CSS inlining", async () => { + const { html } = await renderMarkdownDocument( + `## Section\n\nParagraph with **bold** text.`, + { keepTitle: true, theme: "grace" }, + ); + + const h2Style = findInlineStyle(html, "h2", "Section"); + assert.match(h2Style, /background: #92617E/); + assert.match(h2Style, /box-shadow: 0 4px 6px rgba\(0, 0, 0, 0\.1\)/); + + const pMatch = html.match(/
]*style="([^"]*)"[^>]*>/); + assert.ok(pMatch, "Expected inline style on
tag");
+ assert.match(pMatch![1]!, /color:/);
+
+ const strongPattern = /]*style="([^"]*)"[^>]*>bold<\/strong>/;
+ const strongMatch = html.match(strongPattern);
+ assert.ok(strongMatch, "Expected inline style for bold");
+ assert.match(strongMatch![1]!, /font-weight:/);
+});
diff --git a/packages/baoyu-md/src/html-builder.test.ts b/packages/baoyu-md/src/html-builder.test.ts
index 2cab343..b68de0d 100644
--- a/packages/baoyu-md/src/html-builder.test.ts
+++ b/packages/baoyu-md/src/html-builder.test.ts
@@ -59,6 +59,17 @@ test("normalizeCssText and normalizeInlineCss replace variables and strip declar
assert.doesNotMatch(normalizedHtml, /var\(--md-primary-color\)/);
});
+test("normalizeInlineCss removes quoted custom property values without leaving fragments behind", () => {
+ const normalizedHtml = normalizeInlineCss(
+ ``,
+ DEFAULT_STYLE,
+ );
+
+ assert.match(normalizedHtml, /style=" color: #0F4C81"/);
+ assert.doesNotMatch(normalizedHtml, /Courier New/);
+ assert.doesNotMatch(normalizedHtml, /--md-font-family/);
+});
+
test("HTML structure helpers hoist nested lists and remove the first heading", () => {
const nestedList = ` ]*style="([^"]*)"[^>]*>/);
+ assert.ok(pMatch, "Expected inline style on tag");
+ assert.match(pMatch![1]!, /color:/);
+
+ const strongPattern = /]*style="([^"]*)"[^>]*>bold<\/strong>/;
+ const strongMatch = html.match(strongPattern);
+ assert.ok(strongMatch, "Expected inline style for bold");
+ assert.match(strongMatch![1]!, /font-weight:/);
+});
diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.test.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.test.ts
index 2cab343..b68de0d 100644
--- a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.test.ts
+++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.test.ts
@@ -59,6 +59,17 @@ test("normalizeCssText and normalizeInlineCss replace variables and strip declar
assert.doesNotMatch(normalizedHtml, /var\(--md-primary-color\)/);
});
+test("normalizeInlineCss removes quoted custom property values without leaving fragments behind", () => {
+ const normalizedHtml = normalizeInlineCss(
+ ``,
+ DEFAULT_STYLE,
+ );
+
+ assert.match(normalizedHtml, /style=" color: #0F4C81"/);
+ assert.doesNotMatch(normalizedHtml, /Courier New/);
+ assert.doesNotMatch(normalizedHtml, /--md-font-family/);
+});
+
test("HTML structure helpers hoist nested lists and remove the first heading", () => {
const nestedList = ` ]*style="([^"]*)"[^>]*>/);
+ assert.ok(pMatch, "Expected inline style on tag");
+ assert.match(pMatch![1]!, /color:/);
+
+ const strongPattern = /]*style="([^"]*)"[^>]*>bold<\/strong>/;
+ const strongMatch = html.match(strongPattern);
+ assert.ok(strongMatch, "Expected inline style for bold");
+ assert.match(strongMatch![1]!, /font-weight:/);
+});
diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.test.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.test.ts
index 2cab343..b68de0d 100644
--- a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.test.ts
+++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.test.ts
@@ -59,6 +59,17 @@ test("normalizeCssText and normalizeInlineCss replace variables and strip declar
assert.doesNotMatch(normalizedHtml, /var\(--md-primary-color\)/);
});
+test("normalizeInlineCss removes quoted custom property values without leaving fragments behind", () => {
+ const normalizedHtml = normalizeInlineCss(
+ ``,
+ DEFAULT_STYLE,
+ );
+
+ assert.match(normalizedHtml, /style=" color: #0F4C81"/);
+ assert.doesNotMatch(normalizedHtml, /Courier New/);
+ assert.doesNotMatch(normalizedHtml, /--md-font-family/);
+});
+
test("HTML structure helpers hoist nested lists and remove the first heading", () => {
const nestedList = ` ]*style="([^"]*)"[^>]*>/);
+ assert.ok(pMatch, "Expected inline style on tag");
+ assert.match(pMatch![1]!, /color:/);
+
+ const strongPattern = /]*style="([^"]*)"[^>]*>bold<\/strong>/;
+ const strongMatch = html.match(strongPattern);
+ assert.ok(strongMatch, "Expected inline style for bold");
+ assert.match(strongMatch![1]!, /font-weight:/);
+});
diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.test.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.test.ts
index 2cab343..b68de0d 100644
--- a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.test.ts
+++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.test.ts
@@ -59,6 +59,17 @@ test("normalizeCssText and normalizeInlineCss replace variables and strip declar
assert.doesNotMatch(normalizedHtml, /var\(--md-primary-color\)/);
});
+test("normalizeInlineCss removes quoted custom property values without leaving fragments behind", () => {
+ const normalizedHtml = normalizeInlineCss(
+ ``,
+ DEFAULT_STYLE,
+ );
+
+ assert.match(normalizedHtml, /style=" color: #0F4C81"/);
+ assert.doesNotMatch(normalizedHtml, /Courier New/);
+ assert.doesNotMatch(normalizedHtml, /--md-font-family/);
+});
+
test("HTML structure helpers hoist nested lists and remove the first heading", () => {
const nestedList = `
`;
assert.equal(
diff --git a/packages/baoyu-md/src/html-builder.ts b/packages/baoyu-md/src/html-builder.ts
index 3ca61a0..d27e03a 100644
--- a/packages/baoyu-md/src/html-builder.ts
+++ b/packages/baoyu-md/src/html-builder.ts
@@ -100,13 +100,13 @@ export function normalizeCssText(cssText: string, style: StyleConfig = DEFAULT_S
.replace(/var\(--md-accent-color\)/g, style.accentColor)
.replace(/var\(--md-container-bg\)/g, style.containerBg)
.replace(/hsl\(var\(--foreground\)\)/g, "#3f3f3f")
- .replace(/--md-primary-color:\s*[^;"']+;?/g, "")
- .replace(/--md-font-family:\s*[^;"']+;?/g, "")
- .replace(/--md-font-size:\s*[^;"']+;?/g, "")
- .replace(/--blockquote-background:\s*[^;"']+;?/g, "")
- .replace(/--md-accent-color:\s*[^;"']+;?/g, "")
- .replace(/--md-container-bg:\s*[^;"']+;?/g, "")
- .replace(/--foreground:\s*[^;"']+;?/g, "");
+ .replace(/--md-primary-color:\s*[^;]+;?/g, "")
+ .replace(/--md-font-family:\s*[^;]+;?/g, "")
+ .replace(/--md-font-size:\s*[^;]+;?/g, "")
+ .replace(/--blockquote-background:\s*[^;]+;?/g, "")
+ .replace(/--md-accent-color:\s*[^;]+;?/g, "")
+ .replace(/--md-container-bg:\s*[^;]+;?/g, "")
+ .replace(/--foreground:\s*[^;]+;?/g, "");
}
export function normalizeInlineCss(html: string, style: StyleConfig = DEFAULT_STYLE): string {
diff --git a/packages/baoyu-md/src/themes.ts b/packages/baoyu-md/src/themes.ts
index 9c3dbeb..6767ad3 100644
--- a/packages/baoyu-md/src/themes.ts
+++ b/packages/baoyu-md/src/themes.ts
@@ -6,6 +6,7 @@ import type { ThemeName } from "./types.js";
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
export const THEME_DIR = path.resolve(SCRIPT_DIR, "themes");
const FALLBACK_THEMES: ThemeName[] = ["default", "grace", "simple"];
+const THEMES_EXTENDING_DEFAULT = new Set
`;
assert.equal(
diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.ts
index 3ca61a0..d27e03a 100644
--- a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.ts
+++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.ts
@@ -100,13 +100,13 @@ export function normalizeCssText(cssText: string, style: StyleConfig = DEFAULT_S
.replace(/var\(--md-accent-color\)/g, style.accentColor)
.replace(/var\(--md-container-bg\)/g, style.containerBg)
.replace(/hsl\(var\(--foreground\)\)/g, "#3f3f3f")
- .replace(/--md-primary-color:\s*[^;"']+;?/g, "")
- .replace(/--md-font-family:\s*[^;"']+;?/g, "")
- .replace(/--md-font-size:\s*[^;"']+;?/g, "")
- .replace(/--blockquote-background:\s*[^;"']+;?/g, "")
- .replace(/--md-accent-color:\s*[^;"']+;?/g, "")
- .replace(/--md-container-bg:\s*[^;"']+;?/g, "")
- .replace(/--foreground:\s*[^;"']+;?/g, "");
+ .replace(/--md-primary-color:\s*[^;]+;?/g, "")
+ .replace(/--md-font-family:\s*[^;]+;?/g, "")
+ .replace(/--md-font-size:\s*[^;]+;?/g, "")
+ .replace(/--blockquote-background:\s*[^;]+;?/g, "")
+ .replace(/--md-accent-color:\s*[^;]+;?/g, "")
+ .replace(/--md-container-bg:\s*[^;]+;?/g, "")
+ .replace(/--foreground:\s*[^;]+;?/g, "");
}
export function normalizeInlineCss(html: string, style: StyleConfig = DEFAULT_STYLE): string {
diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes.ts
index 9c3dbeb..6767ad3 100644
--- a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes.ts
+++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes.ts
@@ -6,6 +6,7 @@ import type { ThemeName } from "./types.js";
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
export const THEME_DIR = path.resolve(SCRIPT_DIR, "themes");
const FALLBACK_THEMES: ThemeName[] = ["default", "grace", "simple"];
+const THEMES_EXTENDING_DEFAULT = new Set
`;
assert.equal(
diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts
index 3ca61a0..d27e03a 100644
--- a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts
+++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts
@@ -100,13 +100,13 @@ export function normalizeCssText(cssText: string, style: StyleConfig = DEFAULT_S
.replace(/var\(--md-accent-color\)/g, style.accentColor)
.replace(/var\(--md-container-bg\)/g, style.containerBg)
.replace(/hsl\(var\(--foreground\)\)/g, "#3f3f3f")
- .replace(/--md-primary-color:\s*[^;"']+;?/g, "")
- .replace(/--md-font-family:\s*[^;"']+;?/g, "")
- .replace(/--md-font-size:\s*[^;"']+;?/g, "")
- .replace(/--blockquote-background:\s*[^;"']+;?/g, "")
- .replace(/--md-accent-color:\s*[^;"']+;?/g, "")
- .replace(/--md-container-bg:\s*[^;"']+;?/g, "")
- .replace(/--foreground:\s*[^;"']+;?/g, "");
+ .replace(/--md-primary-color:\s*[^;]+;?/g, "")
+ .replace(/--md-font-family:\s*[^;]+;?/g, "")
+ .replace(/--md-font-size:\s*[^;]+;?/g, "")
+ .replace(/--blockquote-background:\s*[^;]+;?/g, "")
+ .replace(/--md-accent-color:\s*[^;]+;?/g, "")
+ .replace(/--md-container-bg:\s*[^;]+;?/g, "")
+ .replace(/--foreground:\s*[^;]+;?/g, "");
}
export function normalizeInlineCss(html: string, style: StyleConfig = DEFAULT_STYLE): string {
diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts
index 9c3dbeb..6767ad3 100644
--- a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts
+++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts
@@ -6,6 +6,7 @@ import type { ThemeName } from "./types.js";
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
export const THEME_DIR = path.resolve(SCRIPT_DIR, "themes");
const FALLBACK_THEMES: ThemeName[] = ["default", "grace", "simple"];
+const THEMES_EXTENDING_DEFAULT = new Set
`;
assert.equal(
diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts
index 3ca61a0..d27e03a 100644
--- a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts
+++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts
@@ -100,13 +100,13 @@ export function normalizeCssText(cssText: string, style: StyleConfig = DEFAULT_S
.replace(/var\(--md-accent-color\)/g, style.accentColor)
.replace(/var\(--md-container-bg\)/g, style.containerBg)
.replace(/hsl\(var\(--foreground\)\)/g, "#3f3f3f")
- .replace(/--md-primary-color:\s*[^;"']+;?/g, "")
- .replace(/--md-font-family:\s*[^;"']+;?/g, "")
- .replace(/--md-font-size:\s*[^;"']+;?/g, "")
- .replace(/--blockquote-background:\s*[^;"']+;?/g, "")
- .replace(/--md-accent-color:\s*[^;"']+;?/g, "")
- .replace(/--md-container-bg:\s*[^;"']+;?/g, "")
- .replace(/--foreground:\s*[^;"']+;?/g, "");
+ .replace(/--md-primary-color:\s*[^;]+;?/g, "")
+ .replace(/--md-font-family:\s*[^;]+;?/g, "")
+ .replace(/--md-font-size:\s*[^;]+;?/g, "")
+ .replace(/--blockquote-background:\s*[^;]+;?/g, "")
+ .replace(/--md-accent-color:\s*[^;]+;?/g, "")
+ .replace(/--md-container-bg:\s*[^;]+;?/g, "")
+ .replace(/--foreground:\s*[^;]+;?/g, "");
}
export function normalizeInlineCss(html: string, style: StyleConfig = DEFAULT_STYLE): string {
diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts
index 9c3dbeb..6767ad3 100644
--- a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts
+++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts
@@ -6,6 +6,7 @@ import type { ThemeName } from "./types.js";
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
export const THEME_DIR = path.resolve(SCRIPT_DIR, "themes");
const FALLBACK_THEMES: ThemeName[] = ["default", "grace", "simple"];
+const THEMES_EXTENDING_DEFAULT = new Set