@antdv-next/x-markdown 0.1.4 → 0.3.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/dist/XMarkdown/components/AnimationText.vue.d.ts +6 -0
- package/dist/XMarkdown/components/AnimationText.vue_vue_type_script_setup_true_lang.js +58 -2
- package/dist/XMarkdown/components/Section.js +5 -0
- package/dist/XMarkdown/components/Section.vue.d.ts +76 -0
- package/dist/XMarkdown/components/Section.vue_vue_type_script_lang.js +54 -0
- package/dist/XMarkdown/composables/index.d.ts +2 -1
- package/dist/XMarkdown/composables/index.js +3 -2
- package/dist/XMarkdown/composables/useStreaming.d.ts +37 -1
- package/dist/XMarkdown/composables/useStreaming.js +449 -34
- package/dist/XMarkdown/composables/useTypewriter.d.ts +11 -0
- package/dist/XMarkdown/composables/useTypewriter.js +378 -0
- package/dist/XMarkdown/core/Parser.d.ts +15 -0
- package/dist/XMarkdown/core/Parser.js +42 -14
- package/dist/XMarkdown/core/VueRenderer.js +16 -9
- package/dist/XMarkdown/core/detectUnclosedComponentTags.d.ts +12 -0
- package/dist/XMarkdown/core/detectUnclosedComponentTags.js +240 -6
- package/dist/XMarkdown/core/index.js +1 -1
- package/dist/XMarkdown/index.d.ts +6 -2
- package/dist/XMarkdown/index.js +5 -3
- package/dist/XMarkdown/index.vue.d.ts +1 -1
- package/dist/XMarkdown/index.vue_vue_type_script_setup_true_lang.js +64 -30
- package/dist/XMarkdown/interface.d.ts +241 -14
- package/dist/XMarkdown/utils/streaming.d.ts +6 -0
- package/dist/XMarkdown/utils/streaming.js +32 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -3
- package/package.json +2 -2
- package/plugins/Latex/index.js +8 -2
|
@@ -15,6 +15,8 @@ export interface FenceState {
|
|
|
15
15
|
inFenced: boolean;
|
|
16
16
|
fenceChar: string;
|
|
17
17
|
fenceLen: number;
|
|
18
|
+
/** Spaces before the fence run of the current line; a fence may be indented up to 3 */
|
|
19
|
+
lineIndent: number;
|
|
18
20
|
/** Leading `` ` ``/`~` run of the current (possibly incomplete) line */
|
|
19
21
|
lineFenceChar: string;
|
|
20
22
|
lineFenceLen: number;
|
|
@@ -22,25 +24,244 @@ export interface FenceState {
|
|
|
22
24
|
/** Whether every char after the leading run is whitespace (closing fences allow only whitespace) */
|
|
23
25
|
lineTailBlank: boolean;
|
|
24
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Incremental table-shape state over `pending`, updated in O(1) per character —
|
|
29
|
+
* the same trick FenceState already uses. Re-scanning the whole pending buffer
|
|
30
|
+
* on every character is O(N²), and a table stays pending until its terminating
|
|
31
|
+
* blank line, so a long table pays that cost in full.
|
|
32
|
+
*/
|
|
33
|
+
export interface TableState {
|
|
34
|
+
/** Number of '\n' seen in pending */
|
|
35
|
+
newlines: number;
|
|
36
|
+
/** Whether the previous character was '\n' (used to detect the '\n\n' terminator) */
|
|
37
|
+
lastWasNewline: boolean;
|
|
38
|
+
/** pending contains a blank line, i.e. the table block already ended */
|
|
39
|
+
hasBlankLine: boolean;
|
|
40
|
+
/** pending's first line — the header row */
|
|
41
|
+
firstLine: string;
|
|
42
|
+
/** pending's second line — the delimiter row; may still be growing */
|
|
43
|
+
secondLine: string;
|
|
44
|
+
/**
|
|
45
|
+
* Memoized header/delimiter verdict. Stays null while the delimiter row is
|
|
46
|
+
* still being streamed (the verdict can change as it grows) and is frozen
|
|
47
|
+
* once that row is terminated, after which it never changes again.
|
|
48
|
+
*/
|
|
49
|
+
shape: boolean | null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Incremental section-boundary state for `streaming.incremental`. A section
|
|
53
|
+
* boundary is an offset (into the input) where a new top-level block starts
|
|
54
|
+
* and everything before it can be parsed on its own with the same result as
|
|
55
|
+
* parsing the whole document. Only column-0 ATX headings qualify, and whether
|
|
56
|
+
* such a line really starts a top-level block is decided by lexing the current
|
|
57
|
+
* section with marked (`trackSectionBoundary`) — never by a hand-written model
|
|
58
|
+
* of marked's block grammar.
|
|
59
|
+
*/
|
|
60
|
+
export interface SectionState {
|
|
61
|
+
/** Offsets where a new section starts. The first section implicitly starts at 0. */
|
|
62
|
+
offsets: number[];
|
|
63
|
+
/** Offset of the first character of the line currently being streamed */
|
|
64
|
+
lineStart: number;
|
|
65
|
+
/**
|
|
66
|
+
* Set once a construct that can be referenced from another section has been
|
|
67
|
+
* seen (link reference / footnote definition). Splitting is disabled for the
|
|
68
|
+
* rest of the stream and any offsets recorded so far are discarded.
|
|
69
|
+
*/
|
|
70
|
+
noSplit: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Set once any line has carried the label terminator `]:`, the one thing
|
|
73
|
+
* every link reference / footnote definition contains. It is only a cheap
|
|
74
|
+
* gate that keeps the marked `links` probe off documents that cannot contain
|
|
75
|
+
* a definition; whether a definition really exists is marked's answer.
|
|
76
|
+
* Sticky, because a definition can complete arbitrarily far from its `]:`
|
|
77
|
+
* line — a title may span any number of lines, blank lines included — so
|
|
78
|
+
* there is no line count after which the question stops mattering.
|
|
79
|
+
*/
|
|
80
|
+
sawDefinitionTrigger: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Input length the last `links` probe ran on (-1 before the first). Re-running
|
|
83
|
+
* the same text (the pass is idempotent) must not pay for the same lex twice,
|
|
84
|
+
* and the probe itself only runs when a recorded boundary makes its answer
|
|
85
|
+
* matter — see `settleDefinition`.
|
|
86
|
+
*/
|
|
87
|
+
definitionCheckedLength: number;
|
|
88
|
+
/**
|
|
89
|
+
* An open raw block whose body may contain blank lines and heading-looking
|
|
90
|
+
* lines: `<pre>`/`<script>`/`<style>`/`<textarea>`, an HTML comment, a
|
|
91
|
+
* processing instruction, a declaration, CDATA, or `$$` / `\[` math. Its
|
|
92
|
+
* raw text is re-interpreted by the browser and DOMPurify (a `<?php` opens a
|
|
93
|
+
* bogus comment that can swallow a following `<h1>` open tag), so no
|
|
94
|
+
* boundary is recorded until it closes. `bodyChars` matters only for `exact`
|
|
95
|
+
* (`$$` math): the plugin's rule needs a non-empty body between the opener
|
|
96
|
+
* and its closing run.
|
|
97
|
+
*/
|
|
98
|
+
rawBlock: {
|
|
99
|
+
close: string;
|
|
100
|
+
exact: boolean;
|
|
101
|
+
bodyChars?: number;
|
|
102
|
+
} | null;
|
|
103
|
+
/**
|
|
104
|
+
* A memoised "the current section still ends inside an open block" verdict
|
|
105
|
+
* (marked lexed `text[sectionStart..end]` and a heading there would be
|
|
106
|
+
* swallowed). It keeps a long fenced code block full of column-0 `#` lines
|
|
107
|
+
* from being re-lexed once per line; the check re-runs once the prefix has
|
|
108
|
+
* grown by more than `OPEN_BLOCK_MEMO_CHARS` or the fence scanner's verdict
|
|
109
|
+
* changes. It belongs to the current section implicitly: `offsets` only
|
|
110
|
+
* changes together with clearing this field. `fenceCause` says the refusal
|
|
111
|
+
* came from an unclosed fenced code block, whose body blank lines do not end
|
|
112
|
+
* (marked's own last top-level token is a fenced `code` token) — only such a
|
|
113
|
+
* memo survives a blank line. Only refusals are stored — reusing a stale
|
|
114
|
+
* refusal loses a split, never invents one.
|
|
115
|
+
*/
|
|
116
|
+
openBlock: {
|
|
117
|
+
end: number;
|
|
118
|
+
fenceOpen: boolean;
|
|
119
|
+
fenceCause: boolean;
|
|
120
|
+
} | null;
|
|
121
|
+
}
|
|
25
122
|
export interface StreamCache {
|
|
26
123
|
pending: string;
|
|
27
124
|
token: StreamCacheTokenType;
|
|
28
125
|
processedLength: number;
|
|
29
126
|
completeMarkdown: string;
|
|
30
127
|
fence: FenceState;
|
|
128
|
+
table: TableState;
|
|
129
|
+
sections: SectionState;
|
|
130
|
+
}
|
|
131
|
+
export interface AnimationConfig {
|
|
132
|
+
/**
|
|
133
|
+
* @description 淡入动画的持续时间(毫秒)
|
|
134
|
+
* @description The duration of the fade-in animation in milliseconds
|
|
135
|
+
* @default 200
|
|
136
|
+
*/
|
|
137
|
+
fadeDuration?: number;
|
|
138
|
+
/**
|
|
139
|
+
* @description 动画的缓动函数
|
|
140
|
+
* @description Easing function for the animation
|
|
141
|
+
* @default 'ease-in-out'
|
|
142
|
+
*/
|
|
143
|
+
easing?: string;
|
|
144
|
+
/**
|
|
145
|
+
* @description 淡入的单位。`chunk` 每次新到的文本单独淡入;`sentence` 把新到的文本并入当前句子,到分隔符才开始下一个淡入单元。与 `typewriter` 同时使用时应选 `sentence`,否则每帧放出的几个字都会各自成为一个淡入节点
|
|
146
|
+
* @description Unit of the fade-in. `chunk` fades in each newly arrived piece of text on its own; `sentence` appends new text to the current sentence and starts a new fade-in unit only after a delimiter. Use `sentence` together with `typewriter`, otherwise every few characters revealed per frame become their own fade-in node
|
|
147
|
+
* @default 'chunk'
|
|
148
|
+
*/
|
|
149
|
+
splitBy?: "chunk" | "sentence";
|
|
150
|
+
/**
|
|
151
|
+
* @description `splitBy` 为 `sentence` 时的句子分隔符
|
|
152
|
+
* @description Sentence delimiters used when `splitBy` is `sentence`
|
|
153
|
+
* @default ['。', '!', '?', '.', '!', '?', '\n']
|
|
154
|
+
*/
|
|
155
|
+
delimiters?: string[];
|
|
156
|
+
/**
|
|
157
|
+
* @description `splitBy` 为 `sentence` 时一个淡入单元最多容纳的字符数,超过后新到的文本另起一个单元
|
|
158
|
+
* @description With `splitBy: 'sentence'`, the most characters one fade-in unit holds; text arriving beyond it starts a new unit
|
|
159
|
+
* @default 120
|
|
160
|
+
*/
|
|
161
|
+
maxSentenceChars?: number;
|
|
162
|
+
}
|
|
163
|
+
export interface TypewriterConfig {
|
|
164
|
+
/**
|
|
165
|
+
* @description 放出文本的单位。`char` 逐字放出;`sentence` 攒到分隔符再一起放出(围栏代码和行内代码里的分隔符不算,换行总是分隔符)
|
|
166
|
+
* @description Unit in which text is revealed. `char` reveals character by character; `sentence` reveals up to the next delimiter at once (delimiters inside fenced or inline code do not count, a newline always does)
|
|
167
|
+
* @default 'char'
|
|
168
|
+
*/
|
|
169
|
+
unit?: "char" | "sentence";
|
|
170
|
+
/**
|
|
171
|
+
* @description 句子分隔符
|
|
172
|
+
* @description Sentence delimiters
|
|
173
|
+
* @default ['。', '!', '?', '.', '!', '?', '\n']
|
|
174
|
+
*/
|
|
175
|
+
delimiters?: string[];
|
|
176
|
+
/**
|
|
177
|
+
* @description 最低放出速度(字/秒)。速度会随 chunk 到达节奏自适应,这是下限
|
|
178
|
+
* @description Minimum reveal speed in characters per second. The speed adapts to the chunk cadence; this is the floor
|
|
179
|
+
* @default 24
|
|
180
|
+
*/
|
|
181
|
+
minCps?: number;
|
|
182
|
+
/**
|
|
183
|
+
* @description 最高放出速度(字/秒)
|
|
184
|
+
* @description Maximum reveal speed in characters per second
|
|
185
|
+
* @default 3000
|
|
186
|
+
*/
|
|
187
|
+
maxCps?: number;
|
|
188
|
+
/**
|
|
189
|
+
* @description `unit` 为 `char` 时,放出一个分隔符后停顿的毫秒数
|
|
190
|
+
* @description With `unit: 'char'`, how many milliseconds to pause after revealing a delimiter
|
|
191
|
+
* @default 0
|
|
192
|
+
*/
|
|
193
|
+
pauseMs?: number;
|
|
194
|
+
/**
|
|
195
|
+
* @description `unit` 为 `sentence` 时,自上一个分隔符起最多攒多少个字符;超过后退回逐字放出,直到下一个分隔符出现。防止长 URL、单行 JSON 这类没有标点的内容长时间不显示
|
|
196
|
+
* @description With `unit: 'sentence'`, the longest run since the previous delimiter that is held back; beyond it text is revealed character by character until the next delimiter appears. Prevents a long URL or a one-line JSON blob from staying invisible
|
|
197
|
+
* @default 120
|
|
198
|
+
*/
|
|
199
|
+
maxSentenceChars?: number;
|
|
200
|
+
}
|
|
201
|
+
export interface TailConfig {
|
|
202
|
+
/**
|
|
203
|
+
* @description 尾部显示的内容,默认为 `▋`
|
|
204
|
+
* @description The content to display as tail, default is `▋`
|
|
205
|
+
* @default '▋'
|
|
206
|
+
*/
|
|
207
|
+
content?: string;
|
|
208
|
+
/**
|
|
209
|
+
* @description 自定义尾部组件,优先级高于 content
|
|
210
|
+
* @description Custom tail component, takes precedence over content
|
|
211
|
+
*/
|
|
212
|
+
component?: Component;
|
|
31
213
|
}
|
|
32
214
|
export interface StreamingOption {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
215
|
+
/**
|
|
216
|
+
* @description 指示是否还有后续内容块,为 false 时刷新所有缓存并完成渲染
|
|
217
|
+
* @description Indicates whether more content chunks are expected. When false, flushes all cached content and completes rendering
|
|
218
|
+
* @default false
|
|
219
|
+
*/
|
|
220
|
+
hasNextChunk?: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* @description 流式期间按标题把正文切成若干段,只有正在增长的最后一段随每个 chunk 重新解析、消毒和渲染,前面的段直接复用。只在顶格的 ATX 标题(`# ` ~ `###### `)前切分,且该行必须真的开启一个新的顶层块——切分器把当前段交给渲染器所用的同一个 marked 实例来判定,而不是自己复刻块级语法,因此不会在围栏代码、HTML 块、列表、引用块或缩进代码内部切分。浏览器与 DOMPurify 会重新解释的原始块(`<pre>`、注释、`<?`、`<!`、`<,图片、HTML、表格仍按 `placeholder` 处理。对某个语法显式配置了 `incompleteMarkdownComponentMap` 时以占位组件为准。
|
|
255
|
+
* @description How markdown syntax that has not finished streaming is shown. `placeholder`: hold it back, or show the placeholder component from `incompleteMarkdownComponentMap`; `complete`: show half-written emphasis, inline code, link text and list items as finished text right away (`**bold so far` renders bold, `[link text](https://` shows its text), while images, HTML and tables still follow `placeholder`. A token with an explicit `incompleteMarkdownComponentMap` entry always uses its placeholder.
|
|
256
|
+
* @default 'placeholder'
|
|
257
|
+
*/
|
|
258
|
+
incompleteMarkdown?: "placeholder" | "complete";
|
|
259
|
+
/**
|
|
260
|
+
* @description 打字机效果:新到的内容不是整块出现,而是按 chunk 到达的节奏匀速放出。放出的永远是 `content` 的前缀,`hasNextChunk` 变为 false 时立即放完。传对象可配置单位、速度和分隔符
|
|
261
|
+
* @description Typewriter effect: newly arrived content is revealed at a steady pace that follows the chunk cadence instead of appearing in blocks. What is shown is always a prefix of `content`; everything is revealed at once when `hasNextChunk` becomes false. Pass an object to configure the unit, speed and delimiters
|
|
262
|
+
* @default false
|
|
263
|
+
*/
|
|
264
|
+
typewriter?: boolean | TypewriterConfig;
|
|
44
265
|
}
|
|
45
266
|
export interface XMarkdownProps {
|
|
46
267
|
content?: string;
|
|
@@ -50,7 +271,11 @@ export interface XMarkdownProps {
|
|
|
50
271
|
* Extra props passed to custom components in `components` by tag name, keeping component references stable and avoiding remounts caused by inline functions
|
|
51
272
|
*/
|
|
52
273
|
componentsProps?: Record<string, Record<string, unknown>>;
|
|
53
|
-
|
|
274
|
+
/**
|
|
275
|
+
* @description 流式渲染行为的配置。传布尔值即开启预设:`true` 表示还有后续内容(等同 `hasNextChunk: true`)并打开 `incremental`、`incompleteMarkdown: 'complete'`、`typewriter`;`false` 表示流已结束,按最终内容一次性渲染。传对象则逐项配置
|
|
276
|
+
* @description Configuration for streaming rendering behavior. A boolean enables the preset: `true` means more content is coming (same as `hasNextChunk: true`) with `incremental`, `incompleteMarkdown: 'complete'` and `typewriter` switched on; `false` means the stream has ended and the final content is rendered at once. Pass an object to configure each option
|
|
277
|
+
*/
|
|
278
|
+
streaming?: boolean | StreamingOption;
|
|
54
279
|
config?: MarkedConfig;
|
|
55
280
|
debug?: boolean;
|
|
56
281
|
protectCustomTagNewlines?: boolean;
|
|
@@ -76,6 +301,9 @@ export interface AnimationTextProps {
|
|
|
76
301
|
text: string;
|
|
77
302
|
fadeDuration?: number;
|
|
78
303
|
easing?: string;
|
|
304
|
+
splitBy?: "chunk" | "sentence";
|
|
305
|
+
delimiters?: string[];
|
|
306
|
+
maxSentenceChars?: number;
|
|
79
307
|
}
|
|
80
308
|
export interface DebugPanelProps {
|
|
81
309
|
className?: string;
|
|
@@ -98,8 +326,7 @@ export interface RendererOptions {
|
|
|
98
326
|
components?: Record<string, Component>;
|
|
99
327
|
componentsProps?: Record<string, Record<string, unknown>>;
|
|
100
328
|
enableAnimation?: boolean;
|
|
101
|
-
animationConfig?:
|
|
102
|
-
fadeDuration?: number;
|
|
103
|
-
easing?: string;
|
|
104
|
-
};
|
|
329
|
+
animationConfig?: AnimationConfig;
|
|
105
330
|
}
|
|
331
|
+
/** 与上游 `TypewriterOption` 对齐的导出名。 Alias export matching the upstream name. */
|
|
332
|
+
export type { TypewriterConfig as TypewriterOption };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { StreamingOption, XMarkdownProps } from '../interface';
|
|
2
|
+
/**
|
|
3
|
+
* Normalise the `streaming` prop. Objects pass through untouched (the
|
|
4
|
+
* behaviour of every existing caller), booleans expand to the preset.
|
|
5
|
+
*/
|
|
6
|
+
export declare const resolveStreaming: (streaming: XMarkdownProps["streaming"]) => StreamingOption | undefined;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/XMarkdown/utils/streaming.ts
|
|
2
|
+
/**
|
|
3
|
+
* The preset behind `streaming={true}` / `streaming={false}`: every streaming
|
|
4
|
+
* capability that needs no per-app configuration, switched on. The boolean is
|
|
5
|
+
* `hasNextChunk`, so callers can pass their own "is the answer still
|
|
6
|
+
* streaming" flag straight through.
|
|
7
|
+
*/
|
|
8
|
+
var PRESET = {
|
|
9
|
+
incremental: true,
|
|
10
|
+
incompleteMarkdown: "complete",
|
|
11
|
+
typewriter: true,
|
|
12
|
+
animationConfig: Object.freeze({ splitBy: "sentence" })
|
|
13
|
+
};
|
|
14
|
+
var STREAMING_ON = Object.freeze({
|
|
15
|
+
...PRESET,
|
|
16
|
+
hasNextChunk: true
|
|
17
|
+
});
|
|
18
|
+
var STREAMING_OFF = Object.freeze({
|
|
19
|
+
...PRESET,
|
|
20
|
+
hasNextChunk: false
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Normalise the `streaming` prop. Objects pass through untouched (the
|
|
24
|
+
* behaviour of every existing caller), booleans expand to the preset.
|
|
25
|
+
*/
|
|
26
|
+
var resolveStreaming = (streaming) => {
|
|
27
|
+
if (streaming === true) return STREAMING_ON;
|
|
28
|
+
if (streaming === false) return STREAMING_OFF;
|
|
29
|
+
return streaming;
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { resolveStreaming };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
export { default as XMarkdown } from './XMarkdown/index.vue';
|
|
2
2
|
export type { XMarkdownProps } from './XMarkdown/interface';
|
|
3
|
-
export type { StreamingOption } from './XMarkdown/interface';
|
|
3
|
+
export type { StreamingOption, TypewriterOption } from './XMarkdown/interface';
|
|
4
|
+
export type { AnimationConfig, TypewriterConfig } from './XMarkdown/interface';
|
|
5
|
+
export type { StreamCacheTokenType } from './XMarkdown/interface';
|
|
4
6
|
export type { MarkedConfig } from './XMarkdown/interface';
|
|
5
7
|
export type { ComponentProps } from './XMarkdown/interface';
|
|
6
8
|
export { Parser } from './XMarkdown/core/Parser';
|
|
7
9
|
export { VueRenderer } from './XMarkdown/core/VueRenderer';
|
|
8
10
|
export { detectUnclosedComponentTags } from './XMarkdown/core/detectUnclosedComponentTags';
|
|
9
|
-
export { useStreaming } from './XMarkdown/composables/useStreaming';
|
|
11
|
+
export { useStreaming, useStreamingCore, } from './XMarkdown/composables/useStreaming';
|
|
12
|
+
export { useTypewriter } from './XMarkdown/composables/useTypewriter';
|
|
10
13
|
export { useParser } from './XMarkdown/composables/useParser';
|
|
11
14
|
export { useRenderer } from './XMarkdown/composables/useRenderer';
|
|
12
15
|
export { useTail } from './XMarkdown/composables/useTail';
|
|
13
16
|
export { AnimationText, DebugPanel, TailIndicator, } from './XMarkdown/components';
|
|
17
|
+
export { resolveStreaming } from './XMarkdown/utils/streaming';
|
|
14
18
|
export { resolveTailContent } from './XMarkdown/utils/tail';
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import AnimationText_default from "./XMarkdown/components/AnimationText.js";
|
|
2
2
|
import DebugPanel_default from "./XMarkdown/components/DebugPanel2.js";
|
|
3
3
|
import TailIndicator_default from "./XMarkdown/components/TailIndicator.js";
|
|
4
|
-
import {
|
|
4
|
+
import { detectUnclosedComponentTags } from "./XMarkdown/core/detectUnclosedComponentTags.js";
|
|
5
|
+
import { resolveStreaming } from "./XMarkdown/utils/streaming.js";
|
|
6
|
+
import { useStreaming, useStreamingCore } from "./XMarkdown/composables/useStreaming.js";
|
|
7
|
+
import useTypewriter from "./XMarkdown/composables/useTypewriter.js";
|
|
5
8
|
import { Parser } from "./XMarkdown/core/Parser.js";
|
|
6
9
|
import { useParser } from "./XMarkdown/composables/useParser.js";
|
|
7
|
-
import { detectUnclosedComponentTags } from "./XMarkdown/core/detectUnclosedComponentTags.js";
|
|
8
10
|
import { VueRenderer } from "./XMarkdown/core/VueRenderer.js";
|
|
9
11
|
import { useRenderer } from "./XMarkdown/composables/useRenderer.js";
|
|
10
12
|
import { useTail } from "./XMarkdown/composables/useTail.js";
|
|
11
13
|
import XMarkdown_default from "./XMarkdown/index2.js";
|
|
12
14
|
import { resolveTailContent } from "./XMarkdown/utils/tail.js";
|
|
13
|
-
export { AnimationText_default as AnimationText, DebugPanel_default as DebugPanel, Parser, TailIndicator_default as TailIndicator, VueRenderer, XMarkdown_default as XMarkdown, detectUnclosedComponentTags, resolveTailContent, useParser, useRenderer, useStreaming, useTail };
|
|
15
|
+
export { AnimationText_default as AnimationText, DebugPanel_default as DebugPanel, Parser, TailIndicator_default as TailIndicator, VueRenderer, XMarkdown_default as XMarkdown, detectUnclosedComponentTags, resolveStreaming, resolveTailContent, useParser, useRenderer, useStreaming, useStreamingCore, useTail, useTypewriter };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antdv-next/x-markdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"dompurify": "^3.1.0",
|
|
34
34
|
"katex": "^0.16.25",
|
|
35
|
-
"marked": "^
|
|
35
|
+
"marked": "^16.2.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/dompurify": "^3.0.5"
|
package/plugins/Latex/index.js
CHANGED
|
@@ -38,14 +38,20 @@ function inlineKatex(renderer, replaceAlignStart) {
|
|
|
38
38
|
if (!match) return;
|
|
39
39
|
const rawText = dollarMatch?.[2] || nonStandardMatch?.[1] || nonStandardMatch?.[2] || "";
|
|
40
40
|
const text = replaceAlignStart ? replaceAlign(rawText.trim()) : rawText.trim();
|
|
41
|
+
const isBracketSyntax = nonStandardMatch?.[2] !== void 0;
|
|
42
|
+
const hasNewline = rawText.includes("\n");
|
|
41
43
|
return {
|
|
42
44
|
type: "inlineKatex",
|
|
43
45
|
raw: match[0],
|
|
44
46
|
text,
|
|
45
|
-
displayMode: true
|
|
47
|
+
displayMode: true,
|
|
48
|
+
isBlock: isBracketSyntax && hasNewline
|
|
46
49
|
};
|
|
47
50
|
},
|
|
48
|
-
renderer: (token) =>
|
|
51
|
+
renderer: (token) => {
|
|
52
|
+
const html = renderer(token);
|
|
53
|
+
return token.isBlock ? `<span class="block-katex">${html}</span>` : `<span class="inline-katex">${html}</span>`;
|
|
54
|
+
}
|
|
49
55
|
};
|
|
50
56
|
}
|
|
51
57
|
function blockKatex(renderer, replaceAlignStart) {
|