@incremark/core 0.3.0 → 0.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.
@@ -140,6 +140,30 @@ interface ParserState {
140
140
  definitions: DefinitionMap;
141
141
  footnoteDefinitions: FootnoteDefinitionMap;
142
142
  }
143
+ /**
144
+ * 数学公式配置选项
145
+ */
146
+ interface MathOptions {
147
+ /**
148
+ * 启用 TeX 风格的公式分隔符 (default: `false`)
149
+ *
150
+ * 开启后同时支持:
151
+ * - 行内公式:\(...\)
152
+ * - 块级公式:\[...\]
153
+ *
154
+ * 这是 LaTeX/TeX 原生语法,MathJax 和 KaTeX 都支持。
155
+ * 开启此选项可以兼容从 LaTeX 文档或学术 AI 工具输出的内容。
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * // 启用 TeX 风格分隔符
160
+ * const parser = createIncremarkParser({
161
+ * math: { tex: true }
162
+ * })
163
+ * ```
164
+ */
165
+ tex?: boolean;
166
+ }
143
167
  /**
144
168
  * 解析器配置
145
169
  */
@@ -147,11 +171,12 @@ interface ParserOptions {
147
171
  /** 启用 GFM 扩展(表格、任务列表等) */
148
172
  gfm?: boolean;
149
173
  /**
150
- * 启用数学公式支持($..$ 行内公式和 $$...$$ 块级公式)
174
+ * 启用数学公式支持
151
175
  * - false/undefined: 禁用(默认)
152
- * - true: 启用数学公式解析
176
+ * - true: 启用数学公式解析(仅支持 $...$ 和 $$...$$ 语法)
177
+ * - MathOptions: 启用并配置额外选项(如 LaTeX 风格的 \(...\) 和 \[...\] 语法)
153
178
  */
154
- math?: boolean;
179
+ math?: boolean | MathOptions;
155
180
  /**
156
181
  * 启用 ::: 容器语法支持(用于边界检测)
157
182
  * - false: 禁用(默认)
@@ -222,4 +247,4 @@ interface ContainerMatch {
222
247
  isEnd: boolean;
223
248
  }
224
249
 
225
- export type { AstNode as A, BlockStatus as B, ContainerConfig as C, DefinitionMap as D, FootnoteDefinitionMap as F, HtmlTreeExtensionOptions as H, IncrementalUpdate as I, ParsedBlock as P, ParserState as a, ParserOptions as b, BlockContext as c, ContainerMatch as d };
250
+ export type { AstNode as A, BlockStatus as B, ContainerConfig as C, DefinitionMap as D, FootnoteDefinitionMap as F, HtmlTreeExtensionOptions as H, IncrementalUpdate as I, MathOptions as M, ParsedBlock as P, ParserState as a, ParserOptions as b, BlockContext as c, ContainerMatch as d };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { I as IncrementalUpdate, P as ParsedBlock, D as DefinitionMap, F as FootnoteDefinitionMap, a as ParserState, B as BlockStatus } from './index-mZ7yCqNH.js';
2
- export { A as AstNode, b as ParserOptions } from './index-mZ7yCqNH.js';
3
- import { E as EngineParserOptions, I as IAstBuilder } from './types-C_EW5vfp.js';
4
- export { a as EngineType, b as IncremarkPlugin, M as MarkedEngineExtension, c as MicromarkEngineExtension } from './types-C_EW5vfp.js';
1
+ import { I as IncrementalUpdate, P as ParsedBlock, D as DefinitionMap, F as FootnoteDefinitionMap, a as ParserState, B as BlockStatus } from './index-CWuosVAK.js';
2
+ export { A as AstNode, M as MathOptions, b as ParserOptions } from './index-CWuosVAK.js';
3
+ import { E as EngineParserOptions, I as IAstBuilder } from './types-N1b99kYB.js';
4
+ export { a as EngineType, b as IncremarkPlugin, M as MarkedEngineExtension, c as MicromarkEngineExtension } from './types-N1b99kYB.js';
5
5
  import { Root, RootContent, Text } from 'mdast';
6
6
  export { Root, RootContent } from 'mdast';
7
- export { M as MarkedAstBuilder } from './MarkedAstBuildter-BsjxZko_.js';
7
+ export { M as MarkedAstBuilder } from './MarkedAstBuildter-DDP1An5M.js';
8
8
  import 'micromark-util-types';
9
9
  import 'mdast-util-from-markdown';
10
10
  import 'marked';
@@ -45,7 +45,7 @@ declare class IncremarkParser {
45
45
  /** 边界检测器 */
46
46
  private readonly boundaryDetector;
47
47
  /** AST 构建器 */
48
- private readonly astBuilder;
48
+ private astBuilder;
49
49
  /** Definition 管理器 */
50
50
  private readonly definitionManager;
51
51
  /** Footnote 管理器 */
@@ -129,6 +129,27 @@ declare class IncremarkParser {
129
129
  * @returns 解析结果
130
130
  */
131
131
  render(content: string): IncrementalUpdate;
132
+ /**
133
+ * 更新解析器配置(动态更新,不需要重建 parser 实例)
134
+ *
135
+ * 注意:更新配置后会自动调用 reset() 重置状态
136
+ *
137
+ * @param options 部分配置选项
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * // 动态启用 TeX 数学公式语法
142
+ * parser.updateOptions({ math: { tex: true } })
143
+ *
144
+ * // 禁用 GFM
145
+ * parser.updateOptions({ gfm: false })
146
+ *
147
+ * // 切换引擎
148
+ * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'
149
+ * parser.updateOptions({ astBuilder: MicromarkAstBuilder })
150
+ * ```
151
+ */
152
+ updateOptions(options: Partial<IncremarkParserOptions>): void;
132
153
  }
133
154
  /**
134
155
  * 创建 Incremark 解析器实例
package/dist/index.js CHANGED
@@ -1351,24 +1351,48 @@ function createOptimisticReferenceExtension() {
1351
1351
  }
1352
1352
 
1353
1353
  // src/extensions/marked-extensions/mathExtension.ts
1354
- function createBlockMathExtension() {
1354
+ function resolveOptions(options) {
1355
+ return {
1356
+ tex: options?.tex ?? false
1357
+ };
1358
+ }
1359
+ function createBlockMathExtension(options) {
1360
+ const resolved = resolveOptions(options);
1355
1361
  return {
1356
1362
  name: "blockMath",
1357
1363
  level: "block",
1358
1364
  start(src) {
1359
- const match = src.match(/^ {0,3}\$\$/m);
1360
- return match?.index;
1365
+ const dollarMatch = src.match(/^ {0,3}\$\$/m);
1366
+ let bracketMatch = null;
1367
+ if (resolved.tex) {
1368
+ bracketMatch = src.match(/^ {0,3}\\\[/m);
1369
+ }
1370
+ if (dollarMatch && bracketMatch) {
1371
+ return Math.min(dollarMatch.index, bracketMatch.index);
1372
+ }
1373
+ return dollarMatch?.index ?? bracketMatch?.index;
1361
1374
  },
1362
1375
  tokenizer(src) {
1363
- const rule = /^ {0,3}\$\$([\s\S]*?)\$\$ *(?:\n+|$)/;
1364
- const match = rule.exec(src);
1365
- if (match) {
1376
+ const dollarRule = /^ {0,3}\$\$([\s\S]*?)\$\$ *(?:\n+|$)/;
1377
+ const dollarMatch = dollarRule.exec(src);
1378
+ if (dollarMatch) {
1366
1379
  return {
1367
1380
  type: "blockMath",
1368
- raw: match[0],
1369
- text: match[1].trim()
1381
+ raw: dollarMatch[0],
1382
+ text: dollarMatch[1].trim()
1370
1383
  };
1371
1384
  }
1385
+ if (resolved.tex) {
1386
+ const bracketRule = /^ {0,3}\\\[([\s\S]*?)\\\] *(?:\n+|$)/;
1387
+ const bracketMatch = bracketRule.exec(src);
1388
+ if (bracketMatch) {
1389
+ return {
1390
+ type: "blockMath",
1391
+ raw: bracketMatch[0],
1392
+ text: bracketMatch[1].trim()
1393
+ };
1394
+ }
1395
+ }
1372
1396
  return void 0;
1373
1397
  },
1374
1398
  renderer() {
@@ -1376,26 +1400,46 @@ function createBlockMathExtension() {
1376
1400
  }
1377
1401
  };
1378
1402
  }
1379
- function createInlineMathExtension() {
1403
+ function createInlineMathExtension(options) {
1404
+ const resolved = resolveOptions(options);
1380
1405
  return {
1381
1406
  name: "inlineMath",
1382
1407
  level: "inline",
1383
1408
  start(src) {
1384
- const index = src.indexOf("$");
1385
- if (index === -1) return void 0;
1386
- if (src[index + 1] === "$") return void 0;
1387
- return index;
1409
+ const dollarIndex = src.indexOf("$");
1410
+ const validDollarIndex = dollarIndex !== -1 && src[dollarIndex + 1] !== "$" ? dollarIndex : -1;
1411
+ let parenIndex = -1;
1412
+ if (resolved.tex) {
1413
+ parenIndex = src.indexOf("\\(");
1414
+ }
1415
+ if (validDollarIndex !== -1 && parenIndex !== -1) {
1416
+ return Math.min(validDollarIndex, parenIndex);
1417
+ }
1418
+ if (validDollarIndex !== -1) return validDollarIndex;
1419
+ if (parenIndex !== -1) return parenIndex;
1420
+ return void 0;
1388
1421
  },
1389
1422
  tokenizer(src) {
1390
- const rule = /^\$(?!\$)((?:\\.|[^\\\n$])+?)\$(?!\d)/;
1391
- const match = rule.exec(src);
1392
- if (match) {
1423
+ const dollarRule = /^\$(?!\$)((?:\\.|[^\\\n$])+?)\$(?!\d)/;
1424
+ const dollarMatch = dollarRule.exec(src);
1425
+ if (dollarMatch) {
1393
1426
  return {
1394
1427
  type: "inlineMath",
1395
- raw: match[0],
1396
- text: match[1].trim()
1428
+ raw: dollarMatch[0],
1429
+ text: dollarMatch[1].trim()
1397
1430
  };
1398
1431
  }
1432
+ if (resolved.tex) {
1433
+ const parenRule = /^\\\(([\s\S]*?)\\\)/;
1434
+ const parenMatch = parenRule.exec(src);
1435
+ if (parenMatch) {
1436
+ return {
1437
+ type: "inlineMath",
1438
+ raw: parenMatch[0],
1439
+ text: parenMatch[1].trim()
1440
+ };
1441
+ }
1442
+ }
1399
1443
  return void 0;
1400
1444
  },
1401
1445
  renderer() {
@@ -2053,8 +2097,9 @@ var MarkedAstBuilder = class {
2053
2097
  const inlineExts = [optimisticRefExt.tokenizer, ...userInlineExts];
2054
2098
  const inlineStartExts = [optimisticRefExt.start, ...userInlineStartExts];
2055
2099
  if (this.options.math) {
2056
- const blockMathExt = createBlockMathExtension();
2057
- const inlineMathExt = createInlineMathExtension();
2100
+ const mathOptions = typeof this.options.math === "object" ? this.options.math : {};
2101
+ const blockMathExt = createBlockMathExtension(mathOptions);
2102
+ const inlineMathExt = createInlineMathExtension(mathOptions);
2058
2103
  blockExts.unshift(blockMathExt.tokenizer);
2059
2104
  blockStartExts.unshift(blockMathExt.start);
2060
2105
  inlineExts.unshift(inlineMathExt.tokenizer);
@@ -2280,6 +2325,28 @@ var MarkedAstBuilder = class {
2280
2325
  }
2281
2326
  return blocks;
2282
2327
  }
2328
+ /**
2329
+ * 更新配置选项
2330
+ * @param options 部分配置选项
2331
+ */
2332
+ updateOptions(options) {
2333
+ Object.assign(this.options, options);
2334
+ if ("containers" in options) {
2335
+ this.containerConfig = typeof options.containers === "object" ? options.containers : options.containers === true ? {} : void 0;
2336
+ }
2337
+ if ("htmlTree" in options) {
2338
+ this.htmlTreeOptions = typeof options.htmlTree === "object" ? options.htmlTree : options.htmlTree === true ? {} : void 0;
2339
+ }
2340
+ if (options.plugins || options.markedExtensions) {
2341
+ this.userExtensions.length = 0;
2342
+ if (options.plugins) {
2343
+ this.userExtensions.push(...extractMarkedExtensions(options.plugins));
2344
+ }
2345
+ if (options.markedExtensions) {
2346
+ this.userExtensions.push(...options.markedExtensions);
2347
+ }
2348
+ }
2349
+ }
2283
2350
  };
2284
2351
 
2285
2352
  // src/parser/IncremarkParser.ts
@@ -2569,6 +2636,40 @@ var IncremarkParser = class {
2569
2636
  this.append(content);
2570
2637
  return this.finalize();
2571
2638
  }
2639
+ /**
2640
+ * 更新解析器配置(动态更新,不需要重建 parser 实例)
2641
+ *
2642
+ * 注意:更新配置后会自动调用 reset() 重置状态
2643
+ *
2644
+ * @param options 部分配置选项
2645
+ *
2646
+ * @example
2647
+ * ```ts
2648
+ * // 动态启用 TeX 数学公式语法
2649
+ * parser.updateOptions({ math: { tex: true } })
2650
+ *
2651
+ * // 禁用 GFM
2652
+ * parser.updateOptions({ gfm: false })
2653
+ *
2654
+ * // 切换引擎
2655
+ * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'
2656
+ * parser.updateOptions({ astBuilder: MicromarkAstBuilder })
2657
+ * ```
2658
+ */
2659
+ updateOptions(options) {
2660
+ this.reset();
2661
+ Object.assign(this.options, options);
2662
+ if (options.astBuilder) {
2663
+ const BuilderClass = options.astBuilder;
2664
+ if (!(this.astBuilder instanceof BuilderClass)) {
2665
+ this.astBuilder = new BuilderClass(this.options);
2666
+ } else {
2667
+ this.astBuilder.updateOptions(options);
2668
+ }
2669
+ } else {
2670
+ this.astBuilder.updateOptions(options);
2671
+ }
2672
+ }
2572
2673
  };
2573
2674
  function createIncremarkParser(options) {
2574
2675
  return new IncremarkParser(options);