ds-markdown 0.0.14-beta.1 → 0.0.15-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +241 -80
- package/README.ja.md +256 -103
- package/README.ko.md +17 -0
- package/README.md +200 -39
- package/dist/cjs/MarkdownCMD/index.js +2 -2
- package/dist/cjs/MarkdownCMD/index.js.map +1 -1
- package/dist/cjs/components/HighReactMarkdown/index.d.ts +3 -1
- package/dist/cjs/components/HighReactMarkdown/index.js +24 -4
- package/dist/cjs/components/HighReactMarkdown/index.js.map +1 -1
- package/dist/cjs/defined.d.ts +8 -0
- package/dist/cjs/utils/remarkMathBracket.d.ts +7 -0
- package/dist/cjs/utils/remarkMathBracket.js +27 -0
- package/dist/cjs/utils/remarkMathBracket.js.map +1 -0
- package/dist/esm/MarkdownCMD/index.js +2 -2
- package/dist/esm/MarkdownCMD/index.js.map +1 -1
- package/dist/esm/components/HighReactMarkdown/index.d.ts +3 -1
- package/dist/esm/components/HighReactMarkdown/index.js +25 -5
- package/dist/esm/components/HighReactMarkdown/index.js.map +1 -1
- package/dist/esm/defined.d.ts +8 -0
- package/dist/esm/utils/remarkMathBracket.d.ts +7 -0
- package/dist/esm/utils/remarkMathBracket.js +23 -0
- package/dist/esm/utils/remarkMathBracket.js.map +1 -0
- package/dist/katex.css +1 -0
- package/package.json +7 -4
package/README.ja.md
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
- 高頻度タイピングサポート(`requestAnimationFrame` モードでは `0ms` に近いタイピング間隔をサポート)
|
|
39
39
|
- フレーム同期レンダリング、ブラウザの 60fps と完璧にマッチ
|
|
40
40
|
- スマート文字バッチ処理により、より自然な視覚効果
|
|
41
|
+
- タイピングの中断 `stop` と再開 `resume` をサポート
|
|
41
42
|
|
|
42
43
|
### 🔧 **柔軟で使いやすい**
|
|
43
44
|
|
|
@@ -45,6 +46,13 @@
|
|
|
45
46
|
- **命令的 API**:ストリーミングデータに適し、より良いパフォーマンス
|
|
46
47
|
- **ネイティブ TypeScript サポート**:完全な型ヒント
|
|
47
48
|
|
|
49
|
+
### 🧮 **数式サポート**
|
|
50
|
+
|
|
51
|
+
- **KaTeX 統合**:高性能な数式レンダリング
|
|
52
|
+
- **デュアル構文サポート**:`$...$` と `\[...\]` の2つの区切り文字
|
|
53
|
+
- **ストリーミング対応**:タイピングアニメーションでの数式の完璧なサポート
|
|
54
|
+
- **テーマ適応**:ライト/ダークテーマへの自動適応
|
|
55
|
+
|
|
48
56
|
---
|
|
49
57
|
|
|
50
58
|
## 📦 クイックインストール
|
|
@@ -64,39 +72,16 @@ pnpm add ds-markdown
|
|
|
64
72
|
|
|
65
73
|
インストール不要、ブラウザで直接使用できます:
|
|
66
74
|
|
|
75
|
+
[DEMO](https://stackblitz.com/edit/stackblitz-starters-7vcclcw7?file=index.html)
|
|
76
|
+
|
|
67
77
|
```html
|
|
68
78
|
<!-- スタイルのインポート -->
|
|
69
79
|
<link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/style.css" />
|
|
80
|
+
<link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/katex.css" />
|
|
70
81
|
|
|
71
82
|
<!-- コンポーネントのインポート -->
|
|
72
|
-
<script type="
|
|
73
|
-
|
|
74
|
-
"imports": {
|
|
75
|
-
"react": "https://esm.sh/react@19.1.0",
|
|
76
|
-
"react-dom/client": "https://esm.sh/react-dom@19.1.0/client",
|
|
77
|
-
"ds-markdown": "https://esm.sh/ds-markdown"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
</script>
|
|
81
|
-
<script type="module" src="https://esm.sh/tsx"></script>
|
|
82
|
-
|
|
83
|
-
<script type="text/babel">
|
|
84
|
-
import { createRoot } from 'react-dom/client';
|
|
85
|
-
import DsMarkdown from 'ds-markdown';
|
|
86
|
-
|
|
87
|
-
const markdown = `
|
|
88
|
-
# Hello ds-markdown
|
|
89
|
-
|
|
90
|
-
これは**高性能**なタイピングアニメーションコンポーネントです!
|
|
91
|
-
|
|
92
|
-
## 特徴
|
|
93
|
-
- ⚡ 遅延ゼロのストリーミング
|
|
94
|
-
- 🎬 スムーズなタイピングアニメーション
|
|
95
|
-
- 🎯 完璧なシンタックスサポート
|
|
96
|
-
`;
|
|
97
|
-
|
|
98
|
-
const root = createRoot(document.getElementById('root'));
|
|
99
|
-
root.render(<DsMarkdown interval={20}>{markdown}</DsMarkdown>);
|
|
83
|
+
<script type="module">
|
|
84
|
+
import Markdown from 'https://esm.sh/ds-markdown';
|
|
100
85
|
</script>
|
|
101
86
|
```
|
|
102
87
|
|
|
@@ -104,6 +89,8 @@ pnpm add ds-markdown
|
|
|
104
89
|
|
|
105
90
|
### 基本的な使用法
|
|
106
91
|
|
|
92
|
+
[DEMO](https://stackblitz.com/edit/vitejs-vite-z94syu8j?file=src%2FApp.tsx)
|
|
93
|
+
|
|
107
94
|
```tsx
|
|
108
95
|
import DsMarkdown from 'ds-markdown';
|
|
109
96
|
import 'ds-markdown/style.css';
|
|
@@ -117,6 +104,23 @@ function App() {
|
|
|
117
104
|
}
|
|
118
105
|
```
|
|
119
106
|
|
|
107
|
+
### 数式サポート
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import DsMarkdown from 'ds-markdown';
|
|
111
|
+
import 'ds-markdown/style.css';
|
|
112
|
+
import 'ds-markdown/katex.css'; // 数式スタイルのインポート
|
|
113
|
+
|
|
114
|
+
function MathDemo() {
|
|
115
|
+
return (
|
|
116
|
+
<DsMarkdown interval={20} answerType="answer" math={{ isOpen: true, splitSymbol: 'dollar' }}>
|
|
117
|
+
# ピタゴラスの定理 直角三角形では、斜辺の二乗は二つの直角辺の二乗の和に等しい: $a^2 + b^2 = c^2$ ここで: - $a$ と $b$ は直角辺 - $c$ は斜辺 古典的な「3-4-5」三角形の場合: $c = \sqrt
|
|
118
|
+
{3 ^ (2 + 4) ^ 2} = \sqrt{25} = 5$
|
|
119
|
+
</DsMarkdown>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
120
124
|
### AI 会話シナリオ
|
|
121
125
|
|
|
122
126
|
```tsx
|
|
@@ -173,74 +177,151 @@ React 19 は多くのエキサイティングな新機能をもたらします
|
|
|
173
177
|
| `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | タイマータイプ | 現在のデフォルトは`setTimeout`、後で`requestAnimationFrame`に変更予定 |
|
|
174
178
|
| `answerType` | `'thinking'` \| `'answer'` | コンテンツタイプ | `'answer'` |
|
|
175
179
|
| `theme` | `'light'` \| `'dark'` | テーマタイプ | `'light'` |
|
|
180
|
+
| `math` | `IMarkdownMath` | 数式設定 | `{ isOpen: false, splitSymbol: 'dollar' }` |
|
|
176
181
|
| `onEnd` | `(data: EndData) => void` | タイピング完了コールバック | - |
|
|
177
182
|
| `onStart` | `(data: StartData) => void` | タイピング開始コールバック | - |
|
|
178
183
|
| `onTypedChar` | `(data: CharData) => void` | 文字ごとのタイピングコールバック | - |
|
|
179
184
|
|
|
180
|
-
###
|
|
185
|
+
### 数式設定
|
|
181
186
|
|
|
182
|
-
|
|
183
|
-
|
|
187
|
+
| プロパティ | 型 | 説明 | デフォルト |
|
|
188
|
+
| ------------- | ------------------------- | ---------------------------- | ---------- |
|
|
189
|
+
| `isOpen` | `boolean` | 数式レンダリングを有効にする | `false` |
|
|
190
|
+
| `splitSymbol` | `'dollar'` \| `'bracket'` | 数式区切り文字タイプ | `'dollar'` |
|
|
184
191
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
192
|
+
**区切り文字の説明:**
|
|
193
|
+
|
|
194
|
+
- `'dollar'`:`$...$` と `$$...$$` 構文を使用
|
|
195
|
+
- `'bracket'`:`\(...\)` と `\[...\]` 構文を使用
|
|
196
|
+
|
|
197
|
+
### 命令的 API(ストリーミングシナリオにおすすめ)
|
|
191
198
|
|
|
192
199
|
| メソッド | パラメータ | 説明 |
|
|
193
200
|
| ----------------- | ------------------------------------------- | ------------------------------------ |
|
|
194
201
|
| `push` | `(content: string, answerType: AnswerType)` | コンテンツを追加してタイピングを開始 |
|
|
195
202
|
| `clear` | - | すべてのコンテンツと状態をクリア |
|
|
196
203
|
| `triggerWholeEnd` | - | 完了コールバックを手動でトリガー |
|
|
204
|
+
| `stop` | - | タイピングを一時停止 |
|
|
205
|
+
| `resume` | - | タイピングを再開 |
|
|
206
|
+
|
|
207
|
+
**使用例:**
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
markdownRef.current?.stop(); // アニメーションを一時停止
|
|
211
|
+
markdownRef.current?.resume(); // アニメーションを再開
|
|
212
|
+
```
|
|
197
213
|
|
|
198
214
|
---
|
|
199
215
|
|
|
200
|
-
##
|
|
216
|
+
## 🧮 数式使用ガイド
|
|
217
|
+
|
|
218
|
+
### 基本構文
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
// 1. 数式サポートを有効にする
|
|
222
|
+
<DsMarkdown math={{ isOpen: true }}>
|
|
223
|
+
# 数式の例
|
|
224
|
+
|
|
225
|
+
// インライン数式
|
|
226
|
+
これはインライン数式です:$E = mc^2$
|
|
227
|
+
|
|
228
|
+
// ブロック数式
|
|
229
|
+
$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
|
|
230
|
+
</DsMarkdown>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 区切り文字の選択
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
// ドル記号区切り文字を使用(デフォルト)
|
|
237
|
+
<DsMarkdown math={{ isOpen: true, splitSymbol: 'dollar' }}>
|
|
238
|
+
インライン:$a + b = c$
|
|
239
|
+
ブロック:$$\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n$$
|
|
240
|
+
</DsMarkdown>
|
|
241
|
+
|
|
242
|
+
// 括弧区切り文字を使用
|
|
243
|
+
<DsMarkdown math={{ isOpen: true, splitSymbol: 'bracket' }}>
|
|
244
|
+
インライン:\(a + b = c\)
|
|
245
|
+
ブロック:\[\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n\]
|
|
246
|
+
</DsMarkdown>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### ストリーミング数式
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
// ストリーミング出力での数式の完璧なサポート
|
|
253
|
+
const mathContent = ['ピタゴラスの定理:', '$a^2 + b^2 = c^2$', '\n\n', 'ここで:', '- $a$ と $b$ は直角辺', '- $c$ は斜辺'];
|
|
254
|
+
|
|
255
|
+
mathContent.forEach((chunk) => {
|
|
256
|
+
markdownRef.current?.push(chunk, 'answer');
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### スタイルカスタマイズ
|
|
261
|
+
|
|
262
|
+
```css
|
|
263
|
+
/* 数式スタイルのカスタマイズ */
|
|
264
|
+
.katex {
|
|
265
|
+
font-size: 1.1em;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.katex-display {
|
|
269
|
+
margin: 1em 0;
|
|
270
|
+
text-align: center;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* ダークテーマ適応 */
|
|
274
|
+
[data-theme='dark'] .katex {
|
|
275
|
+
color: #e1e1e1;
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 🎛️ タイマーモード詳細
|
|
201
282
|
|
|
202
283
|
### `requestAnimationFrame` モード 🌟(推奨)
|
|
203
284
|
|
|
204
285
|
```typescript
|
|
205
286
|
// 🎯 特徴
|
|
206
287
|
- 時間駆動:実際の経過時間に基づいて文字数を計算
|
|
207
|
-
-
|
|
208
|
-
-
|
|
209
|
-
- 高頻度最適化:interval < 16ms
|
|
288
|
+
- バッチ処理:1フレーム内で複数の文字を処理可能
|
|
289
|
+
- フレーム同期:ブラウザの60fpsリフレッシュレートと同期
|
|
290
|
+
- 高頻度最適化:interval < 16msの高速タイピングを完璧にサポート
|
|
210
291
|
|
|
211
292
|
// 🎯 適用シナリオ
|
|
212
|
-
-
|
|
293
|
+
- モダンWebアプリケーションのデフォルト選択
|
|
213
294
|
- 滑らかなアニメーション効果を追求
|
|
214
|
-
- 高頻度タイピング(interval > 0
|
|
215
|
-
- AI
|
|
295
|
+
- 高頻度タイピング(interval > 0で十分)
|
|
296
|
+
- AIリアルタイム会話シナリオ
|
|
216
297
|
```
|
|
217
298
|
|
|
218
299
|
### `setTimeout` モード 📟(互換性)
|
|
219
300
|
|
|
220
301
|
```typescript
|
|
221
302
|
// 🎯 特徴
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
-
|
|
225
|
-
-
|
|
303
|
+
- 単一文字:毎回正確に1文字を処理
|
|
304
|
+
- 固定間隔:設定された時間に厳密に実行
|
|
305
|
+
- ビート感:クラシックタイプライターのリズム感
|
|
306
|
+
- 精密制御:特定のタイミング要件に適している
|
|
226
307
|
|
|
227
308
|
// 🎯 適用シナリオ
|
|
228
|
-
-
|
|
229
|
-
-
|
|
309
|
+
- 精密な時間制御が必要
|
|
310
|
+
- レトロタイプライター効果を演出
|
|
230
311
|
- 互換性要件の高いシナリオ
|
|
231
312
|
```
|
|
232
313
|
|
|
233
314
|
### 📊 パフォーマンス比較
|
|
234
315
|
|
|
235
|
-
|
|
|
236
|
-
| -------------------------------- |
|
|
237
|
-
| **文字処理** |
|
|
238
|
-
| **高頻度間隔** | ✅ 優秀(5ms →
|
|
239
|
-
| **低頻度間隔** | ✅
|
|
240
|
-
| **視覚効果** | 🎬 滑らかなアニメーション感
|
|
241
|
-
| **パフォーマンスオーバーヘッド** | 🟢 低(フレーム同期)
|
|
316
|
+
| 特徴 | requestAnimationFrame | setTimeout |
|
|
317
|
+
| -------------------------------- | ----------------------------------- | ----------------- |
|
|
318
|
+
| **文字処理** | 1フレームで複数文字を処理可能 | 毎回1文字を処理 |
|
|
319
|
+
| **高頻度間隔** | ✅ 優秀(5ms → 1フレーム3文字) | ❌ ラグの可能性 |
|
|
320
|
+
| **低頻度間隔** | ✅ 正常(100ms → 6フレーム後1文字) | ✅ 精密 |
|
|
321
|
+
| **視覚効果** | 🎬 滑らかなアニメーション感 | ⚡ 精密なビート感 |
|
|
322
|
+
| **パフォーマンスオーバーヘッド** | 🟢 低(フレーム同期) | 🟡 中(タイマー) |
|
|
242
323
|
|
|
243
|
-
|
|
324
|
+
高頻度は`requestAnimationFrame`、低頻度は`setTimeout`を推奨
|
|
244
325
|
|
|
245
326
|
---
|
|
246
327
|
|
|
@@ -248,6 +329,8 @@ interface MarkdownCMDRef {
|
|
|
248
329
|
|
|
249
330
|
### 📝 AI ストリーミング会話
|
|
250
331
|
|
|
332
|
+
[DEMO: 🔧 StackBlitz 体験](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
|
|
333
|
+
|
|
251
334
|
````tsx
|
|
252
335
|
import { useRef } from 'react';
|
|
253
336
|
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
@@ -262,18 +345,18 @@ function StreamingChat() {
|
|
|
262
345
|
// 思考段階
|
|
263
346
|
markdownRef.current?.push('🤔 あなたの質問を分析しています...', 'thinking');
|
|
264
347
|
await delay(1000);
|
|
265
|
-
markdownRef.current?.push('\n\n✅
|
|
348
|
+
markdownRef.current?.push('\n\n✅ 分析完了、回答を開始', 'thinking');
|
|
266
349
|
|
|
267
350
|
// ストリーミング回答
|
|
268
351
|
const chunks = [
|
|
269
|
-
'# React 19
|
|
352
|
+
'# React 19 新機能解析\n\n',
|
|
270
353
|
'## 🚀 React Compiler\n',
|
|
271
|
-
'React 19
|
|
272
|
-
'- 🎯 **自動最適化**:手動の
|
|
273
|
-
'- ⚡
|
|
274
|
-
'- 🔧
|
|
275
|
-
'## 📝 Actions
|
|
276
|
-
'新しい
|
|
354
|
+
'React 19 の最大のハイライトは**React Compiler**の導入です:\n\n',
|
|
355
|
+
'- 🎯 **自動最適化**:手動のmemoとuseMemoが不要\n',
|
|
356
|
+
'- ⚡ **パフォーマンス向上**:コンパイル時最適化、実行時ゼロオーバーヘッド\n',
|
|
357
|
+
'- 🔧 **後方互換性**:既存コードの修正不要\n\n',
|
|
358
|
+
'## 📝 Actions フォーム簡素化\n',
|
|
359
|
+
'新しいActions APIによりフォーム処理がより簡単になります:\n\n',
|
|
277
360
|
'```tsx\n',
|
|
278
361
|
'function ContactForm({ action }) {\n',
|
|
279
362
|
' const [state, formAction] = useActionState(action, null);\n',
|
|
@@ -285,7 +368,7 @@ function StreamingChat() {
|
|
|
285
368
|
' );\n',
|
|
286
369
|
'}\n',
|
|
287
370
|
'```\n\n',
|
|
288
|
-
'
|
|
371
|
+
'この回答がお役に立てば幸いです!🎉',
|
|
289
372
|
];
|
|
290
373
|
|
|
291
374
|
for (const chunk of chunks) {
|
|
@@ -296,7 +379,7 @@ function StreamingChat() {
|
|
|
296
379
|
|
|
297
380
|
return (
|
|
298
381
|
<div className="chat-container">
|
|
299
|
-
<button onClick={simulateAIResponse}>🤖 React 19
|
|
382
|
+
<button onClick={simulateAIResponse}>🤖 React 19 新機能について質問</button>
|
|
300
383
|
|
|
301
384
|
<MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('段落完了:', data)} />
|
|
302
385
|
</div>
|
|
@@ -306,9 +389,46 @@ function StreamingChat() {
|
|
|
306
389
|
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
307
390
|
````
|
|
308
391
|
|
|
309
|
-
###
|
|
392
|
+
### 🧮 数式ストリーミングレンダリング
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
function MathStreamingDemo() {
|
|
396
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
397
|
+
|
|
398
|
+
const simulateMathResponse = async () => {
|
|
399
|
+
markdownRef.current?.clear();
|
|
400
|
+
|
|
401
|
+
const mathChunks = [
|
|
402
|
+
'# ピタゴラスの定理の説明\n\n',
|
|
403
|
+
'直角三角形では、斜辺の二乗は二つの直角辺の二乗の和に等しい:\n\n',
|
|
404
|
+
'$a^2 + b^2 = c^2$\n\n',
|
|
405
|
+
'ここで:\n',
|
|
406
|
+
'- $a$ と $b$ は直角辺\n',
|
|
407
|
+
'- $c$ は斜辺\n\n',
|
|
408
|
+
'古典的な「3-4-5」三角形の場合:\n',
|
|
409
|
+
'$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
|
|
410
|
+
'この定理は幾何学で広く応用されています!',
|
|
411
|
+
];
|
|
310
412
|
|
|
311
|
-
|
|
413
|
+
for (const chunk of mathChunks) {
|
|
414
|
+
await delay(150);
|
|
415
|
+
markdownRef.current?.push(chunk, 'answer');
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
return (
|
|
420
|
+
<div>
|
|
421
|
+
<button onClick={simulateMathResponse}>📐 ピタゴラスの定理を説明</button>
|
|
422
|
+
|
|
423
|
+
<MarkdownCMD ref={markdownRef} interval={20} timerType="requestAnimationFrame" math={{ isOpen: true, splitSymbol: 'dollar' }} />
|
|
424
|
+
</div>
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### 🔄 ストリーミングMarkdown構文処理
|
|
430
|
+
|
|
431
|
+
**核心問題**:ストリーミング出力時に不完全なMarkdown構文がレンダリングエラーを引き起こす
|
|
312
432
|
|
|
313
433
|
```tsx
|
|
314
434
|
// 🚨 問題シナリオ
|
|
@@ -316,47 +436,50 @@ push('#'); // "# "
|
|
|
316
436
|
push(' '); // "# "
|
|
317
437
|
push('タイトル'); // "# タイトル"
|
|
318
438
|
push('\n'); // "# タイトル\n"
|
|
319
|
-
push('1'); // "# タイトル\n1" ←
|
|
439
|
+
push('1'); // "# タイトル\n1" ← ここで段落として誤解析される
|
|
320
440
|
push('.'); // "# タイトル\n1." ← 正しいリストを形成
|
|
321
441
|
push(' 項目'); // "# タイトル\n1. 項目"
|
|
322
442
|
```
|
|
323
443
|
|
|
324
|
-
**✅
|
|
444
|
+
**✅ スマート解決策**:内蔵同期バッファリングメカニズム
|
|
325
445
|
|
|
326
446
|
```tsx
|
|
327
|
-
//
|
|
447
|
+
// コンポーネントが構文境界をインテリジェントに処理
|
|
328
448
|
const handleStreamingMarkdown = () => {
|
|
329
449
|
const chunks = ['#', ' ', '使用', 'スキル', '\n', '1', '.', ' ', 'スキル1', '\n', '2', '.', ' スキル2'];
|
|
330
450
|
|
|
331
451
|
chunks.forEach((chunk) => {
|
|
332
452
|
markdownRef.current?.push(chunk, 'answer');
|
|
333
|
-
//
|
|
453
|
+
// 遅延不要、コンポーネントが内部でインテリジェントにバッファリング
|
|
334
454
|
});
|
|
335
455
|
};
|
|
336
456
|
|
|
337
|
-
// 🧠
|
|
338
|
-
// 1. "# 使用スキル\n1"
|
|
339
|
-
// 2.
|
|
340
|
-
// 3. "." を受信して "1."
|
|
341
|
-
// 4.
|
|
457
|
+
// 🧠 インテリジェント処理フロー:
|
|
458
|
+
// 1. "# 使用スキル\n1" のような不完全な構文をリアルタイム検出
|
|
459
|
+
// 2. インテリジェントバッファリング、より多くの文字を待機
|
|
460
|
+
// 3. "." を受信して "1." を形成した後すぐに処理
|
|
461
|
+
// 4. ゼロ遅延、純粋な同期処理
|
|
342
462
|
```
|
|
343
463
|
|
|
344
464
|
**サポートされる構文検出**:
|
|
345
465
|
|
|
346
466
|
````typescript
|
|
347
|
-
// ✅
|
|
348
|
-
'## タイトル'; //
|
|
349
|
-
'1. リスト項目'; //
|
|
350
|
-
'- 項目'; //
|
|
351
|
-
'> 引用コンテンツ'; //
|
|
467
|
+
// ✅ 完全な構文(即座に処理)
|
|
468
|
+
'## タイトル'; // 完全なタイトル
|
|
469
|
+
'1. リスト項目'; // 完全なリスト項目
|
|
470
|
+
'- 項目'; // 完全な順序なしリスト
|
|
471
|
+
'> 引用コンテンツ'; // 完全な引用
|
|
352
472
|
'```javascript'; // コードブロック開始
|
|
353
473
|
'```'; // コードブロック終了
|
|
354
474
|
'改行で終わるコンテンツ\n'; // 改行境界
|
|
475
|
+
'$a + b$'; // 完全な数式
|
|
476
|
+
'$$\\sum x$$'; // 完全なブロック数式
|
|
355
477
|
|
|
356
|
-
// 🔄
|
|
478
|
+
// 🔄 不完全な構文(インテリジェントバッファリング)
|
|
357
479
|
'##'; // タイトル記号のみ
|
|
358
480
|
'1'; // 数字のみ
|
|
359
|
-
'```java'; //
|
|
481
|
+
'```java'; // 可能性のあるコードブロック開始
|
|
482
|
+
'$a +'; // 不完全な数式
|
|
360
483
|
````
|
|
361
484
|
|
|
362
485
|
---
|
|
@@ -369,37 +492,52 @@ const handleStreamingMarkdown = () => {
|
|
|
369
492
|
// ✅ 推奨設定
|
|
370
493
|
<DsMarkdown
|
|
371
494
|
timerType="requestAnimationFrame"
|
|
372
|
-
interval={15} // 15-30ms
|
|
495
|
+
interval={15} // 15-30msが最適な体験
|
|
373
496
|
/>
|
|
374
497
|
|
|
375
|
-
// ❌
|
|
498
|
+
// ❌ 小さすぎる間隔を避ける
|
|
376
499
|
<DsMarkdown interval={1} /> // パフォーマンス問題を引き起こす可能性
|
|
377
500
|
```
|
|
378
501
|
|
|
379
502
|
### 2. ストリーミングデータ処理
|
|
380
503
|
|
|
381
504
|
```tsx
|
|
382
|
-
// ✅ 推奨:命令的
|
|
505
|
+
// ✅ 推奨:命令的API
|
|
383
506
|
const ref = useRef<MarkdownCMDRef>(null);
|
|
384
507
|
useEffect(() => {
|
|
385
508
|
ref.current?.push(newChunk, 'answer');
|
|
386
509
|
}, [newChunk]);
|
|
387
510
|
|
|
388
|
-
// ❌ 避ける:頻繁な
|
|
511
|
+
// ❌ 避ける:頻繁なchildren更新
|
|
389
512
|
const [content, setContent] = useState('');
|
|
390
|
-
//
|
|
513
|
+
// 毎回の更新でコンテンツ全体を再解析
|
|
391
514
|
```
|
|
392
515
|
|
|
393
|
-
### 3.
|
|
516
|
+
### 3. 数式最適化
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
// ✅ 推奨:数式スタイルを必要に応じて読み込み
|
|
520
|
+
import 'ds-markdown/style.css';
|
|
521
|
+
import 'ds-markdown/katex.css'; // 必要な時のみインポート
|
|
522
|
+
|
|
523
|
+
// ✅ 推奨:区切り文字の合理的な使用
|
|
524
|
+
// シンプルな数式には $...$ で簡潔さを
|
|
525
|
+
// 複雑な数式には $$...$$ で明確さを
|
|
526
|
+
|
|
527
|
+
// ❌ 避ける:不要な時に数式を有効にする
|
|
528
|
+
<DsMarkdown math={{ isOpen: true }}>プレーンテキストコンテンツ</DsMarkdown>;
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### 4. 型安全性
|
|
394
532
|
|
|
395
533
|
```tsx
|
|
396
534
|
import { MarkdownCMDRef } from 'ds-markdown';
|
|
397
535
|
|
|
398
536
|
const ref = useRef<MarkdownCMDRef>(null);
|
|
399
|
-
// 完全な
|
|
537
|
+
// 完全なTypeScript型ヒント
|
|
400
538
|
```
|
|
401
539
|
|
|
402
|
-
###
|
|
540
|
+
### 5. スタイルカスタマイズ
|
|
403
541
|
|
|
404
542
|
```css
|
|
405
543
|
/* 思考エリアスタイル */
|
|
@@ -439,18 +577,33 @@ const ref = useRef<MarkdownCMDRef>(null);
|
|
|
439
577
|
padding: 8px 12px;
|
|
440
578
|
text-align: left;
|
|
441
579
|
}
|
|
580
|
+
|
|
581
|
+
/* 数式スタイル */
|
|
582
|
+
.katex {
|
|
583
|
+
font-size: 1.1em;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.katex-display {
|
|
587
|
+
margin: 1em 0;
|
|
588
|
+
text-align: center;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/* ダークテーマ数式 */
|
|
592
|
+
[data-theme='dark'] .katex {
|
|
593
|
+
color: #e1e1e1;
|
|
594
|
+
}
|
|
442
595
|
```
|
|
443
596
|
|
|
444
597
|
---
|
|
445
598
|
|
|
446
599
|
## 🌐 互換性
|
|
447
600
|
|
|
448
|
-
| 環境 | バージョン要件 | 説明
|
|
449
|
-
| -------------- | ----------------------------------- |
|
|
450
|
-
| **React** | 16.8.0+ | Hooks
|
|
451
|
-
| **TypeScript** | 4.0+ |
|
|
452
|
-
| **ブラウザ** | Chrome 60+, Firefox 55+, Safari 12+ | モダンブラウザ
|
|
453
|
-
| **Node.js** | 14.0+ | ビルド環境
|
|
601
|
+
| 環境 | バージョン要件 | 説明 |
|
|
602
|
+
| -------------- | ----------------------------------- | ------------------- |
|
|
603
|
+
| **React** | 16.8.0+ | Hooksサポートが必要 |
|
|
604
|
+
| **TypeScript** | 4.0+ | オプションだが推奨 |
|
|
605
|
+
| **ブラウザ** | Chrome 60+, Firefox 55+, Safari 12+ | モダンブラウザ |
|
|
606
|
+
| **Node.js** | 14.0+ | ビルド環境 |
|
|
454
607
|
|
|
455
608
|
---
|
|
456
609
|
|
|
@@ -458,7 +611,7 @@ const ref = useRef<MarkdownCMDRef>(null);
|
|
|
458
611
|
|
|
459
612
|
Issue と Pull Request の提出を歓迎します!
|
|
460
613
|
|
|
461
|
-
1.
|
|
614
|
+
1. このリポジトリをFork
|
|
462
615
|
2. 機能ブランチを作成:`git checkout -b feature/amazing-feature`
|
|
463
616
|
3. 変更をコミット:`git commit -m 'Add amazing feature'`
|
|
464
617
|
4. ブランチをプッシュ:`git push origin feature/amazing-feature`
|
|
@@ -473,11 +626,11 @@ MIT © [onshinpei](https://github.com/onshinpei)
|
|
|
473
626
|
---
|
|
474
627
|
|
|
475
628
|
<div align="center">
|
|
476
|
-
<strong>このプロジェクトがお役に立てば、⭐️ Star
|
|
629
|
+
<strong>このプロジェクトがお役に立てば、⭐️ Star をお願いします!</strong>
|
|
477
630
|
|
|
478
631
|
<br><br>
|
|
479
632
|
|
|
480
633
|
[🐛 問題報告](https://github.com/onshinpei/ds-markdown/issues) |
|
|
481
634
|
[💡 機能提案](https://github.com/onshinpei/ds-markdown/issues) |
|
|
482
|
-
[📖
|
|
635
|
+
[📖 ドキュメント閲覧](https://onshinpei.github.io/ds-markdown/)
|
|
483
636
|
</div>
|
package/README.ko.md
CHANGED
|
@@ -45,6 +45,13 @@
|
|
|
45
45
|
- **명령형 API**: 스트리밍 데이터에 적합, 더 나은 성능
|
|
46
46
|
- **네이티브 TypeScript 지원**: 완전한 타입 힌트
|
|
47
47
|
|
|
48
|
+
### 🧮 **수식 지원**
|
|
49
|
+
|
|
50
|
+
- **KaTeX 통합**: 고성능 수식 렌더링
|
|
51
|
+
- **이중 구문 지원**: `$...$` 및 `\[...\]` 구분자
|
|
52
|
+
- **스트리밍 호환**: 타이핑 애니메이션에서 수식의 완벽한 지원
|
|
53
|
+
- **테마 적응**: 라이트/다크 테마에 자동 적응
|
|
54
|
+
|
|
48
55
|
---
|
|
49
56
|
|
|
50
57
|
## 📦 빠른 설치
|
|
@@ -195,6 +202,16 @@ interface MarkdownCMDRef {
|
|
|
195
202
|
| `clear` | - | 모든 콘텐츠와 상태 초기화 |
|
|
196
203
|
| `triggerWholeEnd` | - | 완료 콜백 수동 트리거 |
|
|
197
204
|
|
|
205
|
+
| `stop` | - | 타이핑 애니메이션 일시정지 |
|
|
206
|
+
| `resume` | - | 타이핑 애니메이션 재개 |
|
|
207
|
+
|
|
208
|
+
**사용 예시:**
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
markdownRef.current?.stop(); // 애니메이션 일시정지
|
|
212
|
+
markdownRef.current?.resume(); // 애니메이션 재개
|
|
213
|
+
```
|
|
214
|
+
|
|
198
215
|
---
|
|
199
216
|
|
|
200
217
|
## 🎛️ 타이머 모드 상세 설명
|