Jiayu REN96 downloadsRender bold and italic next to CJK punctuation, which otherwise shows up as literal asterisks.
Render bold and italic next to CJK punctuation in Obsidian Live Preview.
CommonMark requires the closing ** of an emphasis run to be right-flanking: either the character before it is not punctuation, or the character after it is whitespace or punctuation. Chinese, Japanese, and Korean text is written without spaces, so the marker often lands exactly where both conditions fail:
前面**文字。**继续写
Here the closing ** is preceded by 。 and followed by 继. No mainstream parser accepts that run, so the line renders as literal asterisks instead of bold text.
This is CommonMark issue #650, open since 2017.
| Markdown | Renders? |
|---|---|
**text。**next |
No — bold/italic case this plugin fixes |
==text。==next |
No — highlight |
~~text。~~next |
No — strikethrough |
**text。** at end of line |
Yes |
**text。**, followed by punctuation |
Yes |
**text。** next followed by a space |
Yes |
** text。** with a space inside the markers |
No — a separate, invalid-markup case |
Highlight and strikethrough suffer from the same problem because their parsers use the same delimiter-flanking logic as emphasis.
Theme agnostic. The plugin never invents its own look: styled spans carry Obsidian's own cm-strong, cm-em, cm-highlight and cm-strikethrough classes, so each theme applies its own bold colour, weight, and highlight background. The excess that the parser styles is reset back to plain text using Obsidian's core variables, which keeps every theme's palette intact.
1. Live Preview rendering. It scans each visible line, finds CJK emphasis that the parser rejected, applies the matching styling — bold, italic, bold+italic, highlight, or strikethrough — and hides the delimiters. Markers come back when the cursor is on that line so they remain editable. Source mode is untouched.
A plugin cannot replace Obsidian's parser, and Obsidian sometimes pairs the closing delimiter with a later one, styling the rest of the paragraph. The plugin neutralises that excess styling at render time, using Obsidian's own theme variables, so themes colour and weight exactly the span you marked. It never modifies the note text.
2. Source rewriting. **文字。**继续 is valid as far as this plugin is concerned, but it still breaks when you export to PDF or open the file in another Markdown editor. The command Fix CJK emphasis in current note rewrites it as:
**文字**。继续
The same rewrite applies to ==, ~~, and *. The punctuation moves outside the delimiters, which is standard practice in Chinese typesetting. Inline code, $$math$$, and fenced code blocks are left alone.
Both commands are also available from the settings tab.
<vault>/.obsidian/plugins/cjk-emphasis-fix/
├── main.js
├── manifest.json
└── versions.json
Enable it under Settings → Community plugins. The repository ships an install.sh that copies the files and enables the plugin in one step:
./install.sh "/path/to/vault"
| Setting | Default | Description |
|---|---|---|
| Enable Live Preview fix | On | Master switch for the editor rendering fix. |
| Show markers on the cursor line | On | Keeps ** visible while editing that line. |
| Fix current note | — | Runs the source rewrite on the open note. |
*, **, ***, ==, and ~~. Underscore emphasis (_text_) is not handled, because CJK notes almost never use it.**text。**next as **text**。next so the file renders correctly outside Obsidian too. It only runs when you invoke it; the plugin never changes your text on its own.npm install
npm run build # type-check, then bundle to main.js
npm test # parser tests, no Obsidian needed
The scanner is a pure function set in src/scanner.ts; the editor integration lives in src/extension.ts and uses only the public registerEditorExtension API.
The code avoids regular-expression lookbehind on purpose, because iOS versions before 16.4 do not support it and the plugin targets mobile as well.
MIT