Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

PunctFlow

Che-YearChe-Year31 downloads

标点流 — 中文 Markdown 智能标点转换:在中文输入法下输入中文标点(如 ·)时自动转换为对应的英文 Markdown 标点(如反引号 `),支持上下文感知、反引号自动配对与批量转换。

Add to Obsidian
  • Overview
  • Scorecard
  • Updates2

中文版本

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.

✨ Features

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

📦 Installation

  1. Build the plugin (requires Node.js ≥ 18):
    npm install
    npm run build
    
  2. Copy the project folder into <your-vault>/.obsidian/plugins/punctflow/ (make sure it contains main.js, manifest.json, and styles.css).
  3. In Obsidian, open Settings → Community plugins, and enable PunctFlow.

Plugin ID: punctflow.

⚙️ Configuration

Open Settings → PunctFlow settings:

  1. Punctuation mapping table: each entry is a "source character → target string". Leaving the target empty deletes the character. Rules are matched from top to bottom (the first hit wins). Use + Add mapping to add, the trash icon to delete, or Reset mappings to restore · → `.
  2. Auto-pair backticks: when enabled, typing · inserts a pair of backticks with the cursor centered; typing · again skips past an existing closing backtick.
  3. Working mode:
    • Realtime (default): converts immediately as you type a mapped character;
    • Manual: never auto-converts; conversion happens only through commands;
    • Paste conversion: converts pasted content automatically after a paste.
  4. Excluded folders: one path per line (relative to the vault root, e.g. journal); files inside these folders are not converted.
  5. Excluded file extensions: one per line without the dot (e.g. txt); files with these extensions are not converted.

🎮 Usage

  • Realtime input: with a Chinese input method active, type · (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).
  • Command palette (Ctrl/Cmd + P):
    • PunctFlow: Convert selection (falls back to the current line when nothing is selected)
    • PunctFlow: Convert current line
    • PunctFlow: Convert whole document
  • Paste conversion: switch the working mode to "Paste conversion", then pasted content is converted automatically.

Typical flow (backtick auto-pairing)

  1. Type · at the cursor → `` is inserted and the cursor is placed between the backticks;
  2. Type your code → `code`;
  3. Type · once more → the cursor skips past the closing backtick, no duplicate backticks.

Scenarios that are never converted (auto-detected)

```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
---

🧠 How it works

1. Context awareness

Before converting, three levels of checks run (by priority):

  1. Line scanning: scans from the start of the file to determine whether the current line is inside frontmatter (---…---) or a fenced code block (``` / ~~~);
  2. CodeMirror 6 syntax tree: the plugin reads the editor's internal CM6 state through a minimal structured interface and resolves the node at the cursor position with 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);
  3. Inline heuristics (fallback when the syntax tree is unavailable):
    • Both sides of the cursor are Chinese characters with an even number of backticks on the line → Chinese personal-name interpunct (卡尔·马克思), not converted;
    • Odd numbers of backticks both before and after the cursor → inside inline code, not converted;
    • Odd number of $ 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.

2. Backtick auto-pairing

When a character mapped to a backtick (·) is typed and conversion should happen:

  • No backtick after the cursor: insert a pair ``, placing the cursor between them (opening inline code);
  • A backtick already follows the cursor (e.g. the closing backtick produced by auto-pairing): delete the just-typed character and move the cursor past the existing backtick — this both "closes" the span and avoids duplicates like `code ``;
  • Odd number of backticks on the line (the opening backtick was typed in English mode, e.g. `code): insert a single closing backtick.

3. Undo merging

  • Realtime conversion: cm.dispatch({ changes, selection }) performs the replacement and the cursor move in a single CodeMirror transaction, undoable with one Ctrl+Z;
  • Batch conversion: the whole range is replaced with a single editor.replaceRange(), also producing a single undo record;
  • The isApplying guard flag prevents the plugin's own edits from triggering editor-change and causing infinite loops.

🛠 Development

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

Project structure

├── 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

📄 License

MIT

HealthExcellent
ReviewPassed
About
Convert common Chinese punctuation to ASCII Markdown equivalents while typing in a Chinese input method. Preserve code blocks, inline code, math, URLs, links, frontmatter and Chinese name middle dots; auto-pair and smart-skip backticks, provide customizable mappings, batch conversion commands, and real-time/manual/paste modes.
MarkdownAutomation
Details
Current version
1.0.2
Last updated
4 weeks ago
Created
Last month
Updates
2 releases
Downloads
31
Compatible with
Obsidian 1.13.0+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Author
Che-YearChe-Yearche-year
GitHubche-year
  1. Community
  2. Plugins
  3. Markdown
  4. PunctFlow

Related plugins

Linter

Format and style your notes. Linter can be used to format YAML tags, aliases, arrays, and metadata; footnotes; headings; spacing; math blocks; regular Markdown contents like list, italics, and bold styles; and more with the use of custom rule options.

Auto Link Title

Automatically fetches the titles of links from the web.

Link Embed

Convert URLs in your notes into embeded previews.

Homepage

Open a note, base, or workspace on startup, or set it for quick access later.

BRAT

Easily install a beta version of a plugin for testing.

Advanced URI

Control everything with URI.

Custom Frames

Turn web apps into panes using iframes with custom styling. Also comes with presets for Google Keep, Todoist and more.

QuickAdd

Quickly add new notes or content to your vault.

Lazy Loader

Load plugins with a delay on startup, so that you can get your app startup down into the sub-second loading time.

Hot Reload

Automatically reload in-development plugins when their files are changed