remark-mdat 2.0.0-preview.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -167,10 +167,15 @@ declare function getMdatReports(files: VFile[]): MdatFileReport[];
167
167
  declare function reporterMdat(files: VFile[]): void;
168
168
  //#endregion
169
169
  //#region src/lib/remark-mdat.d.ts
170
- type Options = Rules;
170
+ type Options = {
171
+ rules?: Rules;
172
+ };
173
+ declare const optionsSchema: z.ZodObject<{
174
+ rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
175
+ }, z.core.$strip>;
171
176
  /**
172
177
  * A remark plugin that expands HTML comments in Markdown files.
173
178
  */
174
- declare const remarkMdat: Plugin<[Options], Root>;
179
+ declare const remarkMdat: Plugin<[Options?], Root>;
175
180
  //#endregion
176
- export { type MdatFileReport, type MdatMessage, type NormalizedRule, type NormalizedRules, type Options, type Rule, type RuleContext, type Rules, type SimplifyDeep, remarkMdat as default, getMdatReports, getSoleRule, getSoleRuleKey, mdat, mdatClean, mdatExpand, mdatSplit, rulesSchema as optionsSchema, rulesSchema, reporterMdat, setLogger };
181
+ export { type MdatFileReport, type MdatMessage, type NormalizedRule, type NormalizedRules, type Options, type Rule, type RuleContext, type Rules, type SimplifyDeep, remarkMdat as default, getMdatReports, getSoleRule, getSoleRuleKey, mdat, mdatClean, mdatExpand, mdatSplit, optionsSchema, reporterMdat, rulesSchema, setLogger };
package/dist/index.js CHANGED
@@ -86,13 +86,13 @@ function getMdatReport(file) {
86
86
  function reporterMdat(files) {
87
87
  for (const file of files) {
88
88
  const { destinationPath, errors, infos, sourcePath, warnings } = getMdatReport(file);
89
- log.info(picocolors.bold("MDAT Report:"));
90
- log.info(`\tFrom: ${picocolors.blue(picocolors.bold(sourcePath))}`);
91
- if (destinationPath !== void 0) log.info(`\tTo: ${picocolors.blue(picocolors.bold(destinationPath))}`);
89
+ log.debug(picocolors.bold("MDAT Report:"));
90
+ log.debug(`\tFrom: ${picocolors.blue(picocolors.bold(sourcePath))}`);
91
+ if (destinationPath !== void 0) log.debug(`\tTo: ${picocolors.blue(picocolors.bold(destinationPath))}`);
92
92
  for (const message of errors) log.error(mdatMessageToLogString(sourcePath, message));
93
93
  for (const message of warnings) log.warn(mdatMessageToLogString(sourcePath, message));
94
- for (const message of infos) log.info(mdatMessageToLogString(sourcePath, message));
95
- if (errors.length === 0 && warnings.length === 0) log.info(`No issues found in ${sourcePath}`);
94
+ for (const message of infos) log.debug(mdatMessageToLogString(sourcePath, message));
95
+ if (errors.length === 0 && warnings.length === 0) log.debug(`No issues found in ${sourcePath}`);
96
96
  else log.error(`${errors.length} errors, ${warnings.length} warnings found in ${sourcePath}`);
97
97
  }
98
98
  }
@@ -466,17 +466,18 @@ async function mdat(tree, file, rules) {
466
466
  //#endregion
467
467
  //#region src/lib/remark-mdat.ts
468
468
  const defaultRules = { mdat: `Powered by the Markdown Autophagic Template system: [mdat](https://github.com/kitschpatrol/mdat).` };
469
+ const optionsSchema = z.object({ rules: rulesSchema.optional() }).describe("MDAT Plugin Options");
469
470
  /**
470
471
  * A remark plugin that expands HTML comments in Markdown files.
471
472
  */
472
- const remarkMdat = function(rules) {
473
+ const remarkMdat = function(options) {
473
474
  const resolvedRules = {
474
475
  ...defaultRules,
475
- ...rules
476
+ ...options?.rules
476
477
  };
477
478
  return async function(tree, file) {
478
479
  await mdat(tree, file, resolvedRules);
479
480
  };
480
481
  };
481
482
  //#endregion
482
- export { remarkMdat as default, getMdatReports, getSoleRule, getSoleRuleKey, mdat, mdatClean, mdatExpand, mdatSplit, rulesSchema as optionsSchema, rulesSchema, reporterMdat, setLogger };
483
+ export { remarkMdat as default, getMdatReports, getSoleRule, getSoleRuleKey, mdat, mdatClean, mdatExpand, mdatSplit, optionsSchema, reporterMdat, rulesSchema, setLogger };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remark-mdat",
3
- "version": "2.0.0-preview.3",
3
+ "version": "2.0.0",
4
4
  "description": "A remark plugin implementing the Markdown Autophagic Template (MDAT) system.",
5
5
  "keywords": [
6
6
  "mdat",
@@ -59,13 +59,13 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@arethetypeswrong/core": "^0.18.2",
62
- "@kitschpatrol/shared-config": "^6.1.0",
62
+ "@kitschpatrol/shared-config": "^6.2.0",
63
63
  "@types/node": "~20.19.37",
64
64
  "bumpp": "^11.0.1",
65
65
  "publint": "^0.3.18",
66
- "tsdown": "^0.21.4",
66
+ "tsdown": "^0.21.7",
67
67
  "typescript": "~5.9.3",
68
- "vitest": "^4.1.1"
68
+ "vitest": "^4.1.2"
69
69
  },
70
70
  "engines": {
71
71
  "node": ">=20.19.6"
package/readme.md CHANGED
@@ -41,6 +41,17 @@
41
41
  - [API](#api)
42
42
  - [Examples](#examples)
43
43
  - [Utilities](#utilities)
44
+ - [Migrating from 1.x to 2.x](#migrating-from-1x-to-2x)
45
+ - [Simplified options](#simplified-options)
46
+ - [Removed options](#removed-options)
47
+ - [Removed rule properties](#removed-rule-properties)
48
+ - [Changed rule properties](#changed-rule-properties)
49
+ - [Removed validation utility](#removed-validation-utility)
50
+ - [Rule function signature change](#rule-function-signature-change)
51
+ - [Stricter argument syntax](#stricter-argument-syntax)
52
+ - [Comment-style comments are ignored](#comment-style-comments-are-ignored)
53
+ - [Compound rule error handling](#compound-rule-error-handling)
54
+ - [Removed export: `deepMergeDefined`](#removed-export-deepmergedefined)
44
55
  - [Implementation notes](#implementation-notes)
45
56
  - [Maintainers](#maintainers)
46
57
  - [Acknowledgments](#acknowledgments)
@@ -53,13 +64,13 @@
53
64
 
54
65
  This is a [remark](https://remark.js.org) plugin that automates the inline expansion of placeholder HTML comments with dynamic content in Markdown, making it easy to keep readme files and other documentation in sync with an external single source of truth.
55
66
 
56
- The plugin can take placeholder comments in a Markdown file like this:
67
+ The plugin finds placeholder comments in a Markdown file like this:
57
68
 
58
69
  ```md
59
70
  <!-- title -->
60
71
  ```
61
72
 
62
- And replace it with dynamic data. In this case, from `package.json`:
73
+ And expands them with the data of your choosing. In this case, it reads the `title` field a nearby `package.json`:
63
74
 
64
75
  ```md
65
76
  <!-- title -->
@@ -75,12 +86,12 @@ This plugin powers the higher-level [`mdat` package](https://github.com/kitschpa
75
86
 
76
87
  ### Dependencies
77
88
 
78
- This library is ESM only and requires Node 20+. It's designed to work with Remark 15. `remark-mdat` is implemented in TypeScript and bundles a complete set of type definitions.
89
+ This library is ESM only and requires Node 20.19.6+. It's designed to work with Remark 15. `remark-mdat` is implemented in TypeScript and bundles a complete set of type definitions.
79
90
 
80
91
  ### Installation
81
92
 
82
93
  ```sh
83
- npm install remark-mdat
94
+ pnpm add remark-mdat
84
95
  ```
85
96
 
86
97
  ## Usage
@@ -102,7 +113,7 @@ remark().use(remarkMdat)
102
113
 
103
114
  #### Options
104
115
 
105
- The plugin accepts an optional `Rules` object as its options. This is a `Record<string, Rule>` where each key is a keyword matching an HTML comment in the Markdown file (e.g. `title` matches `<!-- title -->`).
116
+ The plugin accepts an optional `Options` object with a `rules` field. `Rules` is a `Record<string, Rule>` where each key is a keyword matching an HTML comment in the Markdown file (e.g. `title` matches `<!-- title -->`).
106
117
 
107
118
  HTML comments using code-style notation (`<!-- // ... -->`, `<!-- # ... -->`, `<!-- /* ... */ -->`) are ignored and will not be treated as mdat keywords. Rule keywords cannot start with `/`, `*`, or `#`.
108
119
 
@@ -119,9 +130,9 @@ const rules: Rules = {
119
130
  // Function with arguments: receives parsed options from the comment
120
131
  personalGreeting: (options) => `Hello, ${options.name}!`,
121
132
 
122
- // Object: rule with validation metadata
133
+ // Object: with processing priority
123
134
  title: {
124
- order: 0, // Processing priority (default: 0)
135
+ order: 1, // Runs after other rules (default is 0)
125
136
  content: () => getTitle(), // String, function, or array
126
137
  },
127
138
 
@@ -148,7 +159,7 @@ type RuleContext = {
148
159
  }
149
160
  ```
150
161
 
151
- Frontmatter is automatically extracted from the raw Markdown source using [gray-matter-es](https://github.com/ryoppippi/gray-matter-es), so it works regardless of whether `remark-frontmatter` is in your pipeline. If the document has no frontmatter block, `context.frontmatter` is `undefined`.
162
+ Frontmatter is automatically extracted if available. If the document has no frontmatter block, `context.frontmatter` remains `undefined`.
152
163
 
153
164
  ```ts
154
165
  const rules: Rules = {
@@ -181,11 +192,11 @@ Single primitive value:
181
192
  <!-- repeat(3) -->
182
193
  ```
183
194
 
184
- Any JSON5 value is supported: objects, arrays, strings, numbers, and booleans. Comments without parentheses receive an empty object `{}` as their options.
195
+ Prefer object arguments over single primitive values for all but the most contextually clear argument values.
185
196
 
186
- For simplicity's sake, only a single argument position is supported. If you need pass multiple arguments, wrap them in an object.
197
+ Any JSON5 value is supported: objects, arrays, strings, numbers, and booleans. Comments without parentheses receive an empty object `{}` as their options.
187
198
 
188
- Prefer object arguments for all but the most contextually clear argument values.
199
+ For simplicity's sake, only a single argument position is supported. If you need pass multiple arguments, wrap them in an object. For security's sake, only JSON5 / JSON values are permitted in keyword arguments, no JavaScript is evaluated.
189
200
 
190
201
  ### Examples
191
202
 
@@ -221,20 +232,20 @@ import remarkMdat from 'remark-mdat'
221
232
 
222
233
  // Create the rules
223
234
  const rules: Rules = {
224
- time: () => new Date().toDateString(),
235
+ time: new Date().toDateString(),
225
236
  }
226
237
 
227
238
  const markdownInput = '<!-- time -->'
228
239
 
229
240
  // Pass the rules to remarkMdat
230
- const markdownOutput = await remark().use(remarkMdat, rules).process(markdownInput)
241
+ const markdownOutput = await remark().use(remarkMdat, { rules }).process(markdownInput)
231
242
 
232
243
  console.log(markdownOutput.toString())
233
244
 
234
245
  // Logs:
235
246
  // <!-- time -->
236
247
  //
237
- // Mon Feb 05 2024
248
+ // Mon April 01 2026
238
249
  //
239
250
  // <!-- /time -->
240
251
  ```
@@ -274,10 +285,122 @@ Errors and warnings are reported inline during expansion via [VFile messages](ht
274
285
 
275
286
  _Exported as `mdatExpand(tree: Root, file: VFile, rules: Rules): Promise<void>`_
276
287
 
288
+ ## Migrating from 1.x to 2.x
289
+
290
+ Version 2.0 simplifies and solidifies the API by removing several configuration options and validation features that added complexity without sufficient benefit. The core expansion behavior is unchanged — the plugin still matches HTML comments to rules and expands them — but the way you configure it has changed.
291
+
292
+ ### Simplified options
293
+
294
+ In 1.x, the plugin accepted an options object with multiple fields to customize parsing and generation:
295
+
296
+ ```ts
297
+ // 1.x
298
+ remark().use(remarkMdat, {
299
+ rules: { title: () => '# My Title' },
300
+ addMetaComment: true,
301
+ closingPrefix: '/',
302
+ keywordPrefix: 'mm-',
303
+ metaCommentIdentifier: '+',
304
+ })
305
+ ```
306
+
307
+ In 2.x, the configuration options for parsing and generation have been removed. The `Options` object now contains only a `rules` field:
308
+
309
+ ```ts
310
+ // 2.x
311
+ remark().use(remarkMdat, {
312
+ rules: { title: () => '# My Title' },
313
+ })
314
+ ```
315
+
316
+ If you were importing `MdatOptions`, `MdatExpandOptions`, `MdatCheckOptions`, or `MdatCleanOptions`, replace them with `Options` (for plugin configuration) or `Rules` (for the rules record).
317
+
318
+ ### Removed options
319
+
320
+ The following plugin options have been removed entirely:
321
+
322
+ | Removed option | Migration |
323
+ | ----------------------- | ------------------------------------------------------------------------ |
324
+ | `addMetaComment` | Remove. Auto-generated warning comments are no longer supported. |
325
+ | `metaCommentIdentifier` | Remove. The `<!--+ ... +-->` meta comment syntax is gone. |
326
+ | `closingPrefix` | Remove. The closing prefix is now always `/` (e.g. `<!-- /keyword -->`). |
327
+ | `keywordPrefix` | Remove. Keyword prefixing / namespacing is no longer supported. |
328
+
329
+ ### Removed rule properties
330
+
331
+ | Removed property | Migration |
332
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
333
+ | `required` | Remove. All rules are treated equally. Missing comments produce a warning instead of an error. |
334
+ | `order` | Remove. The 1.x `order` property enforced comment _position_ in the document. In 2.x, `order` controls _processing priority_ only (default: `0`). |
335
+
336
+ ### Changed rule properties
337
+
338
+ | Changed property | Migration |
339
+ | ------------------ | ------------------ |
340
+ | `applicationOrder` | Change to `order`. |
341
+
342
+ ### Removed validation utility
343
+
344
+ The `mdast-util-mdat-check` utility and its export `mdatCheck` have been removed. Validation logic (missing rules, empty content, rule errors) is now handled inline during expansion by `mdatExpand`, which reports issues as VFile messages. Use `reporterMdat` to format and display these messages.
345
+
346
+ ### Rule function signature change
347
+
348
+ In 1.x, rule content functions received the mdast tree directly as the second argument:
349
+
350
+ ```ts
351
+ // 1.x
352
+ const rules = {
353
+ toc: (_options, tree) => generateTocFromTree(tree),
354
+ }
355
+ ```
356
+
357
+ In 2.x, the second argument is a `RuleContext` object containing the tree, parsed frontmatter, and file path:
358
+
359
+ ```ts
360
+ // 2.x
361
+ const rules = {
362
+ toc: (_options, context) => generateTocFromTree(context.tree),
363
+ }
364
+ ```
365
+
366
+ ### Stricter argument syntax
367
+
368
+ In 1.x, the argument parser was very permissive — parentheses were optional, bare key-value pairs were auto-wrapped in braces, and space-separated arguments worked:
369
+
370
+ ```md
371
+ <!-- greeting name: "Alice" -->
372
+ <!-- greeting {name: "Alice"} -->
373
+ <!-- greeting({name: "Alice"}) -->
374
+ ```
375
+
376
+ In 2.x, arguments **must** use function-call syntax with parentheses. The content inside the parentheses is parsed as [JSON5](https://json5.org/):
377
+
378
+ ```md
379
+ <!-- greeting({name: 'Alice'}) -->
380
+ ```
381
+
382
+ Bare or space-separated arguments like `<!-- greeting name: "Alice" -->` will no longer be parsed — the extra text after the keyword is ignored and the rule receives an empty `{}` options object.
383
+
384
+ As a trade-off for the stricter syntax, primitive values are now supported as arguments: `<!-- repeat(3) -->`, `<!-- show("hello") -->`.
385
+
386
+ ### Comment-style comments are ignored
387
+
388
+ HTML comments using code-style prefixes (`<!-- // ... -->`, `<!-- # ... -->`, `<!-- /* ... */ -->`) are now ignored by the parser, so you can use them for regular comments alongside mdat keywords without triggering warnings. This replaces 1.x parser configuration options like `keywordPrefix`.
389
+
390
+ ### Compound rule error handling
391
+
392
+ In 1.x, a failing sub-rule in a compound rule (array of rules) caused the entire expansion to fail. In 2.x, individual sub-rule failures are reported as warnings and skipped — the expansion only fails if every sub-rule fails.
393
+
394
+ ### Removed export: `deepMergeDefined`
395
+
396
+ The `deepMergeDefined` utility has been moved to the [`mdat`](https://github.com/kitschpatrol/mdat) package. If you were importing it from `remark-mdat`, import it from `mdat` instead.
397
+
277
398
  ## Implementation notes
278
399
 
279
400
  This project was split from a monorepo containing both `mdat` and `remark-mdat` into separate repos in July 2024.
280
401
 
402
+ The API was redesigned and simplified for version 2 in March 2026.
403
+
281
404
  Remark is not a peer dependency on account of this discussion: [strip-markdown/issues/24](https://github.com/remarkjs/strip-markdown/issues/24)
282
405
 
283
406
  ## Maintainers