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;