@incremark/core 0.2.4 → 0.2.5

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.
@@ -1,4 +1,4 @@
1
- export { r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, T as isFootnoteContinuation, S as isFootnoteDefinitionStart, h as isHeading, m as isHtmlBlock, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, u as updateContext } from '../index-zDgyJFpf.js';
1
+ export { r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, T as isFootnoteContinuation, S as isFootnoteDefinitionStart, h as isHeading, m as isHtmlBlock, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, u as updateContext } from '../index-BfVDhalw.js';
2
2
  import 'mdast';
3
3
  import 'micromark-util-types';
4
4
  import 'mdast-util-from-markdown';
@@ -228,6 +228,12 @@ interface ParserState {
228
228
  interface ParserOptions {
229
229
  /** 启用 GFM 扩展(表格、任务列表等) */
230
230
  gfm?: boolean;
231
+ /**
232
+ * 启用数学公式支持($..$ 行内公式和 $$...$$ 块级公式)
233
+ * - false/undefined: 禁用(默认)
234
+ * - true: 启用数学公式解析
235
+ */
236
+ math?: boolean;
231
237
  /**
232
238
  * 启用 ::: 容器语法支持(用于边界检测)
233
239
  * - false: 禁用(默认)
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as ParserOptions, I as IncrementalUpdate, a as ParsedBlock, D as DefinitionMap, F as FootnoteDefinitionMap, b as ParserState, B as BlockStatus } from './index-zDgyJFpf.js';
2
- export { A as AstNode, c as BlockContext, e as BlockTypeInfo, C as ContainerConfig, d as ContainerMatch, J as HTML_ATTR_BLACKLIST, K as HTML_PROTOCOL_BLACKLIST, H as HTML_TAG_BLACKLIST, N as HtmlAttrInfo, R as HtmlContentType, M as HtmlElementNode, Q as HtmlTreeExtensionOptions, O as ParsedHtmlTag, s as createHtmlTreeTransformer, r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, x as detectHtmlContentType, E as findHtmlElementsByTag, G as htmlElementToString, L as htmlTreeExtension, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, h as isHeading, m as isHtmlBlock, y as isHtmlElementNode, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, w as parseHtmlFragment, v as parseHtmlTag, t as transformHtmlNodes, u as updateContext, z as walkHtmlElements } from './index-zDgyJFpf.js';
1
+ import { P as ParserOptions, I as IncrementalUpdate, a as ParsedBlock, D as DefinitionMap, F as FootnoteDefinitionMap, b as ParserState, B as BlockStatus } from './index-BfVDhalw.js';
2
+ export { A as AstNode, c as BlockContext, e as BlockTypeInfo, C as ContainerConfig, d as ContainerMatch, J as HTML_ATTR_BLACKLIST, K as HTML_PROTOCOL_BLACKLIST, H as HTML_TAG_BLACKLIST, N as HtmlAttrInfo, R as HtmlContentType, M as HtmlElementNode, Q as HtmlTreeExtensionOptions, O as ParsedHtmlTag, s as createHtmlTreeTransformer, r as createInitialContext, o as detectContainer, p as detectContainerEnd, g as detectFenceEnd, f as detectFenceStart, x as detectHtmlContentType, E as findHtmlElementsByTag, G as htmlElementToString, L as htmlTreeExtension, q as isBlockBoundary, l as isBlockquoteStart, i as isEmptyLine, h as isHeading, m as isHtmlBlock, y as isHtmlElementNode, k as isListItemStart, n as isTableDelimiter, j as isThematicBreak, w as parseHtmlFragment, v as parseHtmlTag, t as transformHtmlNodes, u as updateContext, z as walkHtmlElements } from './index-BfVDhalw.js';
3
3
  import { Root, RootContent, Text } from 'mdast';
4
4
  export { Root, RootContent } from 'mdast';
5
5
  export { calculateLineOffset, generateId, joinLines, resetIdCounter, splitLines } from './utils/index.js';
@@ -40,7 +40,7 @@ declare class IncremarkParser {
40
40
  */
41
41
  private convertHtmlToText;
42
42
  private parse;
43
- private updateDefinationsFromComplatedBlocks;
43
+ private updateDefinitionsFromCompletedBlocks;
44
44
  private findDefinition;
45
45
  private findFootnoteDefinition;
46
46
  /**
@@ -94,7 +94,7 @@ declare class IncremarkParser {
94
94
  finalize(): IncrementalUpdate;
95
95
  /**
96
96
  * 强制中断解析,将所有待处理内容标记为完成
97
- * 语义上等同于 finalize(),但名称更清晰
97
+ * @deprecated 请使用 finalize() 代替,功能完全相同
98
98
  */
99
99
  abort(): IncrementalUpdate;
100
100
  /**
@@ -221,6 +221,11 @@ interface TransformerOptions {
221
221
  plugins?: TransformerPlugin[];
222
222
  /** 状态变化回调 */
223
223
  onChange?: (displayBlocks: DisplayBlock[]) => void;
224
+ /**
225
+ * 所有动画完成时的回调
226
+ * 当队列中没有更多 block 需要处理时触发
227
+ */
228
+ onAllComplete?: () => void;
224
229
  /**
225
230
  * 是否在页面不可见时自动暂停
226
231
  * 默认 true,节省资源
@@ -384,6 +389,7 @@ declare class BlockTransformer<T = unknown> {
384
389
  private clearCache;
385
390
  /**
386
391
  * 获取累积的 chunks(用于 fade-in 效果)
392
+ * stableChars 表示在 chunks 之前的稳定字符数
387
393
  */
388
394
  private getAccumulatedChunks;
389
395
  }
package/dist/index.js CHANGED
@@ -2,6 +2,8 @@ import { fromMarkdown } from 'mdast-util-from-markdown';
2
2
  import { gfmFromMarkdown } from 'mdast-util-gfm';
3
3
  import { gfm } from 'micromark-extension-gfm';
4
4
  import { gfmFootnoteFromMarkdown } from 'mdast-util-gfm-footnote';
5
+ import { math } from 'micromark-extension-math';
6
+ import { mathFromMarkdown } from 'mdast-util-math';
5
7
  import { codes, constants, types } from 'micromark-util-symbol';
6
8
  import { markdownLineEndingOrSpace } from 'micromark-util-character';
7
9
  import { factoryDestination } from 'micromark-factory-destination';
@@ -1245,6 +1247,10 @@ var IncremarkParser = class {
1245
1247
  extensions.push(gfm());
1246
1248
  mdastExtensions.push(...gfmFromMarkdown(), gfmFootnoteFromMarkdown());
1247
1249
  }
1250
+ if (this.options.math) {
1251
+ extensions.push(math());
1252
+ mdastExtensions.push(mathFromMarkdown());
1253
+ }
1248
1254
  if (this.containerConfig !== void 0) {
1249
1255
  extensions.push(directive());
1250
1256
  mdastExtensions.push(directiveFromMarkdown());
@@ -1267,7 +1273,7 @@ var IncremarkParser = class {
1267
1273
  }
1268
1274
  return ast;
1269
1275
  }
1270
- updateDefinationsFromComplatedBlocks(blocks) {
1276
+ updateDefinitionsFromCompletedBlocks(blocks) {
1271
1277
  for (const block of blocks) {
1272
1278
  this.definitionMap = {
1273
1279
  ...this.definitionMap,
@@ -1281,17 +1287,17 @@ var IncremarkParser = class {
1281
1287
  }
1282
1288
  findDefinition(block) {
1283
1289
  const definitions = [];
1284
- function findDefination(node) {
1290
+ function findDefinitionRecursive(node) {
1285
1291
  if (isDefinitionNode(node)) {
1286
1292
  definitions.push(node);
1287
1293
  }
1288
1294
  if ("children" in node && Array.isArray(node.children)) {
1289
1295
  for (const child of node.children) {
1290
- findDefination(child);
1296
+ findDefinitionRecursive(child);
1291
1297
  }
1292
1298
  }
1293
1299
  }
1294
- findDefination(block.node);
1300
+ findDefinitionRecursive(block.node);
1295
1301
  return definitions.reduce((acc, node) => {
1296
1302
  acc[node.identifier] = node;
1297
1303
  return acc;
@@ -1552,7 +1558,7 @@ var IncremarkParser = class {
1552
1558
  const newBlocks = this.nodesToBlocks(ast.children, stableOffset, stableText, "completed");
1553
1559
  this.completedBlocks.push(...newBlocks);
1554
1560
  update.completed = newBlocks;
1555
- this.updateDefinationsFromComplatedBlocks(newBlocks);
1561
+ this.updateDefinitionsFromCompletedBlocks(newBlocks);
1556
1562
  this.context = contextAtLine;
1557
1563
  this.pendingStartLine = stableBoundary + 1;
1558
1564
  }
@@ -1625,7 +1631,7 @@ var IncremarkParser = class {
1625
1631
  );
1626
1632
  this.completedBlocks.push(...finalBlocks);
1627
1633
  update.completed = finalBlocks;
1628
- this.updateDefinationsFromComplatedBlocks(finalBlocks);
1634
+ this.updateDefinitionsFromCompletedBlocks(finalBlocks);
1629
1635
  }
1630
1636
  }
1631
1637
  this.lastPendingBlocks = [];
@@ -1643,7 +1649,7 @@ var IncremarkParser = class {
1643
1649
  }
1644
1650
  /**
1645
1651
  * 强制中断解析,将所有待处理内容标记为完成
1646
- * 语义上等同于 finalize(),但名称更清晰
1652
+ * @deprecated 请使用 finalize() 代替,功能完全相同
1647
1653
  */
1648
1654
  abort() {
1649
1655
  return this.finalize();
@@ -1852,54 +1858,57 @@ function appendToAst(baseNode, sourceNode, startChars, endChars, accumulatedChun
1852
1858
  if (endChars <= startChars) {
1853
1859
  return baseNode;
1854
1860
  }
1855
- const newPart = sliceAst(sourceNode, endChars, accumulatedChunks, startChars);
1856
- if (!newPart) {
1861
+ const fullSlice = sliceAst(sourceNode, endChars, accumulatedChunks);
1862
+ if (!fullSlice) {
1857
1863
  return baseNode;
1858
1864
  }
1859
- return mergeAstNodes(baseNode, newPart);
1865
+ return smartMergeAst(baseNode, fullSlice);
1860
1866
  }
1861
- function mergeAstNodes(baseNode, newPart) {
1862
- if (baseNode.type !== newPart.type) {
1863
- return baseNode;
1867
+ function smartMergeAst(baseNode, fullSlice) {
1868
+ if (baseNode.type !== fullSlice.type) {
1869
+ return fullSlice;
1864
1870
  }
1865
1871
  const base = baseNode;
1866
- const part = newPart;
1867
- if (base.value && typeof base.value === "string" && part.value && typeof part.value === "string") {
1868
- const baseChunks = base.chunks || [];
1869
- const partChunks = part.chunks || [];
1870
- const mergedChunks = [...baseChunks, ...partChunks];
1871
- const mergedValue = base.value + part.value;
1872
- const baseStableLength = base.stableLength ?? 0;
1873
- const result = {
1874
- ...base,
1875
- value: mergedValue,
1876
- stableLength: mergedChunks.length > 0 ? baseStableLength : void 0,
1877
- chunks: mergedChunks.length > 0 ? mergedChunks : void 0
1878
- };
1879
- return result;
1872
+ const full = fullSlice;
1873
+ if (full.value !== void 0) {
1874
+ return fullSlice;
1880
1875
  }
1881
- if (base.children && Array.isArray(base.children) && part.children && Array.isArray(part.children)) {
1882
- if (base.children.length > 0 && part.children.length > 0) {
1883
- const lastBaseChild = base.children[base.children.length - 1];
1884
- const firstPartChild = part.children[0];
1885
- if (lastBaseChild.type === firstPartChild.type) {
1886
- const merged = mergeAstNodes(lastBaseChild, firstPartChild);
1887
- return {
1888
- ...base,
1889
- children: [
1890
- ...base.children.slice(0, -1),
1891
- merged,
1892
- ...part.children.slice(1)
1893
- ]
1894
- };
1876
+ if (base.children && Array.isArray(base.children) && full.children && Array.isArray(full.children)) {
1877
+ if (full.children.length < base.children.length) {
1878
+ return fullSlice;
1879
+ }
1880
+ if (full.children.length === base.children.length) {
1881
+ if (base.children.length === 0) {
1882
+ return fullSlice;
1895
1883
  }
1884
+ const lastIndex = base.children.length - 1;
1885
+ const mergedLast2 = smartMergeAst(
1886
+ base.children[lastIndex],
1887
+ full.children[lastIndex]
1888
+ );
1889
+ return {
1890
+ ...full,
1891
+ children: [
1892
+ ...base.children.slice(0, lastIndex),
1893
+ mergedLast2
1894
+ ]
1895
+ };
1896
1896
  }
1897
+ const baseLastIndex = base.children.length - 1;
1898
+ const mergedLast = smartMergeAst(
1899
+ base.children[baseLastIndex],
1900
+ full.children[baseLastIndex]
1901
+ );
1897
1902
  return {
1898
- ...base,
1899
- children: [...base.children, ...part.children]
1903
+ ...full,
1904
+ children: [
1905
+ ...base.children.slice(0, baseLastIndex),
1906
+ mergedLast,
1907
+ ...full.children.slice(base.children.length)
1908
+ ]
1900
1909
  };
1901
1910
  }
1902
- return baseNode;
1911
+ return fullSlice;
1903
1912
  }
1904
1913
  function cloneNode(node) {
1905
1914
  if (typeof structuredClone === "function") {
@@ -1949,6 +1958,7 @@ var BlockTransformer = class {
1949
1958
  plugins: options.plugins ?? [],
1950
1959
  onChange: options.onChange ?? (() => {
1951
1960
  }),
1961
+ onAllComplete: options.onAllComplete ?? null,
1952
1962
  pauseOnHidden: options.pauseOnHidden ?? true
1953
1963
  };
1954
1964
  this.state = {
@@ -1975,12 +1985,13 @@ var BlockTransformer = class {
1975
1985
  if (this.state.currentBlock) {
1976
1986
  const updated = blocks.find((b) => b.id === this.state.currentBlock.id);
1977
1987
  if (updated && updated.node !== this.state.currentBlock.node) {
1978
- this.clearCache();
1979
1988
  const oldTotal = this.cachedTotalChars ?? this.countChars(this.state.currentBlock.node);
1980
1989
  const newTotal = this.countChars(updated.node);
1981
1990
  if (newTotal < oldTotal || newTotal < this.state.currentProgress) {
1982
1991
  this.state.currentProgress = Math.min(this.state.currentProgress, newTotal);
1992
+ this.chunks = [];
1983
1993
  }
1994
+ this.clearCache();
1984
1995
  this.state.currentBlock = updated;
1985
1996
  if (!this.rafId && !this.isPaused) {
1986
1997
  if (this.state.currentProgress < newTotal) {
@@ -1997,9 +2008,15 @@ var BlockTransformer = class {
1997
2008
  if (this.state.currentBlock?.id === block.id) {
1998
2009
  const oldTotal = this.cachedTotalChars ?? this.countChars(this.state.currentBlock.node);
1999
2010
  const newTotal = this.countChars(block.node);
2011
+ if (newTotal !== oldTotal) {
2012
+ this.clearCache();
2013
+ }
2014
+ if (newTotal < oldTotal || newTotal < this.state.currentProgress) {
2015
+ this.state.currentProgress = Math.min(this.state.currentProgress, newTotal);
2016
+ this.chunks = [];
2017
+ }
2000
2018
  this.state.currentBlock = block;
2001
2019
  if (newTotal > oldTotal && !this.rafId && !this.isPaused && this.state.currentProgress >= oldTotal) {
2002
- this.clearCache();
2003
2020
  this.startIfNeeded();
2004
2021
  }
2005
2022
  }
@@ -2023,6 +2040,7 @@ var BlockTransformer = class {
2023
2040
  this.chunks = [];
2024
2041
  this.clearCache();
2025
2042
  this.emit();
2043
+ this.options.onAllComplete?.();
2026
2044
  }
2027
2045
  /**
2028
2046
  * 重置状态
@@ -2279,6 +2297,7 @@ var BlockTransformer = class {
2279
2297
  this.isRunning = false;
2280
2298
  this.cancelRaf();
2281
2299
  this.emit();
2300
+ this.options.onAllComplete?.();
2282
2301
  }
2283
2302
  }
2284
2303
  cancelRaf() {
@@ -2381,10 +2400,13 @@ var BlockTransformer = class {
2381
2400
  }
2382
2401
  /**
2383
2402
  * 获取累积的 chunks(用于 fade-in 效果)
2403
+ * stableChars 表示在 chunks 之前的稳定字符数
2384
2404
  */
2385
2405
  getAccumulatedChunks() {
2386
2406
  if (this.options.effect === "fade-in" && this.chunks.length > 0) {
2387
- return { stableChars: 0, chunks: this.chunks };
2407
+ const chunksLength = this.chunks.reduce((sum, c) => sum + c.text.length, 0);
2408
+ const stableChars = this.state.currentProgress - chunksLength;
2409
+ return { stableChars: Math.max(0, stableChars), chunks: this.chunks };
2388
2410
  }
2389
2411
  return void 0;
2390
2412
  }