@antdv-next/x-markdown 0.2.0 → 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.
Files changed (28) hide show
  1. package/dist/XMarkdown/components/AnimationText.vue.d.ts +6 -0
  2. package/dist/XMarkdown/components/AnimationText.vue_vue_type_script_setup_true_lang.js +58 -2
  3. package/dist/XMarkdown/components/Section.js +5 -0
  4. package/dist/XMarkdown/components/Section.vue.d.ts +76 -0
  5. package/dist/XMarkdown/components/Section.vue_vue_type_script_lang.js +54 -0
  6. package/dist/XMarkdown/composables/index.d.ts +2 -1
  7. package/dist/XMarkdown/composables/index.js +3 -2
  8. package/dist/XMarkdown/composables/useStreaming.d.ts +37 -1
  9. package/dist/XMarkdown/composables/useStreaming.js +449 -34
  10. package/dist/XMarkdown/composables/useTypewriter.d.ts +11 -0
  11. package/dist/XMarkdown/composables/useTypewriter.js +378 -0
  12. package/dist/XMarkdown/core/Parser.d.ts +15 -0
  13. package/dist/XMarkdown/core/Parser.js +22 -3
  14. package/dist/XMarkdown/core/VueRenderer.js +16 -9
  15. package/dist/XMarkdown/core/detectUnclosedComponentTags.d.ts +12 -0
  16. package/dist/XMarkdown/core/detectUnclosedComponentTags.js +240 -6
  17. package/dist/XMarkdown/core/index.js +1 -1
  18. package/dist/XMarkdown/index.d.ts +6 -2
  19. package/dist/XMarkdown/index.js +5 -3
  20. package/dist/XMarkdown/index.vue.d.ts +1 -1
  21. package/dist/XMarkdown/index.vue_vue_type_script_setup_true_lang.js +64 -30
  22. package/dist/XMarkdown/interface.d.ts +241 -14
  23. package/dist/XMarkdown/utils/streaming.d.ts +6 -0
  24. package/dist/XMarkdown/utils/streaming.js +32 -0
  25. package/dist/index.d.ts +6 -2
  26. package/dist/index.js +5 -3
  27. package/package.json +1 -1
  28. 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
- hasNextChunk: boolean;
34
- enableAnimation?: boolean;
35
- animationConfig?: {
36
- fadeDuration?: number;
37
- easing?: string;
38
- };
39
- tail?: boolean | {
40
- content?: string;
41
- component?: Component;
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>`、注释、`<?`、`<!`、`<![CDATA[`)以及 `$$` / `\[` 公式在闭合前不参与切分。**「没有切分」都是有意为之**:拒绝切分只会少复用一段,而多切一段会改变渲染结果。出现链接引用定义或脚注定义、或自定义组件标签跨越切点时不切分。`$$` 公式以自带的 Latex 插件规则为准,未注册该插件时用 `$$` 包住代码围栏的内容请关闭本选项。传对象可调整:短于 `minSectionChars` 的段并入下一段;`keepSectionsOnEnd`(默认 true)表示流结束(`hasNextChunk` 变为 false)后各段保持不变、已挂载的自定义组件不重新挂载,设为 false 则流结束时回到整篇一次性渲染,用了带全局状态的 marked 扩展(如标题 id 去重)时应关掉。
223
+ * @description Splits the document into sections at headings while streaming so that only the last, still-growing section is re-parsed, sanitized and rendered per chunk; earlier sections are reused as-is. A boundary is only placed before a column-0 ATX heading (`# ` to `###### `) **and only when the renderer's own marked instance reads that line as a new top-level block** — the splitter lexes the current section with the same `config` (extension plugins included) instead of re-implementing the block grammar, so it never splits inside fenced code, an HTML block, a list, a blockquote or indented code. Raw blocks the browser and DOMPurify re-interpret (`<pre>`, comments, `<?`, `<!`, `<![CDATA[`) and `$$` / `\[` math are held out of any split until they close. A case where no boundary is placed is deliberate: refusing only gives up incremental reuse, while an over-eager boundary would change the rendered DOM. Splitting is disabled when a link reference or footnote definition appears, or when a custom component tag spans the boundary. The `$$` math model follows the bundled Latex plugin; without that plugin registered, turn this off for content that wraps code fences in `$$` delimiters. Pass an object to tune it: sections shorter than `minSectionChars` are merged into the next one; `keepSectionsOnEnd` (default true) keeps the sections once the stream ends (`hasNextChunk` becomes false) so mounted custom components are not remounted, while false re-renders the whole document at once when the stream ends — turn it off when using marked extensions with document-wide state (e.g. heading id de-duplication).
224
+ * @default false
225
+ */
226
+ incremental?: boolean | {
227
+ minSectionChars?: number;
228
+ keepSectionsOnEnd?: boolean;
42
229
  };
230
+ /**
231
+ * @description 为块级元素(p、li、h1、h2、h3、h4)启用文字淡入动画
232
+ * @description Enables text fade-in animation for block elements (p, li, h1, h2, h3, h4)
233
+ * @default true
234
+ */
235
+ enableAnimation?: boolean;
236
+ /**
237
+ * @description 文字出现动画效果的配置
238
+ * @description Configuration for text appearance animation effects
239
+ */
240
+ animationConfig?: AnimationConfig;
241
+ /**
242
+ * @description 是否启用尾部动画;传入 `true` 使用默认 `▋`,传入对象可自定义内容
243
+ * @description Whether to enable tail animation; pass `true` for default `▋`, or object to customize content
244
+ * @default false
245
+ */
246
+ tail?: boolean | TailConfig;
247
+ /**
248
+ * @description 未完成的 Markdown 格式转换为自定义加载组件的映射配置,用于在流式渲染过程中为未闭合的链接和图片提供自定义loading组件
249
+ * @description Mapping configuration to convert incomplete Markdown formats to custom loading components, used to provide custom loading components for unclosed links and images during streaming rendering
250
+ * @default { link: 'incomplete-link', image: 'incomplete-image' }
251
+ */
43
252
  incompleteMarkdownComponentMap?: Partial<Record<StreamCacheTokenType, string>>;
253
+ /**
254
+ * @description 尚未写完的 Markdown 语法如何显示。`placeholder`:扣住不显示,或显示 `incompleteMarkdownComponentMap` 指定的占位组件;`complete`:把写到一半的强调、行内代码、链接文字、列表项当作已写完的文本立刻显示(`**加粗中` 显示为加粗,`[链接文字](https://` 先显示文字),图片、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
- streaming?: StreamingOption;
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 { useStreaming } from "./XMarkdown/composables/useStreaming.js";
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.2.0",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "dist",
@@ -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) => `<span class="inline-katex">${renderer(token)}</span>`
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) {