ds-markdown 0.1.1 → 0.1.2-beta.1

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.ko.md CHANGED
@@ -20,39 +20,31 @@
20
20
 
21
21
  ## ✨ 핵심 기능
22
22
 
23
- ### 🎯 **완벽한 재현**
23
+ ### 🤖 **AI 대화 시나리오**
24
24
 
25
25
  - [DeepSeek 웹사이트](https://chat.deepseek.com/) 채팅 응답 효과를 1:1로 재현
26
26
  - 사고 과정(`thinking`)과 답변 내용(`answer`) 두 가지 모드 지원
27
- - 코드 하이라이팅, 테이블, 목록 등을 포함한 네이티브 Markdown 구문 지원
28
- - 라이트/다크 테마 지원, 다양한 시나리오에 완벽하게 대응
27
+ - 스트리밍 데이터에 완벽하게 적응, 사용자 입력에 대한 지연 없는 응답
29
28
 
30
- ### **극한의 성능**
29
+ ### 📊 **콘텐츠 표시 시나리오**
31
30
 
32
- - 스마트 배치 처리로 대용량 문서도 지연 없는 렌더링
33
- - 듀얼 타이머 모드: `requestAnimationFrame` + `setTimeout`
34
- - 내장 스트리밍 구문 버퍼링으로 불완전한 Markdown 렌더링 오류 방지
31
+ - 코드 하이라이팅, 테이블, 목록 등을 포함한 완전한 Markdown 구문 지원
32
+ - 수식 렌더링 (KaTeX), `$...$` 및 `\[...\]` 구문 지원
33
+ - 라이트/다크 테마 지원, 다양한 제품 스타일에 적응
34
+ - remark/rehype 플러그인 확장을 지원하는 플러그인 아키텍처
35
+
36
+ ### 🔧 **개발자 경험**
37
+
38
+ - 타이핑 중단 `stop` 및 재개 `resume` 지원
39
+ - 타이핑 비활성화 및 활성화 지원
35
40
 
36
41
  ### 🎬 **부드러운 애니메이션**
37
42
 
43
+ - 듀얼 타이머 모드 최적화, `requestAnimationFrame` 및 `setTimeout` 모드 지원
38
44
  - 고주파 타이핑 지원(`requestAnimationFrame` 모드에서 `0ms`에 가까운 타이핑 간격 지원)
39
- - 프레임 동기화 렌더링으로 브라우저 60fps와 완벽 매칭
45
+ - 프레임 동기화 렌더링으로 브라우저 새로고침 속도와 완벽 매칭
40
46
  - 스마트 문자 배치 처리로 더 자연스러운 시각적 효과
41
47
 
42
- ### 🔧 **유연하고 사용하기 쉬움**
43
-
44
- - **선언적 API**: 간단한 시나리오에 적합, React 스타일
45
- - **명령형 API**: 스트리밍 데이터에 적합, 더 나은 성능
46
- - **네이티브 TypeScript 지원**: 완전한 타입 힌트
47
-
48
- ### 🧮 **수식 지원**
49
-
50
- - **KaTeX 통합**: 고성능 수식 렌더링
51
- - **플러그인 아키텍처**: 플러그인 시스템을 통한 유연한 설정
52
- - **이중 구문 지원**: `$...$` 및 `\[...\]` 구분자
53
- - **스트리밍 호환**: 타이핑 애니메이션에서 수식의 완벽한 지원
54
- - **테마 적응**: 라이트/다크 테마에 자동 적응
55
-
56
48
  ---
57
49
 
58
50
  ## 📦 빠른 설치
@@ -72,39 +64,18 @@ pnpm add ds-markdown
72
64
 
73
65
  설치 없이 브라우저에서 직접 사용할 수 있습니다:
74
66
 
67
+ [DEMO](https://stackblitz.com/edit/stackblitz-starters-7vcclcw7?file=index.html)
68
+
75
69
  ```html
76
- <!-- 스타일 가져오기 -->
70
+ <!-- 스타일 가져오기, 필수 -->
77
71
  <link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/style.css" />
78
72
 
79
- <!-- 컴포넌트 가져오기 -->
80
- <script type="importmap">
81
- {
82
- "imports": {
83
- "react": "https://esm.sh/react@19.1.0",
84
- "react-dom/client": "https://esm.sh/react-dom@19.1.0/client",
85
- "ds-markdown": "https://esm.sh/ds-markdown"
86
- }
87
- }
88
- </script>
89
- <script type="module" src="https://esm.sh/tsx"></script>
90
-
91
- <script type="text/babel">
92
- import { createRoot } from 'react-dom/client';
93
- import DsMarkdown from 'ds-markdown';
94
-
95
- const markdown = `
96
- # Hello ds-markdown
97
-
98
- 이것은 **고성능** 타이핑 애니메이션 컴포넌트입니다!
73
+ <!-- katex 수학 공식 스타일 가져오기, 필요한 경우만 -->
74
+ <link rel="stylesheet" href="https://esm.sh/ds-markdown/dist/katex.css" />
99
75
 
100
- ## 특징
101
- - ⚡ 지연 없는 스트리밍
102
- - 🎬 부드러운 타이핑 애니메이션
103
- - 🎯 완벽한 구문 지원
104
- `;
105
-
106
- const root = createRoot(document.getElementById('root'));
107
- root.render(<DsMarkdown interval={20}>{markdown}</DsMarkdown>);
76
+ <!-- 컴포넌트 가져오기 -->
77
+ <script type="module">
78
+ import Markdown from 'https://esm.sh/ds-markdown';
108
79
  </script>
109
80
  ```
110
81
 
@@ -112,6 +83,8 @@ pnpm add ds-markdown
112
83
 
113
84
  ### 기본 사용법
114
85
 
86
+ [DEMO](https://stackblitz.com/edit/vitejs-vite-z94syu8j?file=src%2FApp.tsx)
87
+
115
88
  ```tsx
116
89
  import DsMarkdown from 'ds-markdown';
117
90
  import 'ds-markdown/style.css';
@@ -125,6 +98,48 @@ function App() {
125
98
  }
126
99
  ```
127
100
 
101
+ ### 타이핑 애니메이션 비활성화
102
+
103
+ ```tsx
104
+ import DsMarkdown from 'ds-markdown';
105
+ import 'ds-markdown/style.css';
106
+
107
+ function StaticDemo() {
108
+ const [disableTyping, setDisableTyping] = useState(false);
109
+
110
+ return (
111
+ <div>
112
+ <button onClick={() => setDisableTyping(!disableTyping)}>{disableTyping ? '활성화' : '비활성화'}타이핑 효과</button>
113
+
114
+ <DsMarkdown interval={20} answerType="answer" disableTyping={disableTyping}>
115
+ # 정적 표시 모드 `disableTyping`이 `true`일 때, 콘텐츠는 타이핑 애니메이션 효과 없이 즉시 모두 표시됩니다. 이는 특정 시나리오에서 매우 유용합니다: - 📄 정적 문서 표시 - 🔄 표시 모드 전환 - ⚡
116
+ 콘텐츠 빠른 미리보기
117
+ </DsMarkdown>
118
+ </div>
119
+ );
120
+ }
121
+ ```
122
+
123
+ ### 수학 공식 지원
124
+
125
+ ```tsx
126
+ import DsMarkdown from 'ds-markdown';
127
+ // 공식을 표시해야 하는 경우 공식 변환 플러그인을 가져옵니다
128
+ import { katexPlugin } from 'ds-markdown/plugins';
129
+ import 'ds-markdown/style.css';
130
+ // 공식을 표시해야 하는 경우 수학 공식 스타일을 가져옵니다
131
+ import 'ds-markdown/katex.css';
132
+
133
+ function MathDemo() {
134
+ return (
135
+ <DsMarkdown interval={20} answerType="answer" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }}>
136
+ # 피타고라스 정리 직각삼각형에서 빗변의 제곱은 두 직각변의 제곱의 합과 같습니다: $a^2 + b^2 = c^2$ 여기서: - $a$와 $b$는 직각변 - $c$는 빗변 고전적인 "구삼고사현오"의 경우: $c = \sqrt
137
+ {3 ^ (2 + 4) ^ 2} = \sqrt{25} = 5$
138
+ </DsMarkdown>
139
+ );
140
+ }
141
+ ```
142
+
128
143
  ### AI 대화 시나리오
129
144
 
130
145
  ```tsx
@@ -173,40 +188,75 @@ React 19는 많은 흥미로운 새 기능을 제공합니다:
173
188
 
174
189
  ## 📚 완전 API 문서
175
190
 
176
- ### 선언적 API (초보자 추천)
191
+ ### 기본 내보내기 DsMarkdown 및 MarkdownCMD props
177
192
 
178
- | 속성 | 타입 | 설명 | 기본값 |
179
- | ------------- | ------------------------------------------- | -------------------- | ---------------------------------------------------------------------- |
180
- | `interval` | `number` | 타이핑 간격 (밀리초) | `30` |
181
- | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | 타이머 타입 | 현재 기본값은 `setTimeout`, 나중에 `requestAnimationFrame`로 변경 예정 |
182
- | `answerType` | `'thinking'` \| `'answer'` | 콘텐츠 타입 | `'answer'` |
183
- | `theme` | `'light'` \| `'dark'` | 테마 타입 | `'light'` |
184
- | `onEnd` | `(data: EndData) => void` | 타이핑 완료 콜백 | - |
185
- | `onStart` | `(data: StartData) => void` | 타이핑 시작 콜백 | - |
186
- | `onTypedChar` | `(data: CharData) => void` | 문자별 타이핑 콜백 | - |
193
+ ```js
194
+ import DsMarkdown, { MarkdownCMD } from 'ds-markdown';
195
+ ```
187
196
 
188
- ### 명령형 API (스트리밍 시나리오 추천)
197
+ | 속성 | 타입 | 설명 | 기본값 |
198
+ | --------------- | --------------------------------------------- | -------------------------- | ---------------------------------------------------------------------- |
199
+ | `interval` | `number` | 타이핑 간격 (밀리초) | `30` |
200
+ | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | 타이머 타입 | 현재 기본값은 `setTimeout`, 나중에 `requestAnimationFrame`로 변경 예정 |
201
+ | `answerType` | `'thinking'` \| `'answer'` | 콘텐츠 타입 (스타일 영향) | `'answer'` |
202
+ | `theme` | `'light'` \| `'dark'` | 테마 타입 | `'light'` |
203
+ | `plugins` | `IMarkdownPlugin[]` | 플러그인 설정 | `[]` |
204
+ | `math` | [IMarkdownMath](#IMarkdownMath) | 수학 공식 설정 | `{ splitSymbol: 'dollar' }` |
205
+ | `onEnd` | `(data: EndData) => void` | 타이핑 완료 콜백 | - |
206
+ | `onStart` | `(data: StartData) => void` | 타이핑 시작 콜백 | - |
207
+ | `onTypedChar` | `(data: `[ITypedChar](#ITypedChar)`) => void` | 문자별 타이핑 콜백 | - |
208
+ | `disableTyping` | `boolean` | 타이핑 애니메이션 비활성화 | `false` |
189
209
 
190
- ```typescript
191
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
210
+ > 참고: 타이핑 중에 `disableTyping`이 `true`에서 `false`로 변경되면 다음 타이핑 트리거 시 남은 모든 문자가 한 번에 표시됩니다.
192
211
 
193
- interface MarkdownCMDRef {
194
- push: (content: string, answerType: AnswerType) => void;
195
- clear: () => void;
196
- triggerWholeEnd: () => void;
197
- }
198
- ```
212
+ ### ITypedChar
213
+
214
+ | 속성 | 타입 | 설명 | 기본값 |
215
+ | -------------- | -------- | --------------------------- | ------ |
216
+ | `percent` | `number` | 타이핑 진행률 백분율 | `0` |
217
+ | `currentChar` | `string` | 현재 타이핑 중인 문자 | - |
218
+ | `currentIndex` | `number` | 전체 문자열에서 현재 인덱스 | `0` |
219
+
220
+ #### IMarkdownMath
221
+
222
+ | 속성 | 타입 | 설명 | 기본값 |
223
+ | ------------- | ------------------------- | ---------------- | ---------- |
224
+ | `splitSymbol` | `'dollar'` \| `'bracket'` | 수학 공식 구분자 | `'dollar'` |
225
+
226
+ **구분자 설명:**
227
+
228
+ - `'dollar'`: `$...$` 및 `$$...$$` 구문 사용
229
+ - `'bracket'`: `\(...\)` 및 `\[...\]` 구문 사용
230
+
231
+ #### IMarkdownPlugin
232
+
233
+ | 속성 | 타입 | 설명 | 기본값 |
234
+ | -------------- | ------------------------- | ---------------- | ------ |
235
+ | `remarkPlugin` | `unknown` | remark 플러그인 | - |
236
+ | `rehypePlugin` | `unknown` | rehype 플러그인 | - |
237
+ | `type` | `'buildIn'` \| `'custom'` | 플러그인 타입 | - |
238
+ | `id` | `any` | 플러그인 고유 ID | - |
239
+
240
+ ### 컴포넌트 노출 메서드
241
+
242
+ #### 기본 내보내기 DsMarkdown
243
+
244
+ | 메서드 | 매개변수 | 설명 |
245
+ | -------- | -------- | --------------- |
246
+ | `stop` | - | 타이핑 일시정지 |
247
+ | `resume` | - | 타이핑 재개 |
248
+
249
+ #### MarkdownCMD 노출 메서드
199
250
 
200
251
  | 메서드 | 매개변수 | 설명 |
201
252
  | ----------------- | ------------------------------------------- | -------------------------- |
202
253
  | `push` | `(content: string, answerType: AnswerType)` | 콘텐츠 추가 및 타이핑 시작 |
203
- | `clear` | - | 모든 콘텐츠와 상태 초기화 |
204
- | `triggerWholeEnd` | - | 완료 콜백 수동 트리거 |
205
-
206
- | `stop` | - | 타이핑 애니메이션 일시정지 |
207
- | `resume` | - | 타이핑 애니메이션 재개 |
254
+ | `clear` | - | 모든 콘텐츠 상태 지우기 |
255
+ | `triggerWholeEnd` | - | 수동으로 완료 콜백 트리거 |
256
+ | `stop` | - | 타이핑 일시정지 |
257
+ | `resume` | - | 타이핑 재개 |
208
258
 
209
- **사용 예시:**
259
+ **사용 예:**
210
260
 
211
261
  ```tsx
212
262
  markdownRef.current?.stop(); // 애니메이션 일시정지
@@ -215,50 +265,168 @@ markdownRef.current?.resume(); // 애니메이션 재개
215
265
 
216
266
  ---
217
267
 
218
- ## 🎛️ 타이머 모드 상세 설명
268
+ ## 🧮 수학 공식 사용 가이드
269
+
270
+ [DEMO1: 피타고라스 정리](https://stackblitz.com/edit/vitejs-vite-z94syu8j?file=src%2FApp.tsx)
271
+
272
+ [DEMO2: 문제 해답](https://stackblitz.com/edit/vitejs-vite-xk9lxagc?file=README.md)
219
273
 
220
- ### `requestAnimationFrame` 모드 🌟 (추천)
274
+ ### 기본 구문
275
+
276
+ ```tsx
277
+ import { katexPlugin } from 'ds-markdown/plugins';
278
+
279
+ // 1. 수학 공식 지원 활성화
280
+ <DsMarkdown plugins={[katexPlugin]}>
281
+ # 수학 공식 예제
282
+
283
+ // 인라인 공식
284
+ 이것은 인라인 공식입니다: $E = mc^2$
285
+
286
+ // 블록 공식
287
+ $$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
288
+ </DsMarkdown>
289
+ ```
290
+
291
+ ### 구분자 선택
292
+
293
+ ```tsx
294
+ // 달러 기호 구분자 사용 (기본값)
295
+ <DsMarkdown
296
+ plugins={[katexPlugin]}
297
+ math={{ splitSymbol: 'dollar' }}
298
+ >
299
+ 인라인: $a + b = c$
300
+ 블록: $$\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n$$
301
+ </DsMarkdown>
302
+
303
+ // 괄호 구분자 사용
304
+ <DsMarkdown
305
+ plugins={[katexPlugin]}
306
+ math={{ splitSymbol: 'bracket' }}
307
+ >
308
+ 인라인: \(a + b = c\)
309
+ 블록: \[\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n\]
310
+ </DsMarkdown>
311
+ ```
312
+
313
+ ### 스트리밍 수학 공식
314
+
315
+ ```tsx
316
+ // 스트리밍 출력에서 수학 공식을 완벽하게 지원
317
+ const mathContent = [
318
+ '피타고라스 정리:',
319
+ '$a^2 + b^2 = c^2$',
320
+ '\n\n',
321
+ '여기서:',
322
+ '- $a$와 $b$는 직각변\n',
323
+ '- $c$는 빗변\n\n',
324
+ '고전적인 "구삼고사현오"의 경우:\n',
325
+ '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
326
+ '이 정리는 기하학에서 광범위하게 응용됩니다!',
327
+ ];
328
+
329
+ mathContent.forEach((chunk) => {
330
+ markdownRef.current?.push(chunk, 'answer');
331
+ });
332
+ ```
333
+
334
+ ### 스타일 커스터마이징
335
+
336
+ ```css
337
+ /* 수학 공식 스타일 커스터마이징 */
338
+ .katex {
339
+ font-size: 1.1em;
340
+ }
341
+
342
+ .katex-display {
343
+ margin: 1em 0;
344
+ text-align: center;
345
+ }
346
+
347
+ /* 다크 테마 적응 */
348
+ [data-theme='dark'] .katex {
349
+ color: #e1e1e1;
350
+ }
351
+ ```
352
+
353
+ ---
354
+
355
+ ## 🔌 플러그인 시스템
356
+
357
+ ### 내장 플러그인
358
+
359
+ #### KaTeX 수학 공식 플러그인
360
+
361
+ ```tsx
362
+ import { katexPlugin } from 'ds-markdown/plugins';
363
+
364
+ // 수학 공식 지원 활성화
365
+ <DsMarkdown plugins={[katexPlugin]}>수학 공식: $E = mc^2$</DsMarkdown>;
366
+ ```
367
+
368
+ ### 커스텀 플러그인
369
+
370
+ ```tsx
371
+ import { createBuildInPlugin } from 'ds-markdown/plugins';
372
+
373
+ // 커스텀 플러그인 생성
374
+ const customPlugin = createBuildInPlugin({
375
+ remarkPlugin: yourRemarkPlugin,
376
+ rehypePlugin: yourRehypePlugin,
377
+ id: Symbol('custom-plugin'),
378
+ });
379
+
380
+ // 커스텀 플러그인 사용
381
+ <DsMarkdown plugins={[katexPlugin, customPlugin]}>콘텐츠</DsMarkdown>;
382
+ ```
383
+
384
+ ---
385
+
386
+ ## 🎛️ 타이머 모드 상세
387
+
388
+ ### `requestAnimationFrame` 모드 🌟 (권장)
221
389
 
222
390
  ```typescript
223
391
  // 🎯 특징
224
- - 시간 기반: 실제 경과 시간을 기반으로 문자 수 계산
392
+ - 시간 기반: 실제 경과 시간을 바탕으로 문자 수 계산
225
393
  - 배치 처리: 단일 프레임 내에서 여러 문자 처리 가능
226
394
  - 프레임 동기화: 브라우저 60fps 새로고침 속도와 동기화
227
- - 고주파 최적화: interval < 16ms 고속 타이핑 완벽 지원
395
+ - 고주파 최적화: interval < 16ms 고속 타이핑을 완벽하게 지원
228
396
 
229
397
  // 🎯 적용 시나리오
230
398
  - 현대 웹 애플리케이션의 기본 선택
231
399
  - 부드러운 애니메이션 효과 추구
232
- - 고주파 타이핑 (interval > 0이면 충분)
400
+ - 고주파 타이핑 (interval > 0으로 충분)
233
401
  - AI 실시간 대화 시나리오
234
402
  ```
235
403
 
236
- ### `setTimeout` 모드 📟 (호환성)
404
+ ### `setTimeout` 모드 📟 (호환)
237
405
 
238
406
  ```typescript
239
407
  // 🎯 특징
240
- - 단일 문자: 번에 정확히 하나의 문자 처리
408
+ - 단일 문자: 매번 정확히 문자씩 처리
241
409
  - 고정 간격: 설정된 시간에 따라 엄격하게 실행
242
- - 리듬감: 클래식 타자기의 리듬
410
+ - 리듬감: 클래식 타자기의 리듬감
243
411
  - 정밀 제어: 특정 타이밍 요구사항에 적합
244
412
 
245
413
  // 🎯 적용 시나리오
246
- - 정밀한 시간 제어가 필요
247
- - 레트로 타자기 효과 생성
414
+ - 정밀한 시간 제어가 필요한 경우
415
+ - 레트로 타자기 효과 연출
248
416
  - 호환성 요구사항이 높은 시나리오
249
417
  ```
250
418
 
251
419
  ### 📊 성능 비교
252
420
 
253
- | 기능 | requestAnimationFrame | setTimeout |
254
- | ----------------- | ---------------------------------- | -------------------- |
255
- | **문자 처리** | 프레임당 여러 문자 처리 가능 | 한 번에 한 문자 처리 |
256
- | **고주파 간격** | ✅ 우수 (5ms → 프레임당 3문자) | ❌ 지연 가능성 |
257
- | **저주파 간격** | ✅ 정상 (100ms → 6프레임 후 1문자) | ✅ 정밀 |
258
- | **시각적 효과** | 🎬 부드러운 애니메이션 느낌 | ⚡ 정밀한 리듬감 |
259
- | **성능 오버헤드** | 🟢 낮음 (프레임 동기화) | 🟡 중간 (타이머) |
421
+ | 특징 | requestAnimationFrame | setTimeout |
422
+ | ----------------- | ---------------------------------- | ---------------- |
423
+ | **문자 처리** | 프레임당 여러 문자 | 한 번에 한 문자 |
424
+ | **고주파** | ✅ 우수 (5ms → 프레임당 3문자) | ❌ 지연 가능성 |
425
+ | **저주파** | ✅ 정상 (100ms → 6프레임 후 1문자) | ✅ 정밀 |
426
+ | **시각적 효과** | 🎬 부드러운 애니메이션 감각 | ⚡ 정밀한 리듬감 |
427
+ | **성능 오버헤드** | 🟢 낮음 (프레임 동기화) | 🟡 보통 (타이머) |
260
428
 
261
- 고주파는 `requestAnimationFrame`, 저주파는 `setTimeout` 추천
429
+ 고주파는 `requestAnimationFrame` 권장, 저주파는 `setTimeout` 권장
262
430
 
263
431
  ---
264
432
 
@@ -266,6 +434,8 @@ markdownRef.current?.resume(); // 애니메이션 재개
266
434
 
267
435
  ### 📝 AI 스트리밍 대화
268
436
 
437
+ [DEMO: 🔧 StackBlitz 체험](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
438
+
269
439
  ````tsx
270
440
  import { useRef } from 'react';
271
441
  import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
@@ -278,18 +448,18 @@ function StreamingChat() {
278
448
  markdownRef.current?.clear();
279
449
 
280
450
  // 사고 단계
281
- markdownRef.current?.push('🤔 질문을 분석하고 있습니다...', 'thinking');
451
+ markdownRef.current?.push('🤔 질문을 분석 중입니다...', 'thinking');
282
452
  await delay(1000);
283
- markdownRef.current?.push('\n\n✅ 분석 완료, 답변을 시작합니다', 'thinking');
453
+ markdownRef.current?.push('\n\n✅ 분석 완료, 답변 시작', 'thinking');
284
454
 
285
455
  // 스트리밍 답변
286
456
  const chunks = [
287
- '# React 19 기능 분석\n\n',
457
+ '# React 19 신기능 분석\n\n',
288
458
  '## 🚀 React Compiler\n',
289
459
  'React 19의 가장 큰 하이라이트는 **React Compiler** 도입입니다:\n\n',
290
460
  '- 🎯 **자동 최적화**: 수동 memo와 useMemo 불필요\n',
291
- '- ⚡ **성능 향상**: 컴파일 타임 최적화, 런타임 오버헤드 제로\n',
292
- '- 🔧 **하위 호환성**: 기존 코드 수정 불필요\n\n',
461
+ '- ⚡ **성능 향상**: 컴파일 타임 최적화, 런타임 제로 오버헤드\n',
462
+ '- 🔧 **후방 호환성**: 기존 코드 수정 불필요\n\n',
293
463
  '## 📝 Actions로 폼 간소화\n',
294
464
  '새로운 Actions API로 폼 처리가 더 간단해집니다:\n\n',
295
465
  '```tsx\n',
@@ -314,9 +484,9 @@ function StreamingChat() {
314
484
 
315
485
  return (
316
486
  <div className="chat-container">
317
- <button onClick={simulateAIResponse}>🤖 React 19 기능에 대해 질문하기</button>
487
+ <button onClick={simulateAIResponse}>🤖 React 19 신기능에 대해 질문</button>
318
488
 
319
- <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('단락 완료:', data)} />
489
+ <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('섹션 완료:', data)} />
320
490
  </div>
321
491
  );
322
492
  }
@@ -324,80 +494,64 @@ function StreamingChat() {
324
494
  const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
325
495
  ````
326
496
 
327
- ### 🔄 스트리밍 Markdown 구문 처리
328
-
329
- **핵심 문제**: 스트리밍 출력 시 불완전한 Markdown 구문이 렌더링 오류를 일으킬 수 있음
497
+ ### 🧮 수학 공식 스트리밍 렌더링
330
498
 
331
499
  ```tsx
332
- // 🚨 문제 시나리오
333
- push('#'); // "# "
334
- push(' '); // "# "
335
- push('제목'); // "# 제목"
336
- push('\n'); // "# 제목\n"
337
- push('1'); // "# 제목\n1" ← 이것은 단락으로 잘못 해석됨
338
- push('.'); // "# 제목\n1." ← 올바른 리스트 형성
339
- push(' 항목'); // "# 제목\n1. 항목"
340
- ```
500
+ import { katexPlugin } from 'ds-markdown/plugins';
341
501
 
342
- **✅ 스마트 솔루션**: 컴포넌트 내장 동기 버퍼링 메커니즘
502
+ function MathStreamingDemo() {
503
+ const markdownRef = useRef<MarkdownCMDRef>(null);
343
504
 
344
- ```tsx
345
- // 컴포넌트가 구문 경계를 지능적으로 처리
346
- const handleStreamingMarkdown = () => {
347
- const chunks = ['#', ' ', '사용', '기술', '\n', '1', '.', ' ', '기술1', '\n', '2', '.', ' 기술2'];
348
-
349
- chunks.forEach((chunk) => {
350
- markdownRef.current?.push(chunk, 'answer');
351
- // 지연 불필요, 컴포넌트 내부에서 지능적 버퍼링
352
- });
353
- };
354
-
355
- // 🧠 스마트 처리 플로우:
356
- // 1. "# 사용기술\n1" 구문 불완전 실시간 감지
357
- // 2. 스마트 버퍼링, 더 많은 문자 대기
358
- // 3. "."을 받아 "1." 형성 후 즉시 처리
359
- // 4. 지연 없음, 순수 동기 처리
360
- ```
505
+ const simulateMathResponse = async () => {
506
+ markdownRef.current?.clear();
361
507
 
362
- **지원되는 구문 감지**:
363
-
364
- ````typescript
365
- // 완전한 구문 (즉시 처리)
366
- '## 제목'; // 완전한 제목
367
- '1. 리스트 항목'; // 완전한 리스트 항목
368
- '- 항목'; // 완전한 무순서 리스트
369
- '> 인용 콘텐츠'; // 완전한 인용
370
- '```javascript'; // 코드 블록 시작
371
- '```'; // 코드 블록
372
- '개행으로 끝나는 콘텐츠\n'; // 개행 경계
373
-
374
- // 🔄 불완전한 구문 (스마트 버퍼링)
375
- '##'; // 제목 기호만
376
- '1'; // 숫자만
377
- '```java'; // 가능한 코드 블록 시작
378
- ````
508
+ const mathChunks = [
509
+ '# 피타고라스 정리 상세 설명\n\n',
510
+ '직각삼각형에서 빗변의 제곱은 두 직각변의 제곱의 합과 같습니다:\n\n',
511
+ '$a^2 + b^2 = c^2$\n\n',
512
+ '여기서:\n',
513
+ '- $a$와 $b$는 직각변\n',
514
+ '- $c$는 빗변\n\n',
515
+ '고전적인 "구삼고사현오"의 경우:\n',
516
+ '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
517
+ ' 정리는 기하학에서 광범위하게 응용됩니다!',
518
+ ];
379
519
 
380
- ---
520
+ for (const chunk of mathChunks) {
521
+ await delay(150);
522
+ markdownRef.current?.push(chunk, 'answer');
523
+ }
524
+ };
525
+
526
+ return (
527
+ <div>
528
+ <button onClick={simulateMathResponse}>📐 피타고라스 정리 설명</button>
529
+
530
+ <MarkdownCMD ref={markdownRef} interval={20} timerType="requestAnimationFrame" plugins={[katexPlugin]} math={{ splitSymbol: 'dollar' }} />
531
+ </div>
532
+ );
533
+ }
534
+ ```
381
535
 
382
536
  ## 🔧 모범 사례
383
537
 
384
538
  ### 1. 성능 최적화
385
539
 
386
540
  ```tsx
387
- // ✅ 추천 구성
541
+ // ✅ 권장 구성
388
542
  <DsMarkdown
389
543
  timerType="requestAnimationFrame"
390
544
  interval={15} // 15-30ms가 최적 경험
391
545
  />
392
546
 
393
547
  // ❌ 너무 작은 간격 피하기
394
- <DsMarkdown interval={1} /> // 성능 문제를 일으킬 수 있음
548
+ <DsMarkdown interval={1} /> // 성능 문제 야기 가능
395
549
  ```
396
550
 
397
551
  ### 2. 스트리밍 데이터 처리
398
552
 
399
553
  ```tsx
400
- // ✅ 추천: 명령형 API
554
+ // ✅ 권장: 명령형 API
401
555
  const ref = useRef<MarkdownCMDRef>(null);
402
556
  useEffect(() => {
403
557
  ref.current?.push(newChunk, 'answer');
@@ -405,97 +559,30 @@ useEffect(() => {
405
559
 
406
560
  // ❌ 피하기: 빈번한 children 업데이트
407
561
  const [content, setContent] = useState('');
408
- // 각 업데이트마다 전체 콘텐츠를 다시 파싱
562
+ // 각 업데이트마다 전체 내용을 재분석
409
563
  ```
410
564
 
411
- ### 3. 타입 안전성
565
+ ### 3. 수학 공식 최적화
412
566
 
413
567
  ```tsx
414
- import { MarkdownCMDRef } from 'ds-markdown';
415
-
416
- const ref = useRef<MarkdownCMDRef>(null);
417
- // 완전한 TypeScript 타입 힌트
418
- ```
419
-
420
- ### 4. 스타일 커스터마이징
421
-
422
- ```css
423
- /* 사고 영역 스타일 */
424
- .ds-markdown-thinking {
425
- background: rgba(255, 193, 7, 0.1);
426
- border-left: 3px solid #ffc107;
427
- padding: 12px;
428
- border-radius: 6px;
429
- margin: 8px 0;
430
- }
431
-
432
- /* 답변 영역 스타일 */
433
- .ds-markdown-answer {
434
- color: #333;
435
- line-height: 1.6;
436
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
437
- }
438
-
439
- /* 코드 블록 스타일 */
440
- .ds-markdown pre {
441
- background: #f8f9fa;
442
- border-radius: 8px;
443
- padding: 16px;
444
- overflow-x: auto;
445
- }
568
+ // 권장: 필요시 수학 공식 스타일 로드
569
+ import 'ds-markdown/style.css';
570
+ import 'ds-markdown/katex.css'; // 필요할 때만 가져오기
446
571
 
447
- /* 테이블 스타일 */
448
- .ds-markdown-table {
449
- border-collapse: collapse;
450
- width: 100%;
451
- margin: 16px 0;
452
- }
572
+ // 권장: 적절한 구분자 사용
573
+ // 간단한 공식에는 $...$가 더 간결
574
+ // 복잡한 공식에는 $$...$$가 더 명확
453
575
 
454
- .ds-markdown-table th,
455
- .ds-markdown-table td {
456
- border: 1px solid #ddd;
457
- padding: 8px 12px;
458
- text-align: left;
459
- }
576
+ // ✅ 권장: 플러그인 구성
577
+ import { katexPlugin } from 'ds-markdown/plugins';
578
+ <DsMarkdown plugins={[katexPlugin]}>수학 공식 내용</DsMarkdown>;
460
579
  ```
461
580
 
462
- ---
463
-
464
- ## 🌐 호환성
465
-
466
- | 환경 | 버전 요구사항 | 설명 |
467
- | -------------- | ----------------------------------- | --------------------- |
468
- | **React** | 16.8.0+ | Hooks 지원 필요 |
469
- | **TypeScript** | 4.0+ | 선택사항, 하지만 추천 |
470
- | **브라우저** | Chrome 60+, Firefox 55+, Safari 12+ | 모던 브라우저 |
471
- | **Node.js** | 14.0+ | 빌드 환경 |
472
-
473
- ---
474
-
475
- ## 🤝 기여 가이드
476
-
477
- Issue와 Pull Request 제출을 환영합니다!
581
+ ### 4. 타입 안전성
478
582
 
479
- 1. 이 리포지토리 포크
480
- 2. 기능 브랜치 생성: `git checkout -b feature/amazing-feature`
481
- 3. 변경사항 커밋: `git commit -m 'Add amazing feature'`
482
- 4. 브랜치 푸시: `git push origin feature/amazing-feature`
483
- 5. Pull Request 제출
484
-
485
- ---
486
-
487
- ## 📄 라이선스
488
-
489
- MIT © [onshinpei](https://github.com/onshinpei)
490
-
491
- ---
583
+ ```tsx
584
+ import { MarkdownCMDRef } from 'ds-markdown';
492
585
 
493
- <div align="center">
494
- <strong>이 프로젝트가 도움이 되었다면, ⭐️ Star로 지원해주세요!</strong>
495
-
496
- <br><br>
497
-
498
- [🐛 문제 보고](https://github.com/onshinpei/ds-markdown/issues) |
499
- [💡 기능 제안](https://github.com/onshinpei/ds-markdown/issues) |
500
- [📖 문서 보기](https://onshinpei.github.io/ds-markdown/)
501
- </div>
586
+ const ref = useRef<MarkdownCMDRef>(null);
587
+ // 완전한 TypeScript 타입 힌트
588
+ ```