@reteps/tree-sitter-htmlmustache 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -33
- package/browser/out/browser/index.d.ts +43 -0
- package/browser/out/browser/index.d.ts.map +1 -0
- package/browser/out/browser/index.mjs +3612 -0
- package/browser/out/browser/index.mjs.map +7 -0
- package/browser/out/core/collectErrors.d.ts +36 -0
- package/browser/out/core/collectErrors.d.ts.map +1 -0
- package/browser/out/core/configSchema.d.ts +63 -0
- package/browser/out/core/configSchema.d.ts.map +1 -0
- package/browser/out/core/customCodeTags.d.ts +34 -0
- package/browser/out/core/customCodeTags.d.ts.map +1 -0
- package/browser/out/core/diagnostic.d.ts +24 -0
- package/browser/out/core/diagnostic.d.ts.map +1 -0
- package/browser/out/core/embeddedRegions.d.ts +12 -0
- package/browser/out/core/embeddedRegions.d.ts.map +1 -0
- package/browser/out/core/formatting/classifier.d.ts +68 -0
- package/browser/out/core/formatting/classifier.d.ts.map +1 -0
- package/browser/out/core/formatting/embedded.d.ts +19 -0
- package/browser/out/core/formatting/embedded.d.ts.map +1 -0
- package/browser/out/core/formatting/formatters.d.ts +85 -0
- package/browser/out/core/formatting/formatters.d.ts.map +1 -0
- package/browser/out/core/formatting/index.d.ts +44 -0
- package/browser/out/core/formatting/index.d.ts.map +1 -0
- package/browser/out/core/formatting/ir.d.ts +100 -0
- package/browser/out/core/formatting/ir.d.ts.map +1 -0
- package/browser/out/core/formatting/mergeOptions.d.ts +18 -0
- package/browser/out/core/formatting/mergeOptions.d.ts.map +1 -0
- package/browser/out/core/formatting/printer.d.ts +18 -0
- package/browser/out/core/formatting/printer.d.ts.map +1 -0
- package/browser/out/core/formatting/utils.d.ts +39 -0
- package/browser/out/core/formatting/utils.d.ts.map +1 -0
- package/browser/out/core/grammar.d.ts +3 -0
- package/browser/out/core/grammar.d.ts.map +1 -0
- package/browser/out/core/htmlBalanceChecker.d.ts +23 -0
- package/browser/out/core/htmlBalanceChecker.d.ts.map +1 -0
- package/browser/out/core/mustacheChecks.d.ts +24 -0
- package/browser/out/core/mustacheChecks.d.ts.map +1 -0
- package/browser/out/core/nodeHelpers.d.ts +54 -0
- package/browser/out/core/nodeHelpers.d.ts.map +1 -0
- package/browser/out/core/ruleMetadata.d.ts +12 -0
- package/browser/out/core/ruleMetadata.d.ts.map +1 -0
- package/browser/out/core/selectorMatcher.d.ts +74 -0
- package/browser/out/core/selectorMatcher.d.ts.map +1 -0
- package/cli/out/main.js +168 -122
- package/package.json +21 -3
- package/src/browser/browser.test.ts +207 -0
- package/src/browser/index.ts +128 -0
- package/src/browser/tsconfig.json +18 -0
- package/src/core/collectErrors.ts +233 -0
- package/src/core/configSchema.ts +273 -0
- package/src/core/customCodeTags.ts +159 -0
- package/src/core/diagnostic.ts +45 -0
- package/src/core/embeddedRegions.ts +70 -0
- package/src/core/formatting/classifier.ts +549 -0
- package/src/core/formatting/embedded.ts +56 -0
- package/src/core/formatting/formatters.ts +1272 -0
- package/src/core/formatting/index.ts +185 -0
- package/src/core/formatting/ir.ts +202 -0
- package/src/core/formatting/mergeOptions.ts +34 -0
- package/src/core/formatting/printer.ts +242 -0
- package/src/core/formatting/utils.ts +193 -0
- package/src/core/grammar.ts +2 -0
- package/src/core/htmlBalanceChecker.ts +382 -0
- package/src/core/mustacheChecks.ts +504 -0
- package/src/core/nodeHelpers.ts +126 -0
- package/src/core/ruleMetadata.ts +63 -0
- package/src/core/selectorMatcher.ts +719 -0
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://github.com/reteps/tree-sitter-htmlmustache/actions/workflows/lint.yml"><img src="https://img.shields.io/github/actions/workflow/status/reteps/tree-sitter-htmlmustache/lint.yml?logo=github&label=Lint" alt="Lint"></a>
|
|
13
13
|
<a href="https://github.com/reteps/tree-sitter-htmlmustache/actions/workflows/lsp.yml"><img src="https://img.shields.io/github/actions/workflow/status/reteps/tree-sitter-htmlmustache/lsp.yml?logo=github&label=LSP" alt="LSP"></a>
|
|
14
|
-
<a href="https://
|
|
14
|
+
<a href="https://open-vsx.org/extension/reteps/htmlmustache-lsp"><img src="https://img.shields.io/open-vsx/v/reteps/htmlmustache-lsp?logo=visualstudiocode&label=VS%20Code" alt="Open VSX"></a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
---
|
|
@@ -294,41 +294,57 @@ Each custom rule requires an `id`, `selector`, and `message`. The `severity` def
|
|
|
294
294
|
|
|
295
295
|
**Selector syntax:**
|
|
296
296
|
|
|
297
|
-
| Selector | Matches
|
|
298
|
-
| ----------------------------------------- |
|
|
299
|
-
| `div` | HTML elements by tag name
|
|
300
|
-
| `*` | Any HTML element
|
|
301
|
-
| `#main` | ID (shorthand for `[id="main"]`)
|
|
302
|
-
| `.panel` | Class (shorthand for `[class~="panel"]`)
|
|
303
|
-
| `div span` | Descendant (span anywhere inside div)
|
|
304
|
-
| `div > span` | Direct child
|
|
305
|
-
| `[style]` | Attribute presence
|
|
306
|
-
| `input[type=hidden]` | Attribute value (exact)
|
|
307
|
-
| `[src^="prefix/"]` | Attribute starts with
|
|
308
|
-
| `[href*="substring"]` | Attribute contains
|
|
309
|
-
| `[src$=".png"]` | Attribute ends with
|
|
310
|
-
| `[class~="warning"]` | Attribute contains whitespace-token
|
|
311
|
-
| `img:not([alt])` | Negated attribute / class / id
|
|
312
|
-
| `{{foo}}` | Escaped variable `{{foo}}`
|
|
313
|
-
| `{{data.foo}}` | Variable with a dotted path
|
|
314
|
-
| `{{{foo}}}` | Triple / unescaped variable
|
|
315
|
-
| `{{options.*}}` | Variable path prefix match
|
|
316
|
-
| `{{*.deprecated}}` | Variable path suffix match
|
|
317
|
-
| `{{*}}` | Any escaped variable
|
|
318
|
-
| `{{{*}}}` | Any triple
|
|
319
|
-
| `{{#items}}` | Section `{{#items}}...{{/items}}`
|
|
320
|
-
| `{{^items}}` | Inverted section `{{^items}}...{{/items}}`
|
|
321
|
-
| `{{#items}} > li` | Direct child inside a section
|
|
322
|
-
| `{{!TODO}}` | Comment with exact content
|
|
323
|
-
| `{{!*TODO*}}` | Comment containing "TODO"
|
|
324
|
-
| `{{>header}}` | Partial invocation
|
|
325
|
-
| `{{>legacy_*}}` | Partial name prefix
|
|
326
|
-
| `pl-multiple-choice:has({{foo}})` | Element containing a given variable
|
|
327
|
-
| `pl-multiple-choice:not(:has(pl-answer))` | Element missing a required descendant
|
|
328
|
-
| `div, span` | Comma-separated alternatives
|
|
297
|
+
| Selector | Matches |
|
|
298
|
+
| ----------------------------------------- | ------------------------------------------ |
|
|
299
|
+
| `div` | HTML elements by tag name |
|
|
300
|
+
| `*` | Any HTML element |
|
|
301
|
+
| `#main` | ID (shorthand for `[id="main"]`) |
|
|
302
|
+
| `.panel` | Class (shorthand for `[class~="panel"]`) |
|
|
303
|
+
| `div span` | Descendant (span anywhere inside div) |
|
|
304
|
+
| `div > span` | Direct child |
|
|
305
|
+
| `[style]` | Attribute presence |
|
|
306
|
+
| `input[type=hidden]` | Attribute value (exact) |
|
|
307
|
+
| `[src^="prefix/"]` | Attribute starts with |
|
|
308
|
+
| `[href*="substring"]` | Attribute contains |
|
|
309
|
+
| `[src$=".png"]` | Attribute ends with |
|
|
310
|
+
| `[class~="warning"]` | Attribute contains whitespace-token |
|
|
311
|
+
| `img:not([alt])` | Negated attribute / class / id |
|
|
312
|
+
| `{{foo}}` | Escaped variable `{{foo}}` |
|
|
313
|
+
| `{{data.foo}}` | Variable with a dotted path |
|
|
314
|
+
| `{{{foo}}}` | Triple / unescaped variable |
|
|
315
|
+
| `{{options.*}}` | Variable path prefix match |
|
|
316
|
+
| `{{*.deprecated}}` | Variable path suffix match |
|
|
317
|
+
| `{{*}}` | Any escaped variable |
|
|
318
|
+
| `{{{*}}}` | Any triple |
|
|
319
|
+
| `{{#items}}` | Section `{{#items}}...{{/items}}` |
|
|
320
|
+
| `{{^items}}` | Inverted section `{{^items}}...{{/items}}` |
|
|
321
|
+
| `{{#items}} > li` | Direct child inside a section |
|
|
322
|
+
| `{{!TODO}}` | Comment with exact content |
|
|
323
|
+
| `{{!*TODO*}}` | Comment containing "TODO" |
|
|
324
|
+
| `{{>header}}` | Partial invocation |
|
|
325
|
+
| `{{>legacy_*}}` | Partial name prefix |
|
|
326
|
+
| `pl-multiple-choice:has({{foo}})` | Element containing a given variable |
|
|
327
|
+
| `pl-multiple-choice:not(:has(pl-answer))` | Element missing a required descendant |
|
|
328
|
+
| `div, span` | Comma-separated alternatives |
|
|
329
|
+
| `:root` | The document root (the whole parse tree) |
|
|
330
|
+
| `:root:has(pl-answer-panel)` | Document contains a descendant anywhere |
|
|
331
|
+
| `:root:not(:has(pl-answer-panel))` | Document is missing a descendant anywhere |
|
|
332
|
+
| `:root > section` | Top-level element (direct child of root) |
|
|
329
333
|
|
|
330
334
|
The `>` (child) combinator is kind-transparent: `div > span` matches even if a Mustache section sits between them (e.g. `<div>{{#show}}<span>{{/show}}</div>`), and `{{#a}} > {{#b}}` matches across intervening HTML elements. `{{#foo}}` matches only positive sections — to target inverted sections use `{{^foo}}`.
|
|
331
335
|
|
|
336
|
+
**Document-scoped conditional rules.** Use `:root` with `:has(...)` / `:not(:has(...))` to express rules that depend on the overall document. Chained `:has(...)` acts as AND, so you can combine "contains X" and "missing Y" in one selector:
|
|
337
|
+
|
|
338
|
+
```jsonc
|
|
339
|
+
{
|
|
340
|
+
"id": "question-needs-answer-panel",
|
|
341
|
+
"selector": ":root:has(pl-question-panel):not(:has(pl-answer-panel))",
|
|
342
|
+
"message": "A question-panel document must also declare a pl-answer-panel.",
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
When `:root` matches, the diagnostic is reported at the start of the document (row 0, column 0) so the squiggle doesn't span the whole file. `:root` here is the tree-sitter fragment root, so it works on partial templates and fragments — unlike browser CSS, which anchors `:root` on `<html>`. Inside `:has(...)`, `:root` refers to the element being has-checked, not the document.
|
|
347
|
+
|
|
332
348
|
### Disabling Lint Rules
|
|
333
349
|
|
|
334
350
|
Disable a lint rule for an entire file with an inline comment:
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser entry point for `@reteps/tree-sitter-htmlmustache`.
|
|
3
|
+
*
|
|
4
|
+
* Exposes `createLinter({ locateWasm, prettier? })` returning a handle with
|
|
5
|
+
* `lint(source, config)` and `format(source, config, opts)`. Internally reuses
|
|
6
|
+
* the shared rule engine and formatter in `src/core/` — browser-safe, no fs.
|
|
7
|
+
*/
|
|
8
|
+
import type { PrettierLike } from '../core/formatting/embedded.js';
|
|
9
|
+
import type { Diagnostic } from '../core/diagnostic.js';
|
|
10
|
+
import type { HtmlMustacheConfig, RulesConfig, RuleSeverity, CustomRule as CustomRuleType } from '../core/configSchema.js';
|
|
11
|
+
import type { CustomCodeTagConfig } from '../core/customCodeTags.js';
|
|
12
|
+
export type Config = Omit<HtmlMustacheConfig, 'include' | 'exclude'>;
|
|
13
|
+
export type CustomRule = CustomRuleType;
|
|
14
|
+
export type CustomTag = CustomCodeTagConfig;
|
|
15
|
+
export type { RulesConfig, RuleSeverity, PrettierLike, Diagnostic };
|
|
16
|
+
export type LocateWasm = string | ((filename: string) => string);
|
|
17
|
+
export interface CreateLinterOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Locates the grammar WASM (`tree-sitter-htmlmustache.wasm`). If a string,
|
|
20
|
+
* treated as the URL for the grammar — web-tree-sitter's own
|
|
21
|
+
* `tree-sitter.wasm` will resolve via its default `locateFile`. Pass a
|
|
22
|
+
* callback to resolve both names explicitly.
|
|
23
|
+
*/
|
|
24
|
+
locateWasm: LocateWasm;
|
|
25
|
+
/** Default prettier used for embedded-region formatting. */
|
|
26
|
+
prettier?: PrettierLike;
|
|
27
|
+
}
|
|
28
|
+
export interface FormatOptions {
|
|
29
|
+
/** Override the factory-level prettier for this call. */
|
|
30
|
+
prettier?: PrettierLike;
|
|
31
|
+
}
|
|
32
|
+
export interface Linter {
|
|
33
|
+
lint(source: string, config?: Config): Diagnostic[];
|
|
34
|
+
format(source: string, config?: Config, opts?: FormatOptions): Promise<string>;
|
|
35
|
+
}
|
|
36
|
+
/** Default severities for every built-in rule. */
|
|
37
|
+
export declare const DEFAULT_CONFIG: Config;
|
|
38
|
+
/**
|
|
39
|
+
* Create a linter/formatter handle. Consumers should cache the result — each
|
|
40
|
+
* call reloads the grammar WASM.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createLinter(opts: CreateLinterOptions): Promise<Linter>;
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,IAAI,cAAc,EAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;AACrE,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,MAAM,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAAC;IACpD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAChF;AAED,kDAAkD;AAClD,eAAO,MAAM,cAAc,EAAE,MAAgD,CAAC;AAc9E;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiD7E"}
|