svelte-streamdown 2.3.0 → 2.3.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.md +1 -5
- package/dist/Streamdown.svelte +0 -10
- package/dist/context.svelte.d.ts +1 -1
- package/dist/context.svelte.js +4 -1
- package/dist/marked/marked-math.js +62 -12
- package/dist/theme.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -273,7 +273,7 @@ The animation system works by:
|
|
|
273
273
|
|
|
274
274
|
### Animation Types
|
|
275
275
|
|
|
276
|
-
Choose from
|
|
276
|
+
Choose from 4 distinct animation styles:
|
|
277
277
|
|
|
278
278
|
#### `fade`
|
|
279
279
|
|
|
@@ -283,10 +283,6 @@ A clean fade-in effect where text smoothly appears from transparent to opaque.
|
|
|
283
283
|
|
|
284
284
|
Text starts slightly blurred and comes into focus while fading in, creating a smooth reveal effect.
|
|
285
285
|
|
|
286
|
-
#### `typewriter`
|
|
287
|
-
|
|
288
|
-
A typewriter effect where text appears character by character, mimicking the look of someone typing.
|
|
289
|
-
|
|
290
286
|
#### `slideUp`
|
|
291
287
|
|
|
292
288
|
Text slides up from below while fading in, creating a dynamic upward motion.
|
package/dist/Streamdown.svelte
CHANGED
package/dist/context.svelte.d.ts
CHANGED
|
@@ -105,7 +105,7 @@ export type StreamdownProps = {
|
|
|
105
105
|
animation?: {
|
|
106
106
|
animateOnMount?: boolean;
|
|
107
107
|
enabled?: boolean;
|
|
108
|
-
type?: 'fade' | 'blur' | '
|
|
108
|
+
type?: 'fade' | 'blur' | 'slideUp' | 'slideDown';
|
|
109
109
|
duration?: number;
|
|
110
110
|
timingFunction?: 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
|
|
111
111
|
tokenize?: 'word' | 'char';
|
package/dist/context.svelte.js
CHANGED
|
@@ -10,7 +10,10 @@ export class StreamdownContext {
|
|
|
10
10
|
animation-duration: ${this.animation.duration}ms;
|
|
11
11
|
animation-timing-function: ${this.animation.timingFunction};
|
|
12
12
|
animation-iteration-count: 1;
|
|
13
|
-
animation-fill-mode: forwards
|
|
13
|
+
animation-fill-mode: forwards;
|
|
14
|
+
white-space: pre-wrap;
|
|
15
|
+
display: inline-block;
|
|
16
|
+
text-decoration: inherit;`
|
|
14
17
|
: undefined);
|
|
15
18
|
animationBlockStyle = $derived(this.animation.enabled
|
|
16
19
|
? `animation-name: sd-${this.animation.type};
|
|
@@ -4,6 +4,17 @@ const blockRule = /^(\$\$)(?:\n((?:\\[\s\S]|[^\\])+?)\n\1(?:\n|$)|([^$\n]+?)\1(?
|
|
|
4
4
|
// Inline math: handles both single ($) and double ($$) dollar delimiters
|
|
5
5
|
// Avoids matching currency by checking context and requiring proper content
|
|
6
6
|
const inlineRule = /^(\${1,2})(?!\$)((?:[^$\n]|\\\$)*?)\1(?!\d)/;
|
|
7
|
+
// Enhanced currency detection patterns
|
|
8
|
+
const currencyPatterns = {
|
|
9
|
+
// Simple price patterns: $123, $123.45, $1,234.56
|
|
10
|
+
simplePrice: /^\d{1,3}(?:,\d{3})*(?:\.\d{2})?$/,
|
|
11
|
+
// Multiple prices or numbers: "123, 456", "123.45, 678.90", "123 or 456"
|
|
12
|
+
multipleNumbers: /^\d+(?:[.,]\d+)*(?:\s*[,;]\s*\d+(?:[.,]\d+)*)+$/,
|
|
13
|
+
// Price ranges: "123-456", "123 - 456", "123 to 456"
|
|
14
|
+
priceRange: /^\d+(?:\.\d{2})?\s*(?:-|to|or)\s*\d+(?:\.\d{2})?$/i,
|
|
15
|
+
// Common currency words nearby (check surrounding context)
|
|
16
|
+
currencyContext: /(?:price|cost|dollar|euro|pound|yen|currency|pay|buy|sell|expensive|cheap)/i
|
|
17
|
+
};
|
|
7
18
|
export function markedMath() {
|
|
8
19
|
return {
|
|
9
20
|
extensions: [
|
|
@@ -40,11 +51,18 @@ export function markedMath() {
|
|
|
40
51
|
const possibleMath = src.substring(currentIndex);
|
|
41
52
|
// Check if this could be math (not currency)
|
|
42
53
|
if (possibleMath.match(inlineRule)) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
const match = possibleMath.match(inlineRule);
|
|
55
|
+
if (match) {
|
|
56
|
+
const content = match[2];
|
|
57
|
+
const dollarCount = match[1]; // '$' or '$$'
|
|
58
|
+
// Only apply currency detection to single dollars
|
|
59
|
+
// Double dollars ($$) indicate explicit math intent
|
|
60
|
+
if (dollarCount === '$' && isCurrencyPattern(content, src, currentIndex)) {
|
|
61
|
+
// This looks like currency with single dollars, skip it
|
|
62
|
+
index += dollarIndex + 1;
|
|
63
|
+
searchSrc = src.substring(index);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
48
66
|
return currentIndex;
|
|
49
67
|
}
|
|
50
68
|
}
|
|
@@ -55,18 +73,19 @@ export function markedMath() {
|
|
|
55
73
|
tokenizer(src) {
|
|
56
74
|
const match = src.match(inlineRule);
|
|
57
75
|
if (match) {
|
|
58
|
-
// Additional validation: avoid currency patterns
|
|
59
76
|
const content = match[2];
|
|
60
|
-
|
|
61
|
-
|
|
77
|
+
const dollarCount = match[1]; // '$' or '$$'
|
|
78
|
+
const isDisplayMode = dollarCount === '$$';
|
|
79
|
+
// Only apply currency detection to single dollars
|
|
80
|
+
// Double dollars ($$) indicate explicit math intent
|
|
81
|
+
if (dollarCount === '$' && isCurrencyPattern(content, src, 0)) {
|
|
82
|
+
// This looks like currency with single dollars, skip it
|
|
62
83
|
return;
|
|
63
84
|
}
|
|
64
|
-
// Double dollars are display mode, single dollars are inline
|
|
65
|
-
const isDisplayMode = match[1] === '$$';
|
|
66
85
|
return {
|
|
67
86
|
type: 'math',
|
|
68
|
-
isInline:
|
|
69
|
-
displayMode: isDisplayMode,
|
|
87
|
+
isInline: true, // Inline tokenizer always produces inline math
|
|
88
|
+
displayMode: isDisplayMode, // $$ = display mode styling, $ = inline styling
|
|
70
89
|
raw: match[0],
|
|
71
90
|
text: content.trim()
|
|
72
91
|
};
|
|
@@ -76,3 +95,34 @@ export function markedMath() {
|
|
|
76
95
|
]
|
|
77
96
|
};
|
|
78
97
|
}
|
|
98
|
+
// Helper function to detect currency patterns
|
|
99
|
+
function isCurrencyPattern(content, fullSrc, dollarIndex) {
|
|
100
|
+
const trimmedContent = content.trim();
|
|
101
|
+
// Check for simple price patterns
|
|
102
|
+
if (currencyPatterns.simplePrice.test(trimmedContent)) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
// Check for multiple numbers/prices pattern (like "199, 199")
|
|
106
|
+
if (currencyPatterns.multipleNumbers.test(trimmedContent)) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
// Check for price ranges
|
|
110
|
+
if (currencyPatterns.priceRange.test(trimmedContent)) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
// Check surrounding context for currency-related words
|
|
114
|
+
const contextStart = Math.max(0, dollarIndex - 50);
|
|
115
|
+
const contextEnd = Math.min(fullSrc.length, dollarIndex + content.length + 50);
|
|
116
|
+
const context = fullSrc.substring(contextStart, contextEnd);
|
|
117
|
+
if (currencyPatterns.currencyContext.test(context)) {
|
|
118
|
+
// If currency context is found and content is purely numeric, likely currency
|
|
119
|
+
if (/^\d+(?:[.,]\d+)*$/.test(trimmedContent)) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Additional check: if content is just numbers with common currency formatting
|
|
124
|
+
if (/^\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?$/.test(trimmedContent)) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
package/dist/theme.js
CHANGED
|
@@ -121,7 +121,7 @@ export const theme = {
|
|
|
121
121
|
base: 'italic'
|
|
122
122
|
},
|
|
123
123
|
del: {
|
|
124
|
-
base: '
|
|
124
|
+
base: 'text-gray-600'
|
|
125
125
|
},
|
|
126
126
|
footnoteRef: {
|
|
127
127
|
base: 'text-gray-600 px-1 py-0.5 rounded-md bg-gray-100/80'
|
|
@@ -250,7 +250,7 @@ export const shadcnTheme = {
|
|
|
250
250
|
base: 'italic text-foreground'
|
|
251
251
|
},
|
|
252
252
|
del: {
|
|
253
|
-
base: '
|
|
253
|
+
base: 'text-muted-foreground'
|
|
254
254
|
},
|
|
255
255
|
footnoteRef: {
|
|
256
256
|
base: 'text-muted-foreground px-1 text-sm inline-block rounded-full bg-muted/80 aspect-square border border-border'
|