@isdk/mdast-plus 0.2.1 → 0.2.2

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.cn.md CHANGED
@@ -68,6 +68,31 @@ const ast = await mdast('==高亮内容==').toAST();
68
68
  const rawAst = await mdast('==高亮内容==').toAST({ stage: 'parse' });
69
69
  ```
70
70
 
71
+ ### 部分执行与调试 (Partial Execution & Debugging)
72
+
73
+ 您可以在任何阶段停止管道以检查中间 AST,即使目标是特定的输出格式(如 `html` 或 `markdown`)。这对于调试非常有帮助。
74
+
75
+ ```typescript
76
+ // 运行 'markdown' 管道但在 'parse' 阶段后停止
77
+ // 返回包含该时刻 AST 的 VFile
78
+ const vfile = await mdast(input).to('markdown', { stage: 'parse' });
79
+ const ast = vfile.result;
80
+ ```
81
+
82
+ ### 运行时覆盖 (Runtime Overrides)
83
+
84
+ 您可以在执行时通过 `.to()` 的 `overrides` 选项覆盖插件选项。这对于在不重建管道的情况下动态调整行为非常有用。
85
+
86
+ ```typescript
87
+ await mdast(input)
88
+ .use({ name: 'myPlugin', plugin: myPlugin, options: [{ foo: 'bar' }] }) // 默认选项
89
+ .to('html', {
90
+ overrides: {
91
+ myPlugin: { foo: 'baz' } // 仅针对本次运行的覆盖
92
+ }
93
+ });
94
+ ```
95
+
71
96
  ### 高级工作流
72
97
 
73
98
  ```typescript
package/README.md CHANGED
@@ -68,6 +68,31 @@ const ast = await mdast('==Highlighted==').toAST();
68
68
  const rawAst = await mdast('==Highlighted==').toAST({ stage: 'parse' });
69
69
  ```
70
70
 
71
+ ### Partial Execution & Debugging
72
+
73
+ You can stop the pipeline at any stage to inspect the intermediate AST, even when targeting a specific output format like `html` or `markdown`.
74
+
75
+ ```typescript
76
+ // Run 'markdown' pipeline but stop after 'parse' stage
77
+ // Returns the VFile with the AST at that point
78
+ const vfile = await mdast(input).to('markdown', { stage: 'parse' });
79
+ const ast = vfile.result;
80
+ ```
81
+
82
+ ### Runtime Overrides
83
+
84
+ You can override plugin options at the moment of execution using the `overrides` option in `.to()`. This is useful for adjusting behavior dynamically without rebuilding the pipeline.
85
+
86
+ ```typescript
87
+ await mdast(input)
88
+ .use({ name: 'myPlugin', plugin: myPlugin, options: [{ foo: 'bar' }] }) // Default option
89
+ .to('html', {
90
+ overrides: {
91
+ myPlugin: { foo: 'baz' } // Override for this run only
92
+ }
93
+ });
94
+ ```
95
+
71
96
  ### Advanced Pipeline
72
97
 
73
98
  ```typescript
package/dist/index.d.mts CHANGED
@@ -1451,6 +1451,26 @@ interface MdastFormat {
1451
1451
  /** Plugins used for serializing the AST into this format (Finalizer + Stringifier). */
1452
1452
  output?: MdastPlugin[];
1453
1453
  }
1454
+ /**
1455
+ * Options for controlling the pipeline execution.
1456
+ */
1457
+ interface PipelineRunOptions {
1458
+ /**
1459
+ * Run the pipeline only up to the specified stage.
1460
+ * Useful for debugging or inspecting intermediate ASTs.
1461
+ */
1462
+ stage?: PipelineStage | PipelineStageName;
1463
+ /**
1464
+ * If `stage` is specified, stop execution at this index (0-based)
1465
+ * within the list of plugins at that stage.
1466
+ * Defaults to 0 (the first plugin).
1467
+ */
1468
+ stopAtIndex?: number;
1469
+ /**
1470
+ * Map of plugin names to their option overrides.
1471
+ */
1472
+ overrides?: Record<string, any>;
1473
+ }
1454
1474
  /**
1455
1475
  * Metadata capturing the origin of a node during conversion.
1456
1476
  */
@@ -1577,13 +1597,20 @@ declare class MdastBasePipeline {
1577
1597
  * @returns The pipeline instance for chaining.
1578
1598
  */
1579
1599
  from(fmt: string | MdastFormat, overrides?: Record<string, any>): this;
1600
+ /**
1601
+ * Resolves the final plugin queue for execution based on the target format and run options.
1602
+ * Calculates the effective plugin list by applying overrides, handling partial execution (stage/stopAtIndex),
1603
+ * and injecting necessary input/output plugins.
1604
+ * @protected
1605
+ */
1606
+ protected resolveRunQueue(format: MdastFormat, overrides?: Record<string, any>, stage?: PipelineStage, stopAtIndex?: number): MdastPlugin[];
1580
1607
  /**
1581
1608
  * Processes the pipeline and serializes the result into the specified format.
1582
1609
  * @param fmt - Target format ID or definition.
1583
- * @param overrides - Optional map to override plugin options.
1610
+ * @param optionsOrOverrides - Pipeline execution options or plugin option overrides.
1584
1611
  * @returns A promise resolving to a VFile containing the result.
1585
1612
  */
1586
- to(fmt: string | MdastFormat, overrides?: Record<string, any>): Promise<VFile>;
1613
+ to(fmt: string | MdastFormat, optionsOrOverrides?: PipelineRunOptions | Record<string, any>): Promise<VFile>;
1587
1614
  /**
1588
1615
  * Adds a plugin or an array of plugins to the pipeline's compile stage.
1589
1616
  * @param plugin - The unified plugin function, a MdastPlugin object, or an array of them.
@@ -1654,17 +1681,16 @@ declare class MdastPipeline extends MdastBasePipeline {
1654
1681
  * @param options - Configuration for the extraction.
1655
1682
  * @param options.stage - Run the pipeline up to this stage only.
1656
1683
  * @param options.overrides - Map for plugin option overrides.
1684
+ * @param options.stopAtIndex - Index of the stage plugin to stop at (0-based). Defaults to 0 (the first plugin in the stage).
1657
1685
  */
1658
- toAst(options?: {
1659
- stage?: PipelineStage | PipelineStageName;
1660
- overrides?: Record<string, any>;
1661
- }): Promise<Root$1>;
1686
+ toAst(options?: PipelineRunOptions): Promise<Root$1>;
1662
1687
  /** Alias for toHtml() */
1663
1688
  toHTML(): Promise<string>;
1664
1689
  /** Alias for toAst() */
1665
1690
  toAST(options?: {
1666
1691
  stage?: PipelineStage | PipelineStageName;
1667
1692
  overrides?: Record<string, any>;
1693
+ stopAtIndex?: number;
1668
1694
  }): Promise<Root$1>;
1669
1695
  }
1670
1696
  /**
@@ -1712,6 +1738,7 @@ interface ReadabilityOptions {
1712
1738
  url?: string;
1713
1739
  readability?: Record<string, any> | false;
1714
1740
  jsdom?: Record<string, any>;
1741
+ hast?: Record<string, any>;
1715
1742
  'rehype-parse'?: Record<string, any>;
1716
1743
  }
1717
1744
  /**
@@ -1751,4 +1778,4 @@ declare const htmlReadabilityPlugins: ({
1751
1778
  after: string;
1752
1779
  })[];
1753
1780
 
1754
- export { DefaultPipelineStage, MdastBasePipeline, type MdastDataOrigin, type MdastFormat, type MdastMark, MdastPipeline, type MdastPlugin, type MdastSub, type MdastSup, PipelineStage, type PipelineStageName, type ReadabilityOptions, astCompiler, astFormat, htmlFormat, htmlReadability, htmlReadabilityPlugin, htmlReadabilityPlugins, jsonParser, markdownFormat, mdast, restoreReadabilityMetaPlugin };
1781
+ export { DefaultPipelineStage, MdastBasePipeline, type MdastDataOrigin, type MdastFormat, type MdastMark, MdastPipeline, type MdastPlugin, type MdastSub, type MdastSup, type PipelineRunOptions, PipelineStage, type PipelineStageName, type ReadabilityOptions, astCompiler, astFormat, htmlFormat, htmlReadability, htmlReadabilityPlugin, htmlReadabilityPlugins, jsonParser, markdownFormat, mdast, restoreReadabilityMetaPlugin };
package/dist/index.d.ts CHANGED
@@ -1451,6 +1451,26 @@ interface MdastFormat {
1451
1451
  /** Plugins used for serializing the AST into this format (Finalizer + Stringifier). */
1452
1452
  output?: MdastPlugin[];
1453
1453
  }
1454
+ /**
1455
+ * Options for controlling the pipeline execution.
1456
+ */
1457
+ interface PipelineRunOptions {
1458
+ /**
1459
+ * Run the pipeline only up to the specified stage.
1460
+ * Useful for debugging or inspecting intermediate ASTs.
1461
+ */
1462
+ stage?: PipelineStage | PipelineStageName;
1463
+ /**
1464
+ * If `stage` is specified, stop execution at this index (0-based)
1465
+ * within the list of plugins at that stage.
1466
+ * Defaults to 0 (the first plugin).
1467
+ */
1468
+ stopAtIndex?: number;
1469
+ /**
1470
+ * Map of plugin names to their option overrides.
1471
+ */
1472
+ overrides?: Record<string, any>;
1473
+ }
1454
1474
  /**
1455
1475
  * Metadata capturing the origin of a node during conversion.
1456
1476
  */
@@ -1577,13 +1597,20 @@ declare class MdastBasePipeline {
1577
1597
  * @returns The pipeline instance for chaining.
1578
1598
  */
1579
1599
  from(fmt: string | MdastFormat, overrides?: Record<string, any>): this;
1600
+ /**
1601
+ * Resolves the final plugin queue for execution based on the target format and run options.
1602
+ * Calculates the effective plugin list by applying overrides, handling partial execution (stage/stopAtIndex),
1603
+ * and injecting necessary input/output plugins.
1604
+ * @protected
1605
+ */
1606
+ protected resolveRunQueue(format: MdastFormat, overrides?: Record<string, any>, stage?: PipelineStage, stopAtIndex?: number): MdastPlugin[];
1580
1607
  /**
1581
1608
  * Processes the pipeline and serializes the result into the specified format.
1582
1609
  * @param fmt - Target format ID or definition.
1583
- * @param overrides - Optional map to override plugin options.
1610
+ * @param optionsOrOverrides - Pipeline execution options or plugin option overrides.
1584
1611
  * @returns A promise resolving to a VFile containing the result.
1585
1612
  */
1586
- to(fmt: string | MdastFormat, overrides?: Record<string, any>): Promise<VFile>;
1613
+ to(fmt: string | MdastFormat, optionsOrOverrides?: PipelineRunOptions | Record<string, any>): Promise<VFile>;
1587
1614
  /**
1588
1615
  * Adds a plugin or an array of plugins to the pipeline's compile stage.
1589
1616
  * @param plugin - The unified plugin function, a MdastPlugin object, or an array of them.
@@ -1654,17 +1681,16 @@ declare class MdastPipeline extends MdastBasePipeline {
1654
1681
  * @param options - Configuration for the extraction.
1655
1682
  * @param options.stage - Run the pipeline up to this stage only.
1656
1683
  * @param options.overrides - Map for plugin option overrides.
1684
+ * @param options.stopAtIndex - Index of the stage plugin to stop at (0-based). Defaults to 0 (the first plugin in the stage).
1657
1685
  */
1658
- toAst(options?: {
1659
- stage?: PipelineStage | PipelineStageName;
1660
- overrides?: Record<string, any>;
1661
- }): Promise<Root$1>;
1686
+ toAst(options?: PipelineRunOptions): Promise<Root$1>;
1662
1687
  /** Alias for toHtml() */
1663
1688
  toHTML(): Promise<string>;
1664
1689
  /** Alias for toAst() */
1665
1690
  toAST(options?: {
1666
1691
  stage?: PipelineStage | PipelineStageName;
1667
1692
  overrides?: Record<string, any>;
1693
+ stopAtIndex?: number;
1668
1694
  }): Promise<Root$1>;
1669
1695
  }
1670
1696
  /**
@@ -1712,6 +1738,7 @@ interface ReadabilityOptions {
1712
1738
  url?: string;
1713
1739
  readability?: Record<string, any> | false;
1714
1740
  jsdom?: Record<string, any>;
1741
+ hast?: Record<string, any>;
1715
1742
  'rehype-parse'?: Record<string, any>;
1716
1743
  }
1717
1744
  /**
@@ -1751,4 +1778,4 @@ declare const htmlReadabilityPlugins: ({
1751
1778
  after: string;
1752
1779
  })[];
1753
1780
 
1754
- export { DefaultPipelineStage, MdastBasePipeline, type MdastDataOrigin, type MdastFormat, type MdastMark, MdastPipeline, type MdastPlugin, type MdastSub, type MdastSup, PipelineStage, type PipelineStageName, type ReadabilityOptions, astCompiler, astFormat, htmlFormat, htmlReadability, htmlReadabilityPlugin, htmlReadabilityPlugins, jsonParser, markdownFormat, mdast, restoreReadabilityMetaPlugin };
1781
+ export { DefaultPipelineStage, MdastBasePipeline, type MdastDataOrigin, type MdastFormat, type MdastMark, MdastPipeline, type MdastPlugin, type MdastSub, type MdastSup, type PipelineRunOptions, PipelineStage, type PipelineStageName, type ReadabilityOptions, astCompiler, astFormat, htmlFormat, htmlReadability, htmlReadabilityPlugin, htmlReadabilityPlugins, jsonParser, markdownFormat, mdast, restoreReadabilityMetaPlugin };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var t,e=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,s=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,a=(t,e,s,a)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let u of n(e))o.call(t,u)||u===s||r(t,u,{get:()=>e[u],enumerable:!(a=i(e,u))||a.enumerable});return t},u=(t,i,n)=>(n=null!=t?e(s(t)):{},a(!i&&t&&t.__esModule?n:r(n,"default",{value:t,enumerable:!0}),t)),l={};((t,e)=>{for(var i in e)r(t,i,{get:e[i],enumerable:!0})})(l,{DefaultPipelineStage:()=>p,MdastBasePipeline:()=>Q,MdastPipeline:()=>U,PipelineStage:()=>c,astCompiler:()=>V,astFormat:()=>G,htmlFormat:()=>L,htmlReadability:()=>Y,htmlReadabilityPlugin:()=>Z,htmlReadabilityPlugins:()=>et,jsonParser:()=>_,markdownFormat:()=>R,mdast:()=>W,restoreReadabilityMetaPlugin:()=>tt}),module.exports=(t=l,a(r({},"__esModule",{value:!0}),t));var c=(t=>(t[t.parse=0]="parse",t[t.normalize=100]="normalize",t[t.compile=200]="compile",t[t.finalize=300]="finalize",t[t.stringify=400]="stringify",t))(c||{}),p=200,f=require("unified"),h=require("vfile"),g=u(require("remark-parse")),m=u(require("remark-stringify")),d=u(require("remark-gfm")),y=u(require("remark-directive")),b=u(require("remark-math")),w=u(require("remark-frontmatter")),v=require("unist-util-visit");function k(t,e){return{type:t,children:e,data:{hName:t}}}var q={mark:(t,e,r)=>"=="+r.containerPhrasing(t,{before:"==",after:"=="})+"==",sub:(t,e,r)=>"~"+r.containerPhrasing(t,{before:"~",after:"~"})+"~",sup:(t,e,r)=>"^"+r.containerPhrasing(t,{before:"^",after:"^"})+"^"},j={plugin:()=>t=>{!function(t){(0,v.visit)(t,"text",(t,e,r)=>{if(!r||void 0===e)return;const i=t.value;let n=0;const s=[];let o=!1;const a=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let u;for(;null!==(u=a.exec(i));){o=!0;const t=u[0],e=u.index;e>n&&s.push({type:"text",value:i.slice(n,e)});let r="mark",l="";t.startsWith("==")?(r="mark",l=t.slice(2,-2)):t.startsWith("~")?(r="sub",l=t.slice(1,-1)):t.startsWith("^")&&(r="sup",l=t.slice(1,-1)),s.push(k(r,[{type:"text",value:l}])),n=a.lastIndex}return o?(n<i.length&&s.push({type:"text",value:i.slice(n)}),r.children.splice(e,1,...s),e+s.length):void 0})}(t)},stage:100},M=require("unist-util-visit"),P={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},x={plugin:()=>async t=>{(0,M.visit)(t,["containerDirective","leafDirective","textDirective"],t=>{const e=t,r=e.name.toLowerCase();if(e.name=P[r]||r,e.children&&e.children.length>0){const t=e.children[0];if(t.data?.directiveLabel||"directiveLabel"===t.type){const r=t;let i="";(0,M.visit)(r,"text",t=>{i+=t.value}),i&&!e.attributes?.title&&(e.attributes=e.attributes||{},e.attributes.title=i.trim()),e.children.shift()}}e.attributes?.title&&(e.attributes.title=String(e.attributes.title).trim()),e.data=e.data||{},e.data.hName=e.data.hName||("containerDirective"===e.type?"div":"span"),e.data.hProperties={...e.data.hProperties||{},...e.attributes,className:[e.name,e.data.hProperties?.className].filter(Boolean).join(" ")}})},stage:100,order:10},S=require("unist-util-visit"),F={plugin:()=>async t=>{(0,S.visit)(t,"tableCell",t=>{if(t.data){const{rowspan:e,colspan:r}=t.data;t.data.hProperties=t.data.hProperties||{},void 0!==e&&(t.data.hProperties.rowSpan=e,delete t.data.rowspan),void 0!==r&&(t.data.hProperties.colSpan=r,delete t.data.colspan)}})},stage:100,order:20},T=require("unist-util-visit"),O=require("shell-quote");var A={plugin:()=>async t=>{(0,T.visit)(t,"code",t=>{if(t.meta){const e=function(t){const e={},r=(0,O.parse)(t);for(const t of r)if("string"==typeof t){const r=t.split("=",2);2===r.length?e[r[0]]=r[1]:e[t]="true"}return e}(t.meta),r=t.data=t.data||{};e.title&&(r.title=e.title),e.filename&&(r.filename=e.filename),r.kv={...r.kv||{},...e}}})},stage:100,order:30},D=require("unist-util-visit"),N={plugin:()=>async t=>{(0,D.visit)(t,"image",t=>{const e=t.data=t.data||{},r=e.hProperties=e.hProperties||{},i=/[#?&](?:width=([0-9]+))?(?:&?height=([0-9]+))?(?:=([0-9]+)x([0-9]+))?$/,n=t.url.match(i);if(n){const e=n[1]||n[3],s=n[2]||n[4];e&&!r.width&&(r.width=parseInt(e,10)),s&&!r.height&&(r.height=parseInt(s,10)),t.url=t.url.replace(i,"")}e.width&&!r.width&&(r.width=e.width),e.height&&!r.height&&(r.height=e.height)})},stage:100,order:40},E=[{plugin:g.default,stage:0},{plugin:d.default,options:[{singleTilde:!1}],stage:0},{plugin:y.default,stage:0},{plugin:b.default,stage:0},{plugin:w.default,options:[["yaml","toml"]],stage:0},x,F,A,N,j],z=[{plugin:m.default,options:[{handlers:q}],stage:400},{plugin:d.default,options:[{singleTilde:!1}],stage:400},{plugin:y.default,stage:400},{plugin:b.default,stage:400},{plugin:w.default,options:[["yaml","toml"]],stage:400}];z.forEach(t=>{t.plugin===m.default?t.order=100:t.order=10});var R={id:"markdown",title:"Markdown (GFM + Directives)",extensions:["md","markdown","mdown","mkdn"],mediaTypes:["text/markdown"],input:E,output:z},$=u(require("rehype-parse")),B=u(require("rehype-remark")),C=u(require("remark-rehype")),H=u(require("rehype-sanitize")),I=u(require("rehype-stringify")),L={id:"html",title:"HTML",extensions:["html","htm"],mediaTypes:["text/html"],input:[{name:"rehype-parse",plugin:$.default,stage:0},{name:"rehype-remark",plugin:B.default,options:[{handlers:{mark:(t,e)=>{const r={type:"mark",children:t.all(e)};return t.patch(e,r),r},sub:(t,e)=>{const r={type:"sub",children:t.all(e)};return t.patch(e,r),r},sup:(t,e)=>{const r={type:"sup",children:t.all(e)};return t.patch(e,r),r}}}],stage:0}],output:[{plugin:C.default,stage:300,order:10},{plugin:H.default,options:[{...H.defaultSchema,tagNames:[...H.defaultSchema.tagNames||[],"mark","sub","sup"],attributes:{...H.defaultSchema.attributes,"*":[...H.defaultSchema.attributes?.["*"]||[],"className","id","style"],td:[...H.defaultSchema.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...H.defaultSchema.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...H.defaultSchema.attributes?.img||[],"width","height"]}}],stage:300,order:20},{plugin:I.default,stage:400}]};function V(){this.Compiler=t=>t}function _(){this.Parser=t=>JSON.parse(t)}var G={id:"ast",title:"MDAST",input:[{plugin:_,stage:0},x,F,A,N,j],output:[{plugin:V,options:[],stage:400}]};function J(t){return"object"==typeof t&&null!==t&&"string"==typeof t.type}var K=class t{constructor(t){this.queue=[],this._data={},this.input=t}static register(t){this.registry.set(t.id,t)}static getFormat(t){return this.registry.get(t)}data(t,e){return"string"==typeof t?this._data[t]=e:Object.assign(this._data,t),this}getFormat(t){return this.constructor.getFormat(t)}resolveFormat(t){if("string"==typeof t){const e=this.getFormat(t);if(!e)throw new Error(`[MdastPlus] Format '${t}' is not registered.`);return e}return t}toRuntimeEntry(t,e,r){let i=e;void 0!==t.stage&&(i="string"==typeof t.stage?c[t.stage]??e:t.stage);let n=t.options||[];const s=t.name||t.plugin.name;if(r&&s&&s in r){const e=r[s];"object"!=typeof e||null===e||Array.isArray(e)?n=Array.isArray(e)?e:[e]:("main"in e&&(t.main=!!e.main),"before"in e&&(t.before=e.before),"after"in e&&(t.after=e.after),n=[e])}return{name:s,plugin:t.plugin,options:n,stage:i,order:t.order||0,main:t.main,before:t.before,after:t.after}}ensureInputPlugins(e,r,i=400){const n=e.some(t=>0===(t.stage??p)),s=J(this.input);if(!n){let n=[];if(s){const e=t.getFormat("ast");e&&e.input&&(n=e.input)}else{const e=t.getFormat("markdown");e&&e.input&&(n=e.input)}for(const t of n){const n=this.toRuntimeEntry(t,0,r);(n.stage??p)<=i&&e.push(n)}}}from(t,e){const r=this.resolveFormat(t);if(!r.input||0===r.input.length)throw new Error(`[MdastPlus] Format '${r.id}' does not support input.`);for(const t of r.input)this.queue.push(this.toRuntimeEntry(t,0,e));return this}async to(t,e){const r=this.resolveFormat(t);if(!r.output)throw new Error(`[MdastPlus] Format '${r.id}' does not support output.`);const i=[...this.queue];this.ensureInputPlugins(i,e);for(const t of r.output)i.push(this.toRuntimeEntry(t,300,e));const n=this.assembleProcessor(i);if(J(this.input)){const t=await n.run(this.input),e=n.stringify(t),r=new h.VFile;return"string"==typeof e||Buffer.isBuffer(e)?r.value=e:r.result=e,r}return n.process(this.input)}use(t,...e){return this.useAt("compile",t,...e)}useAt(t,e,...r){if(Array.isArray(t)){for(const i of t)this.useAt(i,e,...r);return this}if(Array.isArray(e)){for(const i of e)this.useAt(t,i,...r);return this}if("object"==typeof t&&null!==t&&"plugin"in t){const i=t,n=void 0!==i.stage?"string"==typeof i.stage?c[i.stage]:i.stage:p,s=void 0!==e?[e,...r]:i.options;this.queue.push(this.toRuntimeEntry({...i,options:s},n))}else{const i="string"==typeof t?c[t]??p:t;if("object"==typeof e&&null!==e&&"plugin"in e){const t=e,n=r.length>0?r:t.options;this.queue.push(this.toRuntimeEntry({...t,options:n},i))}else e&&this.queue.push({plugin:e,options:r,stage:i,order:0})}return this}priority(t){const e=this.queue[this.queue.length-1];return e&&(e.order=t),this}configure(t,...e){for(let r=this.queue.length-1;r>=0;r--){const i=this.queue[r];if((i.name||i.plugin.name)===t){i.options=e;break}}return this}assembleProcessor(t){const e={};for(const r of t){const t=r.stage??p;e[t]||(e[t]=[]),e[t].push(r)}const r=[],i=Object.keys(e).map(Number).sort((t,e)=>t-e);for(const t of i){const i=e[t].sort((t,e)=>(t.order||0)-(e.order||0)),n=i.findIndex(t=>t.main);if(-1!==n){const t=i[n];!1===t.options?.[0]?console.warn(`Main Plugin "${t.name}" is disabled. Skipping.`):(i.splice(n,1),i[0]=t)}let s=!0,o=0;for(;s&&o<i.length;){s=!1,o++;for(let t=0;t<i.length;t++){const e=i[t];if(e.after){const r=i.findIndex(t=>t.name===e.after);if(-1!==r&&r>t){i.splice(t,1),i.splice(r,0,e),s=!0;break}}if(e.before){const r=i.findIndex(t=>t.name===e.before);if(-1!==r&&r<t){i.splice(t,1),i.splice(r,0,e),s=!0;break}}}}r.push(...i)}const n=(0,f.unified)();Object.keys(this._data).length>0&&n.data(this._data);for(const t of r)n.use(t.plugin,...t.options||[]);return n}};K.registry=new Map;var Q=K,U=class extends Q{async toMarkdown(){const t=await this.to("markdown");return String(t)}toMarkdownVFile(){return this.to("markdown")}async toHtml(){const t=await this.to("html");return String(t)}toHtmlVFile(){return this.to("html")}async toAst(t){if(t?.stage){const e="string"==typeof t.stage?c[t.stage]:t.stage,r=this.queue.filter(t=>(t.stage??p)<=e);r.push({plugin:V,options:[],stage:400,order:0}),this.ensureInputPlugins(r,t.overrides,e);const i=this.assembleProcessor(r);if(J(this.input)){return await i.run(this.input)}return(await i.process(this.input)).result}return(await this.to("ast",t?.overrides)).result}toHTML(){return this.toHtml()}toAST(t){return this.toAst(t)}};function W(t){return new U(t)}U.register(R),U.register(L),U.register(G);var X=require("hast-util-from-html"),Y=function(t){const{readability:e,jsdom:r,url:i}=t||{};this.parser=function(t,n){if(!1===e)return(0,X.fromHtml)(t,{fragment:!0});let s,o;try{s=require("jsdom").JSDOM;o=require("@mozilla/readability").Readability}catch(t){throw new Error("[html-readability] Dependency missing. Please install 'jsdom' and '@mozilla/readability'.")}const a=new o(new s(t,{url:i,pretendToBeVisual:!0,...r}).window.document,{maxElemsToParse:1e5,nbTopCandidates:5,charThreshold:500,keepClasses:!0,...e}).parse();if(!a||!a.content)return(0,X.fromHtml)(t,{fragment:!0});const u=(0,X.fromHtml)(a.content,{fragment:!0}),l={title:a.title,byline:a.byline,excerpt:a.excerpt,siteName:a.siteName,lang:a.lang};return n&&(n.data=n.data||{},n.data.readability=l),u&&(u.data=u.data||{},u.data.readability=l),u}},Z={name:"readability",plugin:Y,stage:0,main:!0},tt={name:"restore-readability-meta",plugin:()=>(t,e)=>{e.data?.readability&&(t.data=t.data||{},t.data.readability=e.data.readability)},stage:0,after:"rehype-remark"},et=[Z,tt];
1
+ "use strict";var t,e=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,s=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,a=(t,e,s,a)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let l of n(e))o.call(t,l)||l===s||r(t,l,{get:()=>e[l],enumerable:!(a=i(e,l))||a.enumerable});return t},l=(t,i,n)=>(n=null!=t?e(s(t)):{},a(!i&&t&&t.__esModule?n:r(n,"default",{value:t,enumerable:!0}),t)),u={};((t,e)=>{for(var i in e)r(t,i,{get:e[i],enumerable:!0})})(u,{DefaultPipelineStage:()=>p,MdastBasePipeline:()=>K,MdastPipeline:()=>U,PipelineStage:()=>c,astCompiler:()=>V,astFormat:()=>G,htmlFormat:()=>L,htmlReadability:()=>Z,htmlReadabilityPlugin:()=>tt,htmlReadabilityPlugins:()=>rt,jsonParser:()=>_,markdownFormat:()=>R,mdast:()=>W,restoreReadabilityMetaPlugin:()=>et}),module.exports=(t=u,a(r({},"__esModule",{value:!0}),t));var c=(t=>(t[t.parse=0]="parse",t[t.normalize=100]="normalize",t[t.compile=200]="compile",t[t.finalize=300]="finalize",t[t.stringify=400]="stringify",t))(c||{}),p=200,f=require("unified"),h=require("vfile"),m=l(require("remark-parse")),d=l(require("remark-stringify")),g=l(require("remark-gfm")),y=l(require("remark-directive")),b=l(require("remark-math")),v=l(require("remark-frontmatter")),w=require("unist-util-visit");function k(t,e){return{type:t,children:e,data:{hName:t}}}var q={mark:(t,e,r)=>"=="+r.containerPhrasing(t,{before:"==",after:"=="})+"==",sub:(t,e,r)=>"~"+r.containerPhrasing(t,{before:"~",after:"~"})+"~",sup:(t,e,r)=>"^"+r.containerPhrasing(t,{before:"^",after:"^"})+"^"},j={plugin:()=>t=>{!function(t){(0,w.visit)(t,"text",(t,e,r)=>{if(!r||void 0===e)return;const i=t.value;let n=0;const s=[];let o=!1;const a=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let l;for(;null!==(l=a.exec(i));){o=!0;const t=l[0],e=l.index;e>n&&s.push({type:"text",value:i.slice(n,e)});let r="mark",u="";t.startsWith("==")?(r="mark",u=t.slice(2,-2)):t.startsWith("~")?(r="sub",u=t.slice(1,-1)):t.startsWith("^")&&(r="sup",u=t.slice(1,-1)),s.push(k(r,[{type:"text",value:u}])),n=a.lastIndex}return o?(n<i.length&&s.push({type:"text",value:i.slice(n)}),r.children.splice(e,1,...s),e+s.length):void 0})}(t)},stage:100},M=require("unist-util-visit"),P={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},x={plugin:()=>async t=>{(0,M.visit)(t,["containerDirective","leafDirective","textDirective"],t=>{const e=t,r=e.name.toLowerCase();if(e.name=P[r]||r,e.children&&e.children.length>0){const t=e.children[0];if(t.data?.directiveLabel||"directiveLabel"===t.type){const r=t;let i="";(0,M.visit)(r,"text",t=>{i+=t.value}),i&&!e.attributes?.title&&(e.attributes=e.attributes||{},e.attributes.title=i.trim()),e.children.shift()}}e.attributes?.title&&(e.attributes.title=String(e.attributes.title).trim()),e.data=e.data||{},e.data.hName=e.data.hName||("containerDirective"===e.type?"div":"span"),e.data.hProperties={...e.data.hProperties||{},...e.attributes,className:[e.name,e.data.hProperties?.className].filter(Boolean).join(" ")}})},stage:100,order:10},S=require("unist-util-visit"),T={plugin:()=>async t=>{(0,S.visit)(t,"tableCell",t=>{if(t.data){const{rowspan:e,colspan:r}=t.data;t.data.hProperties=t.data.hProperties||{},void 0!==e&&(t.data.hProperties.rowSpan=e,delete t.data.rowspan),void 0!==r&&(t.data.hProperties.colSpan=r,delete t.data.colspan)}})},stage:100,order:20},F=require("unist-util-visit"),N=require("shell-quote");var O={plugin:()=>async t=>{(0,F.visit)(t,"code",t=>{if(t.meta){const e=function(t){const e={},r=(0,N.parse)(t);for(const t of r)if("string"==typeof t){const r=t.split("=",2);2===r.length?e[r[0]]=r[1]:e[t]="true"}return e}(t.meta),r=t.data=t.data||{};e.title&&(r.title=e.title),e.filename&&(r.filename=e.filename),r.kv={...r.kv||{},...e}}})},stage:100,order:30},A=require("unist-util-visit"),D={plugin:()=>async t=>{(0,A.visit)(t,"image",t=>{const e=t.data=t.data||{},r=e.hProperties=e.hProperties||{},i=/[#?&](?:width=([0-9]+))?(?:&?height=([0-9]+))?(?:=([0-9]+)x([0-9]+))?$/,n=t.url.match(i);if(n){const e=n[1]||n[3],s=n[2]||n[4];e&&!r.width&&(r.width=parseInt(e,10)),s&&!r.height&&(r.height=parseInt(s,10)),t.url=t.url.replace(i,"")}e.width&&!r.width&&(r.width=e.width),e.height&&!r.height&&(r.height=e.height)})},stage:100,order:40},z=[{plugin:m.default,stage:0},{plugin:g.default,options:[{singleTilde:!1}],stage:0},{plugin:y.default,stage:0},{plugin:b.default,stage:0},{plugin:v.default,options:[["yaml","toml"]],stage:0},x,T,O,D,j],E=[{plugin:d.default,options:[{handlers:q}],stage:400},{plugin:g.default,options:[{singleTilde:!1}],stage:400},{plugin:y.default,stage:400},{plugin:b.default,stage:400},{plugin:v.default,options:[["yaml","toml"]],stage:400}];E.forEach(t=>{t.plugin===d.default?t.order=100:t.order=10});var R={id:"markdown",title:"Markdown (GFM + Directives)",extensions:["md","markdown","mdown","mkdn"],mediaTypes:["text/markdown"],input:z,output:E},$=l(require("rehype-parse")),B=l(require("rehype-remark")),C=l(require("remark-rehype")),H=l(require("rehype-sanitize")),I=l(require("rehype-stringify")),L={id:"html",title:"HTML",extensions:["html","htm"],mediaTypes:["text/html"],input:[{name:"rehype-parse",plugin:$.default,stage:0},{name:"rehype-remark",plugin:B.default,options:[{handlers:{mark:(t,e)=>{const r={type:"mark",children:t.all(e)};return t.patch(e,r),r},sub:(t,e)=>{const r={type:"sub",children:t.all(e)};return t.patch(e,r),r},sup:(t,e)=>{const r={type:"sup",children:t.all(e)};return t.patch(e,r),r}}}],stage:0}],output:[{plugin:C.default,stage:300,order:10},{plugin:H.default,options:[{...H.defaultSchema,tagNames:[...H.defaultSchema.tagNames||[],"mark","sub","sup"],attributes:{...H.defaultSchema.attributes,"*":[...H.defaultSchema.attributes?.["*"]||[],"className","id","style"],td:[...H.defaultSchema.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...H.defaultSchema.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...H.defaultSchema.attributes?.img||[],"width","height"]}}],stage:300,order:20},{plugin:I.default,stage:400}]};function V(){this.Compiler=t=>t}function _(){this.Parser=t=>JSON.parse(t)}var G={id:"ast",title:"MDAST",input:[{plugin:_,stage:0},x,T,O,D,j],output:[{plugin:V,options:[],stage:400}]};function J(t){return"object"==typeof t&&null!==t&&"string"==typeof t.type}var Q=class t{constructor(t){this.queue=[],this._data={},this.input=t}static register(t){this.registry.set(t.id,t)}static getFormat(t){return this.registry.get(t)}data(t,e){return"string"==typeof t?this._data[t]=e:Object.assign(this._data,t),this}getFormat(t){return this.constructor.getFormat(t)}resolveFormat(t){if("string"==typeof t){const e=this.getFormat(t);if(!e)throw new Error(`[MdastPlus] Format '${t}' is not registered.`);return e}return t}toRuntimeEntry(t,e,r){let i=e;void 0!==t.stage&&(i="string"==typeof t.stage?c[t.stage]??e:t.stage);let n=t.options||[];const s=t.name||t.plugin.name;if(r&&s&&s in r){const e=r[s];"object"!=typeof e||null===e||Array.isArray(e)?n=Array.isArray(e)?e:[e]:("main"in e&&(t.main=!!e.main),"before"in e&&(t.before=e.before),"after"in e&&(t.after=e.after),n=[e])}return{name:s,plugin:t.plugin,options:n,stage:i,order:t.order||0,main:t.main,before:t.before,after:t.after}}ensureInputPlugins(e,r,i=400){const n=e.some(t=>0===(t.stage??p)),s=J(this.input);if(!n){let n=[];if(s){const e=t.getFormat("ast");e&&e.input&&(n=e.input)}else{const e=t.getFormat("markdown");e&&e.input&&(n=e.input)}for(const t of n){const n=this.toRuntimeEntry(t,0,r);(n.stage??p)<=i&&e.push(n)}}}from(t,e){const r=this.resolveFormat(t);if(!r.input||0===r.input.length)throw new Error(`[MdastPlus] Format '${r.id}' does not support input.`);for(const t of r.input)this.queue.push(this.toRuntimeEntry(t,0,e));return this}resolveRunQueue(t,e,r,i){let n=[];if(n=e?this.queue.map(t=>this.toRuntimeEntry(t,t.stage??p,e)):[...this.queue],void 0!==r){const t=r;n=n.filter(e=>(e.stage??p)<=t);const s=n.findIndex(e=>(e.stage??p)===t),o=-1!==s?s+(i??0):n.length-1,a=n.slice(0,o+1),l=n.filter(t=>t.main&&!a.includes(t));n=a.concat(l),this.ensureInputPlugins(n,e,t),n.push({plugin:V,options:[],stage:400,order:0})}else if(this.ensureInputPlugins(n,e,400),t.output)for(const r of t.output)n.push(this.toRuntimeEntry(r,300,e));return n}async to(t,e){const r=this.resolveFormat(t);if(!r.output)throw new Error(`[MdastPlus] Format '${r.id}' does not support output.`);let i,n,s;if(e){const t=e;"overrides"in t||"stage"in t||"stopAtIndex"in t?(i=t.overrides,n="string"==typeof t.stage?c[t.stage]:t.stage,s=t.stopAtIndex):i=e}const o=this.resolveRunQueue(r,i,n,s),a=this.assembleProcessor(o);if(J(this.input)){const t=await a.run(this.input),e=a.stringify(t),r=new h.VFile;return"string"==typeof e||Buffer.isBuffer(e)?r.value=e:r.result=e,r}return a.process(this.input)}use(t,...e){return this.useAt("compile",t,...e)}useAt(t,e,...r){if(Array.isArray(t)){for(const i of t)this.useAt(i,e,...r);return this}if(Array.isArray(e)){for(const i of e)this.useAt(t,i,...r);return this}if("object"==typeof t&&null!==t&&"plugin"in t){const i=t,n=void 0!==i.stage?"string"==typeof i.stage?c[i.stage]:i.stage:p,s=void 0!==e?[e,...r]:i.options;this.queue.push(this.toRuntimeEntry({...i,options:s},n))}else{const i="string"==typeof t?c[t]??p:t;if("object"==typeof e&&null!==e&&"plugin"in e){const t=e,n=r.length>0?r:t.options;this.queue.push(this.toRuntimeEntry({...t,options:n},i))}else e&&this.queue.push({plugin:e,options:r,stage:i,order:0})}return this}priority(t){const e=this.queue[this.queue.length-1];return e&&(e.order=t),this}configure(t,...e){for(let r=this.queue.length-1;r>=0;r--){const i=this.queue[r];if((i.name||i.plugin.name)===t){i.options=e;break}}return this}assembleProcessor(t){const e={};for(const r of t){const t=r.stage??p;e[t]||(e[t]=[]),e[t].push(r)}const r=[],i=Object.keys(e).map(Number).sort((t,e)=>t-e);for(const t of i){const i=e[t].sort((t,e)=>(t.order||0)-(e.order||0)),n=i.findIndex(t=>t.main);if(-1!==n){const t=i[n];!1===t.options?.[0]?console.warn(`Main Plugin "${t.name}" is disabled. Skipping.`):0!==n&&(i.splice(n,1),i[0]=t)}let s=!0,o=0;for(;s&&o<i.length;){s=!1,o++;for(let t=0;t<i.length;t++){const e=i[t];if(e.after){const r=i.findIndex(t=>t.name===e.after);if(-1!==r&&r>t){i.splice(t,1),i.splice(r,0,e),s=!0;break}}if(e.before){const r=i.findIndex(t=>t.name===e.before);if(-1!==r&&r<t){i.splice(t,1),i.splice(r,0,e),s=!0;break}}}}r.push(...i)}const n=(0,f.unified)();Object.keys(this._data).length>0&&n.data(this._data);for(const t of r)n.use(t.plugin,...t.options||[]);return n}};Q.registry=new Map;var K=Q,U=class extends K{async toMarkdown(){const t=await this.to("markdown");return String(t)}toMarkdownVFile(){return this.to("markdown")}async toHtml(){const t=await this.to("html");return String(t)}toHtmlVFile(){return this.to("html")}async toAst(t){return(await this.to("ast",t)).result}toHTML(){return this.toHtml()}toAST(t){return this.toAst(t)}};function W(t){return new U(t)}U.register(R),U.register(L),U.register(G);var X=require("hast-util-from-html"),Y=require("hast-util-from-dom"),Z=function(t){const{readability:e,jsdom:r,hast:i,url:n}=t||{};this.parser=function(t,s){if(!1===e)return(0,X.fromHtml)(t,{fragment:!0,...i});let o,a;try{o=require("jsdom").JSDOM;a=require("@mozilla/readability").Readability}catch(t){throw new Error("[html-readability] Dependency missing. Please install 'jsdom' and '@mozilla/readability'.")}const l=new a(new o(t,{url:n,pretendToBeVisual:!0,...r,includeNodeLocations:!0}).window.document,{maxElemsToParse:1e5,nbTopCandidates:5,charThreshold:500,keepClasses:!0,...e,serializer:t=>t}).parse();if(!l||!l.content)return(0,X.fromHtml)(t,{fragment:!0,...i});const u=l.content;let c=(0,Y.fromDom)(u,{afterTransform:i?.afterTransform});const p=!1!==i?.fragment,f={...l};return delete f.content,delete f.textContent,s&&(s.data=s.data||{},s.data.readability=f),c&&(c=p?{type:"root",children:[c]}:{type:"root",children:[{type:"element",tagName:"html",properties:{},children:[{type:"element",tagName:"head",properties:{},children:[]},{type:"element",tagName:"body",properties:{},children:[c]}]}]},c.data=c.data||{},c.data.readability=f),c}},tt={name:"readability",plugin:Z,stage:0,main:!0},et={name:"restore-readability-meta",plugin:()=>(t,e)=>{e.data?.readability&&(t.data=t.data||{},t.data.readability=e.data.readability)},stage:0,after:"rehype-remark"},rt=[tt,et];
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var t=(t=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(t,{get:(t,e)=>("undefined"!=typeof require?require:t)[e]}):t)(function(t){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),e=(t=>(t[t.parse=0]="parse",t[t.normalize=100]="normalize",t[t.compile=200]="compile",t[t.finalize=300]="finalize",t[t.stringify=400]="stringify",t))(e||{}),r=200;import{unified as i}from"unified";import{VFile as n}from"vfile";import o from"remark-parse";import s from"remark-stringify";import a from"remark-gfm";import u from"remark-directive";import p from"remark-math";import l from"remark-frontmatter";import{visit as f}from"unist-util-visit";function m(t,e){return{type:t,children:e,data:{hName:t}}}var c={plugin:()=>t=>{!function(t){f(t,"text",(t,e,r)=>{if(!r||void 0===e)return;const i=t.value;let n=0;const o=[];let s=!1;const a=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let u;for(;null!==(u=a.exec(i));){s=!0;const t=u[0],e=u.index;e>n&&o.push({type:"text",value:i.slice(n,e)});let r="mark",p="";t.startsWith("==")?(r="mark",p=t.slice(2,-2)):t.startsWith("~")?(r="sub",p=t.slice(1,-1)):t.startsWith("^")&&(r="sup",p=t.slice(1,-1)),o.push(m(r,[{type:"text",value:p}])),n=a.lastIndex}return s?(n<i.length&&o.push({type:"text",value:i.slice(n)}),r.children.splice(e,1,...o),e+o.length):void 0})}(t)},stage:100};import{visit as h}from"unist-util-visit";var g={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},d={plugin:()=>async t=>{h(t,["containerDirective","leafDirective","textDirective"],t=>{const e=t,r=e.name.toLowerCase();if(e.name=g[r]||r,e.children&&e.children.length>0){const t=e.children[0];if(t.data?.directiveLabel||"directiveLabel"===t.type){let r="";h(t,"text",t=>{r+=t.value}),r&&!e.attributes?.title&&(e.attributes=e.attributes||{},e.attributes.title=r.trim()),e.children.shift()}}e.attributes?.title&&(e.attributes.title=String(e.attributes.title).trim()),e.data=e.data||{},e.data.hName=e.data.hName||("containerDirective"===e.type?"div":"span"),e.data.hProperties={...e.data.hProperties||{},...e.attributes,className:[e.name,e.data.hProperties?.className].filter(Boolean).join(" ")}})},stage:100,order:10};import{visit as y}from"unist-util-visit";var v={plugin:()=>async t=>{y(t,"tableCell",t=>{if(t.data){const{rowspan:e,colspan:r}=t.data;t.data.hProperties=t.data.hProperties||{},void 0!==e&&(t.data.hProperties.rowSpan=e,delete t.data.rowspan),void 0!==r&&(t.data.hProperties.colSpan=r,delete t.data.colspan)}})},stage:100,order:20};import{visit as w}from"unist-util-visit";import{parse as b}from"shell-quote";var k={plugin:()=>async t=>{w(t,"code",t=>{if(t.meta){const e=function(t){const e={},r=b(t);for(const t of r)if("string"==typeof t){const r=t.split("=",2);2===r.length?e[r[0]]=r[1]:e[t]="true"}return e}(t.meta),r=t.data=t.data||{};e.title&&(r.title=e.title),e.filename&&(r.filename=e.filename),r.kv={...r.kv||{},...e}}})},stage:100,order:30};import{visit as x}from"unist-util-visit";var M={plugin:()=>async t=>{x(t,"image",t=>{const e=t.data=t.data||{},r=e.hProperties=e.hProperties||{},i=/[#?&](?:width=([0-9]+))?(?:&?height=([0-9]+))?(?:=([0-9]+)x([0-9]+))?$/,n=t.url.match(i);if(n){const e=n[1]||n[3],o=n[2]||n[4];e&&!r.width&&(r.width=parseInt(e,10)),o&&!r.height&&(r.height=parseInt(o,10)),t.url=t.url.replace(i,"")}e.width&&!r.width&&(r.width=e.width),e.height&&!r.height&&(r.height=e.height)})},stage:100,order:40},T=[{plugin:o,stage:0},{plugin:a,options:[{singleTilde:!1}],stage:0},{plugin:u,stage:0},{plugin:p,stage:0},{plugin:l,options:[["yaml","toml"]],stage:0},d,v,k,M,c],S=[{plugin:s,options:[{handlers:{mark:(t,e,r)=>"=="+r.containerPhrasing(t,{before:"==",after:"=="})+"==",sub:(t,e,r)=>"~"+r.containerPhrasing(t,{before:"~",after:"~"})+"~",sup:(t,e,r)=>"^"+r.containerPhrasing(t,{before:"^",after:"^"})+"^"}}],stage:400},{plugin:a,options:[{singleTilde:!1}],stage:400},{plugin:u,stage:400},{plugin:p,stage:400},{plugin:l,options:[["yaml","toml"]],stage:400}];S.forEach(t=>{t.plugin===s?t.order=100:t.order=10});var j={id:"markdown",title:"Markdown (GFM + Directives)",extensions:["md","markdown","mdown","mkdn"],mediaTypes:["text/markdown"],input:T,output:S};import P from"rehype-parse";import F from"rehype-remark";import q from"remark-rehype";import A,{defaultSchema as D}from"rehype-sanitize";import E from"rehype-stringify";var N={id:"html",title:"HTML",extensions:["html","htm"],mediaTypes:["text/html"],input:[{name:"rehype-parse",plugin:P,stage:0},{name:"rehype-remark",plugin:F,options:[{handlers:{mark:(t,e)=>{const r={type:"mark",children:t.all(e)};return t.patch(e,r),r},sub:(t,e)=>{const r={type:"sub",children:t.all(e)};return t.patch(e,r),r},sup:(t,e)=>{const r={type:"sup",children:t.all(e)};return t.patch(e,r),r}}}],stage:0}],output:[{plugin:q,stage:300,order:10},{plugin:A,options:[{...D,tagNames:[...D.tagNames||[],"mark","sub","sup"],attributes:{...D.attributes,"*":[...D.attributes?.["*"]||[],"className","id","style"],td:[...D.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...D.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...D.attributes?.img||[],"width","height"]}}],stage:300,order:20},{plugin:E,stage:400}]};function z(){this.Compiler=t=>t}function $(){this.Parser=t=>JSON.parse(t)}var H={id:"ast",title:"MDAST",input:[{plugin:$,stage:0},d,v,k,M,c],output:[{plugin:z,options:[],stage:400}]};function O(t){return"object"==typeof t&&null!==t&&"string"==typeof t.type}var B=class t{constructor(t){this.queue=[],this._data={},this.input=t}static register(t){this.registry.set(t.id,t)}static getFormat(t){return this.registry.get(t)}data(t,e){return"string"==typeof t?this._data[t]=e:Object.assign(this._data,t),this}getFormat(t){return this.constructor.getFormat(t)}resolveFormat(t){if("string"==typeof t){const e=this.getFormat(t);if(!e)throw new Error(`[MdastPlus] Format '${t}' is not registered.`);return e}return t}toRuntimeEntry(t,r,i){let n=r;void 0!==t.stage&&(n="string"==typeof t.stage?e[t.stage]??r:t.stage);let o=t.options||[];const s=t.name||t.plugin.name;if(i&&s&&s in i){const e=i[s];"object"!=typeof e||null===e||Array.isArray(e)?o=Array.isArray(e)?e:[e]:("main"in e&&(t.main=!!e.main),"before"in e&&(t.before=e.before),"after"in e&&(t.after=e.after),o=[e])}return{name:s,plugin:t.plugin,options:o,stage:n,order:t.order||0,main:t.main,before:t.before,after:t.after}}ensureInputPlugins(e,i,n=400){const o=e.some(t=>0===(t.stage??r)),s=O(this.input);if(!o){let o=[];if(s){const e=t.getFormat("ast");e&&e.input&&(o=e.input)}else{const e=t.getFormat("markdown");e&&e.input&&(o=e.input)}for(const t of o){const o=this.toRuntimeEntry(t,0,i);(o.stage??r)<=n&&e.push(o)}}}from(t,e){const r=this.resolveFormat(t);if(!r.input||0===r.input.length)throw new Error(`[MdastPlus] Format '${r.id}' does not support input.`);for(const t of r.input)this.queue.push(this.toRuntimeEntry(t,0,e));return this}async to(t,e){const r=this.resolveFormat(t);if(!r.output)throw new Error(`[MdastPlus] Format '${r.id}' does not support output.`);const i=[...this.queue];this.ensureInputPlugins(i,e);for(const t of r.output)i.push(this.toRuntimeEntry(t,300,e));const o=this.assembleProcessor(i);if(O(this.input)){const t=await o.run(this.input),e=o.stringify(t),r=new n;return"string"==typeof e||Buffer.isBuffer(e)?r.value=e:r.result=e,r}return o.process(this.input)}use(t,...e){return this.useAt("compile",t,...e)}useAt(t,i,...n){if(Array.isArray(t)){for(const e of t)this.useAt(e,i,...n);return this}if(Array.isArray(i)){for(const e of i)this.useAt(t,e,...n);return this}if("object"==typeof t&&null!==t&&"plugin"in t){const o=t,s=void 0!==o.stage?"string"==typeof o.stage?e[o.stage]:o.stage:r,a=void 0!==i?[i,...n]:o.options;this.queue.push(this.toRuntimeEntry({...o,options:a},s))}else{const o="string"==typeof t?e[t]??r:t;if("object"==typeof i&&null!==i&&"plugin"in i){const t=i,e=n.length>0?n:t.options;this.queue.push(this.toRuntimeEntry({...t,options:e},o))}else i&&this.queue.push({plugin:i,options:n,stage:o,order:0})}return this}priority(t){const e=this.queue[this.queue.length-1];return e&&(e.order=t),this}configure(t,...e){for(let r=this.queue.length-1;r>=0;r--){const i=this.queue[r];if((i.name||i.plugin.name)===t){i.options=e;break}}return this}assembleProcessor(t){const e={};for(const i of t){const t=i.stage??r;e[t]||(e[t]=[]),e[t].push(i)}const n=[],o=Object.keys(e).map(Number).sort((t,e)=>t-e);for(const t of o){const r=e[t].sort((t,e)=>(t.order||0)-(e.order||0)),i=r.findIndex(t=>t.main);if(-1!==i){const t=r[i];!1===t.options?.[0]?console.warn(`Main Plugin "${t.name}" is disabled. Skipping.`):(r.splice(i,1),r[0]=t)}let o=!0,s=0;for(;o&&s<r.length;){o=!1,s++;for(let t=0;t<r.length;t++){const e=r[t];if(e.after){const i=r.findIndex(t=>t.name===e.after);if(-1!==i&&i>t){r.splice(t,1),r.splice(i,0,e),o=!0;break}}if(e.before){const i=r.findIndex(t=>t.name===e.before);if(-1!==i&&i<t){r.splice(t,1),r.splice(i,0,e),o=!0;break}}}}n.push(...r)}const s=i();Object.keys(this._data).length>0&&s.data(this._data);for(const t of n)s.use(t.plugin,...t.options||[]);return s}};B.registry=new Map;var C=B,I=class extends C{async toMarkdown(){const t=await this.to("markdown");return String(t)}toMarkdownVFile(){return this.to("markdown")}async toHtml(){const t=await this.to("html");return String(t)}toHtmlVFile(){return this.to("html")}async toAst(t){if(t?.stage){const i="string"==typeof t.stage?e[t.stage]:t.stage,n=this.queue.filter(t=>(t.stage??r)<=i);n.push({plugin:z,options:[],stage:400,order:0}),this.ensureInputPlugins(n,t.overrides,i);const o=this.assembleProcessor(n);if(O(this.input)){return await o.run(this.input)}return(await o.process(this.input)).result}return(await this.to("ast",t?.overrides)).result}toHTML(){return this.toHtml()}toAST(t){return this.toAst(t)}};function L(t){return new I(t)}I.register(j),I.register(N),I.register(H);import{fromHtml as V}from"hast-util-from-html";var G=function(e){const{readability:r,jsdom:i,url:n}=e||{};this.parser=function(e,o){if(!1===r)return V(e,{fragment:!0});let s,a;try{s=t("jsdom").JSDOM;a=t("@mozilla/readability").Readability}catch(t){throw new Error("[html-readability] Dependency missing. Please install 'jsdom' and '@mozilla/readability'.")}const u=new a(new s(e,{url:n,pretendToBeVisual:!0,...i}).window.document,{maxElemsToParse:1e5,nbTopCandidates:5,charThreshold:500,keepClasses:!0,...r}).parse();if(!u||!u.content)return V(e,{fragment:!0});const p=V(u.content,{fragment:!0}),l={title:u.title,byline:u.byline,excerpt:u.excerpt,siteName:u.siteName,lang:u.lang};return o&&(o.data=o.data||{},o.data.readability=l),p&&(p.data=p.data||{},p.data.readability=l),p}},J={name:"readability",plugin:G,stage:0,main:!0},R={name:"restore-readability-meta",plugin:()=>(t,e)=>{e.data?.readability&&(t.data=t.data||{},t.data.readability=e.data.readability)},stage:0,after:"rehype-remark"},K=[J,R];export{r as DefaultPipelineStage,C as MdastBasePipeline,I as MdastPipeline,e as PipelineStage,z as astCompiler,H as astFormat,N as htmlFormat,G as htmlReadability,J as htmlReadabilityPlugin,K as htmlReadabilityPlugins,$ as jsonParser,j as markdownFormat,L as mdast,R as restoreReadabilityMetaPlugin};
1
+ var t=(t=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(t,{get:(t,e)=>("undefined"!=typeof require?require:t)[e]}):t)(function(t){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),e=(t=>(t[t.parse=0]="parse",t[t.normalize=100]="normalize",t[t.compile=200]="compile",t[t.finalize=300]="finalize",t[t.stringify=400]="stringify",t))(e||{}),r=200;import{unified as i}from"unified";import{VFile as n}from"vfile";import o from"remark-parse";import s from"remark-stringify";import a from"remark-gfm";import l from"remark-directive";import p from"remark-math";import u from"remark-frontmatter";import{visit as m}from"unist-util-visit";function f(t,e){return{type:t,children:e,data:{hName:t}}}var c={plugin:()=>t=>{!function(t){m(t,"text",(t,e,r)=>{if(!r||void 0===e)return;const i=t.value;let n=0;const o=[];let s=!1;const a=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let l;for(;null!==(l=a.exec(i));){s=!0;const t=l[0],e=l.index;e>n&&o.push({type:"text",value:i.slice(n,e)});let r="mark",p="";t.startsWith("==")?(r="mark",p=t.slice(2,-2)):t.startsWith("~")?(r="sub",p=t.slice(1,-1)):t.startsWith("^")&&(r="sup",p=t.slice(1,-1)),o.push(f(r,[{type:"text",value:p}])),n=a.lastIndex}return s?(n<i.length&&o.push({type:"text",value:i.slice(n)}),r.children.splice(e,1,...o),e+o.length):void 0})}(t)},stage:100};import{visit as h}from"unist-util-visit";var d={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},g={plugin:()=>async t=>{h(t,["containerDirective","leafDirective","textDirective"],t=>{const e=t,r=e.name.toLowerCase();if(e.name=d[r]||r,e.children&&e.children.length>0){const t=e.children[0];if(t.data?.directiveLabel||"directiveLabel"===t.type){let r="";h(t,"text",t=>{r+=t.value}),r&&!e.attributes?.title&&(e.attributes=e.attributes||{},e.attributes.title=r.trim()),e.children.shift()}}e.attributes?.title&&(e.attributes.title=String(e.attributes.title).trim()),e.data=e.data||{},e.data.hName=e.data.hName||("containerDirective"===e.type?"div":"span"),e.data.hProperties={...e.data.hProperties||{},...e.attributes,className:[e.name,e.data.hProperties?.className].filter(Boolean).join(" ")}})},stage:100,order:10};import{visit as y}from"unist-util-visit";var v={plugin:()=>async t=>{y(t,"tableCell",t=>{if(t.data){const{rowspan:e,colspan:r}=t.data;t.data.hProperties=t.data.hProperties||{},void 0!==e&&(t.data.hProperties.rowSpan=e,delete t.data.rowspan),void 0!==r&&(t.data.hProperties.colSpan=r,delete t.data.colspan)}})},stage:100,order:20};import{visit as w}from"unist-util-visit";import{parse as b}from"shell-quote";var k={plugin:()=>async t=>{w(t,"code",t=>{if(t.meta){const e=function(t){const e={},r=b(t);for(const t of r)if("string"==typeof t){const r=t.split("=",2);2===r.length?e[r[0]]=r[1]:e[t]="true"}return e}(t.meta),r=t.data=t.data||{};e.title&&(r.title=e.title),e.filename&&(r.filename=e.filename),r.kv={...r.kv||{},...e}}})},stage:100,order:30};import{visit as x}from"unist-util-visit";var T={plugin:()=>async t=>{x(t,"image",t=>{const e=t.data=t.data||{},r=e.hProperties=e.hProperties||{},i=/[#?&](?:width=([0-9]+))?(?:&?height=([0-9]+))?(?:=([0-9]+)x([0-9]+))?$/,n=t.url.match(i);if(n){const e=n[1]||n[3],o=n[2]||n[4];e&&!r.width&&(r.width=parseInt(e,10)),o&&!r.height&&(r.height=parseInt(o,10)),t.url=t.url.replace(i,"")}e.width&&!r.width&&(r.width=e.width),e.height&&!r.height&&(r.height=e.height)})},stage:100,order:40},M=[{plugin:o,stage:0},{plugin:a,options:[{singleTilde:!1}],stage:0},{plugin:l,stage:0},{plugin:p,stage:0},{plugin:u,options:[["yaml","toml"]],stage:0},g,v,k,T,c],S=[{plugin:s,options:[{handlers:{mark:(t,e,r)=>"=="+r.containerPhrasing(t,{before:"==",after:"=="})+"==",sub:(t,e,r)=>"~"+r.containerPhrasing(t,{before:"~",after:"~"})+"~",sup:(t,e,r)=>"^"+r.containerPhrasing(t,{before:"^",after:"^"})+"^"}}],stage:400},{plugin:a,options:[{singleTilde:!1}],stage:400},{plugin:l,stage:400},{plugin:p,stage:400},{plugin:u,options:[["yaml","toml"]],stage:400}];S.forEach(t=>{t.plugin===s?t.order=100:t.order=10});var j={id:"markdown",title:"Markdown (GFM + Directives)",extensions:["md","markdown","mdown","mkdn"],mediaTypes:["text/markdown"],input:M,output:S};import N from"rehype-parse";import P from"rehype-remark";import A from"remark-rehype";import F,{defaultSchema as q}from"rehype-sanitize";import D from"rehype-stringify";var E={id:"html",title:"HTML",extensions:["html","htm"],mediaTypes:["text/html"],input:[{name:"rehype-parse",plugin:N,stage:0},{name:"rehype-remark",plugin:P,options:[{handlers:{mark:(t,e)=>{const r={type:"mark",children:t.all(e)};return t.patch(e,r),r},sub:(t,e)=>{const r={type:"sub",children:t.all(e)};return t.patch(e,r),r},sup:(t,e)=>{const r={type:"sup",children:t.all(e)};return t.patch(e,r),r}}}],stage:0}],output:[{plugin:A,stage:300,order:10},{plugin:F,options:[{...q,tagNames:[...q.tagNames||[],"mark","sub","sup"],attributes:{...q.attributes,"*":[...q.attributes?.["*"]||[],"className","id","style"],td:[...q.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...q.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...q.attributes?.img||[],"width","height"]}}],stage:300,order:20},{plugin:D,stage:400}]};function z(){this.Compiler=t=>t}function $(){this.Parser=t=>JSON.parse(t)}var H={id:"ast",title:"MDAST",input:[{plugin:$,stage:0},g,v,k,T,c],output:[{plugin:z,options:[],stage:400}]};function I(t){return"object"==typeof t&&null!==t&&"string"==typeof t.type}var L=class t{constructor(t){this.queue=[],this._data={},this.input=t}static register(t){this.registry.set(t.id,t)}static getFormat(t){return this.registry.get(t)}data(t,e){return"string"==typeof t?this._data[t]=e:Object.assign(this._data,t),this}getFormat(t){return this.constructor.getFormat(t)}resolveFormat(t){if("string"==typeof t){const e=this.getFormat(t);if(!e)throw new Error(`[MdastPlus] Format '${t}' is not registered.`);return e}return t}toRuntimeEntry(t,r,i){let n=r;void 0!==t.stage&&(n="string"==typeof t.stage?e[t.stage]??r:t.stage);let o=t.options||[];const s=t.name||t.plugin.name;if(i&&s&&s in i){const e=i[s];"object"!=typeof e||null===e||Array.isArray(e)?o=Array.isArray(e)?e:[e]:("main"in e&&(t.main=!!e.main),"before"in e&&(t.before=e.before),"after"in e&&(t.after=e.after),o=[e])}return{name:s,plugin:t.plugin,options:o,stage:n,order:t.order||0,main:t.main,before:t.before,after:t.after}}ensureInputPlugins(e,i,n=400){const o=e.some(t=>0===(t.stage??r)),s=I(this.input);if(!o){let o=[];if(s){const e=t.getFormat("ast");e&&e.input&&(o=e.input)}else{const e=t.getFormat("markdown");e&&e.input&&(o=e.input)}for(const t of o){const o=this.toRuntimeEntry(t,0,i);(o.stage??r)<=n&&e.push(o)}}}from(t,e){const r=this.resolveFormat(t);if(!r.input||0===r.input.length)throw new Error(`[MdastPlus] Format '${r.id}' does not support input.`);for(const t of r.input)this.queue.push(this.toRuntimeEntry(t,0,e));return this}resolveRunQueue(t,e,i,n){let o=[];if(o=e?this.queue.map(t=>this.toRuntimeEntry(t,t.stage??r,e)):[...this.queue],void 0!==i){const t=i;o=o.filter(e=>(e.stage??r)<=t);const s=o.findIndex(e=>(e.stage??r)===t),a=-1!==s?s+(n??0):o.length-1,l=o.slice(0,a+1),p=o.filter(t=>t.main&&!l.includes(t));o=l.concat(p),this.ensureInputPlugins(o,e,t),o.push({plugin:z,options:[],stage:400,order:0})}else if(this.ensureInputPlugins(o,e,400),t.output)for(const r of t.output)o.push(this.toRuntimeEntry(r,300,e));return o}async to(t,r){const i=this.resolveFormat(t);if(!i.output)throw new Error(`[MdastPlus] Format '${i.id}' does not support output.`);let o,s,a;if(r){const t=r;"overrides"in t||"stage"in t||"stopAtIndex"in t?(o=t.overrides,s="string"==typeof t.stage?e[t.stage]:t.stage,a=t.stopAtIndex):o=r}const l=this.resolveRunQueue(i,o,s,a),p=this.assembleProcessor(l);if(I(this.input)){const t=await p.run(this.input),e=p.stringify(t),r=new n;return"string"==typeof e||Buffer.isBuffer(e)?r.value=e:r.result=e,r}return p.process(this.input)}use(t,...e){return this.useAt("compile",t,...e)}useAt(t,i,...n){if(Array.isArray(t)){for(const e of t)this.useAt(e,i,...n);return this}if(Array.isArray(i)){for(const e of i)this.useAt(t,e,...n);return this}if("object"==typeof t&&null!==t&&"plugin"in t){const o=t,s=void 0!==o.stage?"string"==typeof o.stage?e[o.stage]:o.stage:r,a=void 0!==i?[i,...n]:o.options;this.queue.push(this.toRuntimeEntry({...o,options:a},s))}else{const o="string"==typeof t?e[t]??r:t;if("object"==typeof i&&null!==i&&"plugin"in i){const t=i,e=n.length>0?n:t.options;this.queue.push(this.toRuntimeEntry({...t,options:e},o))}else i&&this.queue.push({plugin:i,options:n,stage:o,order:0})}return this}priority(t){const e=this.queue[this.queue.length-1];return e&&(e.order=t),this}configure(t,...e){for(let r=this.queue.length-1;r>=0;r--){const i=this.queue[r];if((i.name||i.plugin.name)===t){i.options=e;break}}return this}assembleProcessor(t){const e={};for(const i of t){const t=i.stage??r;e[t]||(e[t]=[]),e[t].push(i)}const n=[],o=Object.keys(e).map(Number).sort((t,e)=>t-e);for(const t of o){const r=e[t].sort((t,e)=>(t.order||0)-(e.order||0)),i=r.findIndex(t=>t.main);if(-1!==i){const t=r[i];!1===t.options?.[0]?console.warn(`Main Plugin "${t.name}" is disabled. Skipping.`):0!==i&&(r.splice(i,1),r[0]=t)}let o=!0,s=0;for(;o&&s<r.length;){o=!1,s++;for(let t=0;t<r.length;t++){const e=r[t];if(e.after){const i=r.findIndex(t=>t.name===e.after);if(-1!==i&&i>t){r.splice(t,1),r.splice(i,0,e),o=!0;break}}if(e.before){const i=r.findIndex(t=>t.name===e.before);if(-1!==i&&i<t){r.splice(t,1),r.splice(i,0,e),o=!0;break}}}}n.push(...r)}const s=i();Object.keys(this._data).length>0&&s.data(this._data);for(const t of n)s.use(t.plugin,...t.options||[]);return s}};L.registry=new Map;var O=L,B=class extends O{async toMarkdown(){const t=await this.to("markdown");return String(t)}toMarkdownVFile(){return this.to("markdown")}async toHtml(){const t=await this.to("html");return String(t)}toHtmlVFile(){return this.to("html")}async toAst(t){return(await this.to("ast",t)).result}toHTML(){return this.toHtml()}toAST(t){return this.toAst(t)}};function C(t){return new B(t)}B.register(j),B.register(E),B.register(H);import{fromHtml as V}from"hast-util-from-html";import{fromDom as R}from"hast-util-from-dom";var G=function(e){const{readability:r,jsdom:i,hast:n,url:o}=e||{};this.parser=function(e,s){if(!1===r)return V(e,{fragment:!0,...n});let a,l;try{a=t("jsdom").JSDOM;l=t("@mozilla/readability").Readability}catch(t){throw new Error("[html-readability] Dependency missing. Please install 'jsdom' and '@mozilla/readability'.")}const p=new l(new a(e,{url:o,pretendToBeVisual:!0,...i,includeNodeLocations:!0}).window.document,{maxElemsToParse:1e5,nbTopCandidates:5,charThreshold:500,keepClasses:!0,...r,serializer:t=>t}).parse();if(!p||!p.content)return V(e,{fragment:!0,...n});const u=p.content;let m=R(u,{afterTransform:n?.afterTransform});const f=!1!==n?.fragment,c={...p};return delete c.content,delete c.textContent,s&&(s.data=s.data||{},s.data.readability=c),m&&(m=f?{type:"root",children:[m]}:{type:"root",children:[{type:"element",tagName:"html",properties:{},children:[{type:"element",tagName:"head",properties:{},children:[]},{type:"element",tagName:"body",properties:{},children:[m]}]}]},m.data=m.data||{},m.data.readability=c),m}},J={name:"readability",plugin:G,stage:0,main:!0},Q={name:"restore-readability-meta",plugin:()=>(t,e)=>{e.data?.readability&&(t.data=t.data||{},t.data.readability=e.data.readability)},stage:0,after:"rehype-remark"},K=[J,Q];export{r as DefaultPipelineStage,O as MdastBasePipeline,B as MdastPipeline,e as PipelineStage,z as astCompiler,H as astFormat,E as htmlFormat,G as htmlReadability,J as htmlReadabilityPlugin,K as htmlReadabilityPlugins,$ as jsonParser,j as markdownFormat,C as mdast,Q as restoreReadabilityMetaPlugin};
package/docs/README.md CHANGED
@@ -72,6 +72,31 @@ const ast = await mdast('==Highlighted==').toAST();
72
72
  const rawAst = await mdast('==Highlighted==').toAST({ stage: 'parse' });
73
73
  ```
74
74
 
75
+ ### Partial Execution & Debugging
76
+
77
+ You can stop the pipeline at any stage to inspect the intermediate AST, even when targeting a specific output format like `html` or `markdown`.
78
+
79
+ ```typescript
80
+ // Run 'markdown' pipeline but stop after 'parse' stage
81
+ // Returns the VFile with the AST at that point
82
+ const vfile = await mdast(input).to('markdown', { stage: 'parse' });
83
+ const ast = vfile.result;
84
+ ```
85
+
86
+ ### Runtime Overrides
87
+
88
+ You can override plugin options at the moment of execution using the `overrides` option in `.to()`. This is useful for adjusting behavior dynamically without rebuilding the pipeline.
89
+
90
+ ```typescript
91
+ await mdast(input)
92
+ .use({ name: 'myPlugin', plugin: myPlugin, options: [{ foo: 'bar' }] }) // Default option
93
+ .to('html', {
94
+ overrides: {
95
+ myPlugin: { foo: 'baz' } // Override for this run only
96
+ }
97
+ });
98
+ ```
99
+
75
100
  ### Advanced Pipeline
76
101
 
77
102
  ```typescript
@@ -17,6 +17,32 @@ Thank you for your interest in contributing to `@isdk/mdast-plus`! This document
17
17
  * `stringify`: Serializing AST to output.
18
18
  3. **Universal Data Protocols**: Nodes use `node.data` for metadata, and `node.data.hProperties` for HTML attributes.
19
19
 
20
+ ### Understanding the Pipeline
21
+
22
+ The `MdastPipeline` class orchestrates the transformation process. Understanding its lifecycle is crucial for complex customizations.
23
+
24
+ #### 1. Registration (`use`)
25
+
26
+ When you call `.use()`, plugins are not executed immediately. Instead, they are wrapped as `MdastPlugin` entries and pushed into a `queue`.
27
+
28
+ #### 2. Resolution (`resolveRunQueue`)
29
+
30
+ When `.to(format)` is called, the pipeline resolves the final list of plugins to execute:
31
+
32
+ - **Overrides**: Applies runtime options provided in `.to()`.
33
+ - **Filtering**: If a specific `stage` or `stopAtIndex` is requested, the queue is sliced accordingly.
34
+ - **Main Plugin Preservation**: Ensures "main" plugins (like parsers) are kept even if sliced out, unless explicitly disabled.
35
+ - **Input/Output Injection**: Automatically adds input plugins (if missing) and format-specific output plugins.
36
+
37
+ #### 3. Assembly (`assembleProcessor`)
38
+
39
+ The resolved queue is then assembled into a `unified` processor:
40
+
41
+ - **Grouping**: Plugins are grouped by `PipelineStage`.
42
+ - **Replacement**: If a stage has a `main: true` plugin, it replaces the default plugin for that stage.
43
+ - **Sorting**: Plugins within a stage are sorted by `order` and semantic `before`/`after` constraints.
44
+ - **Execution**: The `unified` processor runs the plugins in sequence.
45
+
20
46
  ## Getting Started
21
47
 
22
48
  ### Prerequisites
@@ -68,6 +68,31 @@ const ast = await mdast('==高亮内容==').toAST();
68
68
  const rawAst = await mdast('==高亮内容==').toAST({ stage: 'parse' });
69
69
  ```
70
70
 
71
+ ### 部分执行与调试 (Partial Execution & Debugging)
72
+
73
+ 您可以在任何阶段停止管道以检查中间 AST,即使目标是特定的输出格式(如 `html` 或 `markdown`)。这对于调试非常有帮助。
74
+
75
+ ```typescript
76
+ // 运行 'markdown' 管道但在 'parse' 阶段后停止
77
+ // 返回包含该时刻 AST 的 VFile
78
+ const vfile = await mdast(input).to('markdown', { stage: 'parse' });
79
+ const ast = vfile.result;
80
+ ```
81
+
82
+ ### 运行时覆盖 (Runtime Overrides)
83
+
84
+ 您可以在执行时通过 `.to()` 的 `overrides` 选项覆盖插件选项。这对于在不重建管道的情况下动态调整行为非常有用。
85
+
86
+ ```typescript
87
+ await mdast(input)
88
+ .use({ name: 'myPlugin', plugin: myPlugin, options: [{ foo: 'bar' }] }) // 默认选项
89
+ .to('html', {
90
+ overrides: {
91
+ myPlugin: { foo: 'baz' } // 仅针对本次运行的覆盖
92
+ }
93
+ });
94
+ ```
95
+
71
96
  ### 高级工作流
72
97
 
73
98
  ```typescript