fix(render): separate tag chip CSS from fields

中文: 移除 Anki 字段中的标签 chip 内联样式,仅输出 class 和 data-tag,并把 QA Group 模型样式放入 Anki 模板 CSS。

English: Remove inline styles from rendered tag chips, keep semantic class/data attributes in fields, and move QA Group tag styling into Anki model CSS.
This commit is contained in:
Dusk 2026-04-23 22:20:37 +08:00
parent e45abb579f
commit 978a8c1e02
4 changed files with 30 additions and 14 deletions

View file

@ -87,6 +87,31 @@ export const QA_GROUP_MODEL_CSS = [
" font-size: 1.08em;",
"}",
"",
".ahs-ob-tag {",
" display: inline-block;",
" box-sizing: border-box;",
" max-width: 100%;",
" margin: 0 4px 3px 0;",
" padding: 1px 8px;",
" border: 1px solid rgba(124, 101, 255, 0.16);",
" border-radius: 999px;",
" background: rgba(124, 101, 255, 0.12);",
" color: #5b4fd6;",
" font-size: 0.88em;",
" font-weight: 500;",
" line-height: 1.55;",
" vertical-align: baseline;",
" white-space: nowrap;",
" text-decoration: none;",
"}",
"",
".nightMode .ahs-ob-tag,",
".card.nightMode .ahs-ob-tag {",
" background: rgba(150, 135, 255, 0.18);",
" color: #c9c1ff;",
" border-color: rgba(150, 135, 255, 0.28);",
"}",
"",
".meta {",
" margin-top: 1.2em;",
" padding-top: 0.65em;",

View file

@ -13,7 +13,7 @@ export interface RenderPlan {
warnings: DeckResolutionWarning[];
}
const MANUAL_RENDER_CONFIG_VERSION = "manual-render-v2";
const MANUAL_RENDER_CONFIG_VERSION = "manual-render-v3";
export class RenderConfigService {
constructor(private readonly deckResolutionService = new DeckResolutionService()) {}
@ -49,4 +49,4 @@ function resolveNoteModel(cardType: IndexedCard["cardType"], settings: PluginSet
}
return cardType === "semantic-qa" ? settings.semanticQaNoteType : settings.qaNoteType;
}
}

View file

@ -31,6 +31,7 @@ describe("ManualCardRenderer", () => {
expect(rendered.renderedFields.body).toContain('data-tag="项目A"');
expect(rendered.renderedFields.body).toContain('data-tag="📖::一人公司"');
expect(rendered.renderedFields.body).toContain('data-tag="3地区"');
expect(rendered.renderedFields.body).not.toContain('style="');
});
it("deletes pure tag lines before rendering remaining inline tags as chips", () => {
@ -106,4 +107,4 @@ function createPlannedCard(overrides: Partial<IndexedCard> = {}): PlannedCard {
noteModel: "Basic",
renderConfigHash: "render-config",
};
}
}

View file

@ -7,16 +7,6 @@ const PRECEDING_TAG_TEXT_PATTERN = /[\p{L}\p{N}_/#]/u;
const EXCLUDED_HTML_TAGS = new Set(["code", "pre"]);
const TAG_CHIP_CLASS = "ahs-ob-tag";
const TAG_CHIP_STYLE = [
"display:inline-block",
"padding:1px 8px",
"border-radius:999px",
"background:rgba(90,120,255,.12)",
"color:#5865d6",
"font-weight:500",
"line-height:1.5",
"margin:0 4px 2px 0",
].join(";");
export function renderObsidianTagChipsInText(text: string): string {
if (!text || !text.includes("#")) {
@ -110,7 +100,7 @@ function hasValidTagBoundary(text: string, startIndex: number): boolean {
}
function buildTagChip(rawTag: string, normalizedTag: string): string {
return `<span class="${TAG_CHIP_CLASS}" data-tag="${escapeHtml(normalizedTag)}" style="${TAG_CHIP_STYLE}">${escapeHtml(rawTag)}</span>`;
return `<span class="${TAG_CHIP_CLASS}" data-tag="${escapeHtml(normalizedTag)}">${escapeHtml(rawTag)}</span>`;
}
function updateExcludedTagStack(tagSource: string, excludedTagStack: string[]): void {