mirror of
https://github.com/vercel/streamdown.git
synced 2026-09-19 02:18:37 +08:00
872da1afd1
* Add MermaidErrorComponent support * Update docs * Merge mermaid props * Merge mermaid contexts * Run Ultracite * Update index.tsx * Create favicon.ico * Update cjk-support.mdx * Create plain-singers-clean.md * Update mermaid.tsx
146 lines
5.6 KiB
Plaintext
146 lines
5.6 KiB
Plaintext
---
|
||
title: CJK Language Support
|
||
description: Full support for Chinese, Japanese, and Korean text with proper emphasis formatting.
|
||
---
|
||
|
||
Streamdown includes built-in support for CJK (Chinese, Japanese, Korean) languages, ensuring that emphasis markers like bold and italic work correctly with ideographic punctuation. This is particularly important for AI-generated content, where language models naturally place emphasis markers around phrases that include or end with punctuation.
|
||
|
||
## The Problem
|
||
|
||
The CommonMark/GFM specification has a [limitation](https://github.com/commonmark/commonmark-spec/issues/650) where emphasis markers (`**` or `*`) adjacent to ideographic punctuation marks occasionally fail to be recognized. This causes formatting to break in CJK text:
|
||
|
||
```markdown
|
||
**この文は太字になりません(This won't be bolded)。**この文のせいで(It is due to this sentence)。
|
||
```
|
||
|
||
Without CJK-friendly parsing, the text above would render as plain text instead of bold because the closing `**` appears next to the Japanese period.
|
||
|
||
## The Solution
|
||
|
||
Streamdown uses the [remark-cjk-friendly](https://www.npmjs.com/package/remark-cjk-friendly) and [remark-cjk-friendly-gfm-strikethrough](https://www.npmjs.com/package/remark-cjk-friendly-gfm-strikethrough) plugins to handle CJK text properly. This plugin implements an improved parsing approach that correctly recognizes emphasis markers adjacent to ideographic punctuation.
|
||
|
||
## Supported Features
|
||
|
||
### Bold Text with Punctuation
|
||
|
||
Works correctly with all ideographic punctuation marks:
|
||
|
||
```markdown
|
||
**日本語の文章(括弧付き)。**この文が後に続いても大丈夫です。
|
||
**中文文本(带括号)。**这句子继续也没问题。
|
||
**한국어 구문(괄호 포함)**을 강조.
|
||
```
|
||
|
||
{/* The following lang="..." is crucial to ensure proper han character rendering */}
|
||
|
||
Japanese: <span lang="ja"><strong>日本語の文章(括弧付き)。</strong>この文が後に続いても大丈夫です。</span>
|
||
|
||
Chinese: <span lang="zh-Hans"><strong>中文文本(带括号)。</strong>这句子继续也没问题。</span>
|
||
|
||
Korean: <span lang="ko"><strong>한국어 구문(괄호 포함)</strong>을 강조.</span>
|
||
|
||
### Italic Text with Punctuation
|
||
|
||
```markdown
|
||
*これは斜体のテキストです(括弧付き)。*この文が後に続いても大丈夫です。
|
||
*这是斜体文字(带括号)。*这句子继续也没问题。
|
||
*이 텍스트(괄호 포함)*는 기울임꼴입니다.
|
||
```
|
||
|
||
Japanese: <span lang="ja"><em>これは斜体のテキストです(括弧付き)。</em>この文が後に続いても大丈夫です。</span>
|
||
|
||
Chinese: <span lang="zh-Hans"><em>这是斜体文字(带括号)。</em>这句子继续也没问题。</span>
|
||
|
||
Korean: <span lang="ko"><em>이 텍스트(괄호 포함)</em>는 기울임꼴입니다.</span>
|
||
|
||
### Strikethrough with Punctuation
|
||
|
||
Streamdown includes `remark-cjk-friendly-gfm-strikethrough` for proper strikethrough support:
|
||
|
||
```markdown
|
||
~~削除されたテキスト(括弧付き)。~~この文は正しいです。
|
||
~~删除的文字(带括号)。~~这个句子是正确的。
|
||
~~이 텍스트(괄호 포함)~~를 삭제합니다.
|
||
```
|
||
|
||
Japanese: <span lang="ja"><del>削除されたテキスト(括弧付き)。</del>この文は正しいです。</span>
|
||
|
||
Chinese: <span lang="zh-Hans"><del>删除的文字(带括号)。</del>这个句子是正确的。</span>
|
||
|
||
Korean: <span lang="ko"><del>이 텍스트(괄호 포함)</del>를 삭제합니다。</span>
|
||
|
||
### Mixed Content
|
||
|
||
CJK and English text work seamlessly together:
|
||
|
||
```markdown
|
||
**重要提示(Important Notice):**请注意。
|
||
```
|
||
|
||
Result: <span lang="zh-Hans"><strong>重要提示(Important Notice):</strong>请注意。</span>
|
||
|
||
## Supported Punctuation
|
||
|
||
The plugin handles all common ideographic punctuation marks:
|
||
|
||
- Parentheses: `()`
|
||
- Brackets: `【】「」〈〉`
|
||
- Periods: `。.`
|
||
- Commas: `,、`
|
||
- Questions: `?`
|
||
- Exclamations: `!`
|
||
- Colons: `:`
|
||
|
||
## Why This Matters for AI
|
||
|
||
Language models generate markdown naturally, often placing emphasis markers around phrases that include punctuation. Without CJK-friendly parsing, AI-generated content in Chinese, Japanese, or Korean would have broken formatting.
|
||
|
||
<dl>
|
||
<dt>❌ Without CJK support:</dt>
|
||
<dd>
|
||
- The model writes:{" "}
|
||
<span lang="ja">`**この用語(読み方など)**について説明します。`</span>- The
|
||
user sees: <span lang="ja">
|
||
\*\*この用語(読み方など)\*\*について説明します。
|
||
</span> (not bold!)
|
||
</dd>
|
||
<dt>✅ With CJK support:</dt>
|
||
<dd>
|
||
- The model writes:{" "}
|
||
<span lang="ja">`**この用語(読み方など)**について説明します。`</span>- The
|
||
user sees: <span lang="ja">
|
||
<strong>この用語(読み方など)</strong>について説明します。
|
||
</span> (properly bolded!)
|
||
</dd>
|
||
</dl>
|
||
|
||
## Configuration
|
||
|
||
CJK support is enabled by default with no configuration required. The plugins are included in the default remark plugin list:
|
||
|
||
```tsx
|
||
import { Streamdown } from "streamdown";
|
||
|
||
export default function Page() {
|
||
return <Streamdown>{markdown}</Streamdown>;
|
||
}
|
||
```
|
||
|
||
### Disabling CJK Support
|
||
|
||
If you need to disable CJK support, you can override the default remark plugins:
|
||
|
||
```tsx
|
||
import { Streamdown } from "streamdown";
|
||
import remarkGfm from "remark-gfm";
|
||
import remarkMath from "remark-math";
|
||
|
||
export default function Page() {
|
||
return (
|
||
<Streamdown remarkPlugins={[remarkGfm, remarkMath]}>{markdown}</Streamdown>
|
||
);
|
||
}
|
||
```
|
||
|
||
Note: This removes all default remark plugins, so you'll need to add back any others you need.
|