From f193999b4d17df73dc9c366666af7971b06e9135 Mon Sep 17 00:00:00 2001 From: aidenlx <31102694+aidenlx@users.noreply.github.com> Date: Fri, 22 Sep 2023 16:52:30 +0800 Subject: [PATCH] feat(obsidian/template): support text color and background color in colored template previous version only accept backgound color --- .../note-feature/template-preview/preview.ts | 4 +- .../src/services/note-parser/service.ts | 75 +++++++++++++++++-- .../services/template/defaults/zt-colored.ejs | 5 +- app/obsidian/src/services/template/render.ts | 6 +- 4 files changed, 79 insertions(+), 11 deletions(-) diff --git a/app/obsidian/src/note-feature/template-preview/preview.ts b/app/obsidian/src/note-feature/template-preview/preview.ts index 240f4654..c55c559e 100644 --- a/app/obsidian/src/note-feature/template-preview/preview.ts +++ b/app/obsidian/src/note-feature/template-preview/preview.ts @@ -129,8 +129,10 @@ export class TemplatePreview extends TemplatePreviewBase { case "colored": markdown = renderer.renderColored({ content: "I'm Highlight", - color: "#FF0000", + color: "#FF000080", colorName: "red", + bgColor: "#FF000080", + bgColorName: "red", }); break; default: diff --git a/app/obsidian/src/services/note-parser/service.ts b/app/obsidian/src/services/note-parser/service.ts index 8f39ee31..3e9e9501 100644 --- a/app/obsidian/src/services/note-parser/service.ts +++ b/app/obsidian/src/services/note-parser/service.ts @@ -42,6 +42,20 @@ class Note { } } +function cssColorToHexName(code: string) { + if (!code) + return { + colorName: null, + color: null, + }; + const hex = colord(code).toHex().toUpperCase(); + const name = colors[hex.substring(0, 7) as keyof typeof colors]; + return { + colorName: name ?? hex, + color: hex, + }; +} + export class NoteParser extends Service { plugin = this.use(ZoteroPlugin); @@ -49,20 +63,67 @@ export class NoteParser extends Service { tdService = new globalThis.TurndownService() .addRule("color", { filter: (node, _opts) => { - return node.nodeName === "SPAN" && !!node.style.backgroundColor; + return node.nodeName === "SPAN" && Boolean(node.style.color); + }, + replacement: (content, node, _opts) => { + if (!(node instanceof HTMLElement)) { + throw new Error("Unexpected node"); + } + const { color, colorName } = cssColorToHexName(node.style.color); + + const child = node.firstChild as HTMLSpanElement | null; + if ( + child === node.lastChild && + child?.nodeName === "SPAN" && + Boolean(child.style.backgroundColor) + ) { + const { color: bgColor, colorName: bgColorName } = cssColorToHexName( + child.style.backgroundColor, + ); + return this.plugin.templateRenderer.renderColored({ + content, + color, + colorName, + bgColor, + bgColorName, + }); + } else { + return this.plugin.templateRenderer.renderColored({ + content, + color, + colorName, + bgColor: null, + bgColorName: null, + }); + } + }, + }) + .addRule("bg-color", { + filter: (node, _opts) => { + return node.nodeName === "SPAN" && Boolean(node.style.backgroundColor); }, replacement: (content, node, _opts) => { if (!(node instanceof HTMLElement)) { throw new Error("Unexpected node"); } - const colorCode = node.style.backgroundColor; - const hex = colord(colorCode).toHex(); + const { color: bgColor, colorName: bgColorName } = cssColorToHexName( + node.style.backgroundColor, + ); + const parent = node.parentElement as HTMLSpanElement | null; + if ( + parent?.nodeName === "SPAN" && + Boolean(parent.style.color) && + !node.nextSibling + ) { + // nested color are handled by color rule + return content; + } return this.plugin.templateRenderer.renderColored({ - color: hex, content, - colorName: - colors[hex.substring(0, 7).toUpperCase() as keyof typeof colors] ?? - hex, + color: null, + colorName: null, + bgColor, + bgColorName, }); }, }) diff --git a/app/obsidian/src/services/template/defaults/zt-colored.ejs b/app/obsidian/src/services/template/defaults/zt-colored.ejs index b1220c9f..12e058f7 100644 --- a/app/obsidian/src/services/template/defaults/zt-colored.ejs +++ b/app/obsidian/src/services/template/defaults/zt-colored.ejs @@ -1 +1,4 @@ -<%= it.content %> \ No newline at end of file +<%= it.content %> \ No newline at end of file diff --git a/app/obsidian/src/services/template/render.ts b/app/obsidian/src/services/template/render.ts index c6a350f3..f86a426b 100644 --- a/app/obsidian/src/services/template/render.ts +++ b/app/obsidian/src/services/template/render.ts @@ -21,9 +21,11 @@ import { toHelper } from "./helper/to-helper"; import { TemplateSettings } from "./settings"; interface ColoredText { - color: string; content: string; - colorName: string; + color: string | null; + colorName: string | null; + bgColor: string | null; + bgColorName: string | null; } export interface TemplateDataMap { note: DocItemHelper;