Birchove182 downloadsPromote or demote Markdown heading levels (h1-h6) for the selected lines via hotkeys or the editor context menu. Body text, images, tables, tags and code blocks are left untouched.
Promote or demote Markdown heading levels (h1–h6) for the selected lines in Obsidian — via hotkeys, the command palette, or the editor right-click menu. Body text, images, tables, tags and code blocks are left untouched.
选中一段文字,一键把其中的标题升级(## → #)或降级(## → ###)。正文、图片、表格、标签、代码块一律不受影响。
## Title → # Title## Title → ### Title# characters followed by whitespace. In Obsidian a # without a trailing space is a tag (#tag), and tags are never modified```/~~~ code fences and %% comment blocks are skipped automatically, so shell/Python comments are never corrupted![[…]]), tables, lists and blockquotes pass through unchangedMod+P) and search for “heading level”.| Action | macOS | Windows / Linux |
|---|---|---|
Promote heading (## → #) |
⌘ + ⌥ + ↑ |
Ctrl + Alt + ↑ |
Demote heading (## → ###) |
⌘ + ⌥ + ↓ |
Ctrl + Alt + ↓ |
The plugin registers hotkeys with Obsidian's Mod modifier, which maps to ⌘ Cmd on macOS and Ctrl on Windows/Linux automatically. If a default conflicts with your setup, rebind or remove it in Settings → Hotkeys (search for “heading”) — every user binding there takes precedence.
#, then at least one space/tab. So:#tag, #, ## (no trailing whitespace) → not touched (tag-like)####### seven hashes → not a heading, not touched> # Title) are out of scope and not touched (they don't start at column 0).# ATX headings.This plugin targets the official Obsidian community store. Once it is approved, install it via Settings → Community plugins → Browse → “Heading Level Changer”.
main.js, manifest.json into <your-vault>/.obsidian/plugins/heading-level-changer/.Or use BRAT with this repository.
npm install # install dev dependencies
npm run dev # watch mode (esbuild), outputs main.js
npm run build # type-check (tsc) + production build
npm test # unit tests for the heading logic (48 cases)
npm run smoke # end-to-end test of the built main.js against a mocked editor
Project layout:
main.ts — plugin entry: commands, default hotkeys, editor context menu, selection handlingsrc/logic.ts — pure, obsidian-free logic: heading parsing, level shifting, code-fence/comment detectiontests/logic.test.ts — unit testsscripts/smoke.cjs — loads the built main.js with a mocked obsidian module and simulates real command invocationsgit init, commit, and push to a GitHub repository (conventionally named heading-level-changer or obsidian-heading-level-changer).npm version patch|minor|major — this runs version-bump.mjs, keeping manifest.json and versions.json in sync.git push --tags). The bundled GitHub Action (.github/workflows/release.yml) builds and creates a draft release containing main.js and manifest.json; review and publish it.main.js and manifest.json as assets (they do).manifest.json fields accurate: id must stay heading-level-changer, version must match the release tag, and minAppVersion must reflect the oldest supported Obsidian version.Notes on store compliance:
Plugin, addCommand, editor-menu, Editor.transaction, Notice) — no private APIs, no network access, no data collection.isDesktopOnly is false; the editor APIs used are available on mobile as well.## → # / ## → ###)![[…]])、表格、列表、引用块一律不受影响# 后没有空格的行(如 #tag)在 Obsidian 中是标签,绝不会被修改~~~ 代码块和 %% 注释块内部的行(例如 shell、python 注释)自动跳过Mod+P),搜索 "heading level"。| 操作 | macOS | Windows / Linux |
|---|---|---|
升级标题(## → #) |
⌘ + ⌥ + ↑ |
Ctrl + Alt + ↑ |
降级标题(## → ###) |
⌘ + ⌥ + ↓ |
Ctrl + Alt + ↓ |
快捷键使用 Obsidian 的 Mod 修饰键,macOS 上自动对应 ⌘ Cmd,Windows/Linux 上对应 Ctrl。如果与你的其他设置冲突,可在 设置 → 快捷键 中搜索 "heading" 改绑或移除。
# + 至少一个空格或 Tab。因此:#tag、#、##(# 后无空格)→ 视为标签类内容,不修改;#######(7 个及以上 #)→ 不是标题,不修改;> # 标题)不在处理范围内(未从行首开始)。# 风格的 ATX 标题,不处理下划线式(setext)标题。main.js 和 manifest.json 复制到 <你的库>/.obsidian/plugins/heading-level-changer/,重启 Obsidian 后在社区插件中启用;也可以用 BRAT 添加本仓库。开发命令见上方 Development 小节;上架社区市场的完整清单见 Releasing & community-store submission checklist 小节。