mdrefine 0.1.0-beta.2 → 0.1.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/core/engine.js +10 -5
- package/dist/core/engine.js.map +1 -1
- package/dist/rules/style.js +75 -29
- package/dist/rules/style.js.map +1 -1
- package/docs/configuration.md +11 -6
- package/docs/design.md +18 -5
- package/docs/quick-start.md +1 -1
- package/docs/releases/0.1.0-beta.3.md +61 -0
- package/docs/releases.md +6 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ The CLI requires Node.js 22.12 or newer. The npm package is `mdrefine`; the
|
|
|
35
35
|
executable is `mdtools`. To install the beta in your document workspace:
|
|
36
36
|
|
|
37
37
|
```sh
|
|
38
|
-
npm install --save-dev --save-exact mdrefine@0.1.0-beta.
|
|
38
|
+
npm install --save-dev --save-exact mdrefine@0.1.0-beta.3
|
|
39
39
|
npx --no-install mdtools --help
|
|
40
40
|
```
|
|
41
41
|
|
package/dist/core/engine.js
CHANGED
|
@@ -163,27 +163,32 @@ export function semanticFingerprint(document, workspace) {
|
|
|
163
163
|
export function format(source, options = {}) {
|
|
164
164
|
const { config, rules } = prepare(options);
|
|
165
165
|
let output = source;
|
|
166
|
-
|
|
167
|
-
const fingerprint = semanticFingerprint(
|
|
166
|
+
let document = parse(source, config.dialect, options.path, options.plugins);
|
|
167
|
+
const fingerprint = semanticFingerprint(document, options.workspace);
|
|
168
168
|
const seen = new Set([source]);
|
|
169
169
|
try {
|
|
170
170
|
for (let pass = 0; pass < 8; pass++) {
|
|
171
171
|
const before = output;
|
|
172
172
|
for (const phase of ["inline", "block", "document"]) {
|
|
173
|
-
const document = parse(output, config.dialect, options.path, options.plugins);
|
|
174
173
|
const edits = inspect(document, config, rules, options.workspace, phase).flatMap((item) => item.edit ? [item.edit] : []);
|
|
175
174
|
if (!edits.length)
|
|
176
175
|
continue;
|
|
177
176
|
const candidate = applyEdits(output, edits);
|
|
178
|
-
if (
|
|
177
|
+
if (candidate === output)
|
|
178
|
+
continue;
|
|
179
|
+
const candidateDocument = parse(candidate, config.dialect, options.path, options.plugins);
|
|
180
|
+
if (semanticFingerprint(candidateDocument, options.workspace) !== fingerprint)
|
|
179
181
|
throw new Error(`Formatting in the ${phase} phase would change parsed meaning; the document was left unchanged.`);
|
|
180
182
|
output = candidate;
|
|
183
|
+
// Rules consume the document without mutating it. Reuse the validated
|
|
184
|
+
// tree until another phase changes its source, including final diagnostics.
|
|
185
|
+
document = candidateDocument;
|
|
181
186
|
}
|
|
182
187
|
if (output === before)
|
|
183
188
|
return {
|
|
184
189
|
output,
|
|
185
190
|
changed: output !== source,
|
|
186
|
-
diagnostics: inspect(
|
|
191
|
+
diagnostics: inspect(document, config, rules, options.workspace),
|
|
187
192
|
};
|
|
188
193
|
if (seen.has(output))
|
|
189
194
|
throw new Error("Formatting rules oscillate; the document was left unchanged.");
|
package/dist/core/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAc/C,MAAM,CAAC,MAAM,YAAY,GAAyB;IAChD,GAAG,UAAU;IACb,GAAG,YAAY;IACf,GAAG,SAAS;IACZ,GAAG,cAAc;CAClB,CAAC;AACF,MAAM,UAAU,YAAY,CAAC,UAAoB,EAAE;IACjD,MAAM,KAAK,GAAG,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9D,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;YACxD,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AACD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACvF,SAAS,OAAO,CAAC,OAAuB;IACtC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,eAAgC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC9C,uEAAuE;YACvE,6DAA6D;YAC7D,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC/C,CAAC,CAAC,aAAa;gBACf,CAAC,CAAC,CAAC,eAAe,KAAK,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,KAAK,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7F,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AACD,SAAS,UAAU,CACjB,MAAc,EACd,IAAY,EACZ,QAA0B,EAC1B,OAAgB;IAEhB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO;QACL,GAAG,OAAO;QACV,IAAI;QACJ,QAAQ;QACR,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;QAC/B,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;KACjD,CAAC;AACJ,CAAC;AACD,SAAS,OAAO,CACd,QAAkB,EAClB,MAAsB,EACtB,KAA2B,EAC3B,SAAqB,EACrB,KAAc;IAEd,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAE,CAAC;QAC1B,IACE,OAAO,CAAC,QAAQ,KAAK,KAAK;YAC1B,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,KAAK,CAAC,CAAC;YAExE,SAAS;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;YAC1B,QAAQ;YACR,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpC,CAAC,CAAC;QACH,KAAK,MAAM,OAAO,IAAI,QAAQ;YAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;gBAC5B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAClF,CAAC;AACD,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,UAA0B,EAAE;IAC/D,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E,OAAO,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;AAC7D,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,KAAa;IACtD,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7E,IAAI,QAA0B,CAAC;IAC/B,MAAM,QAAQ,GAAW,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;YAC7B,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YAC3B,IAAI,CAAC,KAAK,GAAG,CAAC;YACd,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK;YACrB,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM;YAExB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,IACE,QAAQ;YACR,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK;YAC7B,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG;YACzB,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;YAE3B,SAAS;QACX,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC;YAC1E,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;QACJ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IACD,IAAI,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,OAAO,EAAE;QACnC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,+FAA+F;AAC/F,MAAM,UAAU,mBAAmB,CAAC,QAAkB,EAAE,SAAqB;IAC3E,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,IAAI,GAAG,KAAK,EAAE,EAAE;QACjD,MAAM,UAAU,GAAG,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAClF,OAAO,UAAU,EAAE,MAAM,KAAK,UAAU;YACtC,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,QAAQ,IAAI,EAAE,EAAE;YACrD,CAAC,CAAC,GAAG,CAAC;IACV,CAAC,CAAC;IACF,SAAS,SAAS,CAAC,IAAW,EAAE,aAAa,GAAG,KAAK;QACnD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,KAAK;gBACZ,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAC1F,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC;gBAC1C,KAAK,EAAE,IAAI;gBACX,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;aAC/D,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,MAAM;gBAAE,SAAS;YACnD,IAAI,GAAG,KAAK,UAAU,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC7C,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACnD,SAAS,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,aAAa,CAAC,CAAC,CAC/E,CAAC;YACJ,CAAC;iBAAM,IAAI,GAAG,KAAK,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;iBACpF,IAAI,GAAG,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACjD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;gBAClD,IAAI,aAAa,IAAI,QAAQ,CAAC,OAAO,KAAK,YAAY;oBACpD,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,gBAAgB,EAChB,CAAC,CAAC,EAAE,MAAc,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,WAAW,EAAE,GAAG,CACpD,CAAC;gBACJ,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YACrB,CAAC;iBAAM,IAAI,GAAG,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;gBACtD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;;gBAClD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAc,EAAE,EAAE;QACvE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAC7D,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,UAA0B,EAAE;IACjE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,CAAC;YACtB,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;gBACpD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC9E,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACxF,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAC7B,CAAC;gBACF,IAAI,CAAC,KAAK,CAAC,MAAM;oBAAE,SAAS;gBAC5B,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC5C,IACE,mBAAmB,CACjB,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EAC/D,OAAO,CAAC,SAAS,CAClB,KAAK,WAAW;oBAEjB,MAAM,IAAI,KAAK,CACb,qBAAqB,KAAK,sEAAsE,CACjG,CAAC;gBACJ,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;YACD,IAAI,MAAM,KAAK,MAAM;gBACnB,OAAO;oBACL,MAAM;oBACN,OAAO,EAAE,MAAM,KAAK,MAAM;oBAC1B,WAAW,EAAE,OAAO,CAClB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EAC5D,MAAM,EACN,KAAK,EACL,OAAO,CAAC,SAAS,CAClB;iBACF,CAAC;YACJ,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAClF,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QACD,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;YACd,WAAW,EAAE;gBACX,UAAU,CAAC,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE;oBAClD,KAAK,EAAE,CAAC;oBACR,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC;aACH;SACF,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import { Ajv } from \"ajv\";\nimport type { Nodes } from \"mdast\";\nimport { resolveConfig, setting } from \"../config/resolve.js\";\nimport { parse } 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}\nfunction diagnostic(\n source: string,\n rule: string,\n severity: \"warn\" | \"error\",\n finding: Finding,\n): Diagnostic {\n const prefix = source.slice(0, finding.start);\n return {\n ...finding,\n rule,\n severity,\n line: prefix.split(\"\\n\").length,\n column: finding.start - prefix.lastIndexOf(\"\\n\"),\n };\n}\nfunction inspect(\n document: Document,\n config: ResolvedConfig,\n rules: Record<string, Rule>,\n workspace?: Workspace,\n phase?: string,\n): Diagnostic[] {\n const result: Diagnostic[] = [];\n const suppressed = suppressions(document);\n for (const [name, value] of Object.entries(config.rules)) {\n const enabled = setting(value);\n const rule = rules[name]!;\n if (\n enabled.severity === \"off\" ||\n (phase && (rule.kind !== \"style\" || (rule.phase ?? \"inline\") !== phase))\n )\n 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(document.source, name, enabled.severity, finding));\n }\n return result.sort((a, b) => a.start - b.start || a.rule.localeCompare(b.rule));\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 let output = source;\n for (const edit of accepted.reverse())\n output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);\n return output;\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 function normalize(node: Nodes, calloutHeader = false): unknown {\n if (node.type === \"wikiLink\") {\n if (node.embed)\n return { type: \"embed\", url: canonicalUrl(node.target ?? \"\", true), label: node.label };\n return {\n type: \"link\",\n url: canonicalUrl(node.target ?? \"\", true),\n title: null,\n children: [{ type: \"text\", value: node.label ?? node.target }],\n };\n }\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\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), (_key, value: unknown) => {\n if (value && typeof value === \"object\" && !Array.isArray(value))\n return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));\n return value;\n });\n}\nexport function format(source: string, options: ProcessOptions = {}): FormatResult {\n const { config, rules } = prepare(options);\n let output = source;\n const initial = parse(source, config.dialect, options.path, options.plugins);\n const fingerprint = semanticFingerprint(initial, options.workspace);\n const seen = new Set([source]);\n try {\n for (let pass = 0; pass < 8; pass++) {\n const before = output;\n for (const phase of [\"inline\", \"block\", \"document\"]) {\n const document = parse(output, config.dialect, options.path, options.plugins);\n const edits = inspect(document, config, rules, options.workspace, phase).flatMap((item) =>\n item.edit ? [item.edit] : [],\n );\n if (!edits.length) continue;\n const candidate = applyEdits(output, edits);\n if (\n semanticFingerprint(\n parse(candidate, config.dialect, options.path, options.plugins),\n options.workspace,\n ) !== fingerprint\n )\n throw new Error(\n `Formatting in the ${phase} phase would change parsed meaning; the document was left unchanged.`,\n );\n output = candidate;\n }\n if (output === before)\n return {\n output,\n changed: output !== source,\n diagnostics: inspect(\n parse(output, config.dialect, options.path, options.plugins),\n config,\n rules,\n options.workspace,\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(source, \"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 } 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}\nfunction diagnostic(\n source: string,\n rule: string,\n severity: \"warn\" | \"error\",\n finding: Finding,\n): Diagnostic {\n const prefix = source.slice(0, finding.start);\n return {\n ...finding,\n rule,\n severity,\n line: prefix.split(\"\\n\").length,\n column: finding.start - prefix.lastIndexOf(\"\\n\"),\n };\n}\nfunction inspect(\n document: Document,\n config: ResolvedConfig,\n rules: Record<string, Rule>,\n workspace?: Workspace,\n phase?: string,\n): Diagnostic[] {\n const result: Diagnostic[] = [];\n const suppressed = suppressions(document);\n for (const [name, value] of Object.entries(config.rules)) {\n const enabled = setting(value);\n const rule = rules[name]!;\n if (\n enabled.severity === \"off\" ||\n (phase && (rule.kind !== \"style\" || (rule.phase ?? \"inline\") !== phase))\n )\n 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(document.source, name, enabled.severity, finding));\n }\n return result.sort((a, b) => a.start - b.start || a.rule.localeCompare(b.rule));\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 let output = source;\n for (const edit of accepted.reverse())\n output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);\n return output;\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 function normalize(node: Nodes, calloutHeader = false): unknown {\n if (node.type === \"wikiLink\") {\n if (node.embed)\n return { type: \"embed\", url: canonicalUrl(node.target ?? \"\", true), label: node.label };\n return {\n type: \"link\",\n url: canonicalUrl(node.target ?? \"\", true),\n title: null,\n children: [{ type: \"text\", value: node.label ?? node.target }],\n };\n }\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\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), (_key, value: unknown) => {\n if (value && typeof value === \"object\" && !Array.isArray(value))\n return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));\n return value;\n });\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 const fingerprint = semanticFingerprint(document, options.workspace);\n const seen = new Set([source]);\n try {\n for (let pass = 0; pass < 8; pass++) {\n const before = output;\n for (const phase of [\"inline\", \"block\", \"document\"]) {\n const edits = inspect(document, config, rules, options.workspace, phase).flatMap((item) =>\n item.edit ? [item.edit] : [],\n );\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 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 return {\n output,\n changed: output !== source,\n diagnostics: inspect(document, config, rules, options.workspace),\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(source, \"engine/unsafe-format\", \"error\", {\n start: 0,\n message: error instanceof Error ? error.message : String(error),\n }),\n ],\n };\n }\n}\n"]}
|
package/dist/rules/style.js
CHANGED
|
@@ -40,6 +40,30 @@ function markerRule(type, fallback) {
|
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
+
// Whitespace inside an inline node is protected; only text-node whitespace can wrap.
|
|
44
|
+
function wrappingAtoms(words) {
|
|
45
|
+
const atoms = [];
|
|
46
|
+
let current = "";
|
|
47
|
+
for (const word of words) {
|
|
48
|
+
if (/^[ \t]+$/.test(word)) {
|
|
49
|
+
if (current)
|
|
50
|
+
atoms.push(current);
|
|
51
|
+
current = "";
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
current += word;
|
|
55
|
+
}
|
|
56
|
+
if (current)
|
|
57
|
+
atoms.push(current);
|
|
58
|
+
// Keep syntax-like markers with the preceding atom to preserve paragraph meaning.
|
|
59
|
+
for (let i = 1; i < atoms.length; i++) {
|
|
60
|
+
if (/^(?:[-+*]|\d+[.)]|#{1,6}|>|[-*_]{3,})$/.test(atoms[i])) {
|
|
61
|
+
atoms.splice(i - 1, 2, `${atoms[i - 1]} ${atoms[i]}`);
|
|
62
|
+
i--;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return atoms;
|
|
66
|
+
}
|
|
43
67
|
const wrap = {
|
|
44
68
|
description: "Reflow paragraphs using configurable width and protected inline atoms.",
|
|
45
69
|
kind: "style",
|
|
@@ -62,14 +86,61 @@ const wrap = {
|
|
|
62
86
|
const original = document.source.slice(start, end);
|
|
63
87
|
const lineStart = document.source.lastIndexOf("\n", start - 1) + 1;
|
|
64
88
|
const prefix = document.source.slice(lineStart, start);
|
|
89
|
+
const continuation = prefix.replace(/(?:[-+*]|\d+[.)]|\[[xX ]\])(?=\s)/g, (value) => " ".repeat(value.length));
|
|
90
|
+
const reportUnbreakable = () => findings.push({
|
|
91
|
+
start,
|
|
92
|
+
end,
|
|
93
|
+
message: `Paragraph exceeds ${width} ${unit} because of an unbreakable atom.`,
|
|
94
|
+
});
|
|
65
95
|
const reportSkipped = (reason) => {
|
|
66
|
-
if (options.reportUnreflowed
|
|
67
|
-
|
|
96
|
+
if (options.reportUnreflowed !== true && options.reportUnbreakable !== true)
|
|
97
|
+
return;
|
|
98
|
+
let breakable = false;
|
|
99
|
+
let unbreakable = false;
|
|
100
|
+
let offset = start;
|
|
101
|
+
let childIndex = 0;
|
|
102
|
+
for (const line of original.split(/(?<=\n)/)) {
|
|
103
|
+
const content = line.replace(/\r?\n$/, "");
|
|
104
|
+
const container = offset === start
|
|
105
|
+
? ""
|
|
106
|
+
: continuation && content.startsWith(continuation)
|
|
107
|
+
? continuation
|
|
108
|
+
: (content.match(/^[ \t>]+/)?.[0] ?? "");
|
|
109
|
+
const linePrefix = offset === start ? prefix : container;
|
|
110
|
+
const words = [];
|
|
111
|
+
while (childIndex < node.children.length &&
|
|
112
|
+
range(node.children[childIndex])[1] <= offset)
|
|
113
|
+
childIndex++;
|
|
114
|
+
for (let i = childIndex; i < node.children.length; i++) {
|
|
115
|
+
const child = node.children[i];
|
|
116
|
+
const [a, b] = range(child);
|
|
117
|
+
if (a >= offset + content.length)
|
|
118
|
+
break;
|
|
119
|
+
if (child.type === "break")
|
|
120
|
+
continue;
|
|
121
|
+
const raw = document.source.slice(Math.max(a, offset + container.length), Math.min(b, offset + content.length));
|
|
122
|
+
if (!raw)
|
|
123
|
+
continue;
|
|
124
|
+
words.push(...(child.type === "text" ? raw.split(/([ \t]+)/).filter(Boolean) : [raw]));
|
|
125
|
+
}
|
|
126
|
+
const atoms = wrappingAtoms(words);
|
|
127
|
+
const available = width - measure(linePrefix);
|
|
128
|
+
if (measure(words.join("").trimEnd()) > available) {
|
|
129
|
+
if (atoms.length > 1)
|
|
130
|
+
breakable = true;
|
|
131
|
+
if (atoms.some((atom) => measure(atom) > available))
|
|
132
|
+
unbreakable = true;
|
|
133
|
+
}
|
|
134
|
+
offset += line.length;
|
|
135
|
+
}
|
|
136
|
+
if (options.reportUnreflowed === true && breakable)
|
|
68
137
|
findings.push({
|
|
69
138
|
start,
|
|
70
139
|
end,
|
|
71
140
|
message: `Paragraph not reflowed: ${reason} (width ${width} ${unit}).`,
|
|
72
141
|
});
|
|
142
|
+
if (options.reportUnbreakable === true && unbreakable)
|
|
143
|
+
reportUnbreakable();
|
|
73
144
|
};
|
|
74
145
|
const reason = node.children.some((child) => child.type === "break")
|
|
75
146
|
? "hard line break"
|
|
@@ -86,7 +157,6 @@ const wrap = {
|
|
|
86
157
|
reportSkipped(reason);
|
|
87
158
|
return;
|
|
88
159
|
}
|
|
89
|
-
const continuation = prefix.replace(/(?:[-+*]|\d+[.)]|\[[xX ]\])(?=\s)/g, (value) => " ".repeat(value.length));
|
|
90
160
|
const words = [];
|
|
91
161
|
let unsupported = false;
|
|
92
162
|
for (const child of node.children) {
|
|
@@ -115,27 +185,7 @@ const wrap = {
|
|
|
115
185
|
reportSkipped("multiline inline syntax or unsupported continuation");
|
|
116
186
|
return;
|
|
117
187
|
}
|
|
118
|
-
|
|
119
|
-
const atoms = [];
|
|
120
|
-
let current = "";
|
|
121
|
-
for (const word of words) {
|
|
122
|
-
if (/^[ \t]+$/.test(word)) {
|
|
123
|
-
if (current)
|
|
124
|
-
atoms.push(current);
|
|
125
|
-
current = "";
|
|
126
|
-
}
|
|
127
|
-
else
|
|
128
|
-
current += word;
|
|
129
|
-
}
|
|
130
|
-
if (current)
|
|
131
|
-
atoms.push(current);
|
|
132
|
-
// Decide breaks with a marker and its preceding atom already grouped.
|
|
133
|
-
for (let i = 1; i < atoms.length; i++) {
|
|
134
|
-
if (/^(?:[-+*]|\d+[.)]|#{1,6}|>|[-*_]{3,})$/.test(atoms[i])) {
|
|
135
|
-
atoms.splice(i - 1, 2, `${atoms[i - 1]} ${atoms[i]}`);
|
|
136
|
-
i--;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
188
|
+
const atoms = wrappingAtoms(words);
|
|
139
189
|
const output = [];
|
|
140
190
|
let line = "";
|
|
141
191
|
let available = width - measure(prefix);
|
|
@@ -162,11 +212,7 @@ const wrap = {
|
|
|
162
212
|
});
|
|
163
213
|
if (options.reportUnbreakable === true &&
|
|
164
214
|
(prefix + replacement).split(/\r?\n/).some((line) => measure(line) > width))
|
|
165
|
-
|
|
166
|
-
start,
|
|
167
|
-
end,
|
|
168
|
-
message: `Paragraph exceeds ${width} ${unit} because of an unbreakable atom.`,
|
|
169
|
-
});
|
|
215
|
+
reportUnbreakable();
|
|
170
216
|
});
|
|
171
217
|
return findings;
|
|
172
218
|
},
|
package/dist/rules/style.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/rules/style.ts"],"names":[],"mappings":"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","sourcesContent":["import { visit } from \"unist-util-visit\";\nimport stringWidth from \"string-width\";\nimport type { Nodes } from \"mdast\";\nimport type { Finding, Rule } from \"../core/types.js\";\nimport { range } from \"../syntax/parse.js\";\n\nexport function optionsSchema(properties: Record<string, unknown>) {\n return { type: \"object\", properties, additionalProperties: false };\n}\nfunction markerRule(type: \"emphasis\" | \"strong\", fallback: string): Rule {\n return {\n description: `Choose ${type} delimiters without reprinting their contents.`,\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({ marker: { enum: [\"*\", \"_\"] } }),\n check({ document, options }) {\n const findings: Finding[] = [];\n visit(document.tree, type, (node) => {\n const [start, end] = range(node);\n const size = type === \"strong\" ? 2 : 1;\n const marker = String(options.marker ?? fallback).repeat(size);\n const original = document.source.slice(start, end);\n if (original.startsWith(marker)) return;\n // Underscores cannot delimit intraword emphasis. Preserve these valid forms.\n if (\n marker.startsWith(\"_\") &&\n (/\\p{L}|\\p{N}/u.test(document.source[start - 1] ?? \"\") ||\n /\\p{L}|\\p{N}/u.test(document.source[end] ?? \"\"))\n )\n return;\n for (const [a, b] of [\n [start, start + size],\n [end - size, end],\n ] as const) {\n findings.push({\n start: a,\n end: b,\n message: `Use ${JSON.stringify(marker)} for ${type}.`,\n edit: { start: a, end: b, text: marker },\n });\n }\n });\n return findings;\n },\n };\n}\n\nconst wrap: Rule = {\n description: \"Reflow paragraphs using configurable width and protected inline atoms.\",\n kind: \"style\",\n phase: \"block\",\n schema: optionsSchema({\n width: { type: \"integer\", minimum: 20, maximum: 500 },\n measure: { enum: [\"columns\", \"codepoints\"] },\n reportUnreflowed: { type: \"boolean\" },\n reportUnbreakable: { type: \"boolean\" },\n }),\n check({ document, options, workspace }) {\n if (document.dialect === \"obsidian\" && workspace?.strictLineBreaks !== true) return [];\n const findings: Finding[] = [];\n const width = Number(options.width ?? 80);\n const measure =\n options.measure === \"codepoints\" ? (text: string) => [...text].length : stringWidth;\n const unit = options.measure === \"codepoints\" ? \"code points\" : \"columns\";\n visit(document.tree, \"paragraph\", (node) => {\n const [start, end] = range(node);\n const original = document.source.slice(start, end);\n const lineStart = document.source.lastIndexOf(\"\\n\", start - 1) + 1;\n const prefix = document.source.slice(lineStart, start);\n const reportSkipped = (reason: string) => {\n if (\n options.reportUnreflowed === true &&\n (prefix + original).split(/\\r?\\n/).some((line) => measure(line) > width)\n )\n findings.push({\n start,\n end,\n message: `Paragraph not reflowed: ${reason} (width ${width} ${unit}).`,\n });\n };\n const reason = node.children.some((child) => child.type === \"break\")\n ? \"hard line break\"\n : node.children.some((child) => child.type === \"html\")\n ? \"inline HTML\"\n : /^\\[![^\\]]+\\]/.test(original)\n ? \"callout header\"\n : /(?:^|\\s)\\^[\\w-]+\\s*$/.test(original)\n ? \"block identifier\"\n : !/^[\\s>\\-*+\\d.[\\]xX)]*$/.test(prefix)\n ? \"unsupported container prefix\"\n : undefined;\n if (reason) {\n reportSkipped(reason);\n return;\n }\n const continuation = prefix.replace(/(?:[-+*]|\\d+[.)]|\\[[xX ]\\])(?=\\s)/g, (value) =>\n \" \".repeat(value.length),\n );\n const words: string[] = [];\n let unsupported = false;\n for (const child of node.children) {\n const [a, b] = range(child);\n const raw = document.source.slice(a, b);\n const lines = raw.split(/\\r?\\n/);\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i]!;\n if (continuation && line.startsWith(continuation))\n lines[i] = line.slice(continuation.length);\n else if (continuation && /^[\\s>]/.test(line)) unsupported = true;\n }\n const value = lines.join(\" \");\n if (child.type === \"text\") {\n // Preserve escaping and entities. Split only ordinary source whitespace.\n words.push(...value.split(/([ \\t]+)/).filter(Boolean));\n } else {\n if (raw.includes(\"\\n\")) unsupported = true;\n words.push(value);\n }\n }\n if (unsupported) {\n reportSkipped(\"multiline inline syntax or unsupported continuation\");\n return;\n }\n // Adjacent inline nodes without source whitespace form a single wrapping atom.\n const atoms: string[] = [];\n let current = \"\";\n for (const word of words) {\n if (/^[ \\t]+$/.test(word)) {\n if (current) atoms.push(current);\n current = \"\";\n } else current += word;\n }\n if (current) atoms.push(current);\n // Decide breaks with a marker and its preceding atom already grouped.\n for (let i = 1; i < atoms.length; i++) {\n if (/^(?:[-+*]|\\d+[.)]|#{1,6}|>|[-*_]{3,})$/.test(atoms[i]!)) {\n atoms.splice(i - 1, 2, `${atoms[i - 1]} ${atoms[i]}`);\n i--;\n }\n }\n const output: string[] = [];\n let line = \"\";\n let available = width - measure(prefix);\n for (const atom of atoms) {\n const candidate = line ? `${line} ${atom}` : atom;\n if (line && measure(candidate) > available) {\n output.push(line);\n line = atom;\n available = width - measure(continuation);\n } else line = candidate;\n }\n if (line) output.push(line);\n const newline = document.source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const replacement = output.join(newline + continuation);\n if (replacement !== original)\n findings.push({\n start,\n end,\n message: `Reflow paragraph to ${width} ${unit}.`,\n edit: { start, end, text: replacement },\n });\n if (\n options.reportUnbreakable === true &&\n (prefix + replacement).split(/\\r?\\n/).some((line) => measure(line) > width)\n )\n findings.push({\n start,\n end,\n message: `Paragraph exceeds ${width} ${unit} because of an unbreakable atom.`,\n });\n });\n return findings;\n },\n};\n\nconst table: Rule = {\n description: \"Align GFM table cells while preserving their inline source.\",\n kind: \"style\",\n phase: \"block\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n visit(document.tree, \"table\", (node) => {\n const [start, end] = range(node);\n // Nested tables retain container prefixes until a dedicated container printer handles them.\n if (node.position!.start.column !== 1) return;\n const rows = node.children.map((row) =>\n row.children.map((cell) => {\n if (!cell.children.length) return \"\";\n const first = range(cell.children[0]!)[0];\n const last = range(cell.children.at(-1)!)[1];\n return document.source.slice(first, last);\n }),\n );\n const count = node.align?.length ?? rows[0]?.length ?? 0;\n if (rows.some((row) => row.length > count)) return;\n const widths = Array.from({ length: count }, (_, i) =>\n Math.max(3, ...rows.map((row) => stringWidth(row[i] ?? \"\"))),\n );\n const rendered = rows.map(\n (row) =>\n `| ${widths.map((width, i) => (row[i] ?? \"\") + \" \".repeat(width - stringWidth(row[i] ?? \"\"))).join(\" | \")} |`,\n );\n rendered.splice(\n 1,\n 0,\n `| ${widths\n .map((width, i) => {\n const align = node.align?.[i];\n return (\n (align === \"left\" || align === \"center\" ? \":\" : \"-\") +\n \"-\".repeat(width - 2) +\n (align === \"right\" || align === \"center\" ? \":\" : \"-\")\n );\n })\n .join(\" | \")} |`,\n );\n const replacement = rendered.join(document.source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\");\n if (replacement !== document.source.slice(start, end))\n findings.push({\n start,\n end,\n message: \"Align table cells.\",\n edit: { start, end, text: replacement },\n });\n });\n return findings;\n },\n};\n\nexport const styleRules: Record<string, Rule> = {\n \"style/wrap\": wrap,\n \"style/inline-code\": {\n description: \"Join multiline code spans using their CommonMark rendered value.\",\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n visit(document.tree, \"inlineCode\", (node) => {\n const [start, end] = range(node);\n if (!/[\\r\\n]/.test(document.source.slice(start, end))) return;\n const value = node.value.replace(/\\r\\n|\\r|\\n/g, \" \");\n const longest = Math.max(0, ...(value.match(/`+/g) ?? []).map((run) => run.length));\n const marker = \"`\".repeat(longest + 1);\n const pad = /^`|`$/.test(value) || (/^ .* $/.test(value) && /[^ ]/.test(value)) ? \" \" : \"\";\n findings.push({\n start,\n end,\n message: \"Join the code span onto one line.\",\n edit: { start, end, text: `${marker}${pad}${value}${pad}${marker}` },\n });\n });\n return findings;\n },\n },\n \"style/emphasis\": markerRule(\"emphasis\", \"_\"),\n \"style/strong\": markerRule(\"strong\", \"*\"),\n \"style/table\": table,\n \"style/final-newline\": {\n description: \"End nonempty documents with a newline.\",\n kind: \"style\",\n phase: \"document\",\n schema: optionsSchema({}),\n check({ document: { source } }) {\n if (!source || source.endsWith(\"\\n\")) return [];\n return [\n {\n start: source.length,\n message: \"Add a final newline.\",\n edit: {\n start: source.length,\n end: source.length,\n text: source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\",\n },\n },\n ];\n },\n },\n \"style/heading\": {\n description: \"Use ATX headings.\",\n kind: \"style\",\n phase: \"block\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n visit(document.tree, \"heading\", (node) => {\n const [start, end] = range(node);\n if (document.source[start] === \"#\" || node.position!.start.column !== 1) return;\n const first = node.children[0];\n const last = node.children.at(-1);\n if (!first || !last) return;\n const text = document.source.slice(range(first)[0], range(last)[1]);\n if (text.includes(\"\\n\")) return;\n findings.push({\n start,\n end,\n message: \"Use an ATX heading.\",\n edit: { start, end, text: `${\"#\".repeat(node.depth)} ${text}` },\n });\n });\n return findings;\n },\n },\n};\n\n/** Collect source-positioned nodes for rule/plugin consumers. */\nexport function nodesOfType(\n document: { tree: import(\"mdast\").Root },\n type: Nodes[\"type\"],\n): Nodes[] {\n const result: Nodes[] = [];\n visit(document.tree, (node) => {\n if (node.type === type) result.push(node);\n });\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/rules/style.ts"],"names":[],"mappings":"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","sourcesContent":["import { visit } from \"unist-util-visit\";\nimport stringWidth from \"string-width\";\nimport type { Nodes } from \"mdast\";\nimport type { Finding, Rule } from \"../core/types.js\";\nimport { range } from \"../syntax/parse.js\";\n\nexport function optionsSchema(properties: Record<string, unknown>) {\n return { type: \"object\", properties, additionalProperties: false };\n}\nfunction markerRule(type: \"emphasis\" | \"strong\", fallback: string): Rule {\n return {\n description: `Choose ${type} delimiters without reprinting their contents.`,\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({ marker: { enum: [\"*\", \"_\"] } }),\n check({ document, options }) {\n const findings: Finding[] = [];\n visit(document.tree, type, (node) => {\n const [start, end] = range(node);\n const size = type === \"strong\" ? 2 : 1;\n const marker = String(options.marker ?? fallback).repeat(size);\n const original = document.source.slice(start, end);\n if (original.startsWith(marker)) return;\n // Underscores cannot delimit intraword emphasis. Preserve these valid forms.\n if (\n marker.startsWith(\"_\") &&\n (/\\p{L}|\\p{N}/u.test(document.source[start - 1] ?? \"\") ||\n /\\p{L}|\\p{N}/u.test(document.source[end] ?? \"\"))\n )\n return;\n for (const [a, b] of [\n [start, start + size],\n [end - size, end],\n ] as const) {\n findings.push({\n start: a,\n end: b,\n message: `Use ${JSON.stringify(marker)} for ${type}.`,\n edit: { start: a, end: b, text: marker },\n });\n }\n });\n return findings;\n },\n };\n}\n\n// Whitespace inside an inline node is protected; only text-node whitespace can wrap.\nfunction wrappingAtoms(words: string[]): string[] {\n const atoms: string[] = [];\n let current = \"\";\n for (const word of words) {\n if (/^[ \\t]+$/.test(word)) {\n if (current) atoms.push(current);\n current = \"\";\n } else current += word;\n }\n if (current) atoms.push(current);\n // Keep syntax-like markers with the preceding atom to preserve paragraph meaning.\n for (let i = 1; i < atoms.length; i++) {\n if (/^(?:[-+*]|\\d+[.)]|#{1,6}|>|[-*_]{3,})$/.test(atoms[i]!)) {\n atoms.splice(i - 1, 2, `${atoms[i - 1]} ${atoms[i]}`);\n i--;\n }\n }\n return atoms;\n}\n\nconst wrap: Rule = {\n description: \"Reflow paragraphs using configurable width and protected inline atoms.\",\n kind: \"style\",\n phase: \"block\",\n schema: optionsSchema({\n width: { type: \"integer\", minimum: 20, maximum: 500 },\n measure: { enum: [\"columns\", \"codepoints\"] },\n reportUnreflowed: { type: \"boolean\" },\n reportUnbreakable: { type: \"boolean\" },\n }),\n check({ document, options, workspace }) {\n if (document.dialect === \"obsidian\" && workspace?.strictLineBreaks !== true) return [];\n const findings: Finding[] = [];\n const width = Number(options.width ?? 80);\n const measure =\n options.measure === \"codepoints\" ? (text: string) => [...text].length : stringWidth;\n const unit = options.measure === \"codepoints\" ? \"code points\" : \"columns\";\n visit(document.tree, \"paragraph\", (node) => {\n const [start, end] = range(node);\n const original = document.source.slice(start, end);\n const lineStart = document.source.lastIndexOf(\"\\n\", start - 1) + 1;\n const prefix = document.source.slice(lineStart, start);\n const continuation = prefix.replace(/(?:[-+*]|\\d+[.)]|\\[[xX ]\\])(?=\\s)/g, (value) =>\n \" \".repeat(value.length),\n );\n const reportUnbreakable = () =>\n findings.push({\n start,\n end,\n message: `Paragraph exceeds ${width} ${unit} because of an unbreakable atom.`,\n });\n const reportSkipped = (reason: string) => {\n if (options.reportUnreflowed !== true && options.reportUnbreakable !== true) return;\n let breakable = false;\n let unbreakable = false;\n let offset = start;\n let childIndex = 0;\n for (const line of original.split(/(?<=\\n)/)) {\n const content = line.replace(/\\r?\\n$/, \"\");\n const container =\n offset === start\n ? \"\"\n : continuation && content.startsWith(continuation)\n ? continuation\n : (content.match(/^[ \\t>]+/)?.[0] ?? \"\");\n const linePrefix = offset === start ? prefix : container;\n const words: string[] = [];\n while (\n childIndex < node.children.length &&\n range(node.children[childIndex]!)[1] <= offset\n )\n childIndex++;\n for (let i = childIndex; i < node.children.length; i++) {\n const child = node.children[i]!;\n const [a, b] = range(child);\n if (a >= offset + content.length) break;\n if (child.type === \"break\") continue;\n const raw = document.source.slice(\n Math.max(a, offset + container.length),\n Math.min(b, offset + content.length),\n );\n if (!raw) continue;\n words.push(...(child.type === \"text\" ? raw.split(/([ \\t]+)/).filter(Boolean) : [raw]));\n }\n const atoms = wrappingAtoms(words);\n const available = width - measure(linePrefix);\n if (measure(words.join(\"\").trimEnd()) > available) {\n if (atoms.length > 1) breakable = true;\n if (atoms.some((atom) => measure(atom) > available)) unbreakable = true;\n }\n offset += line.length;\n }\n if (options.reportUnreflowed === true && breakable)\n findings.push({\n start,\n end,\n message: `Paragraph not reflowed: ${reason} (width ${width} ${unit}).`,\n });\n if (options.reportUnbreakable === true && unbreakable) reportUnbreakable();\n };\n const reason = node.children.some((child) => child.type === \"break\")\n ? \"hard line break\"\n : node.children.some((child) => child.type === \"html\")\n ? \"inline HTML\"\n : /^\\[![^\\]]+\\]/.test(original)\n ? \"callout header\"\n : /(?:^|\\s)\\^[\\w-]+\\s*$/.test(original)\n ? \"block identifier\"\n : !/^[\\s>\\-*+\\d.[\\]xX)]*$/.test(prefix)\n ? \"unsupported container prefix\"\n : undefined;\n if (reason) {\n reportSkipped(reason);\n return;\n }\n const words: string[] = [];\n let unsupported = false;\n for (const child of node.children) {\n const [a, b] = range(child);\n const raw = document.source.slice(a, b);\n const lines = raw.split(/\\r?\\n/);\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i]!;\n if (continuation && line.startsWith(continuation))\n lines[i] = line.slice(continuation.length);\n else if (continuation && /^[\\s>]/.test(line)) unsupported = true;\n }\n const value = lines.join(\" \");\n if (child.type === \"text\") {\n // Preserve escaping and entities. Split only ordinary source whitespace.\n words.push(...value.split(/([ \\t]+)/).filter(Boolean));\n } else {\n if (raw.includes(\"\\n\")) unsupported = true;\n words.push(value);\n }\n }\n if (unsupported) {\n reportSkipped(\"multiline inline syntax or unsupported continuation\");\n return;\n }\n const atoms = wrappingAtoms(words);\n const output: string[] = [];\n let line = \"\";\n let available = width - measure(prefix);\n for (const atom of atoms) {\n const candidate = line ? `${line} ${atom}` : atom;\n if (line && measure(candidate) > available) {\n output.push(line);\n line = atom;\n available = width - measure(continuation);\n } else line = candidate;\n }\n if (line) output.push(line);\n const newline = document.source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const replacement = output.join(newline + continuation);\n if (replacement !== original)\n findings.push({\n start,\n end,\n message: `Reflow paragraph to ${width} ${unit}.`,\n edit: { start, end, text: replacement },\n });\n if (\n options.reportUnbreakable === true &&\n (prefix + replacement).split(/\\r?\\n/).some((line) => measure(line) > width)\n )\n reportUnbreakable();\n });\n return findings;\n },\n};\n\nconst table: Rule = {\n description: \"Align GFM table cells while preserving their inline source.\",\n kind: \"style\",\n phase: \"block\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n visit(document.tree, \"table\", (node) => {\n const [start, end] = range(node);\n // Nested tables retain container prefixes until a dedicated container printer handles them.\n if (node.position!.start.column !== 1) return;\n const rows = node.children.map((row) =>\n row.children.map((cell) => {\n if (!cell.children.length) return \"\";\n const first = range(cell.children[0]!)[0];\n const last = range(cell.children.at(-1)!)[1];\n return document.source.slice(first, last);\n }),\n );\n const count = node.align?.length ?? rows[0]?.length ?? 0;\n if (rows.some((row) => row.length > count)) return;\n const widths = Array.from({ length: count }, (_, i) =>\n Math.max(3, ...rows.map((row) => stringWidth(row[i] ?? \"\"))),\n );\n const rendered = rows.map(\n (row) =>\n `| ${widths.map((width, i) => (row[i] ?? \"\") + \" \".repeat(width - stringWidth(row[i] ?? \"\"))).join(\" | \")} |`,\n );\n rendered.splice(\n 1,\n 0,\n `| ${widths\n .map((width, i) => {\n const align = node.align?.[i];\n return (\n (align === \"left\" || align === \"center\" ? \":\" : \"-\") +\n \"-\".repeat(width - 2) +\n (align === \"right\" || align === \"center\" ? \":\" : \"-\")\n );\n })\n .join(\" | \")} |`,\n );\n const replacement = rendered.join(document.source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\");\n if (replacement !== document.source.slice(start, end))\n findings.push({\n start,\n end,\n message: \"Align table cells.\",\n edit: { start, end, text: replacement },\n });\n });\n return findings;\n },\n};\n\nexport const styleRules: Record<string, Rule> = {\n \"style/wrap\": wrap,\n \"style/inline-code\": {\n description: \"Join multiline code spans using their CommonMark rendered value.\",\n kind: \"style\",\n phase: \"inline\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n visit(document.tree, \"inlineCode\", (node) => {\n const [start, end] = range(node);\n if (!/[\\r\\n]/.test(document.source.slice(start, end))) return;\n const value = node.value.replace(/\\r\\n|\\r|\\n/g, \" \");\n const longest = Math.max(0, ...(value.match(/`+/g) ?? []).map((run) => run.length));\n const marker = \"`\".repeat(longest + 1);\n const pad = /^`|`$/.test(value) || (/^ .* $/.test(value) && /[^ ]/.test(value)) ? \" \" : \"\";\n findings.push({\n start,\n end,\n message: \"Join the code span onto one line.\",\n edit: { start, end, text: `${marker}${pad}${value}${pad}${marker}` },\n });\n });\n return findings;\n },\n },\n \"style/emphasis\": markerRule(\"emphasis\", \"_\"),\n \"style/strong\": markerRule(\"strong\", \"*\"),\n \"style/table\": table,\n \"style/final-newline\": {\n description: \"End nonempty documents with a newline.\",\n kind: \"style\",\n phase: \"document\",\n schema: optionsSchema({}),\n check({ document: { source } }) {\n if (!source || source.endsWith(\"\\n\")) return [];\n return [\n {\n start: source.length,\n message: \"Add a final newline.\",\n edit: {\n start: source.length,\n end: source.length,\n text: source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\",\n },\n },\n ];\n },\n },\n \"style/heading\": {\n description: \"Use ATX headings.\",\n kind: \"style\",\n phase: \"block\",\n schema: optionsSchema({}),\n check({ document }) {\n const findings: Finding[] = [];\n visit(document.tree, \"heading\", (node) => {\n const [start, end] = range(node);\n if (document.source[start] === \"#\" || node.position!.start.column !== 1) return;\n const first = node.children[0];\n const last = node.children.at(-1);\n if (!first || !last) return;\n const text = document.source.slice(range(first)[0], range(last)[1]);\n if (text.includes(\"\\n\")) return;\n findings.push({\n start,\n end,\n message: \"Use an ATX heading.\",\n edit: { start, end, text: `${\"#\".repeat(node.depth)} ${text}` },\n });\n });\n return findings;\n },\n },\n};\n\n/** Collect source-positioned nodes for rule/plugin consumers. */\nexport function nodesOfType(\n document: { tree: import(\"mdast\").Root },\n type: Nodes[\"type\"],\n): Nodes[] {\n const result: Nodes[] = [];\n visit(document.tree, (node) => {\n if (node.type === type) result.push(node);\n });\n return result;\n}\n"]}
|
package/docs/configuration.md
CHANGED
|
@@ -100,12 +100,17 @@ library workflow; formatting rules must preserve document meaning.
|
|
|
100
100
|
Unicode scalar values instead; astral characters count once and combining marks
|
|
101
101
|
count separately. Container prefixes count toward the width in either mode.
|
|
102
102
|
|
|
103
|
-
`reportUnreflowed: true` reports over-width
|
|
104
|
-
block IDs, inline HTML, callout headers, or
|
|
105
|
-
containers. `reportUnbreakable: true` reports
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
`reportUnreflowed: true` reports breakable over-width lines in paragraphs
|
|
104
|
+
protected by hard breaks, block IDs, inline HTML, callout headers, or
|
|
105
|
+
unsupported multiline syntax or containers. `reportUnbreakable: true` reports
|
|
106
|
+
overflow from an atom that cannot be split, including in protected paragraphs.
|
|
107
|
+
Whitespace inside a link, code span, or other protected inline node is not a
|
|
108
|
+
wrapping opportunity. A protected paragraph with both breakable prose and an
|
|
109
|
+
over-width atom can report both causes; an atom-only overflow does not trigger
|
|
110
|
+
`reportUnreflowed`. Hard-break markers are excluded from protected-line width.
|
|
111
|
+
Both options default to false, propose no edits, and use the rule's severity.
|
|
112
|
+
Use severity `error` or `--max-warnings 0` to make these diagnostics fail a
|
|
113
|
+
check; `--check` does not change rule settings.
|
|
109
114
|
|
|
110
115
|
Enable `style/inline-code` to join multiline code spans before paragraph reflow.
|
|
111
116
|
This opt-in rule handles single and multiple backticks, including list and quote
|
package/docs/design.md
CHANGED
|
@@ -62,11 +62,11 @@ dimensions in their aliases remain intact.
|
|
|
62
62
|
The workspace indexes eligible paths first and parses target Markdown only when
|
|
63
63
|
a fragment is checked, caching the result for that invocation. CLI discovery
|
|
64
64
|
also defers reading Markdown until it is selected or needed for a fragment.
|
|
65
|
-
|
|
66
|
-
built on first use instead of scanning every path for each shortened
|
|
67
|
-
is no persistent cache, worker pool, watch service, editor
|
|
68
|
-
language server yet. The library has a pluggable workspace
|
|
69
|
-
specialized hosts.
|
|
65
|
+
Built-in rule-schema validators are reused across documents. A suffix lookup
|
|
66
|
+
index is built on first use instead of scanning every path for each shortened
|
|
67
|
+
link. There is no persistent cache, worker pool, watch service, editor
|
|
68
|
+
extension, or language server yet. The library has a pluggable workspace
|
|
69
|
+
interface for specialized hosts.
|
|
70
70
|
|
|
71
71
|
Run `npm run build` and `node scripts/benchmark.mjs 1000` for a reproducible
|
|
72
72
|
synthetic library benchmark. It reports path-index construction and lint time
|
|
@@ -75,6 +75,19 @@ it. These timings exclude filesystem traversal and do not predict a particular
|
|
|
75
75
|
vault's throughput. Measure the original workload before adding caches or
|
|
76
76
|
workers.
|
|
77
77
|
|
|
78
|
+
Formatting retains the current parsed document within one call, reusing it
|
|
79
|
+
between phases and for final diagnostics. Every changed candidate is parsed and
|
|
80
|
+
checked against the original semantic fingerprint before becoming the next
|
|
81
|
+
phase's input. No-op edits still undergo range and overlap validation. This
|
|
82
|
+
retains the plugin contract that rules must not mutate documents.
|
|
83
|
+
|
|
84
|
+
Run `node scripts/benchmark-format.mjs 100` after building to compare 100
|
|
85
|
+
formatting calls on a synthetic 4.8 KB note needing edits with 100 calls on its
|
|
86
|
+
already-formatted output. It warms both cases, checks output and diagnostics,
|
|
87
|
+
and prints a result hash for comparing implementations. Run several times
|
|
88
|
+
without competing workloads; timings exclude discovery, I/O, CLI serialization,
|
|
89
|
+
and custom plugins.
|
|
90
|
+
|
|
78
91
|
## Maintenance priorities
|
|
79
92
|
|
|
80
93
|
Prioritize reproducible document corruption and renderer disagreement over new
|
package/docs/quick-start.md
CHANGED
|
@@ -9,7 +9,7 @@ The CLI requires Node.js 22.12 or newer. Install the package in your document
|
|
|
9
9
|
workspace:
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npm install --save-dev --save-exact mdrefine@0.1.0-beta.
|
|
12
|
+
npm install --save-dev --save-exact mdrefine@0.1.0-beta.3
|
|
13
13
|
npx --no-install mdtools --help
|
|
14
14
|
```
|
|
15
15
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# mdrefine 0.1.0-beta.3
|
|
2
|
+
|
|
3
|
+
Third public beta of Markdown Tools. npm package: `mdrefine`; executable:
|
|
4
|
+
`mdtools`. Requires Node.js 22.12 or newer. Upgrade with:
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install --save-dev --save-exact mdrefine@0.1.0-beta.3
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Correct wrap diagnostics
|
|
11
|
+
|
|
12
|
+
Protected paragraphs now distinguish breakable prose from indivisible inline
|
|
13
|
+
atoms. A hard-break paragraph whose only over-width content is a long link, code
|
|
14
|
+
span, or other protected atom no longer triggers `reportUnreflowed`. That
|
|
15
|
+
overflow follows `reportUnbreakable`, including when reflow is skipped. A
|
|
16
|
+
paragraph containing both causes can report both when enabled.
|
|
17
|
+
|
|
18
|
+
Whitespace inside protected inline nodes is not a wrapping opportunity.
|
|
19
|
+
Container prefixes count toward width; hard-break markers are excluded from
|
|
20
|
+
protected-line width. Both diagnostic options remain disabled by default and
|
|
21
|
+
propose no edits. Protected paragraph source remains unchanged.
|
|
22
|
+
|
|
23
|
+
Fixed in [PR #36](https://github.com/viell-dev/slop-markdown-tools/pull/36),
|
|
24
|
+
resolving [#34](https://github.com/viell-dev/slop-markdown-tools/issues/34).
|
|
25
|
+
Regression coverage includes both hard-break forms, LF/CRLF, lists, quotes, task
|
|
26
|
+
items, Unicode width measurement, and Obsidian's strict-line-break gate.
|
|
27
|
+
|
|
28
|
+
## Faster formatting
|
|
29
|
+
|
|
30
|
+
The formatter reuses the current parsed document between phases and for final
|
|
31
|
+
diagnostics. It parses each changed candidate and validates its meaning before
|
|
32
|
+
accepting it. Edit-range, overlap, oscillation, and convergence checks remain in
|
|
33
|
+
force; no persistent cache or worker pool is introduced.
|
|
34
|
+
|
|
35
|
+
A warmed synthetic benchmark improved approximately 2.3 times for input needing
|
|
36
|
+
edits and 2.6 times for already-formatted input, with identical result hashes.
|
|
37
|
+
On the reporter's 8,362-document, 36 MB workspace, `format --check --json` fell
|
|
38
|
+
from 314 to 121 seconds, with the same 6,960 would-change files and no remaining
|
|
39
|
+
diagnostics after formatting. These are workload-specific results, not a
|
|
40
|
+
throughput guarantee.
|
|
41
|
+
|
|
42
|
+
Implemented in
|
|
43
|
+
[PR #37](https://github.com/viell-dev/slop-markdown-tools/pull/37), resolving
|
|
44
|
+
[#35](https://github.com/viell-dev/slop-markdown-tools/issues/35).
|
|
45
|
+
Original-workload validation in
|
|
46
|
+
[#23](https://github.com/viell-dev/slop-markdown-tools/issues/23#issuecomment-5735871369)
|
|
47
|
+
also confirms the beta.2 indexing improvements and correct link diagnostics; the
|
|
48
|
+
performance issue is now closed. The source checkout includes
|
|
49
|
+
`scripts/benchmark-format.mjs` for reproducible formatting measurements.
|
|
50
|
+
|
|
51
|
+
## Compatibility
|
|
52
|
+
|
|
53
|
+
No dependency, public API, configuration-schema, or Node.js minimum changes.
|
|
54
|
+
Existing beta.2 configurations remain valid. Consumers enabling wrap diagnostics
|
|
55
|
+
may see findings move from `reportUnreflowed` to `reportUnbreakable`; this is
|
|
56
|
+
the intentional classification correction described above.
|
|
57
|
+
|
|
58
|
+
The API and configuration remain provisional. Semantic guards, conservative
|
|
59
|
+
handling of unsupported constructs, and Obsidian's verified strict-line-break
|
|
60
|
+
requirement remain in force. Repository agent instructions now also prohibit
|
|
61
|
+
self-references in GitHub issue and PR posts.
|
package/docs/releases.md
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Versions and availability
|
|
4
4
|
|
|
5
|
-
These documents cover `mdrefine@0.1.0-beta.
|
|
5
|
+
These documents cover `mdrefine@0.1.0-beta.3`. The executable is `mdtools`;
|
|
6
6
|
prereleases use npm's `beta` channel. Read the
|
|
7
|
-
[beta.
|
|
8
|
-
|
|
7
|
+
[beta.3 release notes](releases/0.1.0-beta.3.md) for changes and limitations.
|
|
8
|
+
Previous releases: [beta.2](releases/0.1.0-beta.2.md) and
|
|
9
|
+
[beta.1](releases/0.1.0-beta.1.md).
|
|
9
10
|
|
|
10
11
|
The registry is the source of truth for package availability:
|
|
11
12
|
|
|
12
13
|
```sh
|
|
13
|
-
npm view mdrefine@0.1.0-beta.
|
|
14
|
+
npm view mdrefine@0.1.0-beta.3 version --registry=https://registry.npmjs.org/
|
|
14
15
|
```
|
|
15
16
|
|
|
16
17
|
An `E404` means the requested package or version is unavailable. A version in
|
|
@@ -31,7 +32,7 @@ Use Node.js 24 and npm 10 or newer from a clean checkout:
|
|
|
31
32
|
```sh
|
|
32
33
|
npm ci
|
|
33
34
|
npm run release:prepare
|
|
34
|
-
npm publish ./artifacts/mdrefine-0.1.0-beta.
|
|
35
|
+
npm publish ./artifacts/mdrefine-0.1.0-beta.3.tgz --dry-run --ignore-scripts --access public --tag beta
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
Preparation runs all checks, packs the allowlisted files, installs that exact
|