@isdk/mdast-plus 0.1.2 → 0.1.3

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 (38) hide show
  1. package/README.cn.md +54 -20
  2. package/README.md +54 -20
  3. package/dist/index.d.mts +187 -133
  4. package/dist/index.d.ts +187 -133
  5. package/dist/index.js +1 -1
  6. package/dist/index.mjs +1 -1
  7. package/docs/README.md +54 -20
  8. package/docs/_media/CONTRIBUTING.md +39 -18
  9. package/docs/_media/README.cn.md +54 -20
  10. package/docs/classes/MdastBasePipeline.md +348 -0
  11. package/docs/classes/MdastPipeline.md +531 -0
  12. package/docs/enumerations/PipelineStage.md +62 -0
  13. package/docs/functions/astCompiler.md +25 -0
  14. package/docs/functions/jsonParser.md +24 -0
  15. package/docs/functions/mdast.md +4 -4
  16. package/docs/globals.md +12 -10
  17. package/docs/interfaces/MdastDataOrigin.md +8 -8
  18. package/docs/interfaces/MdastFormat.md +71 -0
  19. package/docs/interfaces/MdastMark.md +4 -4
  20. package/docs/interfaces/MdastPlugin.md +27 -27
  21. package/docs/interfaces/MdastSub.md +4 -4
  22. package/docs/interfaces/MdastSup.md +4 -4
  23. package/docs/type-aliases/PipelineStageName.md +13 -0
  24. package/docs/variables/DefaultPipelineStage.md +13 -0
  25. package/docs/variables/astFormat.md +15 -0
  26. package/docs/variables/htmlFormat.md +6 -4
  27. package/docs/variables/markdownFormat.md +6 -4
  28. package/package.json +11 -9
  29. package/docs/classes/FluentProcessor.md +0 -210
  30. package/docs/functions/htmlStringify.md +0 -23
  31. package/docs/functions/markdownCommon.md +0 -23
  32. package/docs/interfaces/ConvertResult.md +0 -39
  33. package/docs/interfaces/MdastAsset.md +0 -41
  34. package/docs/interfaces/MdastFormatDefinition.md +0 -51
  35. package/docs/interfaces/MdastReader.md +0 -41
  36. package/docs/interfaces/MdastTransformer.md +0 -33
  37. package/docs/interfaces/MdastWriter.md +0 -47
  38. package/docs/type-aliases/Stage.md +0 -13
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { Plugin, Processor } from 'unified';
2
+ import { VFileCompatible, VFile } from 'vfile';
3
+
1
4
  // ## Interfaces
2
5
 
3
6
  /**
@@ -1141,81 +1144,88 @@ interface Properties {
1141
1144
  }
1142
1145
 
1143
1146
  /**
1144
- * Stages for mdast-plus pipeline processing.
1145
- */
1146
- type Stage = 'normalize' | 'compile' | 'finalize';
1147
+ * PipelineStage defines the execution order of plugins in the processing pipeline.
1148
+ * Plugins are sorted and executed in ascending order based on these stage values.
1149
+ */
1150
+ declare enum PipelineStage {
1151
+ /** Initial stage for parsing raw input (e.g., string to AST). */
1152
+ parse = 0,
1153
+ /** Normalization stage for cleaning up and canonicalizing the AST (e.g., GFM, Directives). */
1154
+ normalize = 100,
1155
+ /** Transformation stage for semantic changes and custom high-level logic. */
1156
+ compile = 200,
1157
+ /** Finalization stage for preparing the AST for output (e.g., Sanitize, bridge to HAST). */
1158
+ finalize = 300,
1159
+ /** Final stage for serializing the AST to the target format result. */
1160
+ stringify = 400
1161
+ }
1162
+ /** The default stage assigned to a plugin if none is specified. */
1163
+ declare const DefaultPipelineStage = PipelineStage.compile;
1164
+ /** String names corresponding to the PipelineStage levels. */
1165
+ type PipelineStageName = keyof typeof PipelineStage;
1147
1166
  /**
1148
- * Definition for an mdast plugin.
1167
+ * Configuration for a plugin within the mdast-plus pipeline.
1168
+ * It wraps a standard unified plugin with execution metadata.
1149
1169
  */
1150
1170
  interface MdastPlugin {
1151
- /** Plugin name */
1152
- name: string;
1153
- /** Processing stage the plugin belongs to */
1154
- stage?: Stage;
1155
- /** Execution order within the stage (lower numbers run first) */
1171
+ /**
1172
+ * Optional name for the plugin.
1173
+ * Used for identification in overrides and logging.
1174
+ * If not provided, defaults to the plugin function's name.
1175
+ */
1176
+ name?: string;
1177
+ /** The standard unified plugin (attacher) function. */
1178
+ plugin: Plugin<any[], any, any>;
1179
+ /**
1180
+ * Arguments passed to the plugin.
1181
+ * MUST be an array of arguments (e.g., [optionsObject]).
1182
+ */
1183
+ options?: any[];
1184
+ /** The stage in which this plugin should run. */
1185
+ stage?: PipelineStage | PipelineStageName;
1186
+ /** Execution priority within the same stage. Lower values run earlier. */
1156
1187
  order?: number;
1157
- /** Transformation function */
1158
- transform: (tree: Root, ctx: any) => Promise<void> | void;
1159
1188
  }
1160
1189
  /**
1161
- * Definition for an mdast format (parser/stringifier).
1162
- */
1163
- interface MdastFormatDefinition {
1164
- /** Function to register parser plugins */
1165
- parse?: (processor: any) => void;
1166
- /** Function to register stringifier plugins */
1167
- stringify?: (processor: any) => void;
1168
- }
1169
- /**
1170
- * Represents an asset (e.g., image) extracted during processing.
1171
- */
1172
- interface MdastAsset {
1173
- /** Relative path or identifier for the asset */
1174
- path: string;
1175
- /** MIME type of the asset */
1176
- contentType: string;
1177
- /** Raw content as bytes */
1178
- bytes: Uint8Array;
1179
- }
1180
- /**
1181
- * Result of a conversion process.
1182
- * @template T - The type of the main content (default: string)
1183
- */
1184
- interface ConvertResult<T = string> {
1185
- /** The converted content */
1186
- content: T;
1187
- /** Extracted assets */
1188
- assets: MdastAsset[];
1190
+ * Defines a document format, encompassing its input (parsing) and output (serialization) strategies.
1191
+ */
1192
+ interface MdastFormat {
1193
+ /** Unique identifier for the format (e.g., 'markdown', 'html'). */
1194
+ id: string;
1195
+ /** Human-readable title. */
1196
+ title?: string;
1197
+ /** File extensions associated with this format. */
1198
+ extensions?: string[];
1199
+ /** MIME types associated with this format. */
1200
+ mediaTypes?: string[];
1201
+ /** Plugins used for reading this format into a standard AST (Parser + Normalizer). */
1202
+ input?: MdastPlugin[];
1203
+ /** Plugins used for serializing the AST into this format (Finalizer + Stringifier). */
1204
+ output?: MdastPlugin[];
1189
1205
  }
1190
1206
  /**
1191
- * Original metadata for a node.
1207
+ * Metadata capturing the origin of a node during conversion.
1192
1208
  */
1193
1209
  interface MdastDataOrigin {
1194
- /** Source format */
1210
+ /** The original source format. */
1195
1211
  format: 'docx' | 'notion' | 'html' | 'markdown' | 'latex' | string;
1196
- /** Raw data from the source */
1212
+ /** The raw content from the source before conversion. */
1197
1213
  raw?: unknown;
1198
- /** Hash of the source content */
1214
+ /** Hash used for caching or change detection. */
1199
1215
  hash?: string;
1200
1216
  [k: string]: unknown;
1201
1217
  }
1202
- /**
1203
- * mdast node for highlighted text (mark).
1204
- */
1218
+ /** Represents a highlighted text (mark) node in mdast. */
1205
1219
  interface MdastMark extends Parent$1 {
1206
1220
  type: 'mark';
1207
1221
  children: PhrasingContent[];
1208
1222
  }
1209
- /**
1210
- * mdast node for subscript text.
1211
- */
1223
+ /** Represents a subscript text node in mdast. */
1212
1224
  interface MdastSub extends Parent$1 {
1213
1225
  type: 'sub';
1214
1226
  children: PhrasingContent[];
1215
1227
  }
1216
- /**
1217
- * mdast node for superscript text.
1218
- */
1228
+ /** Represents a superscript text node in mdast. */
1219
1229
  interface MdastSup extends Parent$1 {
1220
1230
  type: 'sup';
1221
1231
  children: PhrasingContent[];
@@ -1249,128 +1259,172 @@ declare module 'mdast' {
1249
1259
  sup: MdastSup;
1250
1260
  }
1251
1261
  }
1262
+
1252
1263
  /**
1253
- * Interface for reading input into an mdast tree.
1254
- * @template I - Input type
1264
+ * Base implementation of the fluent mdast processing pipeline.
1265
+ * Manages the plugin registry and the execution queue.
1255
1266
  */
1256
- interface MdastReader<I> {
1267
+ declare class MdastBasePipeline {
1268
+ private static readonly registry;
1257
1269
  /**
1258
- * Reads input and returns an mdast Root node.
1259
- * @param input - The input to read
1270
+ * Registers a global document format.
1271
+ * @param format - The format definition to register.
1260
1272
  */
1261
- read(input: I): Promise<Root>;
1262
- }
1263
- /**
1264
- * Interface for transforming an mdast tree.
1265
- */
1266
- interface MdastTransformer {
1273
+ static register(format: MdastFormat): void;
1267
1274
  /**
1268
- * Transforms the given mdast tree.
1269
- * @param tree - The Root node to transform
1275
+ * Retrieves a registered format by its ID.
1276
+ * @param id - The format identifier.
1277
+ * @returns The format definition or undefined if not found.
1270
1278
  */
1271
- transform(tree: Root): Promise<{
1272
- tree: Root;
1273
- assets?: MdastAsset[];
1274
- }>;
1275
- }
1276
- /**
1277
- * Interface for writing an mdast tree to an output format.
1278
- * @template Output - Output type (default: string)
1279
- */
1280
- interface MdastWriter<Output = string> {
1279
+ static getFormat(id: string): MdastFormat | undefined;
1280
+ protected input: VFileCompatible;
1281
+ protected queue: MdastPlugin[];
1281
1282
  /**
1282
- * Writes the mdast tree to the target output.
1283
- * @param tree - The Root node to write
1284
- * @param assets - Optional assets to include
1283
+ * Initializes a new pipeline instance with the given input.
1284
+ * @param input - Content to process (string, Buffer, VFile, or AST Node).
1285
1285
  */
1286
- write(tree: Root, assets?: MdastAsset[]): Promise<ConvertResult<Output>>;
1287
- }
1288
-
1289
- /**
1290
- * Fluent processor for mdast transformations.
1291
- * Allows chaining configuration and finally converting to a target format.
1292
- */
1293
- declare class FluentProcessor {
1294
- /** Map of registered format definitions */
1295
- static formats: Record<string, MdastFormatDefinition>;
1286
+ constructor(input: VFileCompatible);
1296
1287
  /**
1297
- * Registers a new format definition.
1298
- * @param name - The name of the format (e.g., 'docx')
1299
- * @param definition - The format definition containing parse/stringify logic
1288
+ * Instance-level access to the global format registry.
1300
1289
  */
1301
- static registerFormat(name: string, definition: MdastFormatDefinition): void;
1302
- private processor;
1303
- private input;
1304
- private inputFormat;
1305
- private plugins;
1306
- private globalData;
1290
+ getFormat(id: string): MdastFormat | undefined;
1307
1291
  /**
1308
- * Creates a new FluentProcessor instance.
1309
- * @param input - The input content (string or mdast tree)
1292
+ * Resolves a format identifier or object to a valid MdastFormat.
1293
+ * @private
1310
1294
  */
1311
- constructor(input: any);
1295
+ private resolveFormat;
1312
1296
  /**
1313
- * Specifies the input format.
1314
- * @param format - The input format name (default: 'markdown')
1297
+ * Normalizes a plugin entry for runtime execution.
1298
+ * @protected
1315
1299
  */
1316
- from(format: string): this;
1300
+ protected toRuntimeEntry(entry: MdastPlugin, defaultStage: PipelineStage, overrides?: Record<string, any>): MdastPlugin & {
1301
+ stage: PipelineStage;
1302
+ };
1317
1303
  /**
1318
- * Adds a plugin to the processing pipeline.
1319
- * @param plugin - The mdast plugin to use
1304
+ * Ensures that input plugins (parser, normalizers) are present in the queue.
1305
+ * Adds implicit plugins if no parser is detected.
1306
+ * @protected
1320
1307
  */
1321
- use(plugin: MdastPlugin): this;
1308
+ protected ensureInputPlugins(queue: MdastPlugin[], overrides?: Record<string, any>, maxStage?: PipelineStage): void;
1322
1309
  /**
1323
- * Merges global data into the processor.
1324
- * @param data - Key-value pairs to store in global data
1310
+ * Configures the input format and adds its associated plugins to the pipeline.
1311
+ * @param fmt - Format ID or definition.
1312
+ * @param overrides - Optional map to override plugin options by plugin name.
1313
+ * @returns The pipeline instance for chaining.
1325
1314
  */
1326
- data(data: Record<string, any>): this;
1315
+ from(fmt: string | MdastFormat, overrides?: Record<string, any>): this;
1327
1316
  /**
1328
- * Converts the input content to the specified format.
1329
- * @param format - The output format name
1330
- * @returns A promise resolving to the conversion result (content and assets)
1317
+ * Processes the pipeline and serializes the result into the specified format.
1318
+ * @param fmt - Target format ID or definition.
1319
+ * @param overrides - Optional map to override plugin options.
1320
+ * @returns A promise resolving to a VFile containing the result.
1331
1321
  */
1332
- to(format: string): Promise<ConvertResult>;
1322
+ to(fmt: string | MdastFormat, overrides?: Record<string, any>): Promise<VFile>;
1323
+ /**
1324
+ * Adds a plugin to the pipeline's compile stage.
1325
+ * @param plugin - The unified plugin function.
1326
+ * @param options - Arguments for the plugin.
1327
+ * @returns The pipeline instance for chaining.
1328
+ */
1329
+ use(plugin: any, ...options: any[]): this;
1330
+ /**
1331
+ * Adds a plugin to the pipeline at a specific stage.
1332
+ * @param stage - The stage name or numeric value.
1333
+ * @param plugin - The unified plugin function.
1334
+ * @param options - Arguments for the plugin.
1335
+ * @returns The pipeline instance for chaining.
1336
+ */
1337
+ useAt(stage: PipelineStageName, plugin: any, ...options: any[]): this;
1338
+ /**
1339
+ * Sets the priority order for the most recently added plugin.
1340
+ * Plugins with lower order run earlier within the same stage.
1341
+ * @param order - Numeric priority.
1342
+ * @returns The pipeline instance for chaining.
1343
+ */
1344
+ priority(order: number): this;
1345
+ /**
1346
+ * Assembles a unified processor based on the sorted plugin queue.
1347
+ * @protected
1348
+ */
1349
+ protected assembleProcessor(queue: MdastPlugin[]): Processor;
1350
+ }
1351
+ /**
1352
+ * Extended pipeline with convenience methods for common formats.
1353
+ */
1354
+ declare class MdastPipeline extends MdastBasePipeline {
1333
1355
  /**
1334
- * Helper to convert content to Markdown.
1335
- * @returns A promise resolving to the Markdown string
1356
+ * Finalizes the pipeline and returns the result as a Markdown string.
1336
1357
  */
1337
1358
  toMarkdown(): Promise<string>;
1338
1359
  /**
1339
- * Helper to convert content to HTML.
1340
- * @returns A promise resolving to the HTML string
1360
+ * Finalizes the pipeline and returns a VFile containing the Markdown result.
1341
1361
  */
1342
- toHTML(): Promise<string>;
1362
+ toMarkdownVFile(): Promise<VFile>;
1363
+ /**
1364
+ * Finalizes the pipeline and returns the result as an HTML string.
1365
+ */
1366
+ toHtml(): Promise<string>;
1367
+ /**
1368
+ * Finalizes the pipeline and returns a VFile containing the HTML result.
1369
+ */
1370
+ toHtmlVFile(): Promise<VFile>;
1343
1371
  /**
1344
- * Helper to get the processed mdast tree.
1345
- * @returns A promise resolving to the mdast Root node
1372
+ * Finalizes the pipeline and returns the resulting AST (Root node).
1373
+ * @param options - Configuration for the extraction.
1374
+ * @param options.stage - Run the pipeline up to this stage only.
1375
+ * @param options.overrides - Map for plugin option overrides.
1346
1376
  */
1347
- toAST(): Promise<Root>;
1377
+ toAst(options?: {
1378
+ stage?: PipelineStageName;
1379
+ overrides?: Record<string, any>;
1380
+ }): Promise<Root>;
1381
+ /** Alias for toHtml() */
1382
+ toHTML(): Promise<string>;
1383
+ /** Alias for toAst() */
1384
+ toAST(options?: {
1385
+ stage?: PipelineStageName;
1386
+ overrides?: Record<string, any>;
1387
+ }): Promise<Root>;
1348
1388
  }
1349
1389
  /**
1350
1390
  * Entry point for the fluent mdast-plus API.
1351
1391
  * @param input - The input content (string or mdast tree)
1352
1392
  * @returns A FluentProcessor instance
1353
1393
  */
1354
- declare function mdast(input: any): FluentProcessor;
1394
+ declare function mdast(input: VFileCompatible): MdastPipeline;
1355
1395
 
1356
1396
  /**
1357
- * Common remark configuration for Markdown.
1397
+ * Markdown format definition.
1398
+ *
1399
+ * Supports GFM, Directives, Math, and Frontmatter.
1400
+ * Provides a bidirectional mapping between Markdown strings and mdast-plus ASTs.
1358
1401
  */
1359
- declare function markdownCommon(this: any): void;
1402
+ declare const markdownFormat: MdastFormat;
1403
+
1360
1404
  /**
1361
- * Markdown format definition for FluentProcessor.
1362
- * Handles both parsing (Markdown -> MDAST) and stringifying (MDAST -> Markdown).
1405
+ * HTML format definition.
1406
+ *
1407
+ * Provides a bidirectional mapping between HTML strings and mdast-plus ASTs.
1408
+ * Includes built-in sanitization and support for table spans and image dimensions.
1363
1409
  */
1364
- declare const markdownFormat: MdastFormatDefinition;
1410
+ declare const htmlFormat: MdastFormat;
1365
1411
 
1366
1412
  /**
1367
- * Standard compiler/stringifier for HTML.
1413
+ * Pass-through compiler that returns the AST as-is.
1414
+ * Essential for unified processes that should output an object (the AST)
1415
+ * instead of a serialized string.
1416
+ */
1417
+ declare function astCompiler(this: any): void;
1418
+ /**
1419
+ * Parser for stringified JSON AST input.
1420
+ * Allows the pipeline to accept a JSON string and treat it as a unist tree.
1368
1421
  */
1369
- declare function htmlStringify(this: any): void;
1422
+ declare function jsonParser(this: any): void;
1370
1423
  /**
1371
- * HTML format definition for FluentProcessor.
1372
- * Handles both parsing (HTML -> MDAST) and stringifying (MDAST -> HTML).
1424
+ * AST (MDAST) format definition.
1425
+ * Supports reading from JSON strings and provides full normalization
1426
+ * through the standard mdast-plus plugin set.
1373
1427
  */
1374
- declare const htmlFormat: MdastFormatDefinition;
1428
+ declare const astFormat: MdastFormat;
1375
1429
 
1376
- export { type ConvertResult, FluentProcessor, type MdastAsset, type MdastDataOrigin, type MdastFormatDefinition, type MdastMark, type MdastPlugin, type MdastReader, type MdastSub, type MdastSup, type MdastTransformer, type MdastWriter, type Stage, htmlFormat, htmlStringify, markdownCommon, markdownFormat, mdast };
1430
+ export { DefaultPipelineStage, MdastBasePipeline, type MdastDataOrigin, type MdastFormat, type MdastMark, MdastPipeline, type MdastPlugin, type MdastSub, type MdastSup, PipelineStage, type PipelineStageName, astCompiler, astFormat, htmlFormat, jsonParser, markdownFormat, mdast };
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,a=Object.prototype.hasOwnProperty,o=(t,e,s,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let u of n(e))a.call(t,u)||u===s||r(t,u,{get:()=>e[u],enumerable:!(o=i(e,u))||o.enumerable});return t},u=(t,i,n)=>(n=null!=t?e(s(t)):{},o(!i&&t&&t.__esModule?n:r(n,"default",{value:t,enumerable:!0}),t)),c={};((t,e)=>{for(var i in e)r(t,i,{get:e[i],enumerable:!0})})(c,{FluentProcessor:()=>P,htmlFormat:()=>F,htmlStringify:()=>D,markdownCommon:()=>q,markdownFormat:()=>z,mdast:()=>$}),module.exports=(t=c,o(r({},"__esModule",{value:!0}),t));var l=require("unified"),m=u(require("remark-parse")),h=u(require("remark-stringify")),f=u(require("remark-gfm")),p=u(require("remark-directive")),d=u(require("remark-math")),y=u(require("remark-frontmatter")),v=require("unist-util-visit");function g(t,e){return{type:t,children:e,data:{hName:t}}}var w={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}},b={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:"^"})+"^"},k={name:"normalize-inline-styles",stage:"normalize",transform: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 a=!1;const o=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let u;for(;null!==(u=o.exec(i));){a=!0;const t=u[0],e=u.index;e>n&&s.push({type:"text",value:i.slice(n,e)});let r="mark",c="";t.startsWith("==")?(r="mark",c=t.slice(2,-2)):t.startsWith("~")?(r="sub",c=t.slice(1,-1)):t.startsWith("^")&&(r="sup",c=t.slice(1,-1)),s.push(g(r,[{type:"text",value:c}])),n=o.lastIndex}return a?(n<i.length&&s.push({type:"text",value:i.slice(n)}),r.children.splice(e,1,...s),e+s.length):void 0})}(t)}};function q(){const t=this.data();var e,r;r={handlers:b},t[e="toMarkdownExtensions"]?t[e].push(r):t[e]=[r],this.use(f.default,{singleTilde:!1}).use(p.default).use(d.default).use(y.default,["yaml","toml"])}var z={parse:t=>t.use(m.default).use(q),stringify:t=>t.use(h.default).use(q)},x=u(require("rehype-parse")),S=u(require("rehype-remark")),j=u(require("remark-rehype")),O=u(require("rehype-sanitize")),N=u(require("rehype-stringify"));function D(){this.use(j.default).use(O.default,{...O.defaultSchema,tagNames:[...O.defaultSchema.tagNames||[],"mark","sub","sup"],attributes:{...O.defaultSchema.attributes,"*":[...O.defaultSchema.attributes?.["*"]||[],"className","id","style"],td:[...O.defaultSchema.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...O.defaultSchema.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...O.defaultSchema.attributes?.img||[],"width","height"]}}).use(N.default)}var F={parse:t=>t.use(x.default).use(S.default,{handlers:w}),stringify:t=>t.use(D)},M=require("unist-util-visit"),T={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},C={name:"normalize-directive",stage:"normalize",order:10,transform:async t=>{(0,M.visit)(t,["containerDirective","leafDirective","textDirective"],t=>{const e=t,r=e.name.toLowerCase();if(e.name=T[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(" ")}})}},I=require("unist-util-visit"),L={name:"normalize-table-span",stage:"normalize",order:20,transform:async t=>{(0,I.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)}})}},_=require("unist-util-visit"),A=require("shell-quote");var B={name:"extract-code-meta",stage:"normalize",order:30,transform:async t=>{(0,_.visit)(t,"code",t=>{if(t.meta){const e=function(t){const e={},r=(0,A.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}}})}},E=require("unist-util-visit"),H={name:"image-size",stage:"normalize",order:40,transform:async t=>{(0,E.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)})}},J=class t{constructor(t){this.inputFormat="markdown",this.plugins=[],this.globalData={},this.input=t,this.processor=(0,l.unified)(),this.use(C),this.use(L),this.use(B),this.use(H),this.use(k)}static registerFormat(e,r){t.formats[e.toLowerCase()]=r}from(t){return this.inputFormat=t.toLowerCase(),this}use(t){return this.plugins.push(t),this}data(t){return this.globalData={...this.globalData,...t},this}async to(e){e=e.toLowerCase();const r=t.formats[this.inputFormat];r?.parse&&r.parse(this.processor);let i="string"==typeof this.input?this.processor.parse(this.input):this.input;i=await this.processor.run(i),i.data={...i.data,...this.globalData};const n=[...this.plugins].sort((t,e)=>{const r={normalize:0,compile:1,finalize:2},i=t.stage||"normalize",n=e.stage||"normalize";return i!==n?r[i]-r[n]:(t.order||0)-(e.order||0)});for(const t of n)await t.transform(i,this.processor);const s=(0,l.unified)().data("settings",this.processor.data("settings")),a=t.formats[e];a?.stringify&&a.stringify(s),"markdown"!==e||a||z.stringify(s);const o=await s.run(i),u=s.stringify(o),c=[];return i.data&&i.data.assets&&c.push(...i.data.assets),{content:u,assets:c}}async toMarkdown(){return(await this.to("markdown")).content}async toHTML(){return(await this.to("html")).content}async toAST(){return(await this.to("ast")).content}};J.formats={markdown:z,html:F,ast:{parse:t=>{t.Parser=t=>JSON.parse(t)},stringify:t=>{t.Compiler=t=>t}}};var P=J;function $(t){return new P(t)}
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:()=>c,MdastBasePipeline:()=>Q,MdastPipeline:()=>U,PipelineStage:()=>p,astCompiler:()=>_,astFormat:()=>J,htmlFormat:()=>V,jsonParser:()=>G,markdownFormat:()=>$,mdast:()=>W}),module.exports=(t=l,a(r({},"__esModule",{value:!0}),t));var p=(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))(p||{}),c=200,g=require("unified"),h=require("vfile"),m=u(require("remark-parse")),f=u(require("remark-stringify")),d=u(require("remark-gfm")),y=u(require("remark-directive")),w=u(require("remark-math")),v=u(require("remark-frontmatter")),k=require("unist-util-visit");function b(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:"^"})+"^"},M={plugin:()=>t=>{!function(t){(0,k.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(b(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},x=require("unist-util-visit"),F={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},S={plugin:()=>async t=>{(0,x.visit)(t,["containerDirective","leafDirective","textDirective"],t=>{const e=t,r=e.name.toLowerCase();if(e.name=F[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,x.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},P=require("unist-util-visit"),j={plugin:()=>async t=>{(0,P.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"),D=require("shell-quote");var O={plugin:()=>async t=>{(0,T.visit)(t,"code",t=>{if(t.meta){const e=function(t){const e={},r=(0,D.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"),N={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},E=[{plugin:m.default,stage:0},{plugin:d.default,options:[{singleTilde:!1}],stage:0},{plugin:y.default,stage:0},{plugin:w.default,stage:0},{plugin:v.default,options:[["yaml","toml"]],stage:0},S,j,O,N,M],H=[{plugin:f.default,options:[{handlers:q}],stage:400},{plugin:d.default,options:[{singleTilde:!1}],stage:400},{plugin:y.default,stage:400},{plugin:w.default,stage:400},{plugin:v.default,options:[["yaml","toml"]],stage:400}];H.forEach(t=>{t.plugin===f.default?t.order=100:t.order=10});var $={id:"markdown",title:"Markdown (GFM + Directives)",extensions:["md","markdown","mdown","mkdn"],mediaTypes:["text/markdown"],input:E,output:H},z=u(require("rehype-parse")),B=u(require("rehype-remark")),I=u(require("remark-rehype")),L=u(require("rehype-sanitize")),C=u(require("rehype-stringify")),V={id:"html",title:"HTML",extensions:["html","htm"],mediaTypes:["text/html"],input:[{plugin:z.default,stage:0},{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,order:10}],output:[{plugin:I.default,stage:300,order:10},{plugin:L.default,options:[{...L.defaultSchema,tagNames:[...L.defaultSchema.tagNames||[],"mark","sub","sup"],attributes:{...L.defaultSchema.attributes,"*":[...L.defaultSchema.attributes?.["*"]||[],"className","id","style"],td:[...L.defaultSchema.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...L.defaultSchema.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...L.defaultSchema.attributes?.img||[],"width","height"]}}],stage:300,order:20},{plugin:C.default,stage:400}]};function _(){this.Compiler=t=>t}function G(){this.Parser=t=>JSON.parse(t)}var J={id:"ast",title:"MDAST",input:[{plugin:G,stage:0},S,j,O,N,M],output:[{plugin:_,options:[],stage:400}]};function R(t){return"object"==typeof t&&null!==t&&"string"==typeof t.type}var K=class t{constructor(t){this.queue=[],this.input=t}static register(t){this.registry.set(t.id,t)}static getFormat(t){return this.registry.get(t)}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?p[t.stage]??e:t.stage);let n=t.options||[];const s=t.name||t.plugin.name;if(r&&s&&s in r){const t=r[s];n=Array.isArray(t)?t:[t]}return{name:s,plugin:t.plugin,options:n,stage:i,order:t.order||0}}ensureInputPlugins(e,r,i=400){const n=e.some(t=>0===(t.stage??c)),s=R(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??c)<=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(R(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){return this.queue.push({plugin:e,options:r,stage:p[t],order:0}),this}priority(t){const e=this.queue[this.queue.length-1];return e&&(e.order=t),this}assembleProcessor(t){t.sort((t,e)=>{const r=t.stage??c,i=e.stage??c;return r!==i?r-i:t.order-e.order});const e=(0,g.unified)();for(const r of t)e.use(r.plugin,...r.options||[]);return e}};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=p[t.stage],r=this.queue.filter(t=>(t.stage??c)<=e);r.push({plugin:_,options:[],stage:400,order:0}),this.ensureInputPlugins(r,t.overrides,e);const i=this.assembleProcessor(r);if(R(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($),U.register(V),U.register(J);
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{unified as t}from"unified";import r from"remark-parse";import i from"remark-stringify";import e from"remark-gfm";import s from"remark-directive";import n from"remark-math";import a from"remark-frontmatter";import{visit as o}from"unist-util-visit";function m(t,r){return{type:t,children:r,data:{hName:t}}}var c={mark:(t,r)=>{const i={type:"mark",children:t.all(r)};return t.patch(r,i),i},sub:(t,r)=>{const i={type:"sub",children:t.all(r)};return t.patch(r,i),i},sup:(t,r)=>{const i={type:"sup",children:t.all(r)};return t.patch(r,i),i}},l={mark:(t,r,i)=>"=="+i.containerPhrasing(t,{before:"==",after:"=="})+"==",sub:(t,r,i)=>"~"+i.containerPhrasing(t,{before:"~",after:"~"})+"~",sup:(t,r,i)=>"^"+i.containerPhrasing(t,{before:"^",after:"^"})+"^"},p={name:"normalize-inline-styles",stage:"normalize",transform:t=>{!function(t){o(t,"text",(t,r,i)=>{if(!i||void 0===r)return;const e=t.value;let s=0;const n=[];let a=!1;const o=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let c;for(;null!==(c=o.exec(e));){a=!0;const t=c[0],r=c.index;r>s&&n.push({type:"text",value:e.slice(s,r)});let i="mark",l="";t.startsWith("==")?(i="mark",l=t.slice(2,-2)):t.startsWith("~")?(i="sub",l=t.slice(1,-1)):t.startsWith("^")&&(i="sup",l=t.slice(1,-1)),n.push(m(i,[{type:"text",value:l}])),s=o.lastIndex}return a?(s<e.length&&n.push({type:"text",value:e.slice(s)}),i.children.splice(r,1,...n),r+n.length):void 0})}(t)}};function f(){const t=this.data();var r,i;i={handlers:l},t[r="toMarkdownExtensions"]?t[r].push(i):t[r]=[i],this.use(e,{singleTilde:!1}).use(s).use(n).use(a,["yaml","toml"])}var h={parse:t=>t.use(r).use(f),stringify:t=>t.use(i).use(f)};import u from"rehype-parse";import d from"rehype-remark";import v from"remark-rehype";import y,{defaultSchema as g}from"rehype-sanitize";import w from"rehype-stringify";function k(){this.use(v).use(y,{...g,tagNames:[...g.tagNames||[],"mark","sub","sup"],attributes:{...g.attributes,"*":[...g.attributes?.["*"]||[],"className","id","style"],td:[...g.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...g.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...g.attributes?.img||[],"width","height"]}}).use(w)}var z={parse:t=>t.use(u).use(d,{handlers:c}),stringify:t=>t.use(k)};import{visit as b}from"unist-util-visit";var x={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},S={name:"normalize-directive",stage:"normalize",order:10,transform:async t=>{b(t,["containerDirective","leafDirective","textDirective"],t=>{const r=t,i=r.name.toLowerCase();if(r.name=x[i]||i,r.children&&r.children.length>0){const t=r.children[0];if(t.data?.directiveLabel||"directiveLabel"===t.type){let i="";b(t,"text",t=>{i+=t.value}),i&&!r.attributes?.title&&(r.attributes=r.attributes||{},r.attributes.title=i.trim()),r.children.shift()}}r.attributes?.title&&(r.attributes.title=String(r.attributes.title).trim()),r.data=r.data||{},r.data.hName=r.data.hName||("containerDirective"===r.type?"div":"span"),r.data.hProperties={...r.data.hProperties||{},...r.attributes,className:[r.name,r.data.hProperties?.className].filter(Boolean).join(" ")}})}};import{visit as N}from"unist-util-visit";var D={name:"normalize-table-span",stage:"normalize",order:20,transform:async t=>{N(t,"tableCell",t=>{if(t.data){const{rowspan:r,colspan:i}=t.data;t.data.hProperties=t.data.hProperties||{},void 0!==r&&(t.data.hProperties.rowSpan=r,delete t.data.rowspan),void 0!==i&&(t.data.hProperties.colSpan=i,delete t.data.colspan)}})}};import{visit as M}from"unist-util-visit";import{parse as T}from"shell-quote";var I={name:"extract-code-meta",stage:"normalize",order:30,transform:async t=>{M(t,"code",t=>{if(t.meta){const r=function(t){const r={},i=T(t);for(const t of i)if("string"==typeof t){const i=t.split("=",2);2===i.length?r[i[0]]=i[1]:r[t]="true"}return r}(t.meta),i=t.data=t.data||{};r.title&&(i.title=r.title),r.filename&&(i.filename=r.filename),i.kv={...i.kv||{},...r}}})}};import{visit as L}from"unist-util-visit";var q={name:"image-size",stage:"normalize",order:40,transform:async t=>{L(t,"image",t=>{const r=t.data=t.data||{},i=r.hProperties=r.hProperties||{},e=/[#?&](?:width=([0-9]+))?(?:&?height=([0-9]+))?(?:=([0-9]+)x([0-9]+))?$/,s=t.url.match(e);if(s){const r=s[1]||s[3],n=s[2]||s[4];r&&!i.width&&(i.width=parseInt(r,10)),n&&!i.height&&(i.height=parseInt(n,10)),t.url=t.url.replace(e,"")}r.width&&!i.width&&(i.width=r.width),r.height&&!i.height&&(i.height=r.height)})}},A=class r{constructor(r){this.inputFormat="markdown",this.plugins=[],this.globalData={},this.input=r,this.processor=t(),this.use(S),this.use(D),this.use(I),this.use(q),this.use(p)}static registerFormat(t,i){r.formats[t.toLowerCase()]=i}from(t){return this.inputFormat=t.toLowerCase(),this}use(t){return this.plugins.push(t),this}data(t){return this.globalData={...this.globalData,...t},this}async to(i){i=i.toLowerCase();const e=r.formats[this.inputFormat];e?.parse&&e.parse(this.processor);let s="string"==typeof this.input?this.processor.parse(this.input):this.input;s=await this.processor.run(s),s.data={...s.data,...this.globalData};const n=[...this.plugins].sort((t,r)=>{const i={normalize:0,compile:1,finalize:2},e=t.stage||"normalize",s=r.stage||"normalize";return e!==s?i[e]-i[s]:(t.order||0)-(r.order||0)});for(const t of n)await t.transform(s,this.processor);const a=t().data("settings",this.processor.data("settings")),o=r.formats[i];o?.stringify&&o.stringify(a),"markdown"!==i||o||h.stringify(a);const m=await a.run(s),c=a.stringify(m),l=[];return s.data&&s.data.assets&&l.push(...s.data.assets),{content:c,assets:l}}async toMarkdown(){return(await this.to("markdown")).content}async toHTML(){return(await this.to("html")).content}async toAST(){return(await this.to("ast")).content}};A.formats={markdown:h,html:z,ast:{parse:t=>{t.Parser=t=>JSON.parse(t)},stringify:t=>{t.Compiler=t=>t}}};var B=A;function C(t){return new B(t)}export{B as FluentProcessor,z as htmlFormat,k as htmlStringify,f as markdownCommon,h as markdownFormat,C as mdast};
1
+ var t=(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))(t||{}),r=200;import{unified as i}from"unified";import{VFile as e}from"vfile";import s from"remark-parse";import n from"remark-stringify";import o from"remark-gfm";import a from"remark-directive";import u from"remark-math";import p from"remark-frontmatter";import{visit as l}from"unist-util-visit";function m(t,r){return{type:t,children:r,data:{hName:t}}}var c={plugin:()=>t=>{!function(t){l(t,"text",(t,r,i)=>{if(!i||void 0===r)return;const e=t.value;let s=0;const n=[];let o=!1;const a=/(==[^=]+==|~[^~]+~|\^[^^]+\^)/g;let u;for(;null!==(u=a.exec(e));){o=!0;const t=u[0],r=u.index;r>s&&n.push({type:"text",value:e.slice(s,r)});let i="mark",p="";t.startsWith("==")?(i="mark",p=t.slice(2,-2)):t.startsWith("~")?(i="sub",p=t.slice(1,-1)):t.startsWith("^")&&(i="sup",p=t.slice(1,-1)),n.push(m(i,[{type:"text",value:p}])),s=a.lastIndex}return o?(s<e.length&&n.push({type:"text",value:e.slice(s)}),i.children.splice(r,1,...n),r+n.length):void 0})}(t)},stage:100};import{visit as f}from"unist-util-visit";var g={error:"danger",warn:"warning",success:"tip",important:"important",caution:"caution",note:"note"},h={plugin:()=>async t=>{f(t,["containerDirective","leafDirective","textDirective"],t=>{const r=t,i=r.name.toLowerCase();if(r.name=g[i]||i,r.children&&r.children.length>0){const t=r.children[0];if(t.data?.directiveLabel||"directiveLabel"===t.type){let i="";f(t,"text",t=>{i+=t.value}),i&&!r.attributes?.title&&(r.attributes=r.attributes||{},r.attributes.title=i.trim()),r.children.shift()}}r.attributes?.title&&(r.attributes.title=String(r.attributes.title).trim()),r.data=r.data||{},r.data.hName=r.data.hName||("containerDirective"===r.type?"div":"span"),r.data.hProperties={...r.data.hProperties||{},...r.attributes,className:[r.name,r.data.hProperties?.className].filter(Boolean).join(" ")}})},stage:100,order:10};import{visit as d}from"unist-util-visit";var v={plugin:()=>async t=>{d(t,"tableCell",t=>{if(t.data){const{rowspan:r,colspan:i}=t.data;t.data.hProperties=t.data.hProperties||{},void 0!==r&&(t.data.hProperties.rowSpan=r,delete t.data.rowspan),void 0!==i&&(t.data.hProperties.colSpan=i,delete t.data.colspan)}})},stage:100,order:20};import{visit as y}from"unist-util-visit";import{parse as w}from"shell-quote";var k={plugin:()=>async t=>{y(t,"code",t=>{if(t.meta){const r=function(t){const r={},i=w(t);for(const t of i)if("string"==typeof t){const i=t.split("=",2);2===i.length?r[i[0]]=i[1]:r[t]="true"}return r}(t.meta),i=t.data=t.data||{};r.title&&(i.title=r.title),r.filename&&(i.filename=r.filename),i.kv={...i.kv||{},...r}}})},stage:100,order:30};import{visit as b}from"unist-util-visit";var x={plugin:()=>async t=>{b(t,"image",t=>{const r=t.data=t.data||{},i=r.hProperties=r.hProperties||{},e=/[#?&](?:width=([0-9]+))?(?:&?height=([0-9]+))?(?:=([0-9]+)x([0-9]+))?$/,s=t.url.match(e);if(s){const r=s[1]||s[3],n=s[2]||s[4];r&&!i.width&&(i.width=parseInt(r,10)),n&&!i.height&&(i.height=parseInt(n,10)),t.url=t.url.replace(e,"")}r.width&&!i.width&&(i.width=r.width),r.height&&!i.height&&(i.height=r.height)})},stage:100,order:40},M=[{plugin:s,stage:0},{plugin:o,options:[{singleTilde:!1}],stage:0},{plugin:a,stage:0},{plugin:u,stage:0},{plugin:p,options:[["yaml","toml"]],stage:0},h,v,k,x,c],S=[{plugin:n,options:[{handlers:{mark:(t,r,i)=>"=="+i.containerPhrasing(t,{before:"==",after:"=="})+"==",sub:(t,r,i)=>"~"+i.containerPhrasing(t,{before:"~",after:"~"})+"~",sup:(t,r,i)=>"^"+i.containerPhrasing(t,{before:"^",after:"^"})+"^"}}],stage:400},{plugin:o,options:[{singleTilde:!1}],stage:400},{plugin:a,stage:400},{plugin:u,stage:400},{plugin:p,options:[["yaml","toml"]],stage:400}];S.forEach(t=>{t.plugin===n?t.order=100:t.order=10});var F={id:"markdown",title:"Markdown (GFM + Directives)",extensions:["md","markdown","mdown","mkdn"],mediaTypes:["text/markdown"],input:M,output:S};import T from"rehype-parse";import D from"rehype-remark";import A from"remark-rehype";import N,{defaultSchema as P}from"rehype-sanitize";import E from"rehype-stringify";var H={id:"html",title:"HTML",extensions:["html","htm"],mediaTypes:["text/html"],input:[{plugin:T,stage:0},{plugin:D,options:[{handlers:{mark:(t,r)=>{const i={type:"mark",children:t.all(r)};return t.patch(r,i),i},sub:(t,r)=>{const i={type:"sub",children:t.all(r)};return t.patch(r,i),i},sup:(t,r)=>{const i={type:"sup",children:t.all(r)};return t.patch(r,i),i}}}],stage:0,order:10}],output:[{plugin:A,stage:300,order:10},{plugin:N,options:[{...P,tagNames:[...P.tagNames||[],"mark","sub","sup"],attributes:{...P.attributes,"*":[...P.attributes?.["*"]||[],"className","id","style"],td:[...P.attributes?.td||[],"rowSpan","colSpan","rowspan","colspan"],th:[...P.attributes?.th||[],"rowSpan","colSpan","rowspan","colspan"],img:[...P.attributes?.img||[],"width","height"]}}],stage:300,order:20},{plugin:E,stage:400}]};function $(){this.Compiler=t=>t}function z(){this.Parser=t=>JSON.parse(t)}var I={id:"ast",title:"MDAST",input:[{plugin:z,stage:0},h,v,k,x,c],output:[{plugin:$,options:[],stage:400}]};function L(t){return"object"==typeof t&&null!==t&&"string"==typeof t.type}var B=class s{constructor(t){this.queue=[],this.input=t}static register(t){this.registry.set(t.id,t)}static getFormat(t){return this.registry.get(t)}getFormat(t){return this.constructor.getFormat(t)}resolveFormat(t){if("string"==typeof t){const r=this.getFormat(t);if(!r)throw new Error(`[MdastPlus] Format '${t}' is not registered.`);return r}return t}toRuntimeEntry(r,i,e){let s=i;void 0!==r.stage&&(s="string"==typeof r.stage?t[r.stage]??i:r.stage);let n=r.options||[];const o=r.name||r.plugin.name;if(e&&o&&o in e){const t=e[o];n=Array.isArray(t)?t:[t]}return{name:o,plugin:r.plugin,options:n,stage:s,order:r.order||0}}ensureInputPlugins(t,i,e=400){const n=t.some(t=>0===(t.stage??r)),o=L(this.input);if(!n){let n=[];if(o){const t=s.getFormat("ast");t&&t.input&&(n=t.input)}else{const t=s.getFormat("markdown");t&&t.input&&(n=t.input)}for(const s of n){const n=this.toRuntimeEntry(s,0,i);(n.stage??r)<=e&&t.push(n)}}}from(t,r){const i=this.resolveFormat(t);if(!i.input||0===i.input.length)throw new Error(`[MdastPlus] Format '${i.id}' does not support input.`);for(const t of i.input)this.queue.push(this.toRuntimeEntry(t,0,r));return this}async to(t,r){const i=this.resolveFormat(t);if(!i.output)throw new Error(`[MdastPlus] Format '${i.id}' does not support output.`);const s=[...this.queue];this.ensureInputPlugins(s,r);for(const t of i.output)s.push(this.toRuntimeEntry(t,300,r));const n=this.assembleProcessor(s);if(L(this.input)){const t=await n.run(this.input),r=n.stringify(t),i=new e;return"string"==typeof r||Buffer.isBuffer(r)?i.value=r:i.result=r,i}return n.process(this.input)}use(t,...r){return this.useAt("compile",t,...r)}useAt(r,i,...e){return this.queue.push({plugin:i,options:e,stage:t[r],order:0}),this}priority(t){const r=this.queue[this.queue.length-1];return r&&(r.order=t),this}assembleProcessor(t){t.sort((t,i)=>{const e=t.stage??r,s=i.stage??r;return e!==s?e-s:t.order-i.order});const e=i();for(const r of t)e.use(r.plugin,...r.options||[]);return e}};B.registry=new Map;var V=B,j=class extends V{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(i){if(i?.stage){const e=t[i.stage],s=this.queue.filter(t=>(t.stage??r)<=e);s.push({plugin:$,options:[],stage:400,order:0}),this.ensureInputPlugins(s,i.overrides,e);const n=this.assembleProcessor(s);if(L(this.input)){return await n.run(this.input)}return(await n.process(this.input)).result}return(await this.to("ast",i?.overrides)).result}toHTML(){return this.toHtml()}toAST(t){return this.toAst(t)}};function q(t){return new j(t)}j.register(F),j.register(H),j.register(I);export{r as DefaultPipelineStage,V as MdastBasePipeline,j as MdastPipeline,t as PipelineStage,$ as astCompiler,I as astFormat,H as htmlFormat,z as jsonParser,F as markdownFormat,q as mdast};
package/docs/README.md CHANGED
@@ -15,7 +15,7 @@ English | [简体中文](_media/README.cn.md) | [GitHub](https://github.com/isdk
15
15
  ## Features
16
16
 
17
17
  - **Fluent API**: Chainable interface `mdast(input).use(plugin).toHTML()`.
18
- - **Staged Plugins**: Organize transformations into `normalize`, `compile`, and `finalize` stages with priority ordering.
18
+ - **Staged Plugins**: Organize transformations into `parse`, `normalize`, `compile`, `finalize`, and `stringify` stages.
19
19
  - **Semantic Normalization**:
20
20
  - **Directives**: Canonicalizes admonition names and extracts titles from labels.
21
21
  - **Table Spans**: Support for `rowspan` and `colspan` in HTML output.
@@ -44,6 +44,17 @@ const html = await mdast(':::warning[Special Note]\nBe careful!\n:::')
44
44
  // Result: <div title="Special Note" class="warning"><p>Be careful!</p></div>
45
45
  ```
46
46
 
47
+ ### Configure Input Options
48
+
49
+ You can pass options to input plugins (like `remark-gfm` or `remark-parse`) using the second argument of `.from()`:
50
+
51
+ ```typescript
52
+ // Enable single tilde strikethrough (~text~)
53
+ const md = await mdast('Hello ~world~')
54
+ .from('markdown', { remarkGfm: { singleTilde: true } })
55
+ .toMarkdown();
56
+ ```
57
+
47
58
  ### Image Sizing
48
59
 
49
60
  ```typescript
@@ -54,8 +65,11 @@ const html = await mdast('![Cat](cat.png#=500x300)').toHTML();
54
65
  ### AST Output
55
66
 
56
67
  ```typescript
68
+ // Get the fully processed AST (after normalization)
57
69
  const ast = await mdast('==Highlighted==').toAST();
58
- // Returns the mdast Root object
70
+
71
+ // Get the raw AST (after parsing, before normalization)
72
+ const rawAst = await mdast('==Highlighted==').toAST({ stage: 'parse' });
59
73
  ```
60
74
 
61
75
  ### Advanced Pipeline
@@ -63,31 +77,49 @@ const ast = await mdast('==Highlighted==').toAST();
63
77
  ```typescript
64
78
  const { content, assets } = await mdast(myInput)
65
79
  .data({ myGlobal: 'value' })
66
- .use({
67
- name: 'my-plugin',
68
- stage: 'compile',
69
- transform: async (tree) => {
70
- // transform the AST
71
- }
72
- })
80
+ // Add a custom plugin at the 'compile' stage
81
+ .useAt('compile', myPlugin, { option: 1 })
82
+ .priority(10) // Run later than default plugins
73
83
  .to('html');
74
84
  ```
75
85
 
86
+ ### Plugin Behavior
87
+
88
+ `mdast-plus` uses [unified](https://github.com/unifiedjs/unified) internally. If you add the same plugin function multiple times, the last configuration **overrides** the previous ones.
89
+
90
+ ```typescript
91
+ // The plugin will run ONCE with option: 2
92
+ pipeline.use(myPlugin, { option: 1 });
93
+ pipeline.use(myPlugin, { option: 2 });
94
+ ```
95
+
96
+ To run the same plugin logic multiple times (e.g., for different purposes), provide a distinct function reference:
97
+
98
+ ```typescript
99
+ // The plugin will run TWICE
100
+ pipeline.use(myPlugin, { option: 1 });
101
+ pipeline.use(myPlugin.bind({}), { option: 2 });
102
+ ```
103
+
76
104
  ### Arbitrary Formats
77
105
 
78
106
  You can register custom input or output formats:
79
107
 
80
108
  ```typescript
81
- import { FluentProcessor, mdast } from '@isdk/mdast-plus';
109
+ import { MdastPipeline, mdast, PipelineStage } from '@isdk/mdast-plus';
82
110
 
83
111
  // Register a custom output format
84
- FluentProcessor.registerFormat('reverse', {
85
- stringify: (p) => {
86
- p.Compiler = (tree) => {
87
- // your custom stringification logic
88
- return '...';
89
- };
90
- }
112
+ MdastPipeline.register({
113
+ id: 'reverse',
114
+ output: [{
115
+ plugin: function() {
116
+ this.Compiler = (tree) => {
117
+ // your custom stringification logic
118
+ return '...';
119
+ };
120
+ },
121
+ stage: PipelineStage.stringify
122
+ }]
91
123
  });
92
124
 
93
125
  const result = await mdast('Hello').to('reverse');
@@ -99,9 +131,11 @@ const result = await mdast('Hello').to('reverse');
99
131
 
100
132
  Plugins are executed based on their `stage` and `order`:
101
133
 
102
- 1. **normalize** (order 0-100): Cleanup and canonicalize the tree.
103
- 2. **compile** (order 0-100): High-level semantic transformations.
104
- 3. **finalize** (order 0-100): Final preparation before output.
134
+ 1. **parse** (0): Input parsing (e.g., `remark-parse`).
135
+ 2. **normalize** (100): Cleanup and canonicalize the tree.
136
+ 3. **compile** (200): High-level semantic transformations.
137
+ 4. **finalize** (300): Final preparation before output (e.g. `rehype-sanitize`).
138
+ 5. **stringify** (400): Output generation.
105
139
 
106
140
  ## Core Plugins Included
107
141