mdrefine 0.2.0-rc.2 → 0.2.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +577 -0
  2. package/CODE_OF_CONDUCT.md +30 -0
  3. package/CONTRIBUTING.md +189 -16
  4. package/README.md +100 -154
  5. package/SECURITY.md +15 -13
  6. package/config.schema.json +91 -0
  7. package/dist/cli/diff.d.ts +10 -0
  8. package/dist/cli/diff.js +247 -0
  9. package/dist/cli/diff.js.map +1 -0
  10. package/dist/cli/main.js +270 -150
  11. package/dist/cli/main.js.map +1 -1
  12. package/dist/config/load.js +67 -6
  13. package/dist/config/load.js.map +1 -1
  14. package/dist/config/problems.d.ts +7 -0
  15. package/dist/config/problems.js +208 -0
  16. package/dist/config/problems.js.map +1 -0
  17. package/dist/config/resolve.d.ts +42 -109
  18. package/dist/config/resolve.js +193 -52
  19. package/dist/config/resolve.js.map +1 -1
  20. package/dist/core/directives.d.ts +7 -0
  21. package/dist/core/directives.js +25 -13
  22. package/dist/core/directives.js.map +1 -1
  23. package/dist/core/engine.d.ts +42 -4
  24. package/dist/core/engine.js +518 -79
  25. package/dist/core/engine.js.map +1 -1
  26. package/dist/core/frozen.d.ts +6 -0
  27. package/dist/core/frozen.js +15 -0
  28. package/dist/core/frozen.js.map +1 -0
  29. package/dist/core/scope.d.ts +30 -0
  30. package/dist/core/scope.js +122 -0
  31. package/dist/core/scope.js.map +1 -0
  32. package/dist/core/types.d.ts +202 -23
  33. package/dist/core/types.js.map +1 -1
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js.map +1 -1
  36. package/dist/node.d.ts +3 -0
  37. package/dist/node.js +4 -0
  38. package/dist/node.js.map +1 -0
  39. package/dist/rules/blocks.d.ts +34 -0
  40. package/dist/rules/blocks.js +550 -0
  41. package/dist/rules/blocks.js.map +1 -0
  42. package/dist/rules/content.d.ts +2 -0
  43. package/dist/rules/content.js +85 -0
  44. package/dist/rules/content.js.map +1 -0
  45. package/dist/rules/dialects.js +10 -6
  46. package/dist/rules/dialects.js.map +1 -1
  47. package/dist/rules/links.js +302 -6
  48. package/dist/rules/links.js.map +1 -1
  49. package/dist/rules/lists.d.ts +2 -0
  50. package/dist/rules/lists.js +924 -0
  51. package/dist/rules/lists.js.map +1 -0
  52. package/dist/rules/structure.js +127 -1
  53. package/dist/rules/structure.js.map +1 -1
  54. package/dist/rules/style.d.ts +8 -2
  55. package/dist/rules/style.js +1137 -165
  56. package/dist/rules/style.js.map +1 -1
  57. package/dist/syntax/block-identifier.d.ts +18 -0
  58. package/dist/syntax/block-identifier.js +24 -0
  59. package/dist/syntax/block-identifier.js.map +1 -0
  60. package/dist/syntax/obsidian.d.ts +29 -11
  61. package/dist/syntax/obsidian.js +9 -10
  62. package/dist/syntax/obsidian.js.map +1 -1
  63. package/dist/syntax/parse.d.ts +87 -3
  64. package/dist/syntax/parse.js +247 -19
  65. package/dist/syntax/parse.js.map +1 -1
  66. package/dist/workspace/access.d.ts +12 -3
  67. package/dist/workspace/access.js +33 -5
  68. package/dist/workspace/access.js.map +1 -1
  69. package/dist/workspace/discovery.d.ts +85 -0
  70. package/dist/workspace/discovery.js +155 -0
  71. package/dist/workspace/discovery.js.map +1 -0
  72. package/dist/workspace/encoding.d.ts +24 -0
  73. package/dist/workspace/encoding.js +113 -0
  74. package/dist/workspace/encoding.js.map +1 -0
  75. package/dist/workspace/files.d.ts +92 -6
  76. package/dist/workspace/files.js +715 -59
  77. package/dist/workspace/files.js.map +1 -1
  78. package/dist/workspace/git.d.ts +54 -0
  79. package/dist/workspace/git.js +198 -0
  80. package/dist/workspace/git.js.map +1 -0
  81. package/dist/workspace/index.d.ts +58 -3
  82. package/dist/workspace/index.js +136 -37
  83. package/dist/workspace/index.js.map +1 -1
  84. package/dist/workspace/selection.d.ts +2 -2
  85. package/dist/workspace/selection.js +3 -3
  86. package/dist/workspace/selection.js.map +1 -1
  87. package/dist/workspace/slug.js +8 -1
  88. package/dist/workspace/slug.js.map +1 -1
  89. package/dist/workspace/vault.js +3 -1
  90. package/dist/workspace/vault.js.map +1 -1
  91. package/docs/api.md +239 -0
  92. package/docs/benchmarks.md +140 -200
  93. package/docs/changelog.md +1 -0
  94. package/docs/cli.md +281 -89
  95. package/docs/configuration.md +193 -480
  96. package/docs/design.md +163 -284
  97. package/docs/dialects.md +169 -0
  98. package/docs/examples.md +151 -109
  99. package/docs/index.md +21 -37
  100. package/docs/integrations.md +144 -0
  101. package/docs/obsidian.md +91 -115
  102. package/docs/plugins.md +147 -212
  103. package/docs/quick-start.md +68 -74
  104. package/docs/rules.md +1237 -0
  105. package/docs/versions.md +56 -0
  106. package/examples/README.md +17 -14
  107. package/examples/automation/summarize-report.mjs +5 -2
  108. package/examples/library/lint-folder.mjs +5 -4
  109. package/examples/library/lint-workspace.mjs +32 -0
  110. package/examples/plugin/notes/release-checklist.md +2 -2
  111. package/examples/plugin/rules.mjs +17 -23
  112. package/examples/workspaces/obsidian-vault/after/mdtools.config.jsonc +2 -2
  113. package/examples/workspaces/obsidian-vault/before/mdtools.config.jsonc +2 -2
  114. package/examples/workspaces/repository-docs/after/README.md +2 -2
  115. package/examples/workspaces/repository-docs/after/mdtools.config.jsonc +0 -2
  116. package/examples/workspaces/repository-docs/before/README.md +2 -2
  117. package/examples/workspaces/repository-docs/before/docs/guide.md +7 -7
  118. package/examples/workspaces/repository-docs/before/docs/reference.md +3 -1
  119. package/examples/workspaces/repository-docs/before/mdtools.config.jsonc +0 -2
  120. package/package.json +38 -12
  121. package/docs/contributing.md +0 -218
  122. package/docs/releases/0.1.0-beta.1.md +0 -39
  123. package/docs/releases/0.1.0-beta.2.md +0 -83
  124. package/docs/releases/0.1.0-beta.3.md +0 -61
  125. package/docs/releases/0.1.0-beta.4.md +0 -50
  126. package/docs/releases/0.1.0-rc.1.md +0 -99
  127. package/docs/releases/0.2.0-rc.1.md +0 -141
  128. package/docs/releases/0.2.0-rc.2.md +0 -225
  129. package/docs/releases.md +0 -144
  130. package/docs/testing.md +0 -93
@@ -1,5 +1,16 @@
1
1
  import { walk } from "../syntax/walk.js";
2
2
  import { range } from "../syntax/parse.js";
3
+ /** The directive that an HTML node's value holds, if it is one. */
4
+ export function directive(value) {
5
+ const match = /^<!--\s*mdtools-(disable-next-line|disable|enable)(?:\s+([^]*?))?\s*-->$/.exec(value.trim());
6
+ if (!match)
7
+ return undefined;
8
+ const names = match[2]
9
+ ?.trim()
10
+ .split(/[\s,]+/)
11
+ .filter(Boolean) ?? ["*"];
12
+ return { kind: match[1], rules: new Set(names.length ? names : ["*"]) };
13
+ }
3
14
  /** Directives are recognized only in parsed HTML comments, never in code examples. */
4
15
  export function suppressions(document) {
5
16
  // Directives can only appear in HTML comments containing this prefix.
@@ -8,23 +19,24 @@ export function suppressions(document) {
8
19
  const intervals = [];
9
20
  const active = new Map();
10
21
  walk(document.tree, "html", (node) => {
11
- const match = /^<!--\s*mdtools-(disable-next-line|disable|enable)(?:\s+([^]*?))?\s*-->$/.exec(node.value.trim());
12
- if (!match)
22
+ const found = directive(node.value);
23
+ if (!found)
13
24
  return;
14
- const names = match[2]
15
- ?.trim()
16
- .split(/[\s,]+/)
17
- .filter(Boolean) ?? ["*"];
18
- const rules = new Set(names.length ? names : ["*"]);
25
+ const { rules } = found;
19
26
  const [start, end] = range(node);
20
- if (match[1] === "disable-next-line") {
21
- const next = document.source.indexOf("\n", end);
22
- if (next < 0)
27
+ if (found.kind === "disable-next-line") {
28
+ // The line after the directive's own, whichever of CommonMark's line endings ends each.
29
+ const lineBreak = /\r\n|\r|\n/g;
30
+ lineBreak.lastIndex = end;
31
+ const first = lineBreak.exec(document.source);
32
+ if (!first)
23
33
  return;
24
- const last = document.source.indexOf("\n", next + 1);
25
- intervals.push({ start: next + 1, end: last < 0 ? document.source.length : last, rules });
34
+ const next = first.index + first[0].length;
35
+ lineBreak.lastIndex = next;
36
+ const last = lineBreak.exec(document.source);
37
+ intervals.push({ start: next, end: last ? last.index : document.source.length, rules });
26
38
  }
27
- else if (match[1] === "disable") {
39
+ else if (found.kind === "disable") {
28
40
  for (const rule of rules)
29
41
  if (!active.has(rule))
30
42
  active.set(rule, end);
@@ -1 +1 @@
1
- {"version":3,"file":"directives.js","sourceRoot":"","sources":["../../src/core/directives.ts"],"names":[],"mappings":"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","sourcesContent":["import { walk } from \"../syntax/walk.js\";\nimport type { Document, Finding } from \"./types.js\";\nimport { range } from \"../syntax/parse.js\";\n\n/** Directives are recognized only in parsed HTML comments, never in code examples. */\nexport function suppressions(document: Document): (rule: string, finding: Finding) => boolean {\n // Directives can only appear in HTML comments containing this prefix.\n if (!document.source.includes(\"mdtools-\")) return () => false;\n const intervals: { start: number; end: number; rules: Set<string> }[] = [];\n const active = new Map<string, number>();\n walk(document.tree, \"html\", (node) => {\n const match = /^<!--\\s*mdtools-(disable-next-line|disable|enable)(?:\\s+([^]*?))?\\s*-->$/.exec(\n node.value.trim(),\n );\n if (!match) return;\n const names = match[2]\n ?.trim()\n .split(/[\\s,]+/)\n .filter(Boolean) ?? [\"*\"];\n const rules = new Set(names.length ? names : [\"*\"]);\n const [start, end] = range(node);\n if (match[1] === \"disable-next-line\") {\n const next = document.source.indexOf(\"\\n\", end);\n if (next < 0) return;\n const last = document.source.indexOf(\"\\n\", next + 1);\n intervals.push({ start: next + 1, end: last < 0 ? document.source.length : last, rules });\n } else if (match[1] === \"disable\") {\n for (const rule of rules) if (!active.has(rule)) active.set(rule, end);\n } else {\n for (const rule of rules.has(\"*\") ? active.keys() : rules) {\n const from = active.get(rule);\n if (from !== undefined) intervals.push({ start: from, end: start, rules: new Set([rule]) });\n active.delete(rule);\n }\n }\n });\n for (const [rule, start] of active)\n intervals.push({ start, end: document.source.length, rules: new Set([rule]) });\n return (rule, finding) =>\n intervals.some((interval) => {\n const start = finding.edit?.start ?? finding.start;\n const end = finding.edit?.end ?? finding.end ?? finding.start;\n return (\n (interval.rules.has(\"*\") || interval.rules.has(rule)) &&\n start <= interval.end &&\n end >= interval.start\n );\n });\n}\n"]}
1
+ {"version":3,"file":"directives.js","sourceRoot":"","sources":["../../src/core/directives.ts"],"names":[],"mappings":"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","sourcesContent":["import { walk } from \"../syntax/walk.js\";\nimport type { Document, Finding } from \"./types.js\";\nimport { range } from \"../syntax/parse.js\";\n\n/** A suppression directive and the rules it names, `*` for all of them. */\nexport interface Directive {\n kind: \"disable-next-line\" | \"disable\" | \"enable\";\n rules: Set<string>;\n}\n/** The directive that an HTML node's value holds, if it is one. */\nexport function directive(value: string): Directive | undefined {\n const match = /^<!--\\s*mdtools-(disable-next-line|disable|enable)(?:\\s+([^]*?))?\\s*-->$/.exec(\n value.trim(),\n );\n if (!match) return undefined;\n const names = match[2]\n ?.trim()\n .split(/[\\s,]+/)\n .filter(Boolean) ?? [\"*\"];\n return { kind: match[1] as Directive[\"kind\"], rules: new Set(names.length ? names : [\"*\"]) };\n}\n/** Directives are recognized only in parsed HTML comments, never in code examples. */\nexport function suppressions(document: Document): (rule: string, finding: Finding) => boolean {\n // Directives can only appear in HTML comments containing this prefix.\n if (!document.source.includes(\"mdtools-\")) return () => false;\n const intervals: { start: number; end: number; rules: Set<string> }[] = [];\n const active = new Map<string, number>();\n walk(document.tree, \"html\", (node) => {\n const found = directive(node.value);\n if (!found) return;\n const { rules } = found;\n const [start, end] = range(node);\n if (found.kind === \"disable-next-line\") {\n // The line after the directive's own, whichever of CommonMark's line endings ends each.\n const lineBreak = /\\r\\n|\\r|\\n/g;\n lineBreak.lastIndex = end;\n const first = lineBreak.exec(document.source);\n if (!first) return;\n const next = first.index + first[0].length;\n lineBreak.lastIndex = next;\n const last = lineBreak.exec(document.source);\n intervals.push({ start: next, end: last ? last.index : document.source.length, rules });\n } else if (found.kind === \"disable\") {\n for (const rule of rules) if (!active.has(rule)) active.set(rule, end);\n } else {\n for (const rule of rules.has(\"*\") ? active.keys() : rules) {\n const from = active.get(rule);\n if (from !== undefined) intervals.push({ start: from, end: start, rules: new Set([rule]) });\n active.delete(rule);\n }\n }\n });\n for (const [rule, start] of active)\n intervals.push({ start, end: document.source.length, rules: new Set([rule]) });\n return (rule, finding) =>\n intervals.some((interval) => {\n const start = finding.edit?.start ?? finding.start;\n const end = finding.edit?.end ?? finding.end ?? finding.start;\n return (\n (interval.rules.has(\"*\") || interval.rules.has(rule)) &&\n start <= interval.end &&\n end >= interval.start\n );\n });\n}\n"]}
@@ -1,8 +1,46 @@
1
1
  import type { Diagnostic, Document, Edit, FormatResult, Plugin, ProcessOptions, Rule, Workspace } from "./types.js";
2
- export declare const builtInRules: Record<string, Rule>;
3
- export declare function ruleRegistry(plugins?: Plugin[]): Record<string, Rule>;
2
+ /**
3
+ * The built-in rules by rule ID. The table and the rules in it are frozen, so
4
+ * that no caller can change what another one runs.
5
+ */
6
+ export declare const builtInRules: Readonly<Record<string, Readonly<Rule>>>;
7
+ /**
8
+ * The prefix of the engine's own diagnostics, such as `engine/rule-error`. A
9
+ * plugin of this name could report findings that pass for the engine's, which
10
+ * concern the whole document and make the CLI exit with code 2.
11
+ */
12
+ export declare const reservedPluginName = "engine";
13
+ /**
14
+ * The built-in rules and those of `plugins`, by rule ID, in a new table. A
15
+ * plugin name that is invalid, reserved, or used twice, a rule ID that exists
16
+ * already, and a plugin rule that does not have the shape of a `Rule` are
17
+ * errors that name them.
18
+ */
19
+ export declare function ruleRegistry(plugins?: readonly Plugin[]): Record<string, Readonly<Rule>>;
20
+ /**
21
+ * The diagnostics of the enabled rules for `source`, sorted by position. A rule
22
+ * that fails is skipped and reported as `engine/rule-error`. An invalid
23
+ * configuration, an unknown rule, invalid rule options, an invalid plugin, and
24
+ * an error that the workspace throws are thrown.
25
+ */
4
26
  export declare function lint(source: string, options?: ProcessOptions): Diagnostic[];
5
- export declare function applyEdits(source: string, edits: Edit[]): string;
6
- /** Compare semantic trees, with link identity supplied by the selected renderer's resolver. */
27
+ /**
28
+ * `source` with `edits` applied, which are `{ start, end, text }` replacements
29
+ * at UTF-16 offsets into it. Repeats of one edit count once; an edit outside
30
+ * the source, or one that overlaps another, is an error.
31
+ */
32
+ export declare function applyEdits(source: string, edits: readonly Edit[]): string;
33
+ /**
34
+ * The meaning of a parsed document as text, which `format` compares before and
35
+ * after edits to refuse a change of meaning: its syntax tree without positions,
36
+ * with runs of whitespace in text alike, and with each link's destination as
37
+ * the workspace resolves it, so that two spellings of one target are the same.
38
+ */
7
39
  export declare function semanticFingerprint(document: Document, workspace?: Workspace): string;
40
+ /**
41
+ * Format a document: apply the edits of the enabled style rules, in passes
42
+ * until nothing changes, leaving out the edits of a rule that would change the
43
+ * document's meaning. Byte order marks that it starts with stay in the output
44
+ * and are not part of what the rules see. Errors are thrown as by `lint`.
45
+ */
8
46
  export declare function format(source: string, options?: ProcessOptions): FormatResult;