ds-markdown 0.0.14 → 0.0.15-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.en.md CHANGED
@@ -38,6 +38,7 @@ A React component designed specifically for modern AI applications, providing sm
38
38
  - High-frequency typing support (`requestAnimationFrame` mode supports typing intervals as low as `0ms`)
39
39
  - Frame-synchronized rendering, perfectly matching browser 60fps
40
40
  - Smart character batch processing for more natural visual effects
41
+ - Support for typing interruption `stop` and resume `resume`
41
42
 
42
43
  ### 🔧 **Flexible and Easy to Use**
43
44
 
@@ -45,6 +46,13 @@ A React component designed specifically for modern AI applications, providing sm
45
46
  - **Imperative API**: Suitable for streaming data, better performance
46
47
  - **Native TypeScript support**: Complete type hints
47
48
 
49
+ ### 🧮 **Mathematical Formula Support**
50
+
51
+ - **KaTeX Integration**: High-performance mathematical formula rendering
52
+ - **Dual Syntax Support**: `$...$` and `\[...\]` delimiters
53
+ - **Streaming Compatible**: Perfect support for mathematical formulas in typing animations
54
+ - **Theme Adaptation**: Automatic adaptation to light/dark themes
55
+
48
56
  ---
49
57
 
50
58
  ## 📦 Quick Installation
@@ -64,39 +72,16 @@ pnpm add ds-markdown
64
72
 
65
73
  No installation required, use directly in browser:
66
74
 
75
+ [DEMO](https://stackblitz.com/edit/stackblitz-starters-7vcclcw7?file=index.html)
76
+
67
77
  ```html
68
78
  <!-- Import styles -->
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
  <!-- Import component -->
72
- <script type="importmap">
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
- This is a **high-performance** typing animation component!
91
-
92
- ## Features
93
- - ⚡ Zero-delay streaming
94
- - 🎬 Smooth typing animation
95
- - 🎯 Perfect syntax support
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 @@ This is a **high-performance** typing animation component!
104
89
 
105
90
  ### Basic Usage
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
+ ### Mathematical Formula Support
108
+
109
+ ```tsx
110
+ import DsMarkdown from 'ds-markdown';
111
+ import 'ds-markdown/style.css';
112
+ import 'ds-markdown/katex.css'; // Import mathematical formula styles
113
+
114
+ function MathDemo() {
115
+ return (
116
+ <DsMarkdown interval={20} answerType="answer" math={{ isOpen: true, splitSymbol: 'dollar' }}>
117
+ # Pythagorean Theorem In a right triangle, the square of the hypotenuse equals the sum of squares of the two legs: $a^2 + b^2 = c^2$ Where: - $a$ and $b$ are the legs - $c$ is the hypotenuse For
118
+ the classic "3-4-5" triangle: $c = \sqrt{3 ^ (2 + 4) ^ 2} = \sqrt{25} = 5$
119
+ </DsMarkdown>
120
+ );
121
+ }
122
+ ```
123
+
120
124
  ### AI Conversation Scenario
121
125
 
122
126
  ```tsx
@@ -173,21 +177,24 @@ Let's explore these new features together!`);
173
177
  | `timerType` | `'setTimeout'` \| `'requestAnimationFrame'` | Timer type | Current default is `setTimeout`, will change to `requestAnimationFrame` later |
174
178
  | `answerType` | `'thinking'` \| `'answer'` | Content type (affects style theme) | `'answer'` |
175
179
  | `theme` | `'light'` \| `'dark'` | Theme type | `'light'` |
180
+ | `math` | `IMarkdownMath` | Mathematical formula configuration | `{ isOpen: false, splitSymbol: 'dollar' }` |
176
181
  | `onEnd` | `(data: EndData) => void` | Typing completion callback | - |
177
182
  | `onStart` | `(data: StartData) => void` | Typing start callback | - |
178
183
  | `onTypedChar` | `(data: CharData) => void` | Per-character typing callback | - |
179
184
 
180
- ### Imperative API (Recommended for Streaming Scenarios)
185
+ ### Mathematical Formula Configuration
181
186
 
182
- ```typescript
183
- import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
187
+ | Property | Type | Description | Default |
188
+ | ------------- | ------------------------- | ------------------------------------- | ---------- |
189
+ | `isOpen` | `boolean` | Enable mathematical formula rendering | `false` |
190
+ | `splitSymbol` | `'dollar'` \| `'bracket'` | Mathematical formula delimiter type | `'dollar'` |
184
191
 
185
- interface MarkdownCMDRef {
186
- push: (content: string, answerType: AnswerType) => void;
187
- clear: () => void;
188
- triggerWholeEnd: () => void;
189
- }
190
- ```
192
+ **Delimiter Description:**
193
+
194
+ - `'dollar'`: Use `$...$` and `$$...$$` syntax
195
+ - `'bracket'`: Use `\(...\)` and `\[...\]` syntax
196
+
197
+ ### Imperative API (Recommended for Streaming Scenarios)
191
198
 
192
199
  | Method | Parameters | Description |
193
200
  | ----------------- | ------------------------------------------- | ----------------------------- |
@@ -206,16 +213,91 @@ markdownRef.current?.resume(); // Resume animation
206
213
 
207
214
  ---
208
215
 
209
- ## 🎛️ Timer Mode Detailed Explanation
216
+ ## 🧮 Mathematical Formula Usage Guide
217
+
218
+ ### Basic Syntax
219
+
220
+ ```tsx
221
+ // 1. Enable mathematical formula support
222
+ <DsMarkdown math={{ isOpen: true }}>
223
+ # Mathematical Formula Example
224
+
225
+ // Inline formula
226
+ This is an inline formula: $E = mc^2$
227
+
228
+ // Block formula
229
+ $$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
230
+ </DsMarkdown>
231
+ ```
232
+
233
+ ### Delimiter Selection
234
+
235
+ ```tsx
236
+ // Use dollar symbol delimiters (default)
237
+ <DsMarkdown math={{ isOpen: true, splitSymbol: 'dollar' }}>
238
+ Inline: $a + b = c$
239
+ Block: $$\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n$$
240
+ </DsMarkdown>
241
+
242
+ // Use bracket delimiters
243
+ <DsMarkdown math={{ isOpen: true, splitSymbol: 'bracket' }}>
244
+ Inline: \(a + b = c\)
245
+ Block: \[\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n\]
246
+ </DsMarkdown>
247
+ ```
248
+
249
+ ### Streaming Mathematical Formulas
250
+
251
+ ```tsx
252
+ // Perfect support for mathematical formulas in streaming output
253
+ const mathContent = [
254
+ 'Pythagorean Theorem: ',
255
+ '$a^2 + b^2 = c^2$',
256
+ '\n\n',
257
+ 'Where:\n',
258
+ '- $a$ and $b$ are the legs\n',
259
+ '- $c$ is the hypotenuse\n\n',
260
+ 'For the classic "3-4-5" triangle:\n',
261
+ '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
262
+ 'This theorem has wide applications in geometry!',
263
+ ];
264
+
265
+ mathContent.forEach((chunk) => {
266
+ markdownRef.current?.push(chunk, 'answer');
267
+ });
268
+ ```
269
+
270
+ ### Style Customization
271
+
272
+ ```css
273
+ /* Mathematical formula style customization */
274
+ .katex {
275
+ font-size: 1.1em;
276
+ }
277
+
278
+ .katex-display {
279
+ margin: 1em 0;
280
+ text-align: center;
281
+ }
282
+
283
+ /* Dark theme adaptation */
284
+ [data-theme='dark'] .katex {
285
+ color: #e1e1e1;
286
+ }
287
+ ```
288
+
289
+ ---
290
+
291
+ ## 🎛️ Timer Mode Details
210
292
 
211
293
  ### `requestAnimationFrame` Mode 🌟 (Recommended)
212
294
 
213
295
  ```typescript
214
296
  // 🎯 Features
215
297
  - Time-driven: Calculate character count based on actual elapsed time
216
- - Batch processing: Can process multiple characters within a single frame
217
- - Frame-synchronized: Synchronized with browser 60fps refresh rate
218
- - High-frequency optimized: Perfect support for interval < 16ms high-speed typing
298
+ - Batch processing: Can process multiple characters per frame
299
+ - Frame synchronization: Synchronized with browser 60fps refresh rate
300
+ - High-frequency optimization: Perfect support for high-speed typing with interval < 16ms
219
301
 
220
302
  // 🎯 Use Cases
221
303
  - Default choice for modern web applications
@@ -228,9 +310,9 @@ markdownRef.current?.resume(); // Resume animation
228
310
 
229
311
  ```typescript
230
312
  // 🎯 Features
231
- - Single character: Precisely processes one character at a time
232
- - Fixed interval: Executes strictly according to set time
233
- - Rhythmic feel: Classic typewriter rhythm
313
+ - Single character: Process exactly one character each time
314
+ - Fixed interval: Execute strictly according to set time
315
+ - Beat feeling: Classic typewriter rhythm
234
316
  - Precise control: Suitable for specific timing requirements
235
317
 
236
318
  // 🎯 Use Cases
@@ -241,15 +323,15 @@ markdownRef.current?.resume(); // Resume animation
241
323
 
242
324
  ### 📊 Performance Comparison
243
325
 
244
- | Feature | requestAnimationFrame | setTimeout |
245
- | --------------------------- | ----------------------------------------- | ------------------------------- |
246
- | **Character Processing** | Can process multiple characters per frame | Process one character at a time |
247
- | **High-frequency Interval** | ✅ Excellent (5ms → 3 chars per frame) | ❌ May lag |
248
- | **Low-frequency Interval** | ✅ Normal (100ms → 1 char after 6 frames) | ✅ Precise |
249
- | **Visual Effect** | 🎬 Smooth animation feel | ⚡ Precise rhythmic feel |
250
- | **Performance Overhead** | 🟢 Low (frame-synchronized) | 🟡 Medium (timer) |
326
+ | Feature | requestAnimationFrame | setTimeout |
327
+ | --------------------------- | ---------------------------------------------- | ------------------------------- |
328
+ | **Character Processing** | Can process multiple characters per frame | Process one character each time |
329
+ | **High-frequency Interval** | ✅ Excellent (5ms → 3 characters per frame) | ❌ May lag |
330
+ | **Low-frequency Interval** | ✅ Normal (100ms → 1 character after 6 frames) | ✅ Precise |
331
+ | **Visual Effect** | 🎬 Smooth animation feeling | ⚡ Precise beat feeling |
332
+ | **Performance Overhead** | 🟢 Low (frame synchronization) | 🟡 Medium (timer) |
251
333
 
252
- High-frequency recommends `requestAnimationFrame`, low-frequency recommends `setTimeout`
334
+ High-frequency recommended `requestAnimationFrame`, low-frequency recommended `setTimeout`
253
335
 
254
336
  ---
255
337
 
@@ -257,7 +339,7 @@ High-frequency recommends `requestAnimationFrame`, low-frequency recommends `set
257
339
 
258
340
  ### 📝 AI Streaming Conversation
259
341
 
260
- [DEMO: 🔧 StackBlitz 体验](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
342
+ [DEMO: 🔧 StackBlitz Experience](https://stackblitz.com/edit/vitejs-vite-2ri8kex3?file=src%2FApp.tsx)
261
343
 
262
344
  ````tsx
263
345
  import { useRef } from 'react';
@@ -273,7 +355,7 @@ function StreamingChat() {
273
355
  // Thinking phase
274
356
  markdownRef.current?.push('🤔 Analyzing your question...', 'thinking');
275
357
  await delay(1000);
276
- markdownRef.current?.push('\n\n✅ Analysis complete, starting answer', 'thinking');
358
+ markdownRef.current?.push('\n\n✅ Analysis complete, starting to answer', 'thinking');
277
359
 
278
360
  // Streaming answer
279
361
  const chunks = [
@@ -282,7 +364,7 @@ function StreamingChat() {
282
364
  'The biggest highlight of React 19 is the introduction of **React Compiler**:\n\n',
283
365
  '- 🎯 **Automatic Optimization**: No need for manual memo and useMemo\n',
284
366
  '- ⚡ **Performance Boost**: Compile-time optimization, zero runtime overhead\n',
285
- '- 🔧 **Backward Compatible**: Existing code needs no modification\n\n',
367
+ '- 🔧 **Backward Compatible**: No need to modify existing code\n\n',
286
368
  '## 📝 Actions Simplify Forms\n',
287
369
  'The new Actions API makes form handling simpler:\n\n',
288
370
  '```tsx\n',
@@ -307,9 +389,9 @@ function StreamingChat() {
307
389
 
308
390
  return (
309
391
  <div className="chat-container">
310
- <button onClick={simulateAIResponse}>🤖 Ask About React 19 Features</button>
392
+ <button onClick={simulateAIResponse}>🤖 Ask about React 19 New Features</button>
311
393
 
312
- <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('Paragraph completed:', data)} />
394
+ <MarkdownCMD ref={markdownRef} interval={10} timerType="requestAnimationFrame" onEnd={(data) => console.log('Paragraph complete:', data)} />
313
395
  </div>
314
396
  );
315
397
  }
@@ -317,37 +399,74 @@ function StreamingChat() {
317
399
  const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
318
400
  ````
319
401
 
402
+ ### 🧮 Mathematical Formula Streaming Rendering
403
+
404
+ ```tsx
405
+ function MathStreamingDemo() {
406
+ const markdownRef = useRef<MarkdownCMDRef>(null);
407
+
408
+ const simulateMathResponse = async () => {
409
+ markdownRef.current?.clear();
410
+
411
+ const mathChunks = [
412
+ '# Pythagorean Theorem Explanation\n\n',
413
+ 'In a right triangle, the square of the hypotenuse equals the sum of squares of the two legs:\n\n',
414
+ '$a^2 + b^2 = c^2$\n\n',
415
+ 'Where:\n',
416
+ '- $a$ and $b$ are the legs\n',
417
+ '- $c$ is the hypotenuse\n\n',
418
+ 'For the classic "3-4-5" triangle:\n',
419
+ '$c = \\sqrt{3^2 + 4^2} = \\sqrt{25} = 5$\n\n',
420
+ 'This theorem has wide applications in geometry!',
421
+ ];
422
+
423
+ for (const chunk of mathChunks) {
424
+ await delay(150);
425
+ markdownRef.current?.push(chunk, 'answer');
426
+ }
427
+ };
428
+
429
+ return (
430
+ <div>
431
+ <button onClick={simulateMathResponse}>📐 Explain Pythagorean Theorem</button>
432
+
433
+ <MarkdownCMD ref={markdownRef} interval={20} timerType="requestAnimationFrame" math={{ isOpen: true, splitSymbol: 'dollar' }} />
434
+ </div>
435
+ );
436
+ }
437
+ ```
438
+
320
439
  ### 🔄 Streaming Markdown Syntax Processing
321
440
 
322
- **Core Issue**: During streaming output, incomplete Markdown syntax can cause rendering errors
441
+ **Core Problem**: Incomplete Markdown syntax during streaming output can cause rendering errors
323
442
 
324
443
  ```tsx
325
- // 🚨 Problem Scenario
444
+ // 🚨 Problem scenario
326
445
  push('#'); // "# "
327
446
  push(' '); // "# "
328
447
  push('Title'); // "# Title"
329
448
  push('\n'); // "# Title\n"
330
- push('1'); // "# Title\n1" ← This will be misinterpreted as paragraph
449
+ push('1'); // "# Title\n1" ← This will be incorrectly parsed as paragraph
331
450
  push('.'); // "# Title\n1." ← Forms correct list
332
451
  push(' Item'); // "# Title\n1. Item"
333
452
  ```
334
453
 
335
- **✅ Smart Solution**: Built-in synchronous buffering mechanism in component
454
+ **✅ Smart Solution**: Built-in synchronous buffering mechanism
336
455
 
337
456
  ```tsx
338
457
  // Component intelligently handles syntax boundaries
339
458
  const handleStreamingMarkdown = () => {
340
- const chunks = ['#', ' ', 'Using', 'Skills', '\n', '1', '.', ' ', 'Skill1', '\n', '2', '.', ' Skill2'];
459
+ const chunks = ['#', ' ', 'Use', 'Skills', '\n', '1', '.', ' ', 'Skill1', '\n', '2', '.', ' Skill2'];
341
460
 
342
461
  chunks.forEach((chunk) => {
343
462
  markdownRef.current?.push(chunk, 'answer');
344
- // No delay needed, component buffers intelligently internally
463
+ // No delay needed, component internally buffers intelligently
345
464
  });
346
465
  };
347
466
 
348
- // 🧠 Smart Processing Flow:
349
- // 1. Real-time detection of "# Using Skills\n1" incomplete syntax
350
- // 2. Smart buffering, waiting for more characters
467
+ // 🧠 Intelligent processing flow:
468
+ // 1. Real-time detection of incomplete syntax like "# Use Skills\n1"
469
+ // 2. Intelligent buffering, waiting for more characters
351
470
  // 3. Process immediately after receiving "." to form "1."
352
471
  // 4. Zero delay, pure synchronous processing
353
472
  ```
@@ -355,7 +474,7 @@ const handleStreamingMarkdown = () => {
355
474
  **Supported Syntax Detection**:
356
475
 
357
476
  ````typescript
358
- // ✅ Complete syntax (process immediately)
477
+ // ✅ Complete syntax (immediate processing)
359
478
  '## Title'; // Complete title
360
479
  '1. List item'; // Complete list item
361
480
  '- Item'; // Complete unordered list
@@ -363,11 +482,14 @@ const handleStreamingMarkdown = () => {
363
482
  '```javascript'; // Code block start
364
483
  '```'; // Code block end
365
484
  'Content ending with newline\n'; // Newline boundary
485
+ '$a + b$'; // Complete mathematical formula
486
+ '$$\\sum x$$'; // Complete block mathematical formula
366
487
 
367
- // 🔄 Incomplete syntax (smart buffering)
368
- '##'; // Only title symbols
488
+ // 🔄 Incomplete syntax (intelligent buffering)
489
+ '##'; // Only title symbol
369
490
  '1'; // Only number
370
491
  '```java'; // Possible code block start
492
+ '$a +'; // Incomplete mathematical formula
371
493
  ````
372
494
 
373
495
  ---
@@ -380,7 +502,7 @@ const handleStreamingMarkdown = () => {
380
502
  // ✅ Recommended configuration
381
503
  <DsMarkdown
382
504
  timerType="requestAnimationFrame"
383
- interval={15} // 15-30ms for optimal experience
505
+ interval={15} // 15-30ms for best experience
384
506
  />
385
507
 
386
508
  // ❌ Avoid too small intervals
@@ -401,7 +523,22 @@ const [content, setContent] = useState('');
401
523
  // Each update will re-parse the entire content
402
524
  ```
403
525
 
404
- ### 3. Type Safety
526
+ ### 3. Mathematical Formula Optimization
527
+
528
+ ```tsx
529
+ // ✅ Recommended: Load mathematical formula styles on demand
530
+ import 'ds-markdown/style.css';
531
+ import 'ds-markdown/katex.css'; // Only import when needed
532
+
533
+ // ✅ Recommended: Reasonable use of delimiters
534
+ // For simple formulas, use $...$ for conciseness
535
+ // For complex formulas, use $$...$$ for clarity
536
+
537
+ // ❌ Avoid: Enable mathematical formulas when not needed
538
+ <DsMarkdown math={{ isOpen: true }}>Plain text content</DsMarkdown>;
539
+ ```
540
+
541
+ ### 4. Type Safety
405
542
 
406
543
  ```tsx
407
544
  import { MarkdownCMDRef } from 'ds-markdown';
@@ -410,7 +547,7 @@ const ref = useRef<MarkdownCMDRef>(null);
410
547
  // Complete TypeScript type hints
411
548
  ```
412
549
 
413
- ### 4. Style Customization
550
+ ### 5. Style Customization
414
551
 
415
552
  ```css
416
553
  /* Thinking area styles */
@@ -450,22 +587,37 @@ const ref = useRef<MarkdownCMDRef>(null);
450
587
  padding: 8px 12px;
451
588
  text-align: left;
452
589
  }
590
+
591
+ /* Mathematical formula styles */
592
+ .katex {
593
+ font-size: 1.1em;
594
+ }
595
+
596
+ .katex-display {
597
+ margin: 1em 0;
598
+ text-align: center;
599
+ }
600
+
601
+ /* Dark theme mathematical formulas */
602
+ [data-theme='dark'] .katex {
603
+ color: #e1e1e1;
604
+ }
453
605
  ```
454
606
 
455
607
  ---
456
608
 
457
609
  ## 🌐 Compatibility
458
610
 
459
- | Environment | Version Requirement | Description |
460
- | -------------- | ----------------------------------- | ------------------------- |
461
- | **React** | 16.8.0+ | Requires Hooks support |
462
- | **TypeScript** | 4.0+ | Optional, but recommended |
463
- | **Browser** | Chrome 60+, Firefox 55+, Safari 12+ | Modern browsers |
464
- | **Node.js** | 14.0+ | Build environment |
611
+ | Environment | Version Requirement | Description |
612
+ | -------------- | ----------------------------------- | ------------------------ |
613
+ | **React** | 16.8.0+ | Requires Hooks support |
614
+ | **TypeScript** | 4.0+ | Optional but recommended |
615
+ | **Browser** | Chrome 60+, Firefox 55+, Safari 12+ | Modern browsers |
616
+ | **Node.js** | 14.0+ | Build environment |
465
617
 
466
618
  ---
467
619
 
468
- ## 🤝 Contributing Guide
620
+ ## 🤝 Contributing
469
621
 
470
622
  Welcome to submit Issues and Pull Requests!
471
623
 
@@ -484,7 +636,7 @@ MIT © [onshinpei](https://github.com/onshinpei)
484
636
  ---
485
637
 
486
638
  <div align="center">
487
- <strong>If this project helps you, please give it a ⭐️ Star for support!</strong>
639
+ <strong>If this project helps you, please give it a ⭐️ Star!</strong>
488
640
 
489
641
  <br><br>
490
642