diff --git a/src/renderer/others/setting-schema.ts b/src/renderer/others/setting-schema.ts index fd4c2990..98fdfcc8 100644 --- a/src/renderer/others/setting-schema.ts +++ b/src/renderer/others/setting-schema.ts @@ -419,6 +419,14 @@ const schema: SettingSchema = ({ group: 'render', required: true, }, + 'render.heading-number': { + defaultValue: false, + title: 'T_setting-panel.schema.render.heading-number', + type: 'boolean', + format: 'checkbox', + group: 'render', + required: true, + }, 'render.text-autospace': { defaultValue: false, title: 'T_setting-panel.schema.render.text-autospace', diff --git a/src/renderer/plugins/__tests__/markdown-heading-number.ts b/src/renderer/plugins/__tests__/markdown-heading-number.ts index b4f00734..3a9a284f 100644 --- a/src/renderer/plugins/__tests__/markdown-heading-number.ts +++ b/src/renderer/plugins/__tests__/markdown-heading-number.ts @@ -2,8 +2,13 @@ vi.mock('@fe/context', () => ({ Plugin: class {}, })) +vi.mock('@fe/services/setting', () => ({ + getSetting: vi.fn(), +})) + import MarkdownIt from 'markdown-it' import markdownHeadingNumber from '../markdown-heading-number' +import { getSetting } from '@fe/services/setting' function createCtx (md: MarkdownIt) { md.renderer.rules.heading_open = function (tokens, idx, options, _env, slf) { @@ -19,6 +24,12 @@ function createCtx (md: MarkdownIt) { } as any } +const mockedGetSetting = vi.mocked(getSetting) + +beforeEach(() => { + mockedGetSetting.mockReset() +}) + describe('markdown-heading-number plugin', () => { test('registers theme/view styles and markdown renderer plugin', () => { const ctx = createCtx(new MarkdownIt()) @@ -31,13 +42,23 @@ describe('markdown-heading-number plugin', () => { }) test('adds show-number class when front matter enables heading numbers', () => { + mockedGetSetting.mockReturnValue(false) const md = new MarkdownIt() markdownHeadingNumber.register(createCtx(md)) expect(md.render('## Numbered', { attributes: { headingNumber: true } })).toContain('

Numbered

') }) + test('falls back to global setting when front matter does not set heading number', () => { + mockedGetSetting.mockReturnValue(true) + const md = new MarkdownIt() + markdownHeadingNumber.register(createCtx(md)) + + expect(md.render('## Fallback', {})).toContain('

Fallback

') + }) + test('leaves headings unchanged when heading numbers are disabled', () => { + mockedGetSetting.mockReturnValue(false) const md = new MarkdownIt() markdownHeadingNumber.register(createCtx(md)) diff --git a/src/renderer/plugins/markdown-heading-number.ts b/src/renderer/plugins/markdown-heading-number.ts index f78755fc..fb93ad3f 100644 --- a/src/renderer/plugins/markdown-heading-number.ts +++ b/src/renderer/plugins/markdown-heading-number.ts @@ -1,5 +1,6 @@ import type { Plugin } from '@fe/context' import type { FrontMatterAttrs } from '@fe/types' +import { getSetting } from '@fe/services/setting' export default { name: 'markdown-heading-number', @@ -102,8 +103,9 @@ export default { const headingOpen = md.renderer.rules.heading_open! md.renderer.rules.heading_open = function (tokens, idx, opt, env, slf) { - const attrs: FrontMatterAttrs = env.attributes - if (attrs.headingNumber) { + const attrs: FrontMatterAttrs = env?.attributes || {} + const headingNumber = attrs.headingNumber ?? getSetting('render.heading-number', false) + if (headingNumber) { const token = tokens[idx] token.attrJoin('class', 'show-number') } diff --git a/src/renderer/services/export.ts b/src/renderer/services/export.ts index 2e3506f6..dd970907 100644 --- a/src/renderer/services/export.ts +++ b/src/renderer/services/export.ts @@ -12,6 +12,7 @@ import { basename, dirname } from '@fe/utils/path' import { getRepo } from './repo' import { t } from './i18n' import { getContentHtml, getHeadings, getPreviewStyles, getRenderEnv, getRenderIframe } from './view' +import { getSetting } from '@fe/services/setting' type HtmlExportOptions = Partial> @@ -218,7 +219,8 @@ function buildHtml (title: string, body: string, options: HtmlExportOptions) { } const includeToc = options.includeToc || [] const hasToc = includeToc.length > 0 - const headingNumber = !!(getRenderEnv()?.attributes?.headingNumber) + const renderEnv = getRenderEnv() + const headingNumber = renderEnv?.attributes?.headingNumber ?? getSetting('render.heading-number', false) const bodyHtml = enhanceCodeBlocks(body, codeOptions) const codeBlockAssets = buildCodeBlockAssets(codeOptions) diff --git a/src/renderer/types.ts b/src/renderer/types.ts index cf222a28..af78cc8e 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -449,6 +449,7 @@ export interface BuildInSettings { 'render.md-sub': boolean, 'render.md-sup': boolean, 'render.md-cj-friendly': boolean, + 'render.heading-number': boolean, 'render.multimd-multiline': boolean, 'render.multimd-rowspan': boolean, 'render.multimd-headerless': boolean, diff --git a/src/share/i18n/languages/en.ts b/src/share/i18n/languages/en.ts index 797a07d4..182f68f2 100644 --- a/src/share/i18n/languages/en.ts +++ b/src/share/i18n/languages/en.ts @@ -438,6 +438,7 @@ const data = { 'md-html': 'Enable HTML', 'md-breaks': 'Convert \\n to <br>', 'md-linkify': 'Auto convert URL-like text to links', + 'heading-number': 'Enable heading numbers in preview and export', 'md-wiki-links': 'Enable Wiki Links - [[link]]', 'md-hash-tags': 'Enable Hash Tags - #tag', 'md-typographer': 'Enable some language-neutral replacement + quotes beautification', diff --git a/src/share/i18n/languages/ru.ts b/src/share/i18n/languages/ru.ts index f41cb370..95ade389 100644 --- a/src/share/i18n/languages/ru.ts +++ b/src/share/i18n/languages/ru.ts @@ -439,6 +439,7 @@ const data: BaseLanguage = { 'md-html': 'Включить HTML', 'md-breaks': 'Преобразовать \\n в <br>', 'md-linkify': 'Автоматическое преобразование текста, похожего на URL, в ссылки', + 'heading-number': 'Включить нумерацию заголовков', 'md-wiki-links': 'Включить Wiki ссылки - [[ссылка]]', 'md-hash-tags': 'Включить хештеги - #тег', 'md-typographer': 'Включите некоторые языковые замены + улучшение кавычек', diff --git a/src/share/i18n/languages/zh-CN.ts b/src/share/i18n/languages/zh-CN.ts index eceb5c5b..2f99dff5 100644 --- a/src/share/i18n/languages/zh-CN.ts +++ b/src/share/i18n/languages/zh-CN.ts @@ -429,6 +429,7 @@ const data: BaseLanguage = { 'md-html': '启用 HTML', 'md-breaks': '将 \\n 转换为 <br>', 'md-linkify': '自动将类似 URL 的文本转换为链接', + 'heading-number': '启用标题编号', 'md-wiki-links': '启用 Wiki 链接 - [[link]]', 'md-hash-tags': '启用哈希标签 - #tag', 'md-typographer': '启用排版美化,如 (c) -> ©', diff --git a/src/share/i18n/languages/zh-TW.ts b/src/share/i18n/languages/zh-TW.ts index c86e0921..2f4a9fbb 100644 --- a/src/share/i18n/languages/zh-TW.ts +++ b/src/share/i18n/languages/zh-TW.ts @@ -429,6 +429,7 @@ const data: BaseLanguage = { 'md-html': '啟用 HTML', 'md-breaks': '將 \\n 轉換為 <br>', 'md-linkify': '自動將類似 URL 的文字轉換為連結', + 'heading-number': '啟用標題編號', 'md-wiki-links': '啟用 Wiki 連結 - [[link]]', 'md-hash-tags': '啟用哈希標籤 - #tag', 'md-typographer': '啟用排版美化,如 (c) -> ©',