mdrefine 0.1.0-rc.1 → 0.2.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/cli/main.js +1 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/config/resolve.d.ts +5 -1
- package/dist/config/resolve.js +30 -4
- package/dist/config/resolve.js.map +1 -1
- package/dist/core/engine.js +12 -0
- package/dist/core/engine.js.map +1 -1
- package/dist/core/types.d.ts +5 -3
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/rules/dialects.js +47 -1
- package/dist/rules/dialects.js.map +1 -1
- package/dist/rules/links.js +18 -1
- package/dist/rules/links.js.map +1 -1
- package/dist/rules/style.d.ts +8 -0
- package/dist/rules/style.js +204 -22
- package/dist/rules/style.js.map +1 -1
- package/dist/syntax/parse.js +14 -1
- package/dist/syntax/parse.js.map +1 -1
- package/dist/workspace/heading-attributes.d.ts +87 -0
- package/dist/workspace/heading-attributes.js +392 -0
- package/dist/workspace/heading-attributes.js.map +1 -0
- package/dist/workspace/index.js +388 -32
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/slug.d.ts +34 -0
- package/dist/workspace/slug.js +85 -0
- package/dist/workspace/slug.js.map +1 -0
- package/docs/configuration.md +136 -25
- package/docs/design.md +117 -14
- package/docs/index.md +1 -1
- package/docs/plugins.md +7 -4
- package/docs/quick-start.md +5 -3
- package/docs/releases/0.2.0-rc.1.md +141 -0
- package/docs/releases.md +8 -8
- package/examples/forgejo.jsonc +8 -0
- package/examples/gitea.jsonc +8 -0
- package/package.json +12 -11
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# mdrefine — Markdown Tools
|
|
2
2
|
|
|
3
|
-
Configurable linting and formatting for CommonMark, GitHub Markdown,
|
|
4
|
-
Obsidian. Separate `lint` and `format` commands share
|
|
5
|
-
and an extensible rule engine.
|
|
3
|
+
Configurable linting and formatting for CommonMark, GitHub Markdown, Forgejo
|
|
4
|
+
(Codeberg), Gitea, and Obsidian. Separate `lint` and `format` commands share
|
|
5
|
+
syntax, style settings, and an extensible rule engine.
|
|
6
6
|
|
|
7
7
|
[npm package](https://www.npmjs.com/package/mdrefine) ·
|
|
8
8
|
[GitHub releases](https://github.com/viell-dev/slop-markdown-tools/releases)
|
|
@@ -42,7 +42,7 @@ executable is `mdtools`. To install the release candidate in your document
|
|
|
42
42
|
workspace:
|
|
43
43
|
|
|
44
44
|
```sh
|
|
45
|
-
npm install --save-dev --save-exact mdrefine@0.
|
|
45
|
+
npm install --save-dev --save-exact mdrefine@0.2.0-rc.1
|
|
46
46
|
npx --no-install mdtools --help
|
|
47
47
|
```
|
|
48
48
|
|
package/dist/cli/main.js
CHANGED
|
@@ -19,7 +19,7 @@ function common(command) {
|
|
|
19
19
|
return command
|
|
20
20
|
.option("--config <file>", "Explicit JSON, JSONC, or .mjs configuration")
|
|
21
21
|
.option("--root <directory>", "Workspace root (default: configuration directory or cwd)")
|
|
22
|
-
.option("--dialect <dialect>", "commonmark, github, or obsidian")
|
|
22
|
+
.option("--dialect <dialect>", "commonmark, github, forgejo (alias: codeberg), gitea, or obsidian")
|
|
23
23
|
.option("--exclude <path>", "Exclude an exact file or directory (repeatable)", (value, previous) => [...previous, value], [])
|
|
24
24
|
.option("--json", "Machine-readable output")
|
|
25
25
|
.option("--stdin-filepath <file>", "Filename context for stdin")
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAexD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,MAAM,QAAQ,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAC/D,CAAC;AACzB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;KAC1B,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,yEAAyE,CAAC;KACtF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC7B,SAAS,MAAM,CAAC,OAAgB;IAC9B,OAAO,OAAO;SACX,MAAM,CAAC,iBAAiB,EAAE,6CAA6C,CAAC;SACxE,MAAM,CAAC,oBAAoB,EAAE,0DAA0D,CAAC;SACxF,MAAM,CAAC,qBAAqB,EAAE,iCAAiC,CAAC;SAChE,MAAM,CACL,kBAAkB,EAClB,iDAAiD,EACjD,CAAC,KAAa,EAAE,QAAkB,EAAE,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,EAC3D,EAAE,CACH;SACA,MAAM,CAAC,QAAQ,EAAE,yBAAyB,CAAC;SAC3C,MAAM,CAAC,yBAAyB,EAAE,4BAA4B,CAAC;SAC/D,MAAM,CACL,wBAAwB,EACxB,0DAA0D,EAC1D,CAAC,KAAa,EAAE,EAAE;QAChB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,OAAO,MAAM,CAAC;IAChB,CAAC,CACF,CAAC;AACN,CAAC;AAOD,KAAK,UAAU,GAAG,CAAC,IAAuB,EAAE,MAAgB,EAAE,KAAY;IACxE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM;QAC/C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,OAAO;QAAE,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IACzD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzF,GAAG,CAAC,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACnF,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,GAAG,IAAI;aACd,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;aAChF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;QACjE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QACzB,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAsD,EAAE,CAAC;IACtE,iFAAiF;IACjF,MAAM,OAAO,GAAG,IAAI,GAAG,EAA+C,CAAC;IACvE,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;YAC9B,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,OAAO,EACd,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE;gBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,GAAG,CAAC,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1F,CAAC,CACH,CAAC;QACJ,MAAM,OAAO,GAAmB;YAC9B,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAE;SACxC,CAAC;QACF,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC7D,IAAI,MAAM,KAAK,IAAI;YAAE,SAAS;QAC9B,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;aACjF,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5D,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACrC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAC,CACxE,CAAC;IACF,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM;QACxB,KAAK,MAAM,MAAM,IAAI,OAAO;YAC1B,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACrF,IAAI,KAAK,CAAC,IAAI;QACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CACZ;YACE,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,IAAI;YACJ,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM;SACzC,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;SACC,CAAC;QACJ,IAAI,KAAK,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI;YAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;aAC5C,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK;YACxD,KAAK,MAAM,MAAM,IAAI,OAAO;gBAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,CAAC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CACzF,CAAC;QACN,KAAK,MAAM,MAAM,IAAI,OAAO;YAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,WAAW;gBACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,IAAI,CAC/F,CAAC;QACN,IAAI,CAAC,KAAK;YACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,KAAK,CAC1J,CAAC;IACN,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IACrE,MAAM,eAAe,GACnB,KAAK,CAAC,WAAW,KAAK,SAAS;QAC/B,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;IACpF,OAAO,CAAC,QAAQ,GAAG,MAAM;QACvB,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,MAAM,IAAI,eAAe,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAC;AACV,CAAC;AACD,MAAM,CACJ,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,4CAA4C,CAAC,CAC7F,CAAC,MAAM,CAAC,CAAC,MAAgB,EAAE,KAAY,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AACzE,MAAM,CACJ,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,4CAA4C,CAAC,CAC/F;KACE,MAAM,CAAC,SAAS,EAAE,4CAA4C,CAAC;KAC/D,MAAM,CAAC,QAAQ,EAAE,qDAAqD,CAAC;KACvE,MAAM,CAAC,SAAS,EAAE,oCAAoC,CAAC;KACvD,MAAM,CAAC,CAAC,MAAgB,EAAE,KAAY,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAC5E,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;KAC7E,OAAO,CAAC,gBAAgB,CAAC;KACzB,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,MAAe,EAAE,OAAgB,EAAE,EAAE;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAO,CAAC,IAAI,EAAS,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/E,IAAI,KAAK,CAAC,OAAO;QAAE,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CACZ;QACE,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;QACzB,SAAS,EAAE,aAAa,CACtB,MAAM,CAAC,MAAM,EACb,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACjE,MAAM,CAAC,OAAO,CACf;KACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;AACJ,CAAC,CAAC,CAAC;AACL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AACL,IAAI,CAAC;IACH,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { createTwoFilesPatch } from \"diff\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { format, lint, ruleRegistry } from \"../core/engine.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport { resolveConfig } from \"../config/resolve.js\";\nimport { discover, writeAtomic } from \"../workspace/files.js\";\nimport { excludeSelection } from \"../workspace/selection.js\";\nimport { createWorkspace } from \"../workspace/index.js\";\nimport type { Diagnostic, Dialect, ProcessOptions } from \"../core/types.js\";\n\ninterface Flags {\n config?: string;\n root?: string;\n dialect?: Dialect;\n json?: boolean;\n check?: boolean;\n diff?: boolean;\n write?: boolean;\n stdinFilepath?: string;\n maxWarnings?: number;\n exclude?: string[];\n}\nconst manifest = JSON.parse(\n await readFile(fileURLToPath(new URL(\"../../package.json\", import.meta.url)), \"utf8\"),\n) as { version: string };\nconst program = new Command()\n .name(\"mdtools\")\n .description(\"Lint and format Markdown with explicit dialects and configurable rules.\")\n .version(manifest.version);\nfunction common(command: Command): Command {\n return command\n .option(\"--config <file>\", \"Explicit JSON, JSONC, or .mjs configuration\")\n .option(\"--root <directory>\", \"Workspace root (default: configuration directory or cwd)\")\n .option(\"--dialect <dialect>\", \"commonmark, github, or obsidian\")\n .option(\n \"--exclude <path>\",\n \"Exclude an exact file or directory (repeatable)\",\n (value: string, previous: string[]) => [...previous, value],\n [],\n )\n .option(\"--json\", \"Machine-readable output\")\n .option(\"--stdin-filepath <file>\", \"Filename context for stdin\")\n .option(\n \"--max-warnings <count>\",\n \"Fail when warning count exceeds this nonnegative integer\",\n (value: string) => {\n const number = Number(value);\n if (!Number.isInteger(number) || number < 0)\n throw new Error(\"--max-warnings must be a nonnegative integer.\");\n return number;\n },\n );\n}\ninterface Report {\n path: string;\n changed?: boolean;\n diagnostics: Diagnostic[];\n output?: string;\n}\nasync function run(mode: \"lint\" | \"format\", inputs: string[], flags: Flags) {\n if ([flags.check, flags.diff, flags.write].filter(Boolean).length > 1)\n throw new Error(\"Choose only one of --check, --diff, and --write.\");\n if (inputs.includes(\"-\") && flags.exclude?.length)\n throw new Error(\"--exclude cannot be combined with stdin.\");\n const loaded = await loadConfig(path.resolve(flags.root ?? \".\"), flags.config);\n const root = path.resolve(flags.root ?? loaded.root);\n if (flags.dialect) loaded.config.dialect = flags.dialect;\n const resolved = resolveConfig(loaded.config, \"document.md\", loaded.plugins);\n const stdin = inputs.includes(\"-\");\n if (stdin && (inputs.length !== 1 || flags.write))\n throw new Error(\"stdin must be the only input and cannot be combined with --write.\");\n const set = await discover(root, stdin ? [] : inputs, resolved.ignore, resolved.resolve);\n set.selected = await excludeSelection(set.root, set.selected, flags.exclude ?? []);\n if (stdin) {\n const name = path\n .relative(root, path.resolve(flags.stdinFilepath ?? path.join(root, \"stdin.md\")))\n .split(path.sep)\n .join(\"/\");\n if (name.startsWith(\"../\") || path.isAbsolute(name))\n throw new Error(\"--stdin-filepath must be within the workspace.\");\n let source = \"\";\n process.stdin.setEncoding(\"utf8\");\n for await (const chunk of process.stdin) source += String(chunk);\n set.files[name] = source;\n set.selected = [name];\n }\n const reports: Report[] = [];\n const changes: { file: string; before: string; after: string }[] = [];\n // One index per active dialect; build lazily for mixed documentation workspaces.\n const indexes = new Map<Dialect, ReturnType<typeof createWorkspace>>();\n for (const name of set.selected) {\n const config = resolveConfig(loaded.config, name, loaded.plugins);\n if (!indexes.has(config.dialect))\n indexes.set(\n config.dialect,\n createWorkspace(set.files, {\n dialect: config.dialect,\n directories: set.directories,\n ...(set.strictLineBreaks !== undefined ? { strictLineBreaks: set.strictLineBreaks } : {}),\n }),\n );\n const options: ProcessOptions = {\n path: name,\n config: loaded.config,\n plugins: loaded.plugins,\n workspace: indexes.get(config.dialect)!,\n };\n const value = set.files[name]!;\n const source = typeof value === \"function\" ? value() : value;\n if (source === null) continue;\n if (mode === \"lint\") reports.push({ path: name, diagnostics: lint(source, options) });\n else {\n const result = format(source, options);\n reports.push({\n path: name,\n changed: result.changed,\n diagnostics: result.diagnostics,\n ...(stdin && !flags.check ? { output: result.output } : {}),\n });\n if (result.changed) changes.push({ file: name, before: source, after: result.output });\n }\n }\n const unsafe = reports.some((report) =>\n report.diagnostics.some((item) => item.rule === \"engine/unsafe-format\"),\n );\n if (flags.write && !unsafe)\n for (const change of changes)\n await writeAtomic(path.join(set.root, change.file), change.before, change.after);\n if (flags.json)\n process.stdout.write(\n JSON.stringify(\n {\n version: manifest.version,\n mode,\n files: reports,\n written: flags.write === true && !unsafe,\n },\n null,\n 2,\n ) + \"\\n\",\n );\n else {\n if (stdin && mode === \"format\" && !flags.check && !flags.diff)\n process.stdout.write(reports[0]?.output ?? \"\");\n else if (mode === \"format\" && !flags.check && !flags.write)\n for (const change of changes)\n process.stdout.write(\n createTwoFilesPatch(`a/${change.file}`, `b/${change.file}`, change.before, change.after),\n );\n for (const report of reports)\n for (const item of report.diagnostics)\n process.stderr.write(\n `${report.path}:${item.line}:${item.column}: ${item.severity} ${item.rule}: ${item.message}\\n`,\n );\n if (!stdin)\n process.stderr.write(\n `${set.selected.length} file(s) ${mode === \"lint\" ? \"linted\" : \"processed\"}; ${changes.length} ${flags.write && !unsafe ? \"written\" : \"would change\"}.\\n`,\n );\n }\n const diagnostics = reports.flatMap((report) => report.diagnostics);\n const errors = diagnostics.some((item) => item.severity === \"error\");\n const tooManyWarnings =\n flags.maxWarnings !== undefined &&\n diagnostics.filter((item) => item.severity === \"warn\").length > flags.maxWarnings;\n process.exitCode = unsafe\n ? 2\n : errors || tooManyWarnings || (flags.check && changes.length > 0)\n ? 1\n : 0;\n}\ncommon(\n program.command(\"lint\").argument(\"[paths...]\", \"Markdown files/directories, or - for stdin\"),\n).action((inputs: string[], flags: Flags) => run(\"lint\", inputs, flags));\ncommon(\n program.command(\"format\").argument(\"[paths...]\", \"Markdown files/directories, or - for stdin\"),\n)\n .option(\"--check\", \"Fail if formatting changes would be needed\")\n .option(\"--diff\", \"Preview the complete diff (default for file inputs)\")\n .option(\"--write\", \"Write validated formatting changes\")\n .action((inputs: string[], flags: Flags) => run(\"format\", inputs, flags));\ncommon(program.command(\"config\").description(\"Inspect effective configuration\"))\n .command(\"explain <file>\")\n .action(async (file: string, _flags: unknown, command: Command) => {\n const flags = command.parent!.opts<Flags>();\n const loaded = await loadConfig(path.resolve(flags.root ?? \".\"), flags.config);\n if (flags.dialect) loaded.config.dialect = flags.dialect;\n const root = path.resolve(flags.root ?? loaded.root);\n process.stdout.write(\n JSON.stringify(\n {\n root,\n file: loaded.file ?? null,\n effective: resolveConfig(\n loaded.config,\n path.relative(root, path.resolve(file)).split(path.sep).join(\"/\"),\n loaded.plugins,\n ),\n },\n null,\n 2,\n ) + \"\\n\",\n );\n });\nprogram\n .command(\"rules\")\n .description(\"List built-in rules\")\n .action(() => {\n for (const [name, rule] of Object.entries(ruleRegistry()))\n process.stdout.write(`${name}\\t${rule.kind}\\t${rule.description}\\n`);\n });\ntry {\n await program.parseAsync();\n} catch (error) {\n process.stderr.write(`mdtools: ${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 2;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { createTwoFilesPatch } from \"diff\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { format, lint, ruleRegistry } from \"../core/engine.js\";\nimport { loadConfig } from \"../config/load.js\";\nimport { resolveConfig } from \"../config/resolve.js\";\nimport { discover, writeAtomic } from \"../workspace/files.js\";\nimport { excludeSelection } from \"../workspace/selection.js\";\nimport { createWorkspace } from \"../workspace/index.js\";\nimport type { Diagnostic, Dialect, DialectName, ProcessOptions } from \"../core/types.js\";\n\ninterface Flags {\n config?: string;\n root?: string;\n dialect?: DialectName;\n json?: boolean;\n check?: boolean;\n diff?: boolean;\n write?: boolean;\n stdinFilepath?: string;\n maxWarnings?: number;\n exclude?: string[];\n}\nconst manifest = JSON.parse(\n await readFile(fileURLToPath(new URL(\"../../package.json\", import.meta.url)), \"utf8\"),\n) as { version: string };\nconst program = new Command()\n .name(\"mdtools\")\n .description(\"Lint and format Markdown with explicit dialects and configurable rules.\")\n .version(manifest.version);\nfunction common(command: Command): Command {\n return command\n .option(\"--config <file>\", \"Explicit JSON, JSONC, or .mjs configuration\")\n .option(\"--root <directory>\", \"Workspace root (default: configuration directory or cwd)\")\n .option(\n \"--dialect <dialect>\",\n \"commonmark, github, forgejo (alias: codeberg), gitea, or obsidian\",\n )\n .option(\n \"--exclude <path>\",\n \"Exclude an exact file or directory (repeatable)\",\n (value: string, previous: string[]) => [...previous, value],\n [],\n )\n .option(\"--json\", \"Machine-readable output\")\n .option(\"--stdin-filepath <file>\", \"Filename context for stdin\")\n .option(\n \"--max-warnings <count>\",\n \"Fail when warning count exceeds this nonnegative integer\",\n (value: string) => {\n const number = Number(value);\n if (!Number.isInteger(number) || number < 0)\n throw new Error(\"--max-warnings must be a nonnegative integer.\");\n return number;\n },\n );\n}\ninterface Report {\n path: string;\n changed?: boolean;\n diagnostics: Diagnostic[];\n output?: string;\n}\nasync function run(mode: \"lint\" | \"format\", inputs: string[], flags: Flags) {\n if ([flags.check, flags.diff, flags.write].filter(Boolean).length > 1)\n throw new Error(\"Choose only one of --check, --diff, and --write.\");\n if (inputs.includes(\"-\") && flags.exclude?.length)\n throw new Error(\"--exclude cannot be combined with stdin.\");\n const loaded = await loadConfig(path.resolve(flags.root ?? \".\"), flags.config);\n const root = path.resolve(flags.root ?? loaded.root);\n if (flags.dialect) loaded.config.dialect = flags.dialect;\n const resolved = resolveConfig(loaded.config, \"document.md\", loaded.plugins);\n const stdin = inputs.includes(\"-\");\n if (stdin && (inputs.length !== 1 || flags.write))\n throw new Error(\"stdin must be the only input and cannot be combined with --write.\");\n const set = await discover(root, stdin ? [] : inputs, resolved.ignore, resolved.resolve);\n set.selected = await excludeSelection(set.root, set.selected, flags.exclude ?? []);\n if (stdin) {\n const name = path\n .relative(root, path.resolve(flags.stdinFilepath ?? path.join(root, \"stdin.md\")))\n .split(path.sep)\n .join(\"/\");\n if (name.startsWith(\"../\") || path.isAbsolute(name))\n throw new Error(\"--stdin-filepath must be within the workspace.\");\n let source = \"\";\n process.stdin.setEncoding(\"utf8\");\n for await (const chunk of process.stdin) source += String(chunk);\n set.files[name] = source;\n set.selected = [name];\n }\n const reports: Report[] = [];\n const changes: { file: string; before: string; after: string }[] = [];\n // One index per active dialect; build lazily for mixed documentation workspaces.\n const indexes = new Map<Dialect, ReturnType<typeof createWorkspace>>();\n for (const name of set.selected) {\n const config = resolveConfig(loaded.config, name, loaded.plugins);\n if (!indexes.has(config.dialect))\n indexes.set(\n config.dialect,\n createWorkspace(set.files, {\n dialect: config.dialect,\n directories: set.directories,\n ...(set.strictLineBreaks !== undefined ? { strictLineBreaks: set.strictLineBreaks } : {}),\n }),\n );\n const options: ProcessOptions = {\n path: name,\n config: loaded.config,\n plugins: loaded.plugins,\n workspace: indexes.get(config.dialect)!,\n };\n const value = set.files[name]!;\n const source = typeof value === \"function\" ? value() : value;\n if (source === null) continue;\n if (mode === \"lint\") reports.push({ path: name, diagnostics: lint(source, options) });\n else {\n const result = format(source, options);\n reports.push({\n path: name,\n changed: result.changed,\n diagnostics: result.diagnostics,\n ...(stdin && !flags.check ? { output: result.output } : {}),\n });\n if (result.changed) changes.push({ file: name, before: source, after: result.output });\n }\n }\n const unsafe = reports.some((report) =>\n report.diagnostics.some((item) => item.rule === \"engine/unsafe-format\"),\n );\n if (flags.write && !unsafe)\n for (const change of changes)\n await writeAtomic(path.join(set.root, change.file), change.before, change.after);\n if (flags.json)\n process.stdout.write(\n JSON.stringify(\n {\n version: manifest.version,\n mode,\n files: reports,\n written: flags.write === true && !unsafe,\n },\n null,\n 2,\n ) + \"\\n\",\n );\n else {\n if (stdin && mode === \"format\" && !flags.check && !flags.diff)\n process.stdout.write(reports[0]?.output ?? \"\");\n else if (mode === \"format\" && !flags.check && !flags.write)\n for (const change of changes)\n process.stdout.write(\n createTwoFilesPatch(`a/${change.file}`, `b/${change.file}`, change.before, change.after),\n );\n for (const report of reports)\n for (const item of report.diagnostics)\n process.stderr.write(\n `${report.path}:${item.line}:${item.column}: ${item.severity} ${item.rule}: ${item.message}\\n`,\n );\n if (!stdin)\n process.stderr.write(\n `${set.selected.length} file(s) ${mode === \"lint\" ? \"linted\" : \"processed\"}; ${changes.length} ${flags.write && !unsafe ? \"written\" : \"would change\"}.\\n`,\n );\n }\n const diagnostics = reports.flatMap((report) => report.diagnostics);\n const errors = diagnostics.some((item) => item.severity === \"error\");\n const tooManyWarnings =\n flags.maxWarnings !== undefined &&\n diagnostics.filter((item) => item.severity === \"warn\").length > flags.maxWarnings;\n process.exitCode = unsafe\n ? 2\n : errors || tooManyWarnings || (flags.check && changes.length > 0)\n ? 1\n : 0;\n}\ncommon(\n program.command(\"lint\").argument(\"[paths...]\", \"Markdown files/directories, or - for stdin\"),\n).action((inputs: string[], flags: Flags) => run(\"lint\", inputs, flags));\ncommon(\n program.command(\"format\").argument(\"[paths...]\", \"Markdown files/directories, or - for stdin\"),\n)\n .option(\"--check\", \"Fail if formatting changes would be needed\")\n .option(\"--diff\", \"Preview the complete diff (default for file inputs)\")\n .option(\"--write\", \"Write validated formatting changes\")\n .action((inputs: string[], flags: Flags) => run(\"format\", inputs, flags));\ncommon(program.command(\"config\").description(\"Inspect effective configuration\"))\n .command(\"explain <file>\")\n .action(async (file: string, _flags: unknown, command: Command) => {\n const flags = command.parent!.opts<Flags>();\n const loaded = await loadConfig(path.resolve(flags.root ?? \".\"), flags.config);\n if (flags.dialect) loaded.config.dialect = flags.dialect;\n const root = path.resolve(flags.root ?? loaded.root);\n process.stdout.write(\n JSON.stringify(\n {\n root,\n file: loaded.file ?? null,\n effective: resolveConfig(\n loaded.config,\n path.relative(root, path.resolve(file)).split(path.sep).join(\"/\"),\n loaded.plugins,\n ),\n },\n null,\n 2,\n ) + \"\\n\",\n );\n });\nprogram\n .command(\"rules\")\n .description(\"List built-in rules\")\n .action(() => {\n for (const [name, rule] of Object.entries(ruleRegistry()))\n process.stdout.write(`${name}\\t${rule.kind}\\t${rule.description}\\n`);\n });\ntry {\n await program.parseAsync();\n} catch (error) {\n process.stderr.write(`mdtools: ${error instanceof Error ? error.message : String(error)}\\n`);\n process.exitCode = 2;\n}\n"]}
|
package/dist/config/resolve.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type { Config, Plugin, ResolvedConfig, RuleSetting } from "../core/types.js";
|
|
1
|
+
import type { Config, Dialect, DialectName, Plugin, ResolvedConfig, RuleSetting } from "../core/types.js";
|
|
2
|
+
/** Alias names that select an existing dialect; Codeberg runs Forgejo's renderer. */
|
|
3
|
+
export declare const dialectAliases: Record<string, Dialect>;
|
|
4
|
+
export declare const dialects: Dialect[];
|
|
5
|
+
export declare function canonicalDialect(name: DialectName): Dialect;
|
|
2
6
|
export declare const presets: Record<string, Config>;
|
|
3
7
|
export declare const configSchema: {
|
|
4
8
|
$schema: string;
|
package/dist/config/resolve.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Ajv } from "ajv";
|
|
2
2
|
import { minimatch } from "minimatch";
|
|
3
|
+
/** Alias names that select an existing dialect; Codeberg runs Forgejo's renderer. */
|
|
4
|
+
export const dialectAliases = { codeberg: "forgejo" };
|
|
5
|
+
export const dialects = ["commonmark", "github", "forgejo", "gitea", "obsidian"];
|
|
6
|
+
export function canonicalDialect(name) {
|
|
7
|
+
return dialectAliases[name] ?? name;
|
|
8
|
+
}
|
|
3
9
|
export const presets = {
|
|
4
10
|
recommended: {
|
|
5
11
|
rules: {
|
|
@@ -14,6 +20,25 @@ export const presets = {
|
|
|
14
20
|
dialect: "github",
|
|
15
21
|
rules: { "github/task-marker": "warn", "github/alert-marker": "warn", "style/table": "warn" },
|
|
16
22
|
},
|
|
23
|
+
forgejo: {
|
|
24
|
+
dialect: "forgejo",
|
|
25
|
+
rules: {
|
|
26
|
+
"github/task-marker": "warn",
|
|
27
|
+
"github/alert-marker": "warn",
|
|
28
|
+
"style/table": "warn",
|
|
29
|
+
"forgejo/heading-id": "error",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
codeberg: { extends: ["forgejo"] },
|
|
33
|
+
gitea: {
|
|
34
|
+
dialect: "gitea",
|
|
35
|
+
rules: {
|
|
36
|
+
"github/task-marker": "warn",
|
|
37
|
+
"github/alert-marker": "warn",
|
|
38
|
+
"style/table": "warn",
|
|
39
|
+
"forgejo/heading-id": "error",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
17
42
|
obsidian: {
|
|
18
43
|
dialect: "obsidian",
|
|
19
44
|
rules: {
|
|
@@ -26,6 +51,7 @@ export const presets = {
|
|
|
26
51
|
},
|
|
27
52
|
};
|
|
28
53
|
const severity = { enum: ["off", "warn", "error"] };
|
|
54
|
+
const dialect = { enum: [...dialects, ...Object.keys(dialectAliases)] };
|
|
29
55
|
const rules = {
|
|
30
56
|
type: "object",
|
|
31
57
|
additionalProperties: {
|
|
@@ -47,7 +73,7 @@ export const configSchema = {
|
|
|
47
73
|
properties: { gitIgnored: { type: "boolean" }, nestedRepositories: { type: "boolean" } },
|
|
48
74
|
},
|
|
49
75
|
extends: { type: "array", items: { type: "string" } },
|
|
50
|
-
dialect
|
|
76
|
+
dialect,
|
|
51
77
|
rules,
|
|
52
78
|
ignore: { type: "array", items: { type: "string" } },
|
|
53
79
|
plugins: { type: "array", items: { type: "string" } },
|
|
@@ -59,7 +85,7 @@ export const configSchema = {
|
|
|
59
85
|
additionalProperties: false,
|
|
60
86
|
properties: {
|
|
61
87
|
files: { type: "array", items: { type: "string" }, minItems: 1 },
|
|
62
|
-
dialect
|
|
88
|
+
dialect,
|
|
63
89
|
rules,
|
|
64
90
|
},
|
|
65
91
|
},
|
|
@@ -95,7 +121,7 @@ export function resolveConfig(config = {}, path = "document.md", plugins = []) {
|
|
|
95
121
|
merge(preset, [...chain, name]);
|
|
96
122
|
}
|
|
97
123
|
if (part.dialect)
|
|
98
|
-
result.dialect = part.dialect;
|
|
124
|
+
result.dialect = canonicalDialect(part.dialect);
|
|
99
125
|
Object.assign(result.rules, part.rules);
|
|
100
126
|
Object.assign(result.resolve, part.resolve);
|
|
101
127
|
result.ignore.push(...(part.ignore ?? []));
|
|
@@ -107,7 +133,7 @@ export function resolveConfig(config = {}, path = "document.md", plugins = []) {
|
|
|
107
133
|
for (const override of overrides) {
|
|
108
134
|
if (override.files.some((pattern) => minimatch(path.replaceAll("\\", "/"), pattern, { dot: true }))) {
|
|
109
135
|
if (override.dialect)
|
|
110
|
-
result.dialect = override.dialect;
|
|
136
|
+
result.dialect = canonicalDialect(override.dialect);
|
|
111
137
|
Object.assign(result.rules, override.rules);
|
|
112
138
|
}
|
|
113
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv } from \"ajv\";\nimport { minimatch } from \"minimatch\";\nimport type { Config, Plugin, ResolvedConfig, RuleSetting } from \"../core/types.js\";\n\nexport const presets: Record<string, Config> = {\n recommended: {\n rules: {\n \"style/wrap\": [\"warn\", { width: 80 }],\n \"style/emphasis\": [\"warn\", { marker: \"_\" }],\n \"style/strong\": [\"warn\", { marker: \"*\" }],\n \"style/final-newline\": \"warn\",\n \"links/valid\": \"error\",\n },\n },\n github: {\n dialect: \"github\",\n rules: { \"github/task-marker\": \"warn\", \"github/alert-marker\": \"warn\", \"style/table\": \"warn\" },\n },\n obsidian: {\n dialect: \"obsidian\",\n rules: {\n \"obsidian/callout-marker\": \"warn\",\n \"obsidian/block-reference\": \"error\",\n \"obsidian/strict-line-breaks\": \"warn\",\n \"github/task-marker\": \"warn\",\n \"style/table\": \"warn\",\n },\n },\n};\nconst severity = { enum: [\"off\", \"warn\", \"error\"] };\nconst rules = {\n type: \"object\",\n additionalProperties: {\n anyOf: [\n severity,\n { type: \"array\", items: [severity, { type: \"object\" }], minItems: 2, maxItems: 2 },\n ],\n },\n};\nexport const configSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n additionalProperties: false,\n properties: {\n $schema: { type: \"string\" },\n resolve: {\n type: \"object\",\n additionalProperties: false,\n properties: { gitIgnored: { type: \"boolean\" }, nestedRepositories: { type: \"boolean\" } },\n },\n extends: { type: \"array\", items: { type: \"string\" } },\n dialect: { enum: [\"commonmark\", \"github\", \"obsidian\"] },\n rules,\n ignore: { type: \"array\", items: { type: \"string\" } },\n plugins: { type: \"array\", items: { type: \"string\" } },\n overrides: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"files\"],\n additionalProperties: false,\n properties: {\n files: { type: \"array\", items: { type: \"string\" }, minItems: 1 },\n dialect: { enum: [\"commonmark\", \"github\", \"obsidian\"] },\n rules,\n },\n },\n },\n },\n};\nconst validate = new Ajv({ allErrors: true }).compile(configSchema);\nexport function validateConfig(value: unknown): asserts value is Config {\n if (!validate(value))\n throw new Error(`Invalid configuration: ${new Ajv().errorsText(validate.errors)}`);\n}\nexport function setting(value: RuleSetting): {\n severity: \"off\" | \"warn\" | \"error\";\n options: Record<string, unknown>;\n} {\n return Array.isArray(value)\n ? { severity: value[0], options: value[1] }\n : { severity: value, options: {} };\n}\nexport function resolveConfig(\n config: Config = {},\n path = \"document.md\",\n plugins: Plugin[] = [],\n): ResolvedConfig {\n validateConfig(config);\n const available = { ...presets };\n for (const plugin of plugins)\n for (const [name, preset] of Object.entries(plugin.presets ?? {}))\n available[`${plugin.name}/${name}`] = preset;\n const result: ResolvedConfig = { dialect: \"commonmark\", rules: {}, ignore: [], resolve: {} };\n const overrides: NonNullable<Config[\"overrides\"]> = [];\n function merge(part: Config, chain: string[]) {\n validateConfig(part);\n for (const name of part.extends ?? []) {\n if (chain.includes(name))\n throw new Error(`Circular preset: ${[...chain, name].join(\" -> \")}`);\n const preset = available[name];\n if (!preset) throw new Error(`Unknown preset: ${name}`);\n merge(preset, [...chain, name]);\n }\n if (part.dialect) result.dialect = part.dialect;\n Object.assign(result.rules, part.rules);\n Object.assign(result.resolve, part.resolve);\n result.ignore.push(...(part.ignore ?? []));\n overrides.push(...(part.overrides ?? []));\n }\n if (config.extends === undefined) merge(presets.recommended!, []);\n merge(config, []);\n for (const override of overrides) {\n if (\n override.files.some((pattern) =>\n minimatch(path.replaceAll(\"\\\\\", \"/\"), pattern, { dot: true }),\n )\n ) {\n if (override.dialect) result.dialect = override.dialect;\n Object.assign(result.rules, override.rules);\n }\n }\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv } from \"ajv\";\nimport { minimatch } from \"minimatch\";\nimport type {\n Config,\n Dialect,\n DialectName,\n Plugin,\n ResolvedConfig,\n RuleSetting,\n} from \"../core/types.js\";\n\n/** Alias names that select an existing dialect; Codeberg runs Forgejo's renderer. */\nexport const dialectAliases: Record<string, Dialect> = { codeberg: \"forgejo\" };\nexport const dialects: Dialect[] = [\"commonmark\", \"github\", \"forgejo\", \"gitea\", \"obsidian\"];\nexport function canonicalDialect(name: DialectName): Dialect {\n return dialectAliases[name] ?? (name as Dialect);\n}\n\nexport const presets: Record<string, Config> = {\n recommended: {\n rules: {\n \"style/wrap\": [\"warn\", { width: 80 }],\n \"style/emphasis\": [\"warn\", { marker: \"_\" }],\n \"style/strong\": [\"warn\", { marker: \"*\" }],\n \"style/final-newline\": \"warn\",\n \"links/valid\": \"error\",\n },\n },\n github: {\n dialect: \"github\",\n rules: { \"github/task-marker\": \"warn\", \"github/alert-marker\": \"warn\", \"style/table\": \"warn\" },\n },\n forgejo: {\n dialect: \"forgejo\",\n rules: {\n \"github/task-marker\": \"warn\",\n \"github/alert-marker\": \"warn\",\n \"style/table\": \"warn\",\n \"forgejo/heading-id\": \"error\",\n },\n },\n codeberg: { extends: [\"forgejo\"] },\n gitea: {\n dialect: \"gitea\",\n rules: {\n \"github/task-marker\": \"warn\",\n \"github/alert-marker\": \"warn\",\n \"style/table\": \"warn\",\n \"forgejo/heading-id\": \"error\",\n },\n },\n obsidian: {\n dialect: \"obsidian\",\n rules: {\n \"obsidian/callout-marker\": \"warn\",\n \"obsidian/block-reference\": \"error\",\n \"obsidian/strict-line-breaks\": \"warn\",\n \"github/task-marker\": \"warn\",\n \"style/table\": \"warn\",\n },\n },\n};\nconst severity = { enum: [\"off\", \"warn\", \"error\"] };\nconst dialect = { enum: [...dialects, ...Object.keys(dialectAliases)] };\nconst rules = {\n type: \"object\",\n additionalProperties: {\n anyOf: [\n severity,\n { type: \"array\", items: [severity, { type: \"object\" }], minItems: 2, maxItems: 2 },\n ],\n },\n};\nexport const configSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n additionalProperties: false,\n properties: {\n $schema: { type: \"string\" },\n resolve: {\n type: \"object\",\n additionalProperties: false,\n properties: { gitIgnored: { type: \"boolean\" }, nestedRepositories: { type: \"boolean\" } },\n },\n extends: { type: \"array\", items: { type: \"string\" } },\n dialect,\n rules,\n ignore: { type: \"array\", items: { type: \"string\" } },\n plugins: { type: \"array\", items: { type: \"string\" } },\n overrides: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"files\"],\n additionalProperties: false,\n properties: {\n files: { type: \"array\", items: { type: \"string\" }, minItems: 1 },\n dialect,\n rules,\n },\n },\n },\n },\n};\nconst validate = new Ajv({ allErrors: true }).compile(configSchema);\nexport function validateConfig(value: unknown): asserts value is Config {\n if (!validate(value))\n throw new Error(`Invalid configuration: ${new Ajv().errorsText(validate.errors)}`);\n}\nexport function setting(value: RuleSetting): {\n severity: \"off\" | \"warn\" | \"error\";\n options: Record<string, unknown>;\n} {\n return Array.isArray(value)\n ? { severity: value[0], options: value[1] }\n : { severity: value, options: {} };\n}\nexport function resolveConfig(\n config: Config = {},\n path = \"document.md\",\n plugins: Plugin[] = [],\n): ResolvedConfig {\n validateConfig(config);\n const available = { ...presets };\n for (const plugin of plugins)\n for (const [name, preset] of Object.entries(plugin.presets ?? {}))\n available[`${plugin.name}/${name}`] = preset;\n const result: ResolvedConfig = { dialect: \"commonmark\", rules: {}, ignore: [], resolve: {} };\n const overrides: NonNullable<Config[\"overrides\"]> = [];\n function merge(part: Config, chain: string[]) {\n validateConfig(part);\n for (const name of part.extends ?? []) {\n if (chain.includes(name))\n throw new Error(`Circular preset: ${[...chain, name].join(\" -> \")}`);\n const preset = available[name];\n if (!preset) throw new Error(`Unknown preset: ${name}`);\n merge(preset, [...chain, name]);\n }\n if (part.dialect) result.dialect = canonicalDialect(part.dialect);\n Object.assign(result.rules, part.rules);\n Object.assign(result.resolve, part.resolve);\n result.ignore.push(...(part.ignore ?? []));\n overrides.push(...(part.overrides ?? []));\n }\n if (config.extends === undefined) merge(presets.recommended!, []);\n merge(config, []);\n for (const override of overrides) {\n if (\n override.files.some((pattern) =>\n minimatch(path.replaceAll(\"\\\\\", \"/\"), pattern, { dot: true }),\n )\n ) {\n if (override.dialect) result.dialect = canonicalDialect(override.dialect);\n Object.assign(result.rules, override.rules);\n }\n }\n return result;\n}\n"]}
|
package/dist/core/engine.js
CHANGED
|
@@ -5,6 +5,7 @@ import { styleRules } from "../rules/style.js";
|
|
|
5
5
|
import { dialectRules } from "../rules/dialects.js";
|
|
6
6
|
import { structureRules } from "../rules/structure.js";
|
|
7
7
|
import { linkRules } from "../rules/links.js";
|
|
8
|
+
import { headingAnchorSource, headingAttributeSource } from "../workspace/heading-attributes.js";
|
|
8
9
|
import { suppressions } from "./directives.js";
|
|
9
10
|
export const builtInRules = {
|
|
10
11
|
...styleRules,
|
|
@@ -149,6 +150,17 @@ export function semanticFingerprint(document, workspace) {
|
|
|
149
150
|
};
|
|
150
151
|
}
|
|
151
152
|
const result = {};
|
|
153
|
+
// Forgejo and Gitea read a heading's trailing `{...}` block as attributes,
|
|
154
|
+
// character for character, where the tree holds ordinary inline content,
|
|
155
|
+
// and generate the anchor from the heading's last line as written.
|
|
156
|
+
if (node.type === "heading") {
|
|
157
|
+
const attributes = headingAttributeSource(document, node);
|
|
158
|
+
if (attributes !== undefined)
|
|
159
|
+
result.attributes = attributes;
|
|
160
|
+
const anchors = headingAnchorSource(document, node);
|
|
161
|
+
if (anchors !== undefined)
|
|
162
|
+
result.anchors = anchors;
|
|
163
|
+
}
|
|
152
164
|
if (calloutHeader && document.dialect === "obsidian" && node.type === "paragraph") {
|
|
153
165
|
const [start, end] = range(node);
|
|
154
166
|
const header = document.source.slice(start, end).split(/\r?\n/, 1)[0];
|
package/dist/core/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv } from \"ajv\";\nimport type { Nodes } from \"mdast\";\nimport { resolveConfig, setting } from \"../config/resolve.js\";\nimport { parse, range } from \"../syntax/parse.js\";\nimport { styleRules } from \"../rules/style.js\";\nimport { dialectRules } from \"../rules/dialects.js\";\nimport { structureRules } from \"../rules/structure.js\";\nimport { linkRules } from \"../rules/links.js\";\nimport { suppressions } from \"./directives.js\";\nimport type {\n Diagnostic,\n Document,\n Edit,\n Finding,\n FormatResult,\n Plugin,\n ProcessOptions,\n ResolvedConfig,\n Rule,\n Workspace,\n} from \"./types.js\";\n\nexport const builtInRules: Record<string, Rule> = {\n ...styleRules,\n ...dialectRules,\n ...linkRules,\n ...structureRules,\n};\nexport function ruleRegistry(plugins: Plugin[] = []): Record<string, Rule> {\n const rules = { ...builtInRules };\n const names = new Set<string>();\n for (const plugin of plugins) {\n if (!/^[a-z][a-z\\d-]*$/.test(plugin.name) || names.has(plugin.name))\n throw new Error(`Invalid or duplicate plugin name: ${plugin.name}`);\n names.add(plugin.name);\n for (const [name, rule] of Object.entries(plugin.rules ?? {})) {\n const id = `${plugin.name}/${name}`;\n if (rules[id]) throw new Error(`Duplicate rule: ${id}`);\n rules[id] = rule;\n }\n }\n return rules;\n}\nconst ruleValidator = new Ajv({ allErrors: true });\nconst builtInSchemas = new Set(Object.values(builtInRules).map((rule) => rule.schema));\nfunction prepare(options: ProcessOptions) {\n const config = resolveConfig(options.config, options.path, options.plugins);\n const rules = ruleRegistry(options.plugins);\n let pluginValidator: Ajv | undefined;\n for (const [name, value] of Object.entries(config.rules)) {\n const rule = rules[name];\n if (!rule) throw new Error(`Unknown rule: ${name}`);\n const enabled = setting(value);\n if (rule.schema && enabled.severity !== \"off\") {\n // Plugin schema IDs are scoped to this call; distinct plugin instances\n // may legitimately reuse the same ID with different schemas.\n const validator = builtInSchemas.has(rule.schema)\n ? ruleValidator\n : (pluginValidator ??= new Ajv({ allErrors: true }));\n const validate = validator.compile(rule.schema);\n if (!validate(enabled.options))\n throw new Error(`Invalid options for ${name}: ${validator.errorsText(validate.errors)}`);\n }\n }\n return { config, rules };\n}\n/** Offsets where each line starts, computed once per source so findings locate in O(log lines). */\nfunction lineStarts(source: string): number[] {\n const starts = [0];\n for (let at = source.indexOf(\"\\n\"); at >= 0; at = source.indexOf(\"\\n\", at + 1))\n starts.push(at + 1);\n return starts;\n}\nfunction diagnostic(\n starts: number[],\n rule: string,\n severity: \"warn\" | \"error\",\n finding: Finding,\n): Diagnostic {\n let low = 0;\n let high = starts.length - 1;\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n if (starts[middle]! <= finding.start) low = middle;\n else high = middle - 1;\n }\n return { ...finding, rule, severity, line: low + 1, column: finding.start - starts[low]! + 1 };\n}\nconst sortDiagnostics = (a: Diagnostic, b: Diagnostic) =>\n a.start - b.start || a.rule.localeCompare(b.rule);\nfunction inspect(\n document: Document,\n config: ResolvedConfig,\n rules: Record<string, Rule>,\n workspace?: Workspace,\n include: (rule: Rule) => boolean = () => true,\n): Diagnostic[] {\n const result: Diagnostic[] = [];\n const suppressed = suppressions(document);\n const starts = lineStarts(document.source);\n for (const [name, value] of Object.entries(config.rules)) {\n const enabled = setting(value);\n const rule = rules[name]!;\n if (enabled.severity === \"off\" || !include(rule)) continue;\n const findings = rule.check({\n document,\n options: enabled.options,\n ...(workspace ? { workspace } : {}),\n });\n for (const finding of findings)\n if (!suppressed(name, finding))\n result.push(diagnostic(starts, name, enabled.severity, finding));\n }\n return result.sort(sortDiagnostics);\n}\nexport function lint(source: string, options: ProcessOptions = {}): Diagnostic[] {\n const { config, rules } = prepare(options);\n const document = parse(source, config.dialect, options.path, options.plugins);\n return inspect(document, config, rules, options.workspace);\n}\nexport function applyEdits(source: string, edits: Edit[]): string {\n const sorted = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);\n let previous: Edit | undefined;\n const accepted: Edit[] = [];\n for (const edit of sorted) {\n if (\n !Number.isInteger(edit.start) ||\n !Number.isInteger(edit.end) ||\n edit.start < 0 ||\n edit.end < edit.start ||\n edit.end > source.length\n )\n throw new Error(\"Rule returned an invalid edit range.\");\n if (\n previous &&\n edit.start === previous.start &&\n edit.end === previous.end &&\n edit.text === previous.text\n )\n continue;\n if (previous && (edit.start < previous.end || edit.start === previous.start))\n throw new Error(\n \"Enabled rules proposed overlapping edits; disable one of the conflicting rules.\",\n );\n accepted.push(edit);\n previous = edit;\n }\n // Assemble the result in one pass; rebuilding the string per edit is quadratic.\n const parts: string[] = [];\n let cursor = 0;\n for (const edit of accepted) {\n parts.push(source.slice(cursor, edit.start), edit.text);\n cursor = edit.end;\n }\n parts.push(source.slice(cursor));\n return parts.join(\"\");\n}\n/** Compare semantic trees, with link identity supplied by the selected renderer's resolver. */\nexport function semanticFingerprint(document: Document, workspace?: Workspace): string {\n const canonicalUrl = (url: string, wiki = false) => {\n const resolution = workspace?.resolve(document.path, url, document.dialect, wiki);\n return resolution?.status === \"resolved\"\n ? `${resolution.target}#${resolution.fragment ?? \"\"}`\n : url;\n };\n // Keys are emitted in sorted order so the JSON text is canonical without a replacer.\n function normalize(node: Nodes, calloutHeader = false): unknown {\n if (node.type === \"wikiLink\") {\n if (node.embed)\n return { label: node.label, type: \"embed\", url: canonicalUrl(node.target ?? \"\", true) };\n return {\n children: [{ type: \"text\", value: node.label ?? node.target }],\n title: null,\n type: \"link\",\n url: canonicalUrl(node.target ?? \"\", true),\n };\n }\n const result: Record<string, unknown> = {};\n if (calloutHeader && document.dialect === \"obsidian\" && node.type === \"paragraph\") {\n const [start, end] = range(node);\n const header = document.source.slice(start, end).split(/\\r?\\n/, 1)[0]!;\n if (/^\\[![\\w-]+\\]/.test(header)) {\n // CommonMark merges title and body into one paragraph. Preserve their boundary too.\n const title = header.replace(\n /^\\[!([\\w-]+)\\]/,\n (_, marker: string) => `[!${marker.toLowerCase()}]`,\n );\n result.calloutTitle = normalize(parse(title, document.dialect, document.path).tree);\n }\n }\n for (const key of Object.keys(node).sort()) {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (key === \"position\" || key === \"data\") continue;\n if (key === \"children\" && \"children\" in node) {\n result.children = node.children.map((child, index) =>\n normalize(child, index === 0 && (node.type === \"blockquote\" || calloutHeader)),\n );\n } else if (key === \"url\" && typeof value === \"string\") result[key] = canonicalUrl(value);\n else if (key === \"value\" && node.type === \"text\") {\n let text = node.value.replace(/[ \\t\\r\\n]+/g, \" \");\n if (calloutHeader && document.dialect !== \"commonmark\")\n text = text.replace(\n /^\\[!([\\w-]+)\\]/,\n (_, marker: string) => `[!${marker.toLowerCase()}]`,\n );\n result[key] = text;\n } else if (key === \"value\" && node.type === \"inlineCode\")\n result[key] = node.value.replace(/\\r\\n|\\r|\\n/g, \" \");\n else result[key] = value;\n }\n return result;\n }\n return JSON.stringify(normalize(document.tree));\n}\nexport function format(source: string, options: ProcessOptions = {}): FormatResult {\n const { config, rules } = prepare(options);\n let output = source;\n let document = parse(source, config.dialect, options.path, options.plugins);\n // The original fingerprint is only needed once an edit produces a candidate.\n let fingerprint: string | undefined;\n const seen = new Set([source]);\n try {\n for (let pass = 0; pass < 8; pass++) {\n const before = output;\n const findings: Diagnostic[] = [];\n for (const phase of [\"inline\", \"block\", \"document\"]) {\n const diagnostics = inspect(\n document,\n config,\n rules,\n options.workspace,\n (rule) => rule.kind === \"style\" && (rule.phase ?? \"inline\") === phase,\n );\n findings.push(...diagnostics);\n const edits = diagnostics.flatMap((item) => (item.edit ? [item.edit] : []));\n if (!edits.length) continue;\n const candidate = applyEdits(output, edits);\n if (candidate === output) continue;\n const candidateDocument = parse(candidate, config.dialect, options.path, options.plugins);\n fingerprint ??= semanticFingerprint(document, options.workspace);\n if (semanticFingerprint(candidateDocument, options.workspace) !== fingerprint)\n throw new Error(\n `Formatting in the ${phase} phase would change parsed meaning; the document was left unchanged.`,\n );\n output = candidate;\n // Rules consume the document without mutating it. Reuse the validated\n // tree until another phase changes its source, including final diagnostics.\n document = candidateDocument;\n }\n if (output === before) {\n // No phase changed the document, so every style finding of this pass\n // describes the final document; only the non-style rules still need to run.\n const remaining = inspect(\n document,\n config,\n rules,\n options.workspace,\n (rule) => rule.kind !== \"style\",\n );\n return {\n output,\n changed: output !== source,\n diagnostics: [...findings, ...remaining].sort(sortDiagnostics),\n };\n }\n if (seen.has(output))\n throw new Error(\"Formatting rules oscillate; the document was left unchanged.\");\n seen.add(output);\n }\n throw new Error(\n \"Formatting did not converge in eight passes; the document was left unchanged.\",\n );\n } catch (error) {\n return {\n output: source,\n changed: false,\n diagnostics: [\n diagnostic([0], \"engine/unsafe-format\", \"error\", {\n start: 0,\n message: error instanceof Error ? error.message : String(error),\n }),\n ],\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv } from \"ajv\";\nimport type { Nodes } from \"mdast\";\nimport { resolveConfig, setting } from \"../config/resolve.js\";\nimport { parse, range } from \"../syntax/parse.js\";\nimport { styleRules } from \"../rules/style.js\";\nimport { dialectRules } from \"../rules/dialects.js\";\nimport { structureRules } from \"../rules/structure.js\";\nimport { linkRules } from \"../rules/links.js\";\nimport { headingAnchorSource, headingAttributeSource } from \"../workspace/heading-attributes.js\";\nimport { suppressions } from \"./directives.js\";\nimport type {\n Diagnostic,\n Document,\n Edit,\n Finding,\n FormatResult,\n Plugin,\n ProcessOptions,\n ResolvedConfig,\n Rule,\n Workspace,\n} from \"./types.js\";\n\nexport const builtInRules: Record<string, Rule> = {\n ...styleRules,\n ...dialectRules,\n ...linkRules,\n ...structureRules,\n};\nexport function ruleRegistry(plugins: Plugin[] = []): Record<string, Rule> {\n const rules = { ...builtInRules };\n const names = new Set<string>();\n for (const plugin of plugins) {\n if (!/^[a-z][a-z\\d-]*$/.test(plugin.name) || names.has(plugin.name))\n throw new Error(`Invalid or duplicate plugin name: ${plugin.name}`);\n names.add(plugin.name);\n for (const [name, rule] of Object.entries(plugin.rules ?? {})) {\n const id = `${plugin.name}/${name}`;\n if (rules[id]) throw new Error(`Duplicate rule: ${id}`);\n rules[id] = rule;\n }\n }\n return rules;\n}\nconst ruleValidator = new Ajv({ allErrors: true });\nconst builtInSchemas = new Set(Object.values(builtInRules).map((rule) => rule.schema));\nfunction prepare(options: ProcessOptions) {\n const config = resolveConfig(options.config, options.path, options.plugins);\n const rules = ruleRegistry(options.plugins);\n let pluginValidator: Ajv | undefined;\n for (const [name, value] of Object.entries(config.rules)) {\n const rule = rules[name];\n if (!rule) throw new Error(`Unknown rule: ${name}`);\n const enabled = setting(value);\n if (rule.schema && enabled.severity !== \"off\") {\n // Plugin schema IDs are scoped to this call; distinct plugin instances\n // may legitimately reuse the same ID with different schemas.\n const validator = builtInSchemas.has(rule.schema)\n ? ruleValidator\n : (pluginValidator ??= new Ajv({ allErrors: true }));\n const validate = validator.compile(rule.schema);\n if (!validate(enabled.options))\n throw new Error(`Invalid options for ${name}: ${validator.errorsText(validate.errors)}`);\n }\n }\n return { config, rules };\n}\n/** Offsets where each line starts, computed once per source so findings locate in O(log lines). */\nfunction lineStarts(source: string): number[] {\n const starts = [0];\n for (let at = source.indexOf(\"\\n\"); at >= 0; at = source.indexOf(\"\\n\", at + 1))\n starts.push(at + 1);\n return starts;\n}\nfunction diagnostic(\n starts: number[],\n rule: string,\n severity: \"warn\" | \"error\",\n finding: Finding,\n): Diagnostic {\n let low = 0;\n let high = starts.length - 1;\n while (low < high) {\n const middle = (low + high + 1) >> 1;\n if (starts[middle]! <= finding.start) low = middle;\n else high = middle - 1;\n }\n return { ...finding, rule, severity, line: low + 1, column: finding.start - starts[low]! + 1 };\n}\nconst sortDiagnostics = (a: Diagnostic, b: Diagnostic) =>\n a.start - b.start || a.rule.localeCompare(b.rule);\nfunction inspect(\n document: Document,\n config: ResolvedConfig,\n rules: Record<string, Rule>,\n workspace?: Workspace,\n include: (rule: Rule) => boolean = () => true,\n): Diagnostic[] {\n const result: Diagnostic[] = [];\n const suppressed = suppressions(document);\n const starts = lineStarts(document.source);\n for (const [name, value] of Object.entries(config.rules)) {\n const enabled = setting(value);\n const rule = rules[name]!;\n if (enabled.severity === \"off\" || !include(rule)) continue;\n const findings = rule.check({\n document,\n options: enabled.options,\n ...(workspace ? { workspace } : {}),\n });\n for (const finding of findings)\n if (!suppressed(name, finding))\n result.push(diagnostic(starts, name, enabled.severity, finding));\n }\n return result.sort(sortDiagnostics);\n}\nexport function lint(source: string, options: ProcessOptions = {}): Diagnostic[] {\n const { config, rules } = prepare(options);\n const document = parse(source, config.dialect, options.path, options.plugins);\n return inspect(document, config, rules, options.workspace);\n}\nexport function applyEdits(source: string, edits: Edit[]): string {\n const sorted = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);\n let previous: Edit | undefined;\n const accepted: Edit[] = [];\n for (const edit of sorted) {\n if (\n !Number.isInteger(edit.start) ||\n !Number.isInteger(edit.end) ||\n edit.start < 0 ||\n edit.end < edit.start ||\n edit.end > source.length\n )\n throw new Error(\"Rule returned an invalid edit range.\");\n if (\n previous &&\n edit.start === previous.start &&\n edit.end === previous.end &&\n edit.text === previous.text\n )\n continue;\n if (previous && (edit.start < previous.end || edit.start === previous.start))\n throw new Error(\n \"Enabled rules proposed overlapping edits; disable one of the conflicting rules.\",\n );\n accepted.push(edit);\n previous = edit;\n }\n // Assemble the result in one pass; rebuilding the string per edit is quadratic.\n const parts: string[] = [];\n let cursor = 0;\n for (const edit of accepted) {\n parts.push(source.slice(cursor, edit.start), edit.text);\n cursor = edit.end;\n }\n parts.push(source.slice(cursor));\n return parts.join(\"\");\n}\n/** Compare semantic trees, with link identity supplied by the selected renderer's resolver. */\nexport function semanticFingerprint(document: Document, workspace?: Workspace): string {\n const canonicalUrl = (url: string, wiki = false) => {\n const resolution = workspace?.resolve(document.path, url, document.dialect, wiki);\n return resolution?.status === \"resolved\"\n ? `${resolution.target}#${resolution.fragment ?? \"\"}`\n : url;\n };\n // Keys are emitted in sorted order so the JSON text is canonical without a replacer.\n function normalize(node: Nodes, calloutHeader = false): unknown {\n if (node.type === \"wikiLink\") {\n if (node.embed)\n return { label: node.label, type: \"embed\", url: canonicalUrl(node.target ?? \"\", true) };\n return {\n children: [{ type: \"text\", value: node.label ?? node.target }],\n title: null,\n type: \"link\",\n url: canonicalUrl(node.target ?? \"\", true),\n };\n }\n const result: Record<string, unknown> = {};\n // Forgejo and Gitea read a heading's trailing `{...}` block as attributes,\n // character for character, where the tree holds ordinary inline content,\n // and generate the anchor from the heading's last line as written.\n if (node.type === \"heading\") {\n const attributes = headingAttributeSource(document, node);\n if (attributes !== undefined) result.attributes = attributes;\n const anchors = headingAnchorSource(document, node);\n if (anchors !== undefined) result.anchors = anchors;\n }\n if (calloutHeader && document.dialect === \"obsidian\" && node.type === \"paragraph\") {\n const [start, end] = range(node);\n const header = document.source.slice(start, end).split(/\\r?\\n/, 1)[0]!;\n if (/^\\[![\\w-]+\\]/.test(header)) {\n // CommonMark merges title and body into one paragraph. Preserve their boundary too.\n const title = header.replace(\n /^\\[!([\\w-]+)\\]/,\n (_, marker: string) => `[!${marker.toLowerCase()}]`,\n );\n result.calloutTitle = normalize(parse(title, document.dialect, document.path).tree);\n }\n }\n for (const key of Object.keys(node).sort()) {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (key === \"position\" || key === \"data\") continue;\n if (key === \"children\" && \"children\" in node) {\n result.children = node.children.map((child, index) =>\n normalize(child, index === 0 && (node.type === \"blockquote\" || calloutHeader)),\n );\n } else if (key === \"url\" && typeof value === \"string\") result[key] = canonicalUrl(value);\n else if (key === \"value\" && node.type === \"text\") {\n let text = node.value.replace(/[ \\t\\r\\n]+/g, \" \");\n if (calloutHeader && document.dialect !== \"commonmark\")\n text = text.replace(\n /^\\[!([\\w-]+)\\]/,\n (_, marker: string) => `[!${marker.toLowerCase()}]`,\n );\n result[key] = text;\n } else if (key === \"value\" && node.type === \"inlineCode\")\n result[key] = node.value.replace(/\\r\\n|\\r|\\n/g, \" \");\n else result[key] = value;\n }\n return result;\n }\n return JSON.stringify(normalize(document.tree));\n}\nexport function format(source: string, options: ProcessOptions = {}): FormatResult {\n const { config, rules } = prepare(options);\n let output = source;\n let document = parse(source, config.dialect, options.path, options.plugins);\n // The original fingerprint is only needed once an edit produces a candidate.\n let fingerprint: string | undefined;\n const seen = new Set([source]);\n try {\n for (let pass = 0; pass < 8; pass++) {\n const before = output;\n const findings: Diagnostic[] = [];\n for (const phase of [\"inline\", \"block\", \"document\"]) {\n const diagnostics = inspect(\n document,\n config,\n rules,\n options.workspace,\n (rule) => rule.kind === \"style\" && (rule.phase ?? \"inline\") === phase,\n );\n findings.push(...diagnostics);\n const edits = diagnostics.flatMap((item) => (item.edit ? [item.edit] : []));\n if (!edits.length) continue;\n const candidate = applyEdits(output, edits);\n if (candidate === output) continue;\n const candidateDocument = parse(candidate, config.dialect, options.path, options.plugins);\n fingerprint ??= semanticFingerprint(document, options.workspace);\n if (semanticFingerprint(candidateDocument, options.workspace) !== fingerprint)\n throw new Error(\n `Formatting in the ${phase} phase would change parsed meaning; the document was left unchanged.`,\n );\n output = candidate;\n // Rules consume the document without mutating it. Reuse the validated\n // tree until another phase changes its source, including final diagnostics.\n document = candidateDocument;\n }\n if (output === before) {\n // No phase changed the document, so every style finding of this pass\n // describes the final document; only the non-style rules still need to run.\n const remaining = inspect(\n document,\n config,\n rules,\n options.workspace,\n (rule) => rule.kind !== \"style\",\n );\n return {\n output,\n changed: output !== source,\n diagnostics: [...findings, ...remaining].sort(sortDiagnostics),\n };\n }\n if (seen.has(output))\n throw new Error(\"Formatting rules oscillate; the document was left unchanged.\");\n seen.add(output);\n }\n throw new Error(\n \"Formatting did not converge in eight passes; the document was left unchanged.\",\n );\n } catch (error) {\n return {\n output: source,\n changed: false,\n diagnostics: [\n diagnostic([0], \"engine/unsafe-format\", \"error\", {\n start: 0,\n message: error instanceof Error ? error.message : String(error),\n }),\n ],\n };\n }\n}\n"]}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import type { Root } from "mdast";
|
|
|
2
2
|
import type { Extension as SyntaxExtension } from "micromark-util-types";
|
|
3
3
|
import type { Extension as TreeExtension } from "mdast-util-from-markdown";
|
|
4
4
|
import type { AnySchema } from "ajv";
|
|
5
|
-
export type Dialect = "commonmark" | "github" | "obsidian";
|
|
5
|
+
export type Dialect = "commonmark" | "github" | "forgejo" | "gitea" | "obsidian";
|
|
6
|
+
/** A dialect or one of its aliases, accepted wherever configuration names a dialect. */
|
|
7
|
+
export type DialectName = Dialect | "codeberg";
|
|
6
8
|
export type Severity = "off" | "warn" | "error";
|
|
7
9
|
export type RuleSetting = Severity | [Severity, Record<string, unknown>];
|
|
8
10
|
export interface Edit {
|
|
@@ -63,7 +65,7 @@ export interface Plugin {
|
|
|
63
65
|
}
|
|
64
66
|
export interface Override {
|
|
65
67
|
files: string[];
|
|
66
|
-
dialect?:
|
|
68
|
+
dialect?: DialectName;
|
|
67
69
|
rules?: Record<string, RuleSetting>;
|
|
68
70
|
}
|
|
69
71
|
export interface ResolveOptions {
|
|
@@ -73,7 +75,7 @@ export interface ResolveOptions {
|
|
|
73
75
|
export interface Config {
|
|
74
76
|
resolve?: ResolveOptions;
|
|
75
77
|
extends?: string[];
|
|
76
|
-
dialect?:
|
|
78
|
+
dialect?: DialectName;
|
|
77
79
|
rules?: Record<string, RuleSetting>;
|
|
78
80
|
ignore?: string[];
|
|
79
81
|
overrides?: Override[];
|
package/dist/core/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Root } from \"mdast\";\nimport type { Extension as SyntaxExtension } from \"micromark-util-types\";\nimport type { Extension as TreeExtension } from \"mdast-util-from-markdown\";\nimport type { AnySchema } from \"ajv\";\n\nexport type Dialect = \"commonmark\" | \"github\" | \"obsidian\";\nexport type Severity = \"off\" | \"warn\" | \"error\";\nexport type RuleSetting = Severity | [Severity, Record<string, unknown>];\nexport interface Edit {\n start: number;\n end: number;\n text: string;\n}\nexport interface Finding {\n message: string;\n start: number;\n end?: number;\n edit?: Edit;\n}\nexport interface Diagnostic extends Finding {\n rule: string;\n severity: Exclude<Severity, \"off\">;\n line: number;\n column: number;\n}\nexport interface Document {\n source: string;\n path: string;\n tree: Root;\n dialect: Dialect;\n}\nexport interface LinkResolution {\n status: \"resolved\" | \"missing\" | \"ambiguous\" | \"external\" | \"unavailable\" | \"directory\";\n target?: string;\n fragment?: string;\n fragmentExists?: boolean;\n}\nexport interface Workspace {\n resolve(source: string, destination: string, dialect: Dialect, wiki?: boolean): LinkResolution;\n /** Obsidian's strictLineBreaks setting; false prevents semantic-changing prose reflow. */\n strictLineBreaks?: boolean;\n}\nexport interface RuleContext {\n document: Document;\n options: Record<string, unknown>;\n workspace?: Workspace;\n}\nexport interface Rule {\n description: string;\n kind: \"style\" | \"problem\";\n /** Inline edits, then block layout, then document-wide whitespace. */\n phase?: \"inline\" | \"block\" | \"document\";\n schema?: AnySchema;\n check(context: RuleContext): Finding[];\n}\nexport interface Plugin {\n name: string;\n rules?: Record<string, Rule>;\n presets?: Record<string, Config>;\n syntax?: { micromark: SyntaxExtension; mdast: TreeExtension };\n}\nexport interface Override {\n files: string[];\n dialect?:
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Root } from \"mdast\";\nimport type { Extension as SyntaxExtension } from \"micromark-util-types\";\nimport type { Extension as TreeExtension } from \"mdast-util-from-markdown\";\nimport type { AnySchema } from \"ajv\";\n\nexport type Dialect = \"commonmark\" | \"github\" | \"forgejo\" | \"gitea\" | \"obsidian\";\n/** A dialect or one of its aliases, accepted wherever configuration names a dialect. */\nexport type DialectName = Dialect | \"codeberg\";\nexport type Severity = \"off\" | \"warn\" | \"error\";\nexport type RuleSetting = Severity | [Severity, Record<string, unknown>];\nexport interface Edit {\n start: number;\n end: number;\n text: string;\n}\nexport interface Finding {\n message: string;\n start: number;\n end?: number;\n edit?: Edit;\n}\nexport interface Diagnostic extends Finding {\n rule: string;\n severity: Exclude<Severity, \"off\">;\n line: number;\n column: number;\n}\nexport interface Document {\n source: string;\n path: string;\n tree: Root;\n dialect: Dialect;\n}\nexport interface LinkResolution {\n status: \"resolved\" | \"missing\" | \"ambiguous\" | \"external\" | \"unavailable\" | \"directory\";\n target?: string;\n fragment?: string;\n fragmentExists?: boolean;\n}\nexport interface Workspace {\n resolve(source: string, destination: string, dialect: Dialect, wiki?: boolean): LinkResolution;\n /** Obsidian's strictLineBreaks setting; false prevents semantic-changing prose reflow. */\n strictLineBreaks?: boolean;\n}\nexport interface RuleContext {\n document: Document;\n options: Record<string, unknown>;\n workspace?: Workspace;\n}\nexport interface Rule {\n description: string;\n kind: \"style\" | \"problem\";\n /** Inline edits, then block layout, then document-wide whitespace. */\n phase?: \"inline\" | \"block\" | \"document\";\n schema?: AnySchema;\n check(context: RuleContext): Finding[];\n}\nexport interface Plugin {\n name: string;\n rules?: Record<string, Rule>;\n presets?: Record<string, Config>;\n syntax?: { micromark: SyntaxExtension; mdast: TreeExtension };\n}\nexport interface Override {\n files: string[];\n dialect?: DialectName;\n rules?: Record<string, RuleSetting>;\n}\nexport interface ResolveOptions {\n gitIgnored?: boolean;\n nestedRepositories?: boolean;\n}\nexport interface Config {\n resolve?: ResolveOptions;\n extends?: string[];\n dialect?: DialectName;\n rules?: Record<string, RuleSetting>;\n ignore?: string[];\n overrides?: Override[];\n plugins?: string[];\n}\nexport interface ResolvedConfig {\n resolve: ResolveOptions;\n dialect: Dialect;\n rules: Record<string, RuleSetting>;\n ignore: string[];\n}\nexport interface ProcessOptions {\n path?: string;\n config?: Config;\n plugins?: Plugin[];\n workspace?: Workspace;\n}\nexport interface FormatResult {\n output: string;\n changed: boolean;\n diagnostics: Diagnostic[];\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { lint, format, applyEdits, semanticFingerprint, builtInRules, ruleRegistry, } from "./core/engine.js";
|
|
2
|
-
export { resolveConfig, validateConfig, configSchema, presets } from "./config/resolve.js";
|
|
2
|
+
export { resolveConfig, validateConfig, configSchema, presets, dialects, dialectAliases, canonicalDialect, } from "./config/resolve.js";
|
|
3
3
|
export { parse, range, textContent } from "./syntax/parse.js";
|
|
4
4
|
export { createWorkspace } from "./workspace/index.js";
|
|
5
5
|
export type { WorkspaceOptions, WorkspaceSource } from "./workspace/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { lint, format, applyEdits, semanticFingerprint, builtInRules, ruleRegistry, } from "./core/engine.js";
|
|
2
|
-
export { resolveConfig, validateConfig, configSchema, presets } from "./config/resolve.js";
|
|
2
|
+
export { resolveConfig, validateConfig, configSchema, presets, dialects, dialectAliases, canonicalDialect, } from "./config/resolve.js";
|
|
3
3
|
export { parse, range, textContent } from "./syntax/parse.js";
|
|
4
4
|
export { createWorkspace } from "./workspace/index.js";
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC","sourcesContent":["export {\n lint,\n format,\n applyEdits,\n semanticFingerprint,\n builtInRules,\n ruleRegistry,\n} from \"./core/engine.js\";\nexport {\n resolveConfig,\n validateConfig,\n configSchema,\n presets,\n dialects,\n dialectAliases,\n canonicalDialect,\n} from \"./config/resolve.js\";\nexport { parse, range, textContent } from \"./syntax/parse.js\";\nexport { createWorkspace } from \"./workspace/index.js\";\nexport type { WorkspaceOptions, WorkspaceSource } from \"./workspace/index.js\";\nexport type * from \"./core/types.js\";\nexport type { ObsidianLiteral } from \"./syntax/obsidian.js\";\n"]}
|
package/dist/rules/dialects.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { walk } from "../syntax/walk.js";
|
|
2
2
|
import { range } from "../syntax/parse.js";
|
|
3
|
+
import { headingAttributeBlock } from "../workspace/heading-attributes.js";
|
|
3
4
|
import { optionsSchema } from "./style.js";
|
|
5
|
+
const githubAlerts = new Set(["github", "forgejo", "gitea"]);
|
|
4
6
|
function calloutRule(obsidian) {
|
|
5
7
|
return {
|
|
6
8
|
description: obsidian
|
|
@@ -10,7 +12,8 @@ function calloutRule(obsidian) {
|
|
|
10
12
|
phase: "inline",
|
|
11
13
|
schema: optionsSchema({}),
|
|
12
14
|
check({ document }) {
|
|
13
|
-
|
|
15
|
+
// Forgejo and Gitea render the same five GitHub alert types, case-insensitively.
|
|
16
|
+
if (obsidian ? document.dialect !== "obsidian" : !githubAlerts.has(document.dialect))
|
|
14
17
|
return [];
|
|
15
18
|
const findings = [];
|
|
16
19
|
walk(document.tree, "blockquote", (node) => {
|
|
@@ -86,6 +89,49 @@ export const dialectRules = {
|
|
|
86
89
|
return findings;
|
|
87
90
|
},
|
|
88
91
|
},
|
|
92
|
+
"forgejo/heading-id": {
|
|
93
|
+
description: "Report heading attribute ids that are not text, which Forgejo and Gitea before 1.26 cannot render.",
|
|
94
|
+
kind: "problem",
|
|
95
|
+
schema: optionsSchema({}),
|
|
96
|
+
check({ document }) {
|
|
97
|
+
if (document.dialect !== "forgejo" && document.dialect !== "gitea")
|
|
98
|
+
return [];
|
|
99
|
+
const findings = [];
|
|
100
|
+
const { source } = document;
|
|
101
|
+
walk(document.tree, "heading", (node) => {
|
|
102
|
+
const [start, end] = range(node);
|
|
103
|
+
// The block ends an ATX heading's line or the last text line of a
|
|
104
|
+
// Setext heading, whose last line is its underline.
|
|
105
|
+
const breaks = [...source.slice(start, end).matchAll(/\r\n?|\n/g)];
|
|
106
|
+
const underline = breaks.at(-1);
|
|
107
|
+
const previous = breaks.at(-2);
|
|
108
|
+
const lineStart = previous ? start + previous.index + previous[0].length : start;
|
|
109
|
+
let lineEnd = underline ? start + underline.index : end;
|
|
110
|
+
while (source[lineEnd - 1] === " " || source[lineEnd - 1] === "\t")
|
|
111
|
+
lineEnd--;
|
|
112
|
+
let line = source.slice(lineStart, lineEnd);
|
|
113
|
+
let block = headingAttributeBlock(line);
|
|
114
|
+
// Gitea before 1.26 also reads a block followed by a closing `#` sequence.
|
|
115
|
+
if (!block && !underline) {
|
|
116
|
+
const closed = /[ \t]+#+$/.exec(line);
|
|
117
|
+
if (closed) {
|
|
118
|
+
line = line.slice(0, closed.index);
|
|
119
|
+
block = headingAttributeBlock(line);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// goldmark hands a number, boolean, null, or list to the renderers,
|
|
123
|
+
// which expect text: Gitea 1.26 and later give the heading an empty
|
|
124
|
+
// id, Forgejo and earlier Gitea versions fail on the whole document.
|
|
125
|
+
if (block?.id === null)
|
|
126
|
+
findings.push({
|
|
127
|
+
start: lineStart + block.start,
|
|
128
|
+
end: lineStart + line.length,
|
|
129
|
+
message: 'Heading id is not text: Forgejo, and Gitea before 1.26, cannot render a document containing it. Quote it: {id="5"}.',
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
return findings;
|
|
133
|
+
},
|
|
134
|
+
},
|
|
89
135
|
"obsidian/strict-line-breaks": {
|
|
90
136
|
description: "Require verified soft-line-break behavior before reflowing an Obsidian document.",
|
|
91
137
|
kind: "problem",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialects.js","sourceRoot":"","sources":["../../src/rules/dialects.ts"],"names":[],"mappings":"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","sourcesContent":["import { walk } from \"../syntax/walk.js\";\nimport type { Finding, Rule } from \"../core/types.js\";\nimport { range } from \"../syntax/parse.js\";\nimport { optionsSchema } from \"./style.js\";\n\nfunction calloutRule(obsidian: boolean): Rule {\n return {\n description: obsidian\n ? \"Use lowercase Obsidian callout types.\"\n : \"Use uppercase GitHub alert types.\",\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({}),\n check({ document }) {\n if (document.dialect !== (obsidian ? \"obsidian\" : \"github\")) return [];\n const findings: Finding[] = [];\n walk(document.tree, \"blockquote\", (node) => {\n const child = node.children[0];\n if (child?.type !== \"paragraph\") return;\n const start = range(child)[0];\n const match = /^\\[!([\\w-]+)\\]/.exec(document.source.slice(start));\n if (!match) return;\n const original = match[1]!;\n if (\n !obsidian &&\n ![\"NOTE\", \"TIP\", \"IMPORTANT\", \"WARNING\", \"CAUTION\"].includes(original.toUpperCase())\n )\n return;\n const replacement = obsidian ? original.toLowerCase() : original.toUpperCase();\n if (original !== replacement)\n findings.push({\n start: start + 2,\n end: start + 2 + original.length,\n message: `Use ${replacement} for the callout type.`,\n edit: { start: start + 2, end: start + 2 + original.length, text: replacement },\n });\n });\n return findings;\n },\n };\n}\nexport const dialectRules: Record<string, Rule> = {\n \"github/alert-marker\": calloutRule(false),\n \"obsidian/callout-marker\": calloutRule(true),\n \"github/task-marker\": {\n description: \"Use lowercase x in completed task markers.\",\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n walk(document.tree, \"listItem\", (node) => {\n if (node.checked !== true) return;\n const start = range(node)[0];\n const match = /^(?:[-+*]|\\d+[.)])\\s+\\[X\\]/.exec(document.source.slice(start));\n if (!match) return;\n const offset = start + match[0].length - 2;\n findings.push({\n start: offset,\n message: \"Use lowercase x in task markers.\",\n edit: { start: offset, end: offset + 1, text: \"x\" },\n });\n });\n return findings;\n },\n },\n \"obsidian/block-reference\": {\n description: \"Report duplicate block identifiers.\",\n kind: \"problem\",\n schema: optionsSchema({}),\n check({ document }) {\n if (document.dialect !== \"obsidian\") return [];\n const seen = new Set<string>();\n const findings: Finding[] = [];\n walk(document.tree, \"text\", (node) => {\n const match = /(?:^|\\s)\\^([A-Za-z0-9-]+)\\s*$/.exec(node.value);\n if (!match) return;\n const id = match[1]!;\n if (seen.has(id))\n findings.push({ start: range(node)[0], message: `Duplicate block identifier ^${id}.` });\n seen.add(id);\n });\n return findings;\n },\n },\n \"obsidian/strict-line-breaks\": {\n description: \"Require verified soft-line-break behavior before reflowing an Obsidian document.\",\n kind: \"problem\",\n schema: optionsSchema({}),\n check({ document, workspace }) {\n return document.dialect === \"obsidian\" && workspace?.strictLineBreaks !== true\n ? [\n {\n start: 0,\n message:\n \"Obsidian strictLineBreaks is not verified true; paragraph reflow is disabled. Set it in Obsidian or supply workspace.strictLineBreaks to the library.\",\n },\n ]\n : [];\n },\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"dialects.js","sourceRoot":"","sources":["../../src/rules/dialects.ts"],"names":[],"mappings":"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","sourcesContent":["import { walk } from \"../syntax/walk.js\";\nimport type { Dialect, Finding, Rule } from \"../core/types.js\";\nimport { range } from \"../syntax/parse.js\";\nimport { headingAttributeBlock } from \"../workspace/heading-attributes.js\";\nimport { optionsSchema } from \"./style.js\";\n\nconst githubAlerts = new Set<Dialect>([\"github\", \"forgejo\", \"gitea\"]);\nfunction calloutRule(obsidian: boolean): Rule {\n return {\n description: obsidian\n ? \"Use lowercase Obsidian callout types.\"\n : \"Use uppercase GitHub alert types.\",\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({}),\n check({ document }) {\n // Forgejo and Gitea render the same five GitHub alert types, case-insensitively.\n if (obsidian ? document.dialect !== \"obsidian\" : !githubAlerts.has(document.dialect))\n return [];\n const findings: Finding[] = [];\n walk(document.tree, \"blockquote\", (node) => {\n const child = node.children[0];\n if (child?.type !== \"paragraph\") return;\n const start = range(child)[0];\n const match = /^\\[!([\\w-]+)\\]/.exec(document.source.slice(start));\n if (!match) return;\n const original = match[1]!;\n if (\n !obsidian &&\n ![\"NOTE\", \"TIP\", \"IMPORTANT\", \"WARNING\", \"CAUTION\"].includes(original.toUpperCase())\n )\n return;\n const replacement = obsidian ? original.toLowerCase() : original.toUpperCase();\n if (original !== replacement)\n findings.push({\n start: start + 2,\n end: start + 2 + original.length,\n message: `Use ${replacement} for the callout type.`,\n edit: { start: start + 2, end: start + 2 + original.length, text: replacement },\n });\n });\n return findings;\n },\n };\n}\nexport const dialectRules: Record<string, Rule> = {\n \"github/alert-marker\": calloutRule(false),\n \"obsidian/callout-marker\": calloutRule(true),\n \"github/task-marker\": {\n description: \"Use lowercase x in completed task markers.\",\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n walk(document.tree, \"listItem\", (node) => {\n if (node.checked !== true) return;\n const start = range(node)[0];\n const match = /^(?:[-+*]|\\d+[.)])\\s+\\[X\\]/.exec(document.source.slice(start));\n if (!match) return;\n const offset = start + match[0].length - 2;\n findings.push({\n start: offset,\n message: \"Use lowercase x in task markers.\",\n edit: { start: offset, end: offset + 1, text: \"x\" },\n });\n });\n return findings;\n },\n },\n \"obsidian/block-reference\": {\n description: \"Report duplicate block identifiers.\",\n kind: \"problem\",\n schema: optionsSchema({}),\n check({ document }) {\n if (document.dialect !== \"obsidian\") return [];\n const seen = new Set<string>();\n const findings: Finding[] = [];\n walk(document.tree, \"text\", (node) => {\n const match = /(?:^|\\s)\\^([A-Za-z0-9-]+)\\s*$/.exec(node.value);\n if (!match) return;\n const id = match[1]!;\n if (seen.has(id))\n findings.push({ start: range(node)[0], message: `Duplicate block identifier ^${id}.` });\n seen.add(id);\n });\n return findings;\n },\n },\n \"forgejo/heading-id\": {\n description:\n \"Report heading attribute ids that are not text, which Forgejo and Gitea before 1.26 cannot render.\",\n kind: \"problem\",\n schema: optionsSchema({}),\n check({ document }) {\n if (document.dialect !== \"forgejo\" && document.dialect !== \"gitea\") return [];\n const findings: Finding[] = [];\n const { source } = document;\n walk(document.tree, \"heading\", (node) => {\n const [start, end] = range(node);\n // The block ends an ATX heading's line or the last text line of a\n // Setext heading, whose last line is its underline.\n const breaks = [...source.slice(start, end).matchAll(/\\r\\n?|\\n/g)];\n const underline = breaks.at(-1);\n const previous = breaks.at(-2);\n const lineStart = previous ? start + previous.index + previous[0].length : start;\n let lineEnd = underline ? start + underline.index : end;\n while (source[lineEnd - 1] === \" \" || source[lineEnd - 1] === \"\\t\") lineEnd--;\n let line = source.slice(lineStart, lineEnd);\n let block = headingAttributeBlock(line);\n // Gitea before 1.26 also reads a block followed by a closing `#` sequence.\n if (!block && !underline) {\n const closed = /[ \\t]+#+$/.exec(line);\n if (closed) {\n line = line.slice(0, closed.index);\n block = headingAttributeBlock(line);\n }\n }\n // goldmark hands a number, boolean, null, or list to the renderers,\n // which expect text: Gitea 1.26 and later give the heading an empty\n // id, Forgejo and earlier Gitea versions fail on the whole document.\n if (block?.id === null)\n findings.push({\n start: lineStart + block.start,\n end: lineStart + line.length,\n message:\n 'Heading id is not text: Forgejo, and Gitea before 1.26, cannot render a document containing it. Quote it: {id=\"5\"}.',\n });\n });\n return findings;\n },\n },\n \"obsidian/strict-line-breaks\": {\n description: \"Require verified soft-line-break behavior before reflowing an Obsidian document.\",\n kind: \"problem\",\n schema: optionsSchema({}),\n check({ document, workspace }) {\n return document.dialect === \"obsidian\" && workspace?.strictLineBreaks !== true\n ? [\n {\n start: 0,\n message:\n \"Obsidian strictLineBreaks is not verified true; paragraph reflow is disabled. Set it in Obsidian or supply workspace.strictLineBreaks to the library.\",\n },\n ]\n : [];\n },\n },\n};\n"]}
|