Che-Year31 downloads标点流 — 中文 Markdown 智能标点转换:在中文输入法下输入中文标点(如 ·)时自动转换为对应的英文 Markdown 标点(如反引号 `),支持上下文感知、反引号自动配对与批量转换。
PunctFlow is an Obsidian plugin that intelligently converts Chinese punctuation to the corresponding English Markdown punctuation while you type under a Chinese input method — most importantly · (interpunct) → ` (backtick) — reducing the cost of switching between Chinese and English input methods. Core design principles: smart, controllable, and never harmful.
It is an upgraded, generalized version of the dot-to-backtick plugin (which replaces the Chinese interpunct · with a backtick `), extended into a universal smart converter for Chinese punctuation.
| Feature | Description |
|---|---|
| 🔧 Configurable mapping table | Default · → `; add, edit, or remove any mapping in the settings (empty target = delete the character) |
| 🧠 Context awareness | No conversion inside code blocks, inline code, math formulas, URLs, link text, or frontmatter; Chinese personal-name interpuncts (卡尔·马克思) are never converted |
| ⚡ Backtick auto-pairing | Typing · inserts a pair of backticks and places the cursor between them; typing · again skips past the closing backtick so duplicates never appear |
| 🖥 Batch conversion commands | Convert selection / current line / whole document (selection falls back to the current line when nothing is selected) |
| 🎛 Three working modes | Realtime mode (default) / manual mode / paste conversion |
| 🚫 Exclusion rules | Exclude files by folder path or file extension; frontmatter is not converted by default |
| ↩️ Undo merging | Each conversion produces a single transaction, so one Ctrl+Z undoes it |
npm install
npm run build
<your-vault>/.obsidian/plugins/punctflow/ (make sure it contains main.js, manifest.json, and styles.css).Plugin ID:
punctflow.
Open Settings → PunctFlow settings:
· → `.· inserts a pair of backticks with the cursor centered; typing · again skips past an existing closing backtick.journal); files inside these folders are not converted.txt); files with these extensions are not converted.· (usually the backtick key) and the plugin turns it into ` with auto-pairing; mapped characters such as 。 or , behave the same way (depending on your mapping table).PunctFlow: Convert selection (falls back to the current line when nothing is selected)PunctFlow: Convert current linePunctFlow: Convert whole document· at the cursor → `` is inserted and the cursor is placed between the backticks;`code`;· once more → the cursor skips past the closing backtick, no duplicate backticks.```js
// The · inside code blocks is not converted
const a = '卡尔·马克思'; // Chinese personal-name interpuncts are not converted
The · inside inline code is not converted, $The · inside math is not converted$, link text · not converted.
---
title: The · inside frontmatter is not converted
---
Before converting, three levels of checks run (by priority):
---…---) or a fenced code block (``` / ~~~);tree.resolveInner(offset), then walks up the parent chain. If the node name matches code / math / url / link / image / html / comment / frontmatter and similar, conversion is skipped (special case: if the character right after the cursor is a backtick — the user is closing an inline code span — conversion is allowed);卡尔·马克思), not converted;$ before the cursor → inside inline math, not converted;https://... immediately before the cursor → inside a URL, not converted.When the syntax tree is unavailable, the plugin automatically falls back to the heuristics — no configuration needed.
When a character mapped to a backtick (·) is typed and conversion should happen:
``, placing the cursor between them (opening inline code); `code ``;`code): insert a single closing backtick.cm.dispatch({ changes, selection }) performs the replacement and the cursor move in a single CodeMirror transaction, undoable with one Ctrl+Z;editor.replaceRange(), also producing a single undo record;isApplying guard flag prevents the plugin's own edits from triggering editor-change and causing infinite loops.npm install # install dependencies
npm run dev # watch mode build (main.js)
npm run build # production build (tsc type check + esbuild)
npm test # run the simulation test suite
├── main.ts # plugin core logic (including the settings tab)
├── manifest.json # plugin manifest
├── styles.css # settings panel styles
├── esbuild.config.mjs # esbuild build configuration
├── tsconfig.json # TypeScript configuration
├── package.json # dependencies and scripts
├── versions.json # version compatibility manifest
└── .github/workflows/release.yml # release workflow with artifact attestations