feat: add a new independent decorator mode

Resolve: #22
BREAKING CHANGE: adjust some settings, introduce a new decorator mode setting.
This commit is contained in:
dragonish 2026-01-09 13:04:07 +08:00
parent 9e98a8edea
commit c0bd1e15aa
No known key found for this signature in database
GPG key ID: 6F42FA9E807A5177
16 changed files with 2526 additions and 1555 deletions

View file

@ -1,5 +1,9 @@
module.exports = {
ui: "bdd",
spec: ["test/**/**.spec.ts"],
spec: [
"test/common/data.spec.ts",
"test/common/heading.spec.ts",
"test/**/**.spec.ts",
],
import: "tsx",
};

View file

@ -1,5 +1,9 @@
import type { BaseDecoratorOptions, DecoratorOptions } from "./data";
import { defaultHeadingTuple } from "./data";
import type {
OrderedDecoratorOptions,
IndependentDecoratorOptions,
IndependentDecoratorSettings,
} from "./data";
import { getOrderedCustomIdents } from "./data";
import * as presets from "@jsamr/counter-style/presets";
export class Querier {
@ -69,47 +73,12 @@ export class Querier {
}
}
export class Counter extends Querier {
private decoratorOptions: DecoratorOptions;
constructor(decoratorOptions?: BaseDecoratorOptions) {
export class OrderedCounter extends Querier implements Counter {
constructor(private decoratorOptions: OrderedDecoratorOptions) {
super(decoratorOptions?.allowZeroLevel, decoratorOptions?.maxRecLevel);
if (decoratorOptions) {
if (decoratorOptions.ordered) {
const {
styleType,
delimiter,
trailingDelimiter,
customTrailingDelimiter,
leadingDelimiter,
customLeadingDelimiter,
customIdents,
specifiedString,
ignoreTopLevel,
} = decoratorOptions;
this.decoratorOptions = {
ordered: true,
styleType: styleType || "decimal",
delimiter,
trailingDelimiter,
customTrailingDelimiter,
leadingDelimiter,
customLeadingDelimiter,
customIdents,
specifiedString,
ignoreTopLevel,
};
} else {
this.decoratorOptions = {
ordered: false,
levelHeadings: decoratorOptions.levelHeadings || [
...defaultHeadingTuple,
],
};
}
} else {
this.decoratorOptions = { ordered: true, styleType: "decimal" }; // Default to ordered if no options are provided
if (!decoratorOptions.styleType) {
this.decoratorOptions.styleType = "decimal"; // Default to ordered if no options are provided
}
}
@ -119,49 +88,160 @@ export class Counter extends Querier {
return result;
}
if (this.decoratorOptions.ordered) {
let results: string[] = [];
const {
styleType,
delimiter = ".",
trailingDelimiter = false,
customTrailingDelimiter = "",
leadingDelimiter = false,
customLeadingDelimiter = "",
specifiedString = "#",
customIdents = [],
ignoreTopLevel = 0,
} = this.decoratorOptions;
const levels = this.handler(level).slice(ignoreTopLevel);
let results: string[] = [];
const {
styleType = "decimal",
delimiter = ".",
trailingDelimiter = false,
customTrailingDelimiter = "",
leadingDelimiter = false,
customLeadingDelimiter = "",
specifiedString = "#",
customIdents = [],
ignoreTopLevel = 0,
} = this.decoratorOptions;
const levels = this.handler(level).slice(ignoreTopLevel);
switch (styleType) {
case "customIdent":
results = levels.map((level) =>
level > customIdents.length
? level.toString()
: customIdents[level - 1]
);
break;
case "string":
results = levels.map(() => specifiedString.trim() || "#");
break;
default:
results = levels.map((level) =>
presets[styleType].renderCounter(level)
);
}
switch (styleType) {
case "customIdent":
results = levels.map((level) =>
level > customIdents.length
? level.toString()
: customIdents[level - 1]
);
break;
case "string":
results = levels.map(() => specifiedString.trim() || "#");
break;
default:
results = levels.map((level) =>
presets[styleType].renderCounter(level)
);
}
result = results.join(delimiter);
if (result.length > 0) {
result =
(leadingDelimiter ? customLeadingDelimiter || delimiter : "") +
result +
(trailingDelimiter ? customTrailingDelimiter || delimiter : "");
}
} else {
result = this.decoratorOptions.levelHeadings[level - 1];
result = results.join(delimiter);
if (result.length > 0) {
result =
(leadingDelimiter ? customLeadingDelimiter || delimiter : "") +
result +
(trailingDelimiter ? customTrailingDelimiter || delimiter : "");
}
return result;
}
}
export class IndependentCounter extends Querier implements Counter {
constructor(private decoratorOptions: IndependentDecoratorOptions) {
super(decoratorOptions?.allowZeroLevel, decoratorOptions?.maxRecLevel);
}
decorator(level: number): string {
let result = "";
if (level < 1 || level > this.maxRecLevel) {
return result;
}
let results: string[] = [];
let used: Partial<IndependentDecoratorSettings>;
const {
h1 = {},
h2 = {},
h3 = {},
h4 = {},
h5 = {},
h6 = {},
orderedRecLevel = 6,
ignoreTopLevel = 0,
} = this.decoratorOptions;
let levels = this.handler(level).slice(ignoreTopLevel);
if (levels.length === 0) {
return result;
}
const current = Math.min(level, orderedRecLevel);
switch (current) {
case 6:
used = h6;
break;
case 5:
used = h5;
break;
case 4:
used = h4;
break;
case 3:
used = h3;
break;
case 2:
used = h2;
break;
case 1:
default:
used = h1;
break;
}
if (level <= current) {
levels = levels.slice(-1);
} else {
levels = levels.slice(current - ignoreTopLevel - 1);
}
const {
styleType = "decimal",
delimiter = ".",
trailingDelimiter = false,
customTrailingDelimiter = "",
leadingDelimiter = false,
customLeadingDelimiter = "",
customIdents = "",
specifiedString = "#",
} = used;
switch (styleType) {
case "customIdent":
results = levels.map((level) => {
const ci = getOrderedCustomIdents(customIdents);
return level > ci.length ? level.toString() : ci[level - 1];
});
break;
case "string":
results = levels.map(() => specifiedString.trim() || "#");
break;
default:
results = levels.map((level) =>
presets[styleType].renderCounter(level)
);
break;
}
result = results.join(delimiter);
if (result.length > 0) {
result =
(leadingDelimiter ? customLeadingDelimiter || delimiter : "") +
result +
(trailingDelimiter ? customTrailingDelimiter || delimiter : "");
}
return result;
}
}
export class UnorderedCounter implements Counter {
constructor(private levelHeadings: HeadingTuple, private maxRecLevel = 6) {}
decorator(level: number): string {
let result = "";
if (level < 1 || level > this.maxRecLevel) {
return result;
}
result = this.levelHeadings[level - 1];
return result;
}
handler(): void {
//* do nothing.
}
}

View file

@ -9,8 +9,7 @@ export type OrderedCounterStyleType =
| "customIdent"
| "string";
export interface BaseDecoratorOptions {
ordered: boolean;
export interface OrderedDecoratorOptions {
styleType?: OrderedCounterStyleType;
delimiter?: string;
trailingDelimiter?: boolean;
@ -20,41 +19,60 @@ export interface BaseDecoratorOptions {
customIdents?: string[];
specifiedString?: string;
ignoreTopLevel?: number;
levelHeadings?: HeadingTuple;
allowZeroLevel?: boolean;
maxRecLevel?: number;
}
interface OrderedDecoratorOptions {
ordered: true;
export interface IndependentDecoratorSettings {
styleType: OrderedCounterStyleType;
delimiter?: string;
trailingDelimiter?: boolean;
customTrailingDelimiter?: string;
leadingDelimiter?: boolean;
customLeadingDelimiter?: string;
customIdents?: string[];
specifiedString?: string;
delimiter: string;
trailingDelimiter: boolean;
customTrailingDelimiter: string;
leadingDelimiter: boolean;
customLeadingDelimiter: string;
customIdents: string;
specifiedString: string;
}
export interface IndependentDecoratorOptions {
maxRecLevel?: number;
allowZeroLevel?: boolean;
ignoreTopLevel?: number;
orderedRecLevel?: number;
h1?: Partial<IndependentDecoratorSettings>;
h2?: Partial<IndependentDecoratorSettings>;
h3?: Partial<IndependentDecoratorSettings>;
h4?: Partial<IndependentDecoratorSettings>;
h5?: Partial<IndependentDecoratorSettings>;
h6?: Partial<IndependentDecoratorSettings>;
}
interface UnorderedDecoratorOptions {
ordered: false;
levelHeadings: HeadingTuple;
}
interface IndependentSettings {
orderedRecLevel: number;
export type DecoratorOptions =
| OrderedDecoratorOptions
| UnorderedDecoratorOptions;
h1: IndependentDecoratorSettings;
h2: IndependentDecoratorSettings;
h3: IndependentDecoratorSettings;
h4: IndependentDecoratorSettings;
h5: IndependentDecoratorSettings;
h6: IndependentDecoratorSettings;
}
export interface HeadingDecoratorSettings {
enabledInEachNote?: boolean;
ordered: boolean;
decoratorMode?: DecoratorMode;
opacity: OpacityOptions;
position: PostionOptions;
maxRecLevel?: number;
orderedAllowZeroLevel?: boolean;
orderedBasedOnExisting?: boolean;
orderedAlwaysIgnore?: boolean;
orderedIgnoreMaximum?: number;
orderedIgnoreSingle: boolean;
orderedStyleType: OrderedCounterStyleType;
orderedDelimiter: string;
orderedTrailingDelimiter: boolean;
@ -63,11 +81,8 @@ export interface HeadingDecoratorSettings {
orderedCustomLeadingDelimiter?: string;
orderedCustomIdents: string;
orderedSpecifiedString: string;
orderedAllowZeroLevel?: boolean;
orderedBasedOnExisting?: boolean;
orderedAlwaysIgnore?: boolean;
orderedIgnoreSingle: boolean;
orderedIgnoreMaximum?: number;
independentSettings?: IndependentSettings;
unorderedLevelHeadings: string;
}
@ -131,6 +146,8 @@ export const className = {
after: "after-heading-decorator",
afterInside: "after-inside-heading-decorator",
hideSourceNumberSigns: "hide-source-number-signs",
settingContainer: "heading-decorator-setting-container",
settingItem: "heading-decorator-setting-item",
};
export const headingsSelector =
@ -143,6 +160,38 @@ export const defaultHeadingTuple: HeadingTuple = [
"H5",
"H6",
];
const defaultCustomidents =
"Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ";
function defaultIndependentDecoratorSettings(): IndependentDecoratorSettings {
return {
styleType: "decimal",
delimiter: ".",
trailingDelimiter: false,
customTrailingDelimiter: "",
leadingDelimiter: false,
customLeadingDelimiter: "",
customIdents: defaultCustomidents,
specifiedString: "#",
};
}
/**
* Defaults independent settings
*
* @returns independent settings
*/
export function defaultIndependentSettings(): IndependentSettings {
return {
orderedRecLevel: 6,
h1: defaultIndependentDecoratorSettings(),
h2: defaultIndependentDecoratorSettings(),
h3: defaultIndependentDecoratorSettings(),
h4: defaultIndependentDecoratorSettings(),
h5: defaultIndependentDecoratorSettings(),
h6: defaultIndependentDecoratorSettings(),
};
}
/**
* Default settings for heading decorator.
@ -155,20 +204,21 @@ export function defaultHeadingDecoratorSettings(): HeadingDecoratorSettings {
opacity: 20,
position: "before",
maxRecLevel: 6,
ordered: true,
decoratorMode: "orderd",
orderedDelimiter: ".",
orderedTrailingDelimiter: false,
orderedCustomTrailingDelimiter: "",
orderedLeadingDelimiter: false,
orderedCustomLeadingDelimiter: "",
orderedStyleType: "decimal",
orderedCustomIdents: "Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ",
orderedCustomIdents: defaultCustomidents,
orderedSpecifiedString: "#",
orderedAllowZeroLevel: false,
orderedBasedOnExisting: false,
orderedAlwaysIgnore: false,
orderedIgnoreSingle: false,
orderedIgnoreMaximum: 6,
independentSettings: defaultIndependentSettings(),
unorderedLevelHeadings: defaultHeadingTuple.join(" "),
};
}

View file

@ -15,7 +15,12 @@ import {
getOrderedCustomIdents,
findFirstCharacterIndex,
} from "../common/data";
import { Counter, Querier } from "../common/counter";
import {
Querier,
UnorderedCounter,
OrderedCounter,
IndependentCounter,
} from "../common/counter";
import { Heading } from "../common/heading";
/** A StateEffect for updating decorations */
@ -98,7 +103,7 @@ export class HeadingEditorViewPlugin implements PluginValue {
const doc = view.state.doc;
const {
ordered,
decoratorMode = "orderd",
position,
opacity,
maxRecLevel,
@ -116,12 +121,19 @@ export class HeadingEditorViewPlugin implements PluginValue {
orderedBasedOnExisting,
orderedAllowZeroLevel,
unorderedLevelHeadings,
independentSettings,
} = isLivePreviwMode
? pluginData.previewSettings
: pluginData.sourceSettings;
let ignoreTopLevel = 0;
if (ordered) {
let counter: Counter;
if (decoratorMode === "unordered") {
counter = new UnorderedCounter(
getUnorderedLevelHeadings(unorderedLevelHeadings),
maxRecLevel
);
} else {
let ignoreTopLevel = 0;
const ignoreSingle = !orderedAlwaysIgnore && orderedIgnoreSingle;
const ignoreLimit = orderedAlwaysIgnore ? orderedIgnoreMaximum : 0;
if (ignoreSingle || orderedBasedOnExisting) {
@ -149,23 +161,36 @@ export class HeadingEditorViewPlugin implements PluginValue {
if (ignoreTopLevel < ignoreLimit) {
ignoreTopLevel = ignoreLimit;
}
}
const counter = new Counter({
ordered,
maxRecLevel,
styleType: orderedStyleType,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
});
if (decoratorMode === "independent") {
counter = new IndependentCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
orderedRecLevel: independentSettings?.orderedRecLevel,
h1: independentSettings?.h1,
h2: independentSettings?.h2,
h3: independentSettings?.h3,
h4: independentSettings?.h4,
h5: independentSettings?.h5,
h6: independentSettings?.h6,
});
} else {
counter = new OrderedCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
styleType: orderedStyleType,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
});
}
}
const heading = new Heading();
for (let lineIndex = 1; lineIndex <= doc.lines; lineIndex++) {

View file

@ -5,7 +5,12 @@ import {
getOrderedCustomIdents,
getUnorderedLevelHeadings,
} from "../common/data";
import { Querier, Counter } from "../common/counter";
import {
Querier,
UnorderedCounter,
OrderedCounter,
IndependentCounter,
} from "../common/counter";
/**
* File Explorer Heading Decorator.
@ -22,9 +27,9 @@ export function fileExplorerHandler(
cacheHeadings: HeadingCache[]
): void {
const {
decoratorMode = "orderd",
opacity,
position,
ordered,
maxRecLevel,
orderedDelimiter,
orderedTrailingDelimiter,
@ -40,12 +45,19 @@ export function fileExplorerHandler(
orderedBasedOnExisting,
orderedAllowZeroLevel,
unorderedLevelHeadings,
independentSettings,
} = settings;
container.classList.add(className.fileExplorerContainer);
let ignoreTopLevel = 0;
if (ordered) {
let counter: Counter;
if (decoratorMode === "unordered") {
counter = new UnorderedCounter(
getUnorderedLevelHeadings(unorderedLevelHeadings),
maxRecLevel
);
} else {
let ignoreTopLevel = 0;
const ignoreSingle = !orderedAlwaysIgnore && orderedIgnoreSingle;
const ignoreLimit = orderedAlwaysIgnore ? orderedIgnoreMaximum : 0;
if (ignoreSingle || orderedBasedOnExisting) {
@ -61,23 +73,36 @@ export function fileExplorerHandler(
if (ignoreTopLevel < ignoreLimit) {
ignoreTopLevel = ignoreLimit;
}
}
const counter = new Counter({
ordered,
maxRecLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
});
if (decoratorMode === "independent") {
counter = new IndependentCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
orderedRecLevel: independentSettings?.orderedRecLevel,
h1: independentSettings?.h1,
h2: independentSettings?.h2,
h3: independentSettings?.h3,
h4: independentSettings?.h4,
h5: independentSettings?.h5,
h6: independentSettings?.h6,
});
} else {
counter = new OrderedCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
});
}
}
const marginMultiplier =
parseInt(

View file

@ -7,7 +7,12 @@ import {
diffLevel,
compareMarkdownText,
} from "../common/data";
import { Querier, Counter } from "../common/counter";
import {
Querier,
UnorderedCounter,
OrderedCounter,
IndependentCounter,
} from "../common/counter";
/**
* Handle the outline rendering based on the given settings and heading elements.
@ -24,9 +29,9 @@ export function outlineHandler(
cacheHeadings: HeadingCache[]
): void {
const {
decoratorMode = "orderd",
opacity,
position,
ordered,
maxRecLevel,
orderedDelimiter,
orderedTrailingDelimiter,
@ -42,12 +47,19 @@ export function outlineHandler(
orderedBasedOnExisting,
orderedAllowZeroLevel,
unorderedLevelHeadings,
independentSettings,
} = settings;
container.classList.add(className.outlineContainer);
let ignoreTopLevel = 0;
if (ordered) {
let counter: Counter;
if (decoratorMode === "unordered") {
counter = new UnorderedCounter(
getUnorderedLevelHeadings(unorderedLevelHeadings),
maxRecLevel
);
} else {
let ignoreTopLevel = 0;
const ignoreSingle = !orderedAlwaysIgnore && orderedIgnoreSingle;
const ignoreLimit = orderedAlwaysIgnore ? orderedIgnoreMaximum : 0;
if (ignoreSingle || orderedBasedOnExisting) {
@ -63,23 +75,36 @@ export function outlineHandler(
if (ignoreTopLevel < ignoreLimit) {
ignoreTopLevel = ignoreLimit;
}
}
const counter = new Counter({
ordered,
maxRecLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
});
if (decoratorMode === "independent") {
counter = new IndependentCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
orderedRecLevel: independentSettings?.orderedRecLevel,
h1: independentSettings?.h1,
h2: independentSettings?.h2,
h3: independentSettings?.h3,
h4: independentSettings?.h4,
h5: independentSettings?.h5,
h6: independentSettings?.h6,
});
} else {
counter = new OrderedCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
});
}
}
let lastCacheLevel = 0;
let lastReadLevel = 0;

View file

@ -214,8 +214,10 @@ export class HeadingPlugin extends Plugin {
return;
}
const { ordered } = readingSettings;
if (ordered) {
const { decoratorMode = "orderd" } = readingSettings;
if (decoratorMode === "unordered") {
readingUnorderedHandler(readingSettings, headingElements);
} else {
let sourceContent = fileData;
if (!sourceContent) {
const file = this.getActiveFile(cxt.sourcePath);
@ -238,8 +240,6 @@ export class HeadingPlugin extends Plugin {
headingElements,
sourceArr
);
} else {
readingUnorderedHandler(readingSettings, headingElements);
}
} else {
cancelHTMLDecorator(container);

View file

@ -4,7 +4,12 @@ import {
getOrderedCustomIdents,
getUnorderedLevelHeadings,
} from "../common/data";
import { Querier, Counter } from "../common/counter";
import {
Querier,
UnorderedCounter,
OrderedCounter,
IndependentCounter,
} from "../common/counter";
/**
* Handles the quiet outline for a given set of heading elements.
@ -19,9 +24,9 @@ export function quietOutlineHandler(
headingElements: NodeListOf<HTMLElement>
): void {
const {
decoratorMode = "orderd",
opacity,
position,
ordered,
maxRecLevel,
orderedDelimiter,
orderedTrailingDelimiter,
@ -37,12 +42,19 @@ export function quietOutlineHandler(
orderedBasedOnExisting,
orderedAllowZeroLevel,
unorderedLevelHeadings,
independentSettings,
} = settings;
container.classList.add(className.quietOutlineContainer);
let ignoreTopLevel = 0;
if (ordered) {
let counter: Counter;
if (decoratorMode === "unordered") {
counter = new UnorderedCounter(
getUnorderedLevelHeadings(unorderedLevelHeadings),
maxRecLevel
);
} else {
let ignoreTopLevel = 0;
const ignoreSingle = !orderedAlwaysIgnore && orderedIgnoreSingle;
const ignoreLimit = orderedAlwaysIgnore ? orderedIgnoreMaximum : 0;
if (ignoreSingle || orderedBasedOnExisting) {
@ -61,23 +73,36 @@ export function quietOutlineHandler(
if (ignoreTopLevel < ignoreLimit) {
ignoreTopLevel = ignoreLimit;
}
}
const counter = new Counter({
ordered,
maxRecLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
});
if (decoratorMode === "independent") {
counter = new IndependentCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
orderedRecLevel: independentSettings?.orderedRecLevel,
h1: independentSettings?.h1,
h2: independentSettings?.h2,
h3: independentSettings?.h3,
h4: independentSettings?.h4,
h5: independentSettings?.h5,
h6: independentSettings?.h6,
});
} else {
counter = new OrderedCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
});
}
}
headingElements.forEach((headingEle) => {
const level = queryHeadingLevelByQuietOutlineElement(headingEle);

View file

@ -7,7 +7,12 @@ import {
getUnorderedLevelHeadings,
} from "../common/data";
import { Heading } from "../common/heading";
import { Querier, Counter } from "../common/counter";
import {
Querier,
UnorderedCounter,
OrderedCounter,
IndependentCounter,
} from "../common/counter";
/**
* Handles ordered headings of reading view.
@ -24,6 +29,7 @@ export function readingOrderedHandler(
sourceArr: string[]
): void {
const {
decoratorMode = "orderd",
opacity,
position,
maxRecLevel,
@ -40,6 +46,7 @@ export function readingOrderedHandler(
orderedAlwaysIgnore,
orderedBasedOnExisting,
orderedAllowZeroLevel,
independentSettings,
} = settings;
let ignoreTopLevel = 0;
@ -70,20 +77,36 @@ export function readingOrderedHandler(
ignoreTopLevel = ignoreLimit;
}
const counter = new Counter({
ordered: true,
maxRecLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
});
let counter: Counter;
if (decoratorMode === "independent") {
counter = new IndependentCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
orderedRecLevel: independentSettings?.orderedRecLevel,
h1: independentSettings?.h1,
h2: independentSettings?.h2,
h3: independentSettings?.h3,
h4: independentSettings?.h4,
h5: independentSettings?.h5,
h6: independentSettings?.h6,
});
} else {
counter = new OrderedCounter({
maxRecLevel,
ignoreTopLevel,
allowZeroLevel: orderedAllowZeroLevel,
delimiter: orderedDelimiter,
trailingDelimiter: orderedTrailingDelimiter,
customTrailingDelimiter: orderedCustomTrailingDelimiter,
leadingDelimiter: orderedLeadingDelimiter,
customLeadingDelimiter: orderedCustomLeadingDelimiter,
styleType: orderedStyleType,
customIdents: getOrderedCustomIdents(orderedCustomIdents),
specifiedString: orderedSpecifiedString,
});
}
const heading = new Heading();
let headingIndex = 1;
@ -141,11 +164,10 @@ export function readingUnorderedHandler(
): void {
const { opacity, position, maxRecLevel, unorderedLevelHeadings } = settings;
const counter = new Counter({
ordered: false,
maxRecLevel,
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
});
const counter = new UnorderedCounter(
getUnorderedLevelHeadings(unorderedLevelHeadings),
maxRecLevel
);
headingElements.forEach((headingElement) => {
const level = queryHeadingLevelByElement(headingElement);

View file

@ -1,6 +1,11 @@
import { App, ButtonComponent, PluginSettingTab, Setting } from "obsidian";
import type { HeadingPlugin } from "./plugin";
import type { OrderedCounterStyleType } from "../common/data";
import type {
OrderedCounterStyleType,
HeadingDecoratorSettings,
IndependentDecoratorSettings,
} from "../common/data";
import { className, defaultIndependentSettings } from "../common/data";
import { orderedStyleTypeOptions } from "../common/options";
import { FolderSuggest } from "./suggest";
@ -70,12 +75,19 @@ export class HeadingSettingTab extends PluginSettingTab {
.addToggle((toggle) =>
toggle.setValue(settings.enabledInReading).onChange((value) => {
settings.enabledInReading = value;
value
? readingConfigContainerEl.show()
: readingConfigContainerEl.hide();
this.plugin.saveSettings();
})
);
const readingConfigContainerEl = containerEl.createDiv(
className.settingItem
);
let readingConfigBtn: ButtonOrUndefined;
new Setting(containerEl)
new Setting(readingConfigContainerEl)
.setName(i18n.t("setting.enabledInReadingConfig"))
.setDesc(i18n.t("setting.enabledInReadingConfigDesc"))
.addToggle((toggle) => {
@ -96,7 +108,7 @@ export class HeadingSettingTab extends PluginSettingTab {
});
//* readingRenderPolicy
new Setting(containerEl)
new Setting(readingConfigContainerEl)
.setName(i18n.t("setting.renderPolicy"))
.setDesc(i18n.t("setting.renderPolicyDesc"))
.addDropdown((dropdown) => {
@ -114,6 +126,10 @@ export class HeadingSettingTab extends PluginSettingTab {
});
});
if (!settings.enabledInReading) {
readingConfigContainerEl.hide();
}
new Setting(containerEl)
.setName(i18n.t("setting.livePreview"))
.setHeading();
@ -125,12 +141,19 @@ export class HeadingSettingTab extends PluginSettingTab {
.addToggle((toggle) =>
toggle.setValue(settings.enabledInPreview).onChange((value) => {
settings.enabledInPreview = value;
value
? previewConfigContainerEl.show()
: previewConfigContainerEl.hide();
this.plugin.saveSettings();
})
);
const previewConfigContainerEl = containerEl.createDiv(
className.settingItem
);
let previewConfigBtn: ButtonOrUndefined;
new Setting(containerEl)
new Setting(previewConfigContainerEl)
.setName(i18n.t("setting.enabledInPreviewConfig"))
.setDesc(i18n.t("setting.enabledInPreviewConfigDesc"))
.addToggle((toggle) => {
@ -150,6 +173,10 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDisabled(!settings.enabledPreviewSettings);
});
if (!settings.enabledInPreview) {
previewConfigContainerEl.hide();
}
new Setting(containerEl).setName(i18n.t("setting.sourceMode")).setHeading();
//* enabledInSource
@ -159,12 +186,19 @@ export class HeadingSettingTab extends PluginSettingTab {
.addToggle((toggle) =>
toggle.setValue(settings.enabledInSource).onChange((value) => {
settings.enabledInSource = value;
value
? sourceConfigContainerEl.show()
: sourceConfigContainerEl.hide();
this.plugin.saveSettings();
})
);
const sourceConfigContainerEl = containerEl.createDiv(
className.settingItem
);
let sourceConfigBtn: ButtonOrUndefined;
new Setting(containerEl)
new Setting(sourceConfigContainerEl)
.setName(i18n.t("setting.enabledInSourceConfig"))
.setDesc(i18n.t("setting.enabledInSourceConfigDesc"))
.addToggle((toggle) => {
@ -185,7 +219,7 @@ export class HeadingSettingTab extends PluginSettingTab {
});
//* sourceHideNumberSigns
new Setting(containerEl)
new Setting(sourceConfigContainerEl)
.setName(i18n.t("setting.hideNumberSigns"))
.setDesc(i18n.t("setting.hideNumberSignsDesc"))
.addToggle((toggle) => {
@ -197,6 +231,10 @@ export class HeadingSettingTab extends PluginSettingTab {
});
});
if (!settings.enabledInSource) {
sourceConfigContainerEl.hide();
}
new Setting(containerEl).setName(i18n.t("setting.outline")).setHeading();
//* enabledInOutline
@ -206,12 +244,19 @@ export class HeadingSettingTab extends PluginSettingTab {
.addToggle((toggle) =>
toggle.setValue(settings.enabledInOutline).onChange((value) => {
settings.enabledInOutline = value;
value
? outlineConfigContainerEl.show()
: outlineConfigContainerEl.hide();
this.plugin.saveSettings();
})
);
const outlineConfigContainerEl = containerEl.createDiv(
className.settingItem
);
let outlineConfigBtn: ButtonOrUndefined;
new Setting(containerEl)
new Setting(outlineConfigContainerEl)
.setName(i18n.t("setting.enabledInOutlineConfig"))
.setDesc(i18n.t("setting.enabledInOutlineConfigDesc"))
.addToggle((toggle) => {
@ -231,6 +276,10 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDisabled(!settings.enabledOutlineSettings);
});
if (!settings.enabledInOutline) {
outlineConfigContainerEl.hide();
}
new Setting(containerEl)
.setName(i18n.t("setting.quietOutline"))
.setHeading();
@ -241,6 +290,9 @@ export class HeadingSettingTab extends PluginSettingTab {
.addToggle((toggle) =>
toggle.setValue(settings.enabledInQuietOutline).onChange((value) => {
settings.enabledInQuietOutline = value;
value
? quietOutlineConfigContainerEl.show()
: quietOutlineConfigContainerEl.hide();
this.plugin.saveSettings();
})
);
@ -259,8 +311,12 @@ export class HeadingSettingTab extends PluginSettingTab {
);
enabledInQuietOutlineSetting.descEl.appendChild(enabledInQuietOutlineDesc);
const quietOutlineConfigContainerEl = containerEl.createDiv(
className.settingItem
);
let quietOutlineConfigBtn: ButtonOrUndefined;
new Setting(containerEl)
new Setting(quietOutlineConfigContainerEl)
.setName(i18n.t("setting.enabledInQuietOutlineConfig"))
.setDesc(i18n.t("setting.enabledInQuietOutlineConfigDesc"))
.addToggle((toggle) => {
@ -282,6 +338,10 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDisabled(!settings.enabledQuietOutlineSettings);
});
if (!settings.enabledInQuietOutline) {
quietOutlineConfigContainerEl.hide();
}
new Setting(containerEl)
.setName(i18n.t("setting.fileExplorer"))
.setHeading();
@ -292,6 +352,9 @@ export class HeadingSettingTab extends PluginSettingTab {
.addToggle((toggle) =>
toggle.setValue(settings.enabledInFileExplorer).onChange((value) => {
settings.enabledInFileExplorer = value;
value
? fileExplorerConfigContainerEl.show()
: fileExplorerConfigContainerEl.hide();
this.plugin.saveSettings();
})
);
@ -310,8 +373,12 @@ export class HeadingSettingTab extends PluginSettingTab {
);
enabledInFileExplorerSetting.descEl.appendChild(enabledInFileExplorerDesc);
const fileExplorerConfigContainerEl = containerEl.createDiv(
className.settingItem
);
let fileExplorerConfigBtn: ButtonOrUndefined;
new Setting(containerEl)
new Setting(fileExplorerConfigContainerEl)
.setName(i18n.t("setting.enabledInFileExplorerConfig"))
.setDesc(i18n.t("setting.enabledInFileExplorerConfigDesc"))
.addToggle((toggle) => {
@ -333,6 +400,10 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDisabled(!settings.enabledFileExplorerSettings);
});
if (!settings.enabledInFileExplorer) {
fileExplorerConfigContainerEl.hide();
}
new Setting(containerEl).setName(i18n.t("setting.blocklist")).setHeading();
//* folderBlacklist
@ -361,6 +432,10 @@ export class HeadingSettingTab extends PluginSettingTab {
return false;
}
private isDecoratorModeValue(value: string): value is DecoratorMode {
return ["orderd", "independent", "unordered"].includes(value);
}
private isPositionValue(value: string): value is PostionOptions {
return ["before", "after", "before-inside", "after-inside"].includes(value);
}
@ -428,16 +503,50 @@ export class HeadingSettingTab extends PluginSettingTab {
new Setting(containerEl).setName(i18n.t("setting.effect")).setHeading();
//* ordered
//* decoratorMode
new Setting(containerEl)
.setName(i18n.t("setting.ordered"))
.setDesc(i18n.t("setting.orderedDesc"))
.addToggle((toggle) =>
toggle.setValue(settings[settingsType].ordered).onChange((value) => {
settings[settingsType].ordered = value;
this.plugin.saveSettings();
})
);
.setName(i18n.t("setting.decoratorMode"))
.setDesc(i18n.t("setting.decoratorModeDesc"))
.addDropdown((dropdown) => {
const options: Record<DecoratorMode, string> = {
orderd: i18n.t("setting.ordered"),
independent: i18n.t("setting.independent"),
unordered: i18n.t("setting.unordered"),
};
dropdown
.addOptions(options)
.setValue(settings[settingsType].decoratorMode || "orderd")
.onChange((value) => {
settings[settingsType].decoratorMode = this.isDecoratorModeValue(
value
)
? value
: "orderd";
switch (settings[settingsType].decoratorMode) {
case "orderd":
orderedContainerEl.show();
logicContainerEl.show();
independentContainerEl.hide();
unorderedContainerEl.hide();
break;
case "independent":
independentContainerEl.show();
logicContainerEl.show();
orderedContainerEl.hide();
unorderedContainerEl.hide();
break;
case "unordered":
unorderedContainerEl.show();
orderedContainerEl.hide();
independentContainerEl.hide();
logicContainerEl.hide();
break;
}
this.plugin.saveSettings();
});
});
//* opacity
new Setting(containerEl)
@ -502,6 +611,51 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDynamicTooltip();
});
const orderedContainerEl = containerEl.createDiv(
className.settingContainer
);
this.orderedSettings(orderedContainerEl, settings[settingsType]);
if (
settings[settingsType].decoratorMode &&
settings[settingsType].decoratorMode !== "orderd"
) {
orderedContainerEl.hide();
}
const independentContainerEl = containerEl.createDiv(
className.settingContainer
);
this.independentSettings(independentContainerEl, settings[settingsType]);
if (settings[settingsType].decoratorMode !== "independent") {
independentContainerEl.hide();
}
const unorderedContainerEl = containerEl.createDiv(
className.settingContainer
);
this.unorderedSettings(unorderedContainerEl, settings[settingsType]);
if (settings[settingsType].decoratorMode !== "unordered") {
unorderedContainerEl.hide();
}
const logicContainerEl = containerEl.createDiv(className.settingContainer);
this.logicSettings(logicContainerEl, settings[settingsType]);
if (settings[settingsType].decoratorMode === "unordered") {
logicContainerEl.hide();
}
//* Scroll back to the top
containerEl.scrollTo({ top: 0, behavior: "smooth" });
}
private orderedSettings(
containerEl: HTMLElement,
settings: HeadingDecoratorSettings
) {
const {
plugin: { i18n },
} = this;
new Setting(containerEl).setName(i18n.t("setting.ordered")).setHeading();
//* orderedStyleType
@ -511,10 +665,23 @@ export class HeadingSettingTab extends PluginSettingTab {
.addDropdown((dropdown) =>
dropdown
.addOptions(orderedStyleTypeOptions)
.setValue(settings[settingsType].orderedStyleType)
.onChange((value) => {
settings[settingsType].orderedStyleType =
value as OrderedCounterStyleType;
.setValue(settings.orderedStyleType)
.onChange((value: OrderedCounterStyleType) => {
settings.orderedStyleType = value;
switch (value) {
case "customIdent":
orderedCustomIdentsContainerEl.show();
orderedSpecifiedStringContainerEl.hide();
break;
case "string":
orderedSpecifiedStringContainerEl.show();
orderedCustomIdentsContainerEl.hide();
break;
default:
orderedCustomIdentsContainerEl.hide();
orderedSpecifiedStringContainerEl.hide();
break;
}
this.plugin.saveSettings();
})
);
@ -524,12 +691,10 @@ export class HeadingSettingTab extends PluginSettingTab {
.setName(i18n.t("setting.orderedDelimiter"))
.setDesc(i18n.t("setting.orderedDelimiterDesc"))
.addText((text) =>
text
.setValue(settings[settingsType].orderedDelimiter)
.onChange((value) => {
settings[settingsType].orderedDelimiter = value;
this.plugin.saveSettings();
})
text.setValue(settings.orderedDelimiter).onChange((value) => {
settings.orderedDelimiter = value;
this.plugin.saveSettings();
})
);
//* orderedTrailingDelimiter
@ -537,78 +702,217 @@ export class HeadingSettingTab extends PluginSettingTab {
.setName(i18n.t("setting.orderedTrailingDelimiter"))
.setDesc(i18n.t("setting.orderedTrailingDelimiterDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings[settingsType].orderedTrailingDelimiter)
.onChange((value) => {
settings[settingsType].orderedTrailingDelimiter = value;
this.plugin.saveSettings();
})
toggle.setValue(settings.orderedTrailingDelimiter).onChange((value) => {
settings.orderedTrailingDelimiter = value;
value
? orderedCustomTrailingDelimiterContainerEl.show()
: orderedCustomTrailingDelimiterContainerEl.hide();
this.plugin.saveSettings();
})
);
const orderedCustomTrailingDelimiterContainerEl = containerEl.createDiv(
className.settingItem
);
//* orderedCustomTrailingDelimiter
new Setting(containerEl)
new Setting(orderedCustomTrailingDelimiterContainerEl)
.setName(i18n.t("setting.orderedCustomTrailingDelimiter"))
.setDesc(i18n.t("setting.orderedCustomTrailingDelimiterDesc"))
.addText((text) => {
text
.setValue(settings[settingsType].orderedCustomTrailingDelimiter || "")
.setValue(settings.orderedCustomTrailingDelimiter || "")
.onChange((value) => {
settings[settingsType].orderedCustomTrailingDelimiter = value;
settings.orderedCustomTrailingDelimiter = value;
this.plugin.saveSettings();
});
});
if (!settings.orderedTrailingDelimiter) {
orderedCustomTrailingDelimiterContainerEl.hide();
}
//* orderedLeadingDelimiter
new Setting(containerEl)
.setName(i18n.t("setting.orderedLeadingDelimiter"))
.setDesc(i18n.t("setting.orderedLeadingDelimiterDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings[settingsType].orderedLeadingDelimiter || false)
.setValue(settings.orderedLeadingDelimiter || false)
.onChange((value) => {
settings[settingsType].orderedLeadingDelimiter = value;
settings.orderedLeadingDelimiter = value;
value
? orderedCustomLeadingDelimiterContainerEl.show()
: orderedCustomLeadingDelimiterContainerEl.hide();
this.plugin.saveSettings();
})
);
const orderedCustomLeadingDelimiterContainerEl = containerEl.createDiv(
className.settingItem
);
//* orderedCustomLeadingDelimiter
new Setting(containerEl)
new Setting(orderedCustomLeadingDelimiterContainerEl)
.setName(i18n.t("setting.orderedCustomLeadingDelimiter"))
.setDesc(i18n.t("setting.orderedCustomLeadingDelimiterDesc"))
.addText((text) => {
text
.setValue(settings[settingsType].orderedCustomLeadingDelimiter || "")
.setValue(settings.orderedCustomLeadingDelimiter || "")
.onChange((value) => {
settings[settingsType].orderedCustomLeadingDelimiter = value;
settings.orderedCustomLeadingDelimiter = value;
this.plugin.saveSettings();
});
});
if (!settings.orderedLeadingDelimiter) {
orderedCustomLeadingDelimiterContainerEl.hide();
}
const orderedCustomIdentsContainerEl = containerEl.createDiv(
className.settingItem
);
//* orderedCustomIdents
new Setting(containerEl)
new Setting(orderedCustomIdentsContainerEl)
.setName(i18n.t("setting.orderedCustomIdents"))
.setDesc(i18n.t("setting.orderedCustomIdentsDesc"))
.addText((text) =>
text
.setValue(settings[settingsType].orderedCustomIdents)
.onChange((value) => {
settings[settingsType].orderedCustomIdents = value;
this.plugin.saveSettings();
})
text.setValue(settings.orderedCustomIdents).onChange((value) => {
settings.orderedCustomIdents = value;
this.plugin.saveSettings();
})
);
if (settings.orderedStyleType !== "customIdent") {
orderedCustomIdentsContainerEl.hide();
}
const orderedSpecifiedStringContainerEl = containerEl.createDiv(
className.settingItem
);
//* orderedSpecifiedString
new Setting(containerEl)
new Setting(orderedSpecifiedStringContainerEl)
.setName(i18n.t("setting.orderedSpecifiedString"))
.setDesc(i18n.t("setting.orderedSpecifiedStringDesc"))
.addText((text) =>
text
.setValue(settings[settingsType].orderedSpecifiedString)
text.setValue(settings.orderedSpecifiedString).onChange((value) => {
settings.orderedSpecifiedString = value;
this.plugin.saveSettings();
})
);
if (settings.orderedStyleType !== "string") {
orderedSpecifiedStringContainerEl.hide();
}
}
private independentSettings(
containerEl: HTMLElement,
settings: HeadingDecoratorSettings
) {
const {
plugin: { i18n },
} = this;
if (!settings.independentSettings) {
settings.independentSettings = defaultIndependentSettings();
}
new Setting(containerEl)
.setName(i18n.t("setting.independent"))
.setHeading();
//* orderedRecLevel
new Setting(containerEl)
.setName(i18n.t("setting.orderedRecLevel"))
.setDesc(i18n.t("setting.orderedRecLevelDesc"))
.addSlider((slider) => {
slider
.setLimits(2, 6, 1)
.setValue(settings.independentSettings!.orderedRecLevel)
.onChange((value) => {
settings[settingsType].orderedSpecifiedString = value;
settings.independentSettings!.orderedRecLevel = value;
this.plugin.saveSettings();
})
.setDynamicTooltip();
});
//* h1
new Setting(containerEl).setName(i18n.t("setting.h1")).setHeading();
this.independentDecoratorSettings(
containerEl,
settings.independentSettings!.h1
);
//* h2
new Setting(containerEl).setName(i18n.t("setting.h2")).setHeading();
this.independentDecoratorSettings(
containerEl,
settings.independentSettings!.h2
);
//* h3
new Setting(containerEl).setName(i18n.t("setting.h3")).setHeading();
this.independentDecoratorSettings(
containerEl,
settings.independentSettings!.h3
);
//* h4
new Setting(containerEl).setName(i18n.t("setting.h4")).setHeading();
this.independentDecoratorSettings(
containerEl,
settings.independentSettings!.h4
);
//* h5
new Setting(containerEl).setName(i18n.t("setting.h5")).setHeading();
this.independentDecoratorSettings(
containerEl,
settings.independentSettings!.h5
);
//* h6
new Setting(containerEl).setName(i18n.t("setting.h6")).setHeading();
this.independentDecoratorSettings(
containerEl,
settings.independentSettings!.h6
);
}
private unorderedSettings(
containerEl: HTMLElement,
settings: HeadingDecoratorSettings
) {
const {
plugin: { i18n },
} = this;
new Setting(containerEl).setName(i18n.t("setting.unordered")).setHeading();
//* unorderedLevelHeadings
new Setting(containerEl)
.setName(i18n.t("setting.unorderedLevelHeadings"))
.setDesc(i18n.t("setting.unorderedLevelHeadingsDesc"))
.addText((text) =>
text.setValue(settings.unorderedLevelHeadings).onChange((value) => {
settings.unorderedLevelHeadings = value;
this.plugin.saveSettings();
})
);
}
private logicSettings(
containerEl: HTMLElement,
settings: HeadingDecoratorSettings
) {
const {
plugin: { i18n },
} = this;
new Setting(containerEl).setName(i18n.t("setting.logic")).setHeading();
//* orderedAllowZeroLevel
new Setting(containerEl)
@ -616,9 +920,9 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDesc(i18n.t("setting.orderedAllowZeroLevelDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings[settingsType].orderedAllowZeroLevel ?? false)
.setValue(settings.orderedAllowZeroLevel ?? false)
.onChange((value) => {
settings[settingsType].orderedAllowZeroLevel = value;
settings.orderedAllowZeroLevel = value;
this.plugin.saveSettings();
})
);
@ -629,9 +933,9 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDesc(i18n.t("setting.orderedBasedOnExistingDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings[settingsType].orderedBasedOnExisting ?? false)
.setValue(settings.orderedBasedOnExisting ?? false)
.onChange((value) => {
settings[settingsType].orderedBasedOnExisting = value;
settings.orderedBasedOnExisting = value;
this.plugin.saveSettings();
})
);
@ -642,9 +946,9 @@ export class HeadingSettingTab extends PluginSettingTab {
.setDesc(i18n.t("setting.orderedAlwaysIgnoreDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings[settingsType].orderedAlwaysIgnore ?? false)
.setValue(settings.orderedAlwaysIgnore ?? false)
.onChange((value) => {
settings[settingsType].orderedAlwaysIgnore = value;
settings.orderedAlwaysIgnore = value;
this.plugin.saveSettings();
})
);
@ -654,12 +958,10 @@ export class HeadingSettingTab extends PluginSettingTab {
.setName(i18n.t("setting.orderedIgnoreSingle"))
.setDesc(i18n.t("setting.orderedIgnoreSingleDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings[settingsType].orderedIgnoreSingle)
.onChange((value) => {
settings[settingsType].orderedIgnoreSingle = value;
this.plugin.saveSettings();
})
toggle.setValue(settings.orderedIgnoreSingle).onChange((value) => {
settings.orderedIgnoreSingle = value;
this.plugin.saveSettings();
})
);
//* orderedIgnoreMaximum
@ -669,31 +971,13 @@ export class HeadingSettingTab extends PluginSettingTab {
.addSlider((slider) =>
slider
.setLimits(1, 6, 1)
.setValue(settings[settingsType].orderedIgnoreMaximum ?? 6)
.setValue(settings.orderedIgnoreMaximum ?? 6)
.onChange((value) => {
settings[settingsType].orderedIgnoreMaximum = value;
settings.orderedIgnoreMaximum = value;
this.plugin.saveSettings();
})
.setDynamicTooltip()
);
new Setting(containerEl).setName(i18n.t("setting.unordered")).setHeading();
//* unorderedLevelHeadings
new Setting(containerEl)
.setName(i18n.t("setting.unorderedLevelHeadings"))
.setDesc(i18n.t("setting.unorderedLevelHeadingsDesc"))
.addText((text) =>
text
.setValue(settings[settingsType].unorderedLevelHeadings)
.onChange((value) => {
settings[settingsType].unorderedLevelHeadings = value;
this.plugin.saveSettings();
})
);
//* Scroll back to the top
containerEl.scrollTo({ top: 0, behavior: "smooth" });
}
private manageFolderBlacklist(scrollToTop = false) {
@ -826,4 +1110,162 @@ export class HeadingSettingTab extends PluginSettingTab {
containerEl.scrollTo({ top: 0, behavior: "smooth" });
}
}
private independentDecoratorSettings(
containerEl: HTMLElement,
settings: IndependentDecoratorSettings
) {
const {
plugin: { i18n },
} = this;
//* styleType
new Setting(containerEl)
.setName(i18n.t("setting.orderedStyleType"))
.setDesc(i18n.t("setting.orderedStyleTypeDesc"))
.addDropdown((dropdown) =>
dropdown
.addOptions(orderedStyleTypeOptions)
.setValue(settings.styleType)
.onChange((value: OrderedCounterStyleType) => {
settings.styleType = value;
switch (value) {
case "customIdent":
customIdentsContainerEl.show();
specifiedStringContainerEl.hide();
break;
case "string":
specifiedStringContainerEl.show();
customIdentsContainerEl.hide();
break;
default:
customIdentsContainerEl.hide();
specifiedStringContainerEl.hide();
break;
}
this.plugin.saveSettings();
})
);
//* delimiter
new Setting(containerEl)
.setName(i18n.t("setting.orderedDelimiter"))
.setDesc(i18n.t("setting.orderedDelimiterDesc"))
.addText((text) =>
text.setValue(settings.delimiter).onChange((value) => {
settings.delimiter = value;
this.plugin.saveSettings();
})
);
//* trailingDelimiter
new Setting(containerEl)
.setName(i18n.t("setting.orderedTrailingDelimiter"))
.setDesc(i18n.t("setting.orderedTrailingDelimiterDesc"))
.addToggle((toggle) =>
toggle.setValue(settings.trailingDelimiter).onChange((value) => {
settings.trailingDelimiter = value;
value
? customTrailingDelimiterContainerEl.show()
: customTrailingDelimiterContainerEl.hide();
this.plugin.saveSettings();
})
);
const customTrailingDelimiterContainerEl = containerEl.createDiv(
className.settingItem
);
//* customTrailingDelimiter
new Setting(customTrailingDelimiterContainerEl)
.setName(i18n.t("setting.orderedCustomTrailingDelimiter"))
.setDesc(i18n.t("setting.orderedCustomTrailingDelimiterDesc"))
.addText((text) => {
text
.setValue(settings.customTrailingDelimiter || "")
.onChange((value) => {
settings.customTrailingDelimiter = value;
this.plugin.saveSettings();
});
});
if (!settings.trailingDelimiter) {
customTrailingDelimiterContainerEl.hide();
}
//* leadingDelimiter
new Setting(containerEl)
.setName(i18n.t("setting.orderedLeadingDelimiter"))
.setDesc(i18n.t("setting.orderedLeadingDelimiterDesc"))
.addToggle((toggle) =>
toggle
.setValue(settings.leadingDelimiter || false)
.onChange((value) => {
settings.leadingDelimiter = value;
value
? customLeadingDelimiterContainerEl.show()
: customLeadingDelimiterContainerEl.hide();
this.plugin.saveSettings();
})
);
const customLeadingDelimiterContainerEl = containerEl.createDiv(
className.settingItem
);
//* customLeadingDelimiter
new Setting(customLeadingDelimiterContainerEl)
.setName(i18n.t("setting.orderedCustomLeadingDelimiter"))
.setDesc(i18n.t("setting.orderedCustomLeadingDelimiterDesc"))
.addText((text) => {
text
.setValue(settings.customLeadingDelimiter || "")
.onChange((value) => {
settings.customLeadingDelimiter = value;
this.plugin.saveSettings();
});
});
if (!settings.leadingDelimiter) {
customLeadingDelimiterContainerEl.hide();
}
const customIdentsContainerEl = containerEl.createDiv(
className.settingItem
);
//* customIdents
new Setting(customIdentsContainerEl)
.setName(i18n.t("setting.orderedCustomIdents"))
.setDesc(i18n.t("setting.orderedCustomIdentsDesc"))
.addText((text) =>
text.setValue(settings.customIdents).onChange((value) => {
settings.customIdents = value;
this.plugin.saveSettings();
})
);
if (settings.styleType !== "customIdent") {
customIdentsContainerEl.hide();
}
const specifiedStringContainerEl = containerEl.createDiv(
className.settingItem
);
//* specifiedString
new Setting(specifiedStringContainerEl)
.setName(i18n.t("setting.orderedSpecifiedString"))
.setDesc(i18n.t("setting.orderedSpecifiedStringDesc"))
.addText((text) =>
text.setValue(settings.specifiedString).onChange((value) => {
settings.specifiedString = value;
this.plugin.saveSettings();
})
);
if (settings.styleType !== "string") {
specifiedStringContainerEl.hide();
}
}
}

View file

@ -98,8 +98,8 @@
"enabledInEachNote": "Enabled in each note",
"enabledInEachNoteDesc": "Toggle this setting to enable the decoration of headings in each note.",
"effect": "Effect",
"ordered": "Ordered",
"orderedDesc": "Toggle this setting to enable the decoration of headings as an ordered or unordered list.",
"decoratorMode": "Mode",
"decoratorModeDesc": "Toggle this setting to decorate headings as ordered list, independent list, or unordered list.",
"opacity": "Opacity",
"opacityDesc": "Set the opacity of the heading decorator. The value is the form of percentage.",
"position": "Position",
@ -110,32 +110,36 @@
"after": "After the heading",
"beforeInside": "Before the heading (inside)",
"afterInside": "After the heading (inside)",
"ordered": "Ordered",
"orderedStyleType": "Style type",
"orderedStyleTypeDesc": "Set the style type for ordered list.",
"orderedStyleTypeDesc": "Set the style type for decorator.",
"orderedDelimiter": "Delimiter",
"orderedDelimiterDesc": "Set the delimiter for ordered list.",
"orderedDelimiterDesc": "Set the delimiter for decorator.",
"orderedTrailingDelimiter": "Trailing delimiter",
"orderedTrailingDelimiterDesc": "Set whether to add a trailing delimiter for ordered list.",
"orderedTrailingDelimiterDesc": "Set whether to add a trailing delimiter for decorator.",
"orderedCustomTrailingDelimiter": "Custom trailing delimiter",
"orderedCustomTrailingDelimiterDesc": "Ignore the delimiter of the ordered list, customize another trailing delimiter.",
"orderedCustomTrailingDelimiterDesc": "Ignore the delimiter of the decorator, customize another trailing delimiter.",
"orderedLeadingDelimiter": "Leading delimiter",
"orderedLeadingDelimiterDesc": "Set whether to add a leading delimiter for ordered list.",
"orderedLeadingDelimiterDesc": "Set whether to add a leading delimiter for decorator.",
"orderedCustomLeadingDelimiter": "Custom leading delimiter",
"orderedCustomLeadingDelimiterDesc": "Ignore the delimiter of the ordered list, customize another leading delimiter.",
"orderedCustomLeadingDelimiterDesc": "Ignore the delimiter of the decorator, 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.",
"orderedCustomIdentsDesc": "For the \"Custom list styles\" option. Set custom list styles for decorator. Use spaces to separate entries.",
"orderedSpecifiedString": "Specified string",
"orderedSpecifiedStringDesc": "For the \"Specified string\" option. Set a specified string for ordered list.",
"orderedSpecifiedStringDesc": "For the \"Specified string\" option. Set a specified string for decorator.",
"orderedAllowZeroLevel": "Allow zero level",
"orderedAllowZeroLevelDesc": "If the next heading is more than one level higher, the omitted level is zero instead of one.",
"orderedBasedOnExisting": "Based on the existing highest level",
"orderedBasedOnExistingDesc": "Use the highest level of headings in the note as the base for ordered list.",
"orderedBasedOnExistingDesc": "Use the highest level of headings in the note as the base for building decorators.",
"orderedAlwaysIgnore": "Always ignore the top-level headings",
"orderedAlwaysIgnoreDesc": "Exclude the top-level heading when building ordered lists. controlled by the \"Maximum number of ignored levels\" option.",
"orderedAlwaysIgnoreDesc": "Exclude the top-level heading when building decorators. controlled by the \"Maximum number of ignored levels\" option.",
"orderedIgnoreSingle": "Ignore the single heading at the top-level",
"orderedIgnoreSingleDesc": "If the top-level has only a single heading, exclude it when building an ordered list. controlled by the \"Maximum number of ignored levels\" option.",
"orderedIgnoreSingleDesc": "If the top-level has only a single heading, exclude it when building decorators. controlled by the \"Maximum number of ignored levels\" option.",
"orderedIgnoreMaximum": "Maximum number of ignored levels",
"orderedIgnoreMaximumDesc": "When enabling the option to ignore top-level headings, specify the maximum number of levels to ignore.",
"independent": "Independent",
"orderedRecLevel": "Level using ordered list",
"orderedRecLevelDesc": "When the heading level exceeds the specified level, build it as an ordered list.",
"unordered": "Unordered",
"unorderedLevelHeadings": "Level headings",
"unorderedLevelHeadingsDesc": "Set the names for each level. The value is 6 entries separated by spaces.",
@ -149,6 +153,13 @@
"folderBlocklistAddTip": "Add a new folder to the blocklist",
"fileRegexBlocklistIndex": "Note name regex blocklist {index}",
"fileRegexBlocklistPlaceholder": "e.g., /^daily.*/i",
"fileRegexBlocklistAddTip": "Add a new note name regex blocklist"
"fileRegexBlocklistAddTip": "Add a new note name regex blocklist",
"logic": "Logic",
"h1": "H1",
"h2": "H2",
"h3": "H3",
"h4": "H4",
"h5": "H5",
"h6": "H6"
}
}

View file

@ -98,11 +98,11 @@
"enabledInEachNote": "在每個筆記中啟用",
"enabledInEachNoteDesc": "切換此設定以啟用每個筆記中標題的裝飾。",
"effect": "效果",
"ordered": "有序列表",
"orderedDesc": "切換此設定可將標題裝飾為有序或無序列表。",
"opacity": "不透明度",
"decoratorMode": "裝飾器的模式",
"decoratorModeDesc": "切換此設定可將標題裝飾為有序列表、獨立層級或無序列表。",
"opacity": "裝飾器的不透明度",
"opacityDesc": "設定標題裝飾器的不透明度。值是百分比的形式。",
"position": "位置",
"position": "裝飾器的位置",
"positionDesc": "設定標題裝飾器的位置。",
"maxRecLevel": "所識別的最大級別",
"maxRecLevelDesc": "指定所識別標題的最大級別,不處理高於此級別的標題。",
@ -110,32 +110,36 @@
"after": "在標題之後",
"beforeInside": "在標題之前 (內部)",
"afterInside": "在標題之後 (內部)",
"ordered": "有序列表",
"orderedStyleType": "樣式型別",
"orderedStyleTypeDesc": "設定有序列表的樣式型別。",
"orderedStyleTypeDesc": "設定裝飾器的樣式型別。",
"orderedDelimiter": "分隔符",
"orderedDelimiterDesc": "設定有序列表的分隔符。",
"orderedDelimiterDesc": "設定裝飾器的分隔符。",
"orderedTrailingDelimiter": "尾隨分隔符",
"orderedTrailingDelimiterDesc": "設定是否為有序列表補全尾隨分隔符。",
"orderedTrailingDelimiterDesc": "設定是否為裝飾器補全尾隨分隔符。",
"orderedCustomTrailingDelimiter": "自定義尾隨分隔符",
"orderedCustomTrailingDelimiterDesc": "忽略有序列表的分隔符,自定義一個其他的尾隨分隔符。",
"orderedCustomTrailingDelimiterDesc": "忽略裝飾器的分隔符,自定義一個其他的尾隨分隔符。",
"orderedLeadingDelimiter": "前導分隔符",
"orderedLeadingDelimiterDesc": "設定是否為有序列表新增前導分隔符。",
"orderedLeadingDelimiterDesc": "設定是否為裝飾器新增前導分隔符。",
"orderedCustomLeadingDelimiter": "自定義前導分隔符",
"orderedCustomLeadingDelimiterDesc": "忽略有序列表的分隔符,自定義一個其他的前導分隔符。",
"orderedCustomLeadingDelimiterDesc": "忽略裝飾器的分隔符,自定義一個其他的前導分隔符。",
"orderedCustomIdents": "自定義列表樣式",
"orderedCustomIdentsDesc": "針對\"自定義列表樣式\"選項。為有序列表設定自定義列表樣式。使用空格分隔條目。",
"orderedCustomIdentsDesc": "針對\"自定義列表樣式\"選項。為裝飾器設定自定義列表樣式。使用空格分隔條目。",
"orderedSpecifiedString": "指定字串",
"orderedSpecifiedStringDesc": "針對\"指定字串\"選項。為有序列表設定指定的字串。",
"orderedSpecifiedStringDesc": "針對\"指定字串\"選項。為裝飾器設定指定的字串。",
"orderedAllowZeroLevel": "允許零級別",
"orderedAllowZeroLevelDesc": "如果下一個標題高出一個以上的級別,則省略的級別為零而不是一。",
"orderedBasedOnExisting": "基於現有的最高級別",
"orderedBasedOnExistingDesc": "使用筆記中最高級別的標題作為有序列表的基礎。",
"orderedBasedOnExistingDesc": "使用筆記中最高級別的標題作為構建裝飾器的基礎。",
"orderedAlwaysIgnore": "始終忽略頂層的標題",
"orderedAlwaysIgnoreDesc": "在構建有序列表時將頂層的標題排除掉,受\"忽略的最大層級數量\"選項控制。",
"orderedAlwaysIgnoreDesc": "在構建裝飾器時將頂層的標題排除掉,受\"忽略的最大層級數量\"選項控制。",
"orderedIgnoreSingle": "忽略頂層的獨立標題",
"orderedIgnoreSingleDesc": "如果頂層只有一個標題,則在構建有序列表時將其排除。受\"忽略的最大層級數量\"選項控制。",
"orderedIgnoreSingleDesc": "如果頂層只有一個標題,則在構建裝飾器時將其排除。受\"忽略的最大層級數量\"選項控制。",
"orderedIgnoreMaximum": "忽略的最大層級數量",
"orderedIgnoreMaximumDesc": "在啟用忽略頂層標題的選項時,指定可忽略的最大層級數量。",
"independent": "獨立層級",
"orderedRecLevel": "使用有序列表的級別",
"orderedRecLevelDesc": "標題級別超出指定級別後按有序列表進行構建。",
"unordered": "無序列表",
"unorderedLevelHeadings": "級別標題",
"unorderedLevelHeadingsDesc": "設定每個級別的名稱。值為 6 個條目,以空格分隔。",
@ -149,6 +153,13 @@
"folderBlocklistAddTip": "新增新的資料夾到阻止列表",
"fileRegexBlocklistIndex": "筆記名稱正則表示式阻止列表 {index}",
"fileRegexBlocklistPlaceholder": "例如:/^daily.*/i",
"fileRegexBlocklistAddTip": "新增新的筆記名稱正則表示式到阻止列表"
"fileRegexBlocklistAddTip": "新增新的筆記名稱正則表示式到阻止列表",
"logic": "邏輯控制",
"h1": "H1 級別",
"h2": "H2 級別",
"h3": "H3 級別",
"h4": "H4 級別",
"h5": "H5 級別",
"h6": "H6 級別"
}
}

View file

@ -98,11 +98,11 @@
"enabledInEachNote": "在每个笔记中启用",
"enabledInEachNoteDesc": "切换此设置以启用每个笔记中标题的装饰。",
"effect": "效果",
"ordered": "有序列表",
"orderedDesc": "切换此设置可将标题装饰为有序或无序列表。",
"opacity": "不透明度",
"decoratorMode": "装饰器的模式",
"decoratorModeDesc": "切换此设置可将标题装饰为有序列表、独立层级或无序列表。",
"opacity": "装饰器的不透明度",
"opacityDesc": "设置标题装饰器的不透明度。值是百分比的形式。",
"position": "位置",
"position": "装饰器的位置",
"positionDesc": "设置标题装饰器的位置。",
"maxRecLevel": "所识别的最大级别",
"maxRecLevelDesc": "指定所识别标题的最大级别,不处理高于此级别的标题。",
@ -110,32 +110,36 @@
"after": "在标题之后",
"beforeInside": "在标题之前 (内部)",
"afterInside": "在标题之后 (内部)",
"ordered": "有序列表",
"orderedStyleType": "样式类型",
"orderedStyleTypeDesc": "设置有序列表的样式类型。",
"orderedStyleTypeDesc": "设置装饰器的样式类型。",
"orderedDelimiter": "分隔符",
"orderedDelimiterDesc": "设置有序列表的分隔符。",
"orderedDelimiterDesc": "设置装饰器的分隔符。",
"orderedTrailingDelimiter": "尾随分隔符",
"orderedTrailingDelimiterDesc": "设置是否为有序列表添加尾随分隔符。",
"orderedTrailingDelimiterDesc": "设置是否为装饰器添加尾随分隔符。",
"orderedCustomTrailingDelimiter": "自定义尾随分隔符",
"orderedCustomTrailingDelimiterDesc": "忽略有序列表的分隔符,自定义一个其他的尾随分隔符。",
"orderedCustomTrailingDelimiterDesc": "忽略装饰器的分隔符,自定义一个其他的尾随分隔符。",
"orderedLeadingDelimiter": "前导分隔符",
"orderedLeadingDelimiterDesc": "设置是否为有序列表添加前导分隔符。",
"orderedLeadingDelimiterDesc": "设置是否为装饰器添加前导分隔符。",
"orderedCustomLeadingDelimiter": "自定义前导分隔符",
"orderedCustomLeadingDelimiterDesc": "忽略有序列表的分隔符,自定义一个其他的前导分隔符。",
"orderedCustomLeadingDelimiterDesc": "忽略装饰器的分隔符,自定义一个其他的前导分隔符。",
"orderedCustomIdents": "自定义列表样式",
"orderedCustomIdentsDesc": "针对\"自定义列表样式\"选项。为有序列表设置自定义列表样式。使用空格分隔条目。",
"orderedCustomIdentsDesc": "针对\"自定义列表样式\"选项。为装饰器设置自定义列表样式。使用空格分隔条目。",
"orderedSpecifiedString": "指定字符串",
"orderedSpecifiedStringDesc": "针对\"指定字符串\"选项。为有序列表设置指定的字符串。",
"orderedSpecifiedStringDesc": "针对\"指定字符串\"选项。为装饰器设置指定的字符串。",
"orderedAllowZeroLevel": "允许零级别",
"orderedAllowZeroLevelDesc": "如果下一个标题高出一个以上的级别,则省略的级别为零而不是一。",
"orderedBasedOnExisting": "基于现有的最高级别",
"orderedBasedOnExistingDesc": "使用笔记中最高级别的标题作为有序列表的基础。",
"orderedBasedOnExistingDesc": "使用笔记中最高级别的标题作为构建装饰器的基础。",
"orderedAlwaysIgnore": "始终忽略顶层的标题",
"orderedAlwaysIgnoreDesc": "在构建有序列表时将顶层的标题排除掉,受\"忽略的最大层级数量\"选项控制。",
"orderedAlwaysIgnoreDesc": "在构建装饰器时将顶层的标题排除掉,受\"忽略的最大层级数量\"选项控制。",
"orderedIgnoreSingle": "忽略顶层的独立标题",
"orderedIgnoreSingleDesc": "如果顶层只有一个标题,则在构建有序列表时将其排除。受\"忽略的最大层级数量\"选项控制。",
"orderedIgnoreSingleDesc": "如果顶层只有一个标题,则在构建装饰器时将其排除。受\"忽略的最大层级数量\"选项控制。",
"orderedIgnoreMaximum": "忽略的最大层级数量",
"orderedIgnoreMaximumDesc": "在启用忽略顶层标题的选项时,指定可忽略的最大层级数量。",
"independent": "独立层级",
"orderedRecLevel": "使用有序列表的级别",
"orderedRecLevelDesc": "标题级别超出指定级别后按有序列表进行构建。",
"unordered": "无序列表",
"unorderedLevelHeadings": "级别标题",
"unorderedLevelHeadingsDesc": "设置每个级别的名称。值为 6 个条目,以空格分隔。",
@ -149,6 +153,13 @@
"folderBlocklistAddTip": "添加新的文件夹到阻止列表",
"fileRegexBlocklistIndex": "笔记名称正则表达式阻止列表 {index}",
"fileRegexBlocklistPlaceholder": "例如:/^daily.*/i",
"fileRegexBlocklistAddTip": "添加新的笔记名称正则表达式到阻止列表"
"fileRegexBlocklistAddTip": "添加新的笔记名称正则表达式到阻止列表",
"logic": "逻辑控制",
"h1": "H1 级别",
"h2": "H2 级别",
"h3": "H3 级别",
"h4": "H4 级别",
"h5": "H5 级别",
"h6": "H6 级别"
}
}

View file

@ -443,3 +443,19 @@ body {
opacity: 100%;
}
/* file-explorer start */
/* setting start */
body .heading-decorator-setting-container,
.heading-decorator-setting-item + .setting-item-heading {
margin-top: 0.75em;
}
body .heading-decorator-setting-container .setting-item-heading:first-child {
padding-top: 0.75em;
}
body .heading-decorator-setting-item {
padding-top: 0.75em;
border-top: 1px solid var(--background-modifier-border);
}
/* setting end */

File diff suppressed because it is too large Load diff

6
types.d.ts vendored
View file

@ -10,6 +10,7 @@ type _TupleOf<T, N extends number, R extends unknown[]> = R["length"] extends N
type LevelTuple = TupleOf<number, 6>;
type HeadingTuple = TupleOf<string, 6>;
type DecoratorMode = "orderd" | "independent" | "unordered";
type OpacityOptions = 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100;
type PostionOptions = "before" | "before-inside" | "after" | "after-inside";
type RenderPolicy = "partial" | "full";
@ -39,3 +40,8 @@ interface CSSEnabledStatus {
mode: boolean | null;
all: boolean | null;
}
interface Counter {
decorator(level: number): string;
handler(level: number): unknown;
}