From 99943ed6154a0d8bba260f69b3ff1028ebdcc3e9 Mon Sep 17 00:00:00 2001 From: dragonish Date: Sat, 16 Aug 2025 10:25:31 +0800 Subject: [PATCH] feat: add support for custom leading delimiter Resolve: #19 --- common/counter.ts | 16 +++++++++--- common/data.ts | 8 ++++++ components/editor.ts | 4 +++ components/file-explorer.ts | 4 +++ components/outline.ts | 4 +++ components/quiet-outline.ts | 4 +++ components/reading.ts | 4 +++ components/setting-tab.ts | 32 +++++++++++++++++++++++ locales/en.json | 4 +++ locales/zh-TW.json | 4 +++ locales/zh.json | 4 +++ test/common/counter.spec.ts | 52 +++++++++++++++++++++++++++++++++++++ 12 files changed, 136 insertions(+), 4 deletions(-) diff --git a/common/counter.ts b/common/counter.ts index d4d1755..d31d061 100644 --- a/common/counter.ts +++ b/common/counter.ts @@ -82,6 +82,8 @@ export class Counter extends Querier { delimiter, trailingDelimiter, customTrailingDelimiter, + leadingDelimiter, + customLeadingDelimiter, customIdents, specifiedString, ignoreTopLevel, @@ -92,6 +94,8 @@ export class Counter extends Querier { delimiter, trailingDelimiter, customTrailingDelimiter, + leadingDelimiter, + customLeadingDelimiter, customIdents, specifiedString, ignoreTopLevel, @@ -122,6 +126,8 @@ export class Counter extends Querier { delimiter = ".", trailingDelimiter = false, customTrailingDelimiter = "", + leadingDelimiter = false, + customLeadingDelimiter = "", specifiedString = "#", customIdents = [], ignoreTopLevel = 0, @@ -146,10 +152,12 @@ export class Counter extends Querier { } result = results.join(delimiter); - result += - result.length > 0 && trailingDelimiter - ? customTrailingDelimiter || delimiter - : ""; + if (result.length > 0) { + result = + (leadingDelimiter ? customLeadingDelimiter || delimiter : "") + + result + + (trailingDelimiter ? customTrailingDelimiter || delimiter : ""); + } } else { result = this.decoratorOptions.levelHeadings[level - 1]; } diff --git a/common/data.ts b/common/data.ts index 571cc4d..df89f42 100644 --- a/common/data.ts +++ b/common/data.ts @@ -15,6 +15,8 @@ export interface BaseDecoratorOptions { delimiter?: string; trailingDelimiter?: boolean; customTrailingDelimiter?: string; + leadingDelimiter?: boolean; + customLeadingDelimiter?: string; customIdents?: string[]; specifiedString?: string; ignoreTopLevel?: number; @@ -29,6 +31,8 @@ interface OrderedDecoratorOptions { delimiter?: string; trailingDelimiter?: boolean; customTrailingDelimiter?: string; + leadingDelimiter?: boolean; + customLeadingDelimiter?: string; customIdents?: string[]; specifiedString?: string; ignoreTopLevel?: number; @@ -55,6 +59,8 @@ export interface HeadingDecoratorSettings { orderedDelimiter: string; orderedTrailingDelimiter: boolean; orderedCustomTrailingDelimiter?: string; + orderedLeadingDelimiter?: boolean; + orderedCustomLeadingDelimiter?: string; orderedCustomIdents: string; orderedSpecifiedString: string; orderedAllowZeroLevel?: boolean; @@ -156,6 +162,8 @@ export function defaultHeadingDecoratorSettings(): HeadingDecoratorSettings { orderedDelimiter: ".", orderedTrailingDelimiter: false, orderedCustomTrailingDelimiter: "", + orderedLeadingDelimiter: false, + orderedCustomLeadingDelimiter: "", orderedStyleType: "decimal", orderedCustomIdents: "Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ", orderedSpecifiedString: "#", diff --git a/components/editor.ts b/components/editor.ts index bfe5b52..99c38ad 100644 --- a/components/editor.ts +++ b/components/editor.ts @@ -106,6 +106,8 @@ export class HeadingEditorViewPlugin implements PluginValue { orderedDelimiter, orderedTrailingDelimiter, orderedCustomTrailingDelimiter, + orderedLeadingDelimiter, + orderedCustomLeadingDelimiter, orderedCustomIdents, orderedSpecifiedString, orderedAlwaysIgnore, @@ -156,6 +158,8 @@ export class HeadingEditorViewPlugin implements PluginValue { delimiter: orderedDelimiter, trailingDelimiter: orderedTrailingDelimiter, customTrailingDelimiter: orderedCustomTrailingDelimiter, + leadingDelimiter: orderedLeadingDelimiter, + customLeadingDelimiter: orderedCustomLeadingDelimiter, customIdents: getOrderedCustomIdents(orderedCustomIdents), specifiedString: orderedSpecifiedString, ignoreTopLevel, diff --git a/components/file-explorer.ts b/components/file-explorer.ts index c7edc8f..be63ca7 100644 --- a/components/file-explorer.ts +++ b/components/file-explorer.ts @@ -32,6 +32,8 @@ export function fileExplorerHandler( orderedDelimiter, orderedTrailingDelimiter, orderedCustomTrailingDelimiter, + orderedLeadingDelimiter, + orderedCustomLeadingDelimiter, orderedStyleType, orderedSpecifiedString, orderedCustomIdents, @@ -70,6 +72,8 @@ export function fileExplorerHandler( delimiter: orderedDelimiter, trailingDelimiter: orderedTrailingDelimiter, customTrailingDelimiter: orderedCustomTrailingDelimiter, + leadingDelimiter: orderedLeadingDelimiter, + customLeadingDelimiter: orderedCustomLeadingDelimiter, styleType: orderedStyleType, customIdents: getOrderedCustomIdents(orderedCustomIdents), specifiedString: orderedSpecifiedString, diff --git a/components/outline.ts b/components/outline.ts index 72b078b..40a5753 100644 --- a/components/outline.ts +++ b/components/outline.ts @@ -34,6 +34,8 @@ export function outlineHandler( orderedDelimiter, orderedTrailingDelimiter, orderedCustomTrailingDelimiter, + orderedLeadingDelimiter, + orderedCustomLeadingDelimiter, orderedStyleType, orderedSpecifiedString, orderedCustomIdents, @@ -72,6 +74,8 @@ export function outlineHandler( delimiter: orderedDelimiter, trailingDelimiter: orderedTrailingDelimiter, customTrailingDelimiter: orderedCustomTrailingDelimiter, + leadingDelimiter: orderedLeadingDelimiter, + customLeadingDelimiter: orderedCustomLeadingDelimiter, styleType: orderedStyleType, customIdents: getOrderedCustomIdents(orderedCustomIdents), specifiedString: orderedSpecifiedString, diff --git a/components/quiet-outline.ts b/components/quiet-outline.ts index 327d30e..7434d28 100644 --- a/components/quiet-outline.ts +++ b/components/quiet-outline.ts @@ -29,6 +29,8 @@ export function quietOutlineHandler( orderedDelimiter, orderedTrailingDelimiter, orderedCustomTrailingDelimiter, + orderedLeadingDelimiter, + orderedCustomLeadingDelimiter, orderedStyleType, orderedSpecifiedString, orderedCustomIdents, @@ -70,6 +72,8 @@ export function quietOutlineHandler( delimiter: orderedDelimiter, trailingDelimiter: orderedTrailingDelimiter, customTrailingDelimiter: orderedCustomTrailingDelimiter, + leadingDelimiter: orderedLeadingDelimiter, + customLeadingDelimiter: orderedCustomLeadingDelimiter, styleType: orderedStyleType, customIdents: getOrderedCustomIdents(orderedCustomIdents), specifiedString: orderedSpecifiedString, diff --git a/components/reading.ts b/components/reading.ts index 2e1c4aa..a2cb844 100644 --- a/components/reading.ts +++ b/components/reading.ts @@ -31,6 +31,8 @@ export function readingOrderedHandler( orderedDelimiter, orderedTrailingDelimiter, orderedCustomTrailingDelimiter, + orderedLeadingDelimiter, + orderedCustomLeadingDelimiter, orderedStyleType, orderedSpecifiedString, orderedCustomIdents, @@ -75,6 +77,8 @@ export function readingOrderedHandler( delimiter: orderedDelimiter, trailingDelimiter: orderedTrailingDelimiter, customTrailingDelimiter: orderedCustomTrailingDelimiter, + leadingDelimiter: orderedLeadingDelimiter, + customLeadingDelimiter: orderedCustomLeadingDelimiter, styleType: orderedStyleType, customIdents: getOrderedCustomIdents(orderedCustomIdents), specifiedString: orderedSpecifiedString, diff --git a/components/setting-tab.ts b/components/setting-tab.ts index 683893a..16a3a3e 100644 --- a/components/setting-tab.ts +++ b/components/setting-tab.ts @@ -567,6 +567,38 @@ export class HeadingSettingTab extends PluginSettingTab { }); }); + //* orderedLeadingDelimiter + new Setting(containerEl) + .setName(i18n.t("setting.orderedLeadingDelimiter")) + .setDesc(i18n.t("setting.orderedLeadingDelimiterDesc")) + .addToggle((toggle) => + toggle + .setValue( + this.plugin.settings[settingsType].orderedLeadingDelimiter || false + ) + .onChange((value) => { + this.plugin.settings[settingsType].orderedLeadingDelimiter = value; + this.plugin.saveSettings(); + }) + ); + + //* orderedCustomLeadingDelimiter + new Setting(containerEl) + .setName(i18n.t("setting.orderedCustomLeadingDelimiter")) + .setDesc(i18n.t("setting.orderedCustomLeadingDelimiterDesc")) + .addText((text) => { + text + .setValue( + this.plugin.settings[settingsType].orderedCustomLeadingDelimiter || + "" + ) + .onChange((value) => { + this.plugin.settings[settingsType].orderedCustomLeadingDelimiter = + value; + this.plugin.saveSettings(); + }); + }); + //* orderedCustomIdents new Setting(containerEl) .setName(i18n.t("setting.orderedCustomIdents")) diff --git a/locales/en.json b/locales/en.json index 69cd1d3..bcddf85 100644 --- a/locales/en.json +++ b/locales/en.json @@ -118,6 +118,10 @@ "orderedTrailingDelimiterDesc": "Set whether to add a trailing delimiter for ordered list.", "orderedCustomTrailingDelimiter": "Custom trailing delimiter", "orderedCustomTrailingDelimiterDesc": "Ignore the delimiter of the ordered list, customize another trailing delimiter.", + "orderedLeadingDelimiter": "Leading delimiter", + "orderedLeadingDelimiterDesc": "Set whether to add a leading delimiter for ordered list.", + "orderedCustomLeadingDelimiter": "Custom leading delimiter", + "orderedCustomLeadingDelimiterDesc": "Ignore the delimiter of the ordered list, customize another leading delimiter.", "orderedCustomIdents": "Custom list styles", "orderedCustomIdentsDesc": "For the \"Custom list styles\" option. Set custom list styles for ordered list. Use spaces to separate entries.", "orderedSpecifiedString": "Specified string", diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 0aa53b7..fc78b26 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -118,6 +118,10 @@ "orderedTrailingDelimiterDesc": "設定是否為有序列表補全尾隨分隔符。", "orderedCustomTrailingDelimiter": "自定義尾隨分隔符", "orderedCustomTrailingDelimiterDesc": "忽略有序列表的分隔符,自定義一個其他的尾隨分隔符。", + "orderedLeadingDelimiter": "前導分隔符", + "orderedLeadingDelimiterDesc": "設定是否為有序列表新增前導分隔符。", + "orderedCustomLeadingDelimiter": "自定義前導分隔符", + "orderedCustomLeadingDelimiterDesc": "忽略有序列表的分隔符,自定義一個其他的前導分隔符。", "orderedCustomIdents": "自定義列表樣式", "orderedCustomIdentsDesc": "針對\"自定義列表樣式\"選項。為有序列表設定自定義列表樣式。使用空格分隔條目。", "orderedSpecifiedString": "指定字串", diff --git a/locales/zh.json b/locales/zh.json index 3b429bd..eb60402 100644 --- a/locales/zh.json +++ b/locales/zh.json @@ -118,6 +118,10 @@ "orderedTrailingDelimiterDesc": "设置是否为有序列表添加尾随分隔符。", "orderedCustomTrailingDelimiter": "自定义尾随分隔符", "orderedCustomTrailingDelimiterDesc": "忽略有序列表的分隔符,自定义一个其他的尾随分隔符。", + "orderedLeadingDelimiter": "前导分隔符", + "orderedLeadingDelimiterDesc": "设置是否为有序列表添加前导分隔符。", + "orderedCustomLeadingDelimiter": "自定义前导分隔符", + "orderedCustomLeadingDelimiterDesc": "忽略有序列表的分隔符,自定义一个其他的前导分隔符。", "orderedCustomIdents": "自定义列表样式", "orderedCustomIdentsDesc": "针对\"自定义列表样式\"选项。为有序列表设置自定义列表样式。使用空格分隔条目。", "orderedSpecifiedString": "指定字符串", diff --git a/test/common/counter.spec.ts b/test/common/counter.spec.ts index c6c8f90..a641059 100644 --- a/test/common/counter.spec.ts +++ b/test/common/counter.spec.ts @@ -905,6 +905,58 @@ describe("common/counter", function () { expect(counter2.decorator(2)).to.equal("1.1|"); }); + it("Counter.decorator with custom leading delimiter", function () { + const counter1 = new Counter({ + ordered: true, + styleType: "decimal", + delimiter: ".", + customLeadingDelimiter: "", + leadingDelimiter: true, + }); + + expect(counter1.decorator(1)).to.equal(".1"); + expect(counter1.decorator(2)).to.equal(".1.1"); + + const counter2 = new Counter({ + ordered: true, + styleType: "decimal", + delimiter: ".", + customLeadingDelimiter: "|", + leadingDelimiter: true, + }); + + expect(counter2.decorator(1)).to.equal("|1"); + expect(counter2.decorator(2)).to.equal("|1.1"); + }); + + it("Counter.decorator with custom leading delimiter and trailing delimiter", function () { + const counter1 = new Counter({ + ordered: true, + styleType: "decimal", + delimiter: ".", + customTrailingDelimiter: "", + trailingDelimiter: true, + customLeadingDelimiter: "", + leadingDelimiter: true, + }); + + expect(counter1.decorator(1)).to.equal(".1."); + expect(counter1.decorator(2)).to.equal(".1.1."); + + const counter2 = new Counter({ + ordered: true, + styleType: "decimal", + delimiter: ".", + customTrailingDelimiter: ")", + trailingDelimiter: true, + customLeadingDelimiter: "(", + leadingDelimiter: true, + }); + + expect(counter2.decorator(1)).to.equal("(1)"); + expect(counter2.decorator(2)).to.equal("(1.1)"); + }); + it("Counter.decorator with ignoreTopLevel", function () { const counter1 = new Counter({ ordered: true,