@markuplint/pug-parser 5.0.0-rc.2 → 5.0.0-rc.5
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/CHANGELOG.md +15 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/parser.d.ts +4 -29
- package/lib/parser.js +32 -35
- package/lib/pug-parser/index.d.ts +0 -9
- package/lib/pug-parser/index.js +6 -104
- package/lib/types.d.ts +0 -29
- package/lib/utils/get-offset-from-line-and-col.d.ts +1 -8
- package/lib/utils/get-offset-from-line-and-col.js +1 -8
- package/package.json +6 -6
- package/ARCHITECTURE.ja.md +0 -438
- package/ARCHITECTURE.md +0 -438
- package/SKILL.md +0 -118
- package/docs/maintenance.ja.md +0 -188
- package/docs/maintenance.md +0 -188
package/docs/maintenance.ja.md
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# メンテナンスガイド
|
|
2
|
-
|
|
3
|
-
## コマンド
|
|
4
|
-
|
|
5
|
-
| コマンド | 説明 |
|
|
6
|
-
| ------------------------------------------- | ---------------------- |
|
|
7
|
-
| `yarn build --scope @markuplint/pug-parser` | このパッケージをビルド |
|
|
8
|
-
| `yarn dev --scope @markuplint/pug-parser` | ウォッチモードでビルド |
|
|
9
|
-
| `yarn clean --scope @markuplint/pug-parser` | ビルド成果物を削除 |
|
|
10
|
-
| `yarn test --scope @markuplint/pug-parser` | テストを実行 |
|
|
11
|
-
|
|
12
|
-
## テスト
|
|
13
|
-
|
|
14
|
-
テストファイルは `*.spec.ts` の命名規則に従います:
|
|
15
|
-
|
|
16
|
-
| テストファイル | カバレッジ |
|
|
17
|
-
| ------------------------------------------------ | ---------------------------------------------------------------- |
|
|
18
|
-
| `src/index.spec.ts` | PugParser 統合テスト(Pug テンプレートのエンドツーエンドパース) |
|
|
19
|
-
| `src/pug-parser/index.spec.ts` | AST 最適化テスト(pugParse、optimizeAST) |
|
|
20
|
-
| `src/utils/get-offset-from-line-and-col.spec.ts` | オフセット計算ユーティリティのテスト |
|
|
21
|
-
|
|
22
|
-
主なテストパターンでは `nodeListToDebugMaps` を使用したスナップショット形式のアサーションを行います:
|
|
23
|
-
|
|
24
|
-
```ts
|
|
25
|
-
import { nodeListToDebugMaps } from '@markuplint/parser-utils';
|
|
26
|
-
import { parser } from '@markuplint/pug-parser';
|
|
27
|
-
|
|
28
|
-
const doc = parser.parse('div.foo#bar text content');
|
|
29
|
-
const debugMaps = nodeListToDebugMaps(doc.nodeList, true);
|
|
30
|
-
expect(debugMaps).toStrictEqual([
|
|
31
|
-
// 期待されるデバッグ出力
|
|
32
|
-
]);
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## レシピ
|
|
36
|
-
|
|
37
|
-
### 1. 新しい Pug AST ノードタイプの追加
|
|
38
|
-
|
|
39
|
-
1. `src/types.ts` を読み、新しい最適化済み型を追加:
|
|
40
|
-
```ts
|
|
41
|
-
export type ASTNewType = PugAST.NewType & AdditionalASTData;
|
|
42
|
-
```
|
|
43
|
-
2. 新しい型を `ASTNode` 共用体に追加
|
|
44
|
-
3. `src/pug-parser/index.ts` を読み、`optimizeAST()` に新しい `case` を追加:
|
|
45
|
-
```ts
|
|
46
|
-
case 'NewType': {
|
|
47
|
-
const block = optimizeAST(node.block, tokens, pug);
|
|
48
|
-
const newNode: ASTNewType = {
|
|
49
|
-
type: node.type,
|
|
50
|
-
raw,
|
|
51
|
-
offset,
|
|
52
|
-
endOffset,
|
|
53
|
-
line,
|
|
54
|
-
endLine,
|
|
55
|
-
column,
|
|
56
|
-
endColumn,
|
|
57
|
-
block,
|
|
58
|
-
filename: node.filename ?? null,
|
|
59
|
-
};
|
|
60
|
-
nodes.push(newNode);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
4. `src/parser.ts` を読み、`nodeize()` に新しい `case` を追加:
|
|
65
|
-
- HTML 的な要素の場合: `getNamespace()` と属性で `visitElement()` を使用
|
|
66
|
-
- Pug 固有の構文の場合: 子ノードで `visitPsBlock()` を使用
|
|
67
|
-
5. ビルド: `yarn build --scope @markuplint/pug-parser`
|
|
68
|
-
6. テスト: `yarn test --scope @markuplint/pug-parser`
|
|
69
|
-
|
|
70
|
-
### 2. 属性処理の変更
|
|
71
|
-
|
|
72
|
-
1. `src/parser.ts` を読む — `visitAttr()` メソッドには3つのパスがある:
|
|
73
|
-
- **ショートハンド**(`#` / `.`): `AttrState.BeforeValue` を使用し、`potentialName` を設定
|
|
74
|
-
- **通常**: `noQuoteValueType: 'script'` を使用
|
|
75
|
-
- **値パース**: `scriptParser()` で型検出(Numeric、Boolean、String、Template、dynamic)
|
|
76
|
-
2. 変更を行う:
|
|
77
|
-
- 新しいショートハンド構文の場合: 既存の `#`/`.` チェックの前に条件を追加
|
|
78
|
-
- 属性名変換の場合: `attr.name.raw.endsWith('!')` チェックの後に追加
|
|
79
|
-
- 値型検出の場合: `scriptParser()` 結果の switch を変更
|
|
80
|
-
3. `this.updateAttr()` でメタデータを設定: `potentialName`、`potentialValue`、`isDuplicatable`、`valueType`
|
|
81
|
-
4. ビルドとテスト: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
82
|
-
|
|
83
|
-
### 3. AST 最適化の更新
|
|
84
|
-
|
|
85
|
-
1. `src/pug-parser/index.ts` を読む — 最適化パイプライン:
|
|
86
|
-
- `pugParse()` — エントリーポイント: lex → parse → optimize
|
|
87
|
-
- `optimizeAST()` — 再帰的なノード強化
|
|
88
|
-
- `getOffsetsFromLines()` — 累積オフセットルックアップテーブル
|
|
89
|
-
- `getLocationFromToken()` — 行/列によるトークンマッチング
|
|
90
|
-
- `getAttrs()` — レキサートークンからの属性強化
|
|
91
|
-
- `getEndAttributeLocation()` — 属性を含むタグの終了位置
|
|
92
|
-
- `mergeTextNode()` — 連続テキストノードのマージ
|
|
93
|
-
- `getPipelessText()` — パイプレステキストブロックの検出
|
|
94
|
-
- `getRawTextAndLocationEnd()` — 複数行テキストの処理
|
|
95
|
-
- `optimizeASTOfConditionalNode()` — else-if/else チェーンの処理
|
|
96
|
-
2. 変更時の注意点:
|
|
97
|
-
- オフセットは `getOffsetsFromLines()` から `offsets[line - 2]` を使用して計算する必要がある
|
|
98
|
-
- 終了位置は `getLocationFromToken()` でマッチするレキサートークンから取得
|
|
99
|
-
- `raw` は元のソースからスライスする必要がある: `pug.slice(offset, endOffset)`
|
|
100
|
-
- `structuredClone()` によるトークンのクローンが必要 — パーサーはトークン配列を変更する
|
|
101
|
-
3. ビルドとテスト: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
102
|
-
|
|
103
|
-
### 4. インライン HTML 処理の変更
|
|
104
|
-
|
|
105
|
-
1. `src/parser.ts` を読む — `nodeize()` の `Text` ケース:
|
|
106
|
-
- `<` や `#[` を含むテキストは `HtmlInPugParser` でパースされる
|
|
107
|
-
- `#ps:tag-interpolation` ノードは `PugParser` で再帰的にパースされる
|
|
108
|
-
2. タグ補間構文を変更するには:
|
|
109
|
-
- `HtmlInPugParser` コンストラクタの `ignoreTags` を変更
|
|
110
|
-
- `Text` ケースの `#ps:tag-interpolation` 検出を更新
|
|
111
|
-
- `#[` プレフィックスと `]` サフィックスの除去のオフセット計算を更新
|
|
112
|
-
3. インライン HTML の動作を変更するには:
|
|
113
|
-
- `HtmlInPugParser` クラスを変更(`HtmlParser` を拡張)
|
|
114
|
-
- `offsetOffset`、`offsetLine`、`offsetColumn` コンテキストが正しく渡される必要がある
|
|
115
|
-
4. ビルドとテスト: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
116
|
-
|
|
117
|
-
### 5. useOffset インデントフィルタリングの変更
|
|
118
|
-
|
|
119
|
-
1. `src/pug-parser/index.ts` を読む — `pugParse()` 関数
|
|
120
|
-
2. `useOffset` フラグは、ゼロ以外のオフセットでサブテンプレートをパースする際に `indent` と `outdent` トークンをフィルタリングする
|
|
121
|
-
3. 変更するには:
|
|
122
|
-
- `if (useOffset)` ブロック内のフィルタ条件を変更
|
|
123
|
-
- サブテンプレートコンテキストで他のトークンタイプもフィルタリングが必要かを検討
|
|
124
|
-
4. ビルドとテスト: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
125
|
-
|
|
126
|
-
## トラブルシューティング
|
|
127
|
-
|
|
128
|
-
### Pug AST ノードのオフセットがおかしい
|
|
129
|
-
|
|
130
|
-
**症状:** Pug ノードの `offset`、`endOffset`、`endLine`、`endColumn` が markuplint AST 内で不正。
|
|
131
|
-
|
|
132
|
-
**原因:** `optimizeAST()` 関数がオフセットを誤って計算しているか、マッチするレキサートークンが不正。
|
|
133
|
-
|
|
134
|
-
**解決策:**
|
|
135
|
-
|
|
136
|
-
1. `getOffsetsFromLines()` を確認 — 入力に対して累積オフセットテーブルが正しいことを検証
|
|
137
|
-
2. `getLocationFromToken()` を確認 — 行/列で正しいトークンがマッチし、`tokenType` フィルタリングが正しいことを確認
|
|
138
|
-
3. 属性付きタグの場合、`getEndAttributeLocation()` を確認 — 正しいトークンで停止していることを検証
|
|
139
|
-
4. デバッグログを追加: 関連する `optimizeAST()` ケースで `console.log(JSON.stringify(node, null, 2))`
|
|
140
|
-
|
|
141
|
-
### タグ補間がパースされない
|
|
142
|
-
|
|
143
|
-
**症状:** `#[tag content]` が markuplint ノードに展開されず、生テキストとして表示される。
|
|
144
|
-
|
|
145
|
-
**原因:** テキストノードが `HtmlInPugParser` パスに到達していないか、`#ps:tag-interpolation` の検出が失敗している。
|
|
146
|
-
|
|
147
|
-
**解決策:**
|
|
148
|
-
|
|
149
|
-
1. `nodeize()` の `Text` ケースを確認 — `originNode.raw.includes('#[')` が `true` と評価されることを確認
|
|
150
|
-
2. `HtmlInPugParser` を確認 — `ignoreTags` が `#[...]` を正しくマスクしていることを検証
|
|
151
|
-
3. `#ps:tag-interpolation` の検出を確認 — `node.nodeName === '#ps:tag-interpolation'` であることを確認
|
|
152
|
-
4. 再帰的な `PugParser` 呼び出しを確認 — オフセットコンテキスト(`offsetOffset`、`offsetLine`、`offsetColumn`)が正しく計算されていることを検証
|
|
153
|
-
|
|
154
|
-
### 複雑な式の属性パースが失敗する
|
|
155
|
-
|
|
156
|
-
**症状:** 複雑な JavaScript 値を持つ Pug 属性(例: `data-value=obj.prop + 1`)がパースエラーまたは不正な AST を引き起こす。
|
|
157
|
-
|
|
158
|
-
**原因:** 複数トークンの式に対して `scriptParser()` の結果が正しく処理されていない。
|
|
159
|
-
|
|
160
|
-
**解決策:**
|
|
161
|
-
|
|
162
|
-
1. `visitAttr()` メソッドを確認 — 最後の `return` ブロックが複数トークンの式を `isDynamicValue: true, valueType: 'code'` として処理している
|
|
163
|
-
2. `@markuplint/parser-utils` の `scriptParser()` を確認 — 値の式が正しくトークン化されていることを検証
|
|
164
|
-
3. 単一トークンの式の場合、`switch (token.type)` がトークンタイプを正しく処理しているか検証
|
|
165
|
-
|
|
166
|
-
### ショートハンド属性の potentialName がおかしい
|
|
167
|
-
|
|
168
|
-
**症状:** `#my-id` や `.my-class` が間違った `potentialName` を持つ属性を生成する。
|
|
169
|
-
|
|
170
|
-
**原因:** ショートハンド検出または `endOffset` の再計算が誤っている。
|
|
171
|
-
|
|
172
|
-
**解決策:**
|
|
173
|
-
|
|
174
|
-
1. `visitAttr()` の `#`/`.` ブランチを確認 — `potentialName` が `#` の場合 `'id'`、`.` の場合 `'class'` に設定されていることを確認
|
|
175
|
-
2. `nodeize()` の Tag ケースで `endOffset` の再計算を確認 — ショートハンド属性では `attr.offset === attr.endOffset` が true であり、`endOffset` は `attr.offset + attr.val.length - 1` であるべき
|
|
176
|
-
3. Pug AST の `val` 値を検証 — `#my-id` の場合、`val` は `"'my-id'"`(前後にクォート付き)であるべき
|
|
177
|
-
|
|
178
|
-
### パイプレステキストが検出されない
|
|
179
|
-
|
|
180
|
-
**症状:** `.` 付きタグの後のインデントされたテキストがパイプレステキストとして扱われない。
|
|
181
|
-
|
|
182
|
-
**原因:** `getPipelessText()` 関数が `start-pipeless-text` / `end-pipeless-text` トークンを見つけられないか、行範囲チェックが失敗している。
|
|
183
|
-
|
|
184
|
-
**解決策:**
|
|
185
|
-
|
|
186
|
-
1. レキサー出力を確認 — `start-pipeless-text` と `end-pipeless-text` トークンが存在することを検証
|
|
187
|
-
2. 行範囲を確認: `startPipelessText.loc.start.line < node.line && node.line < endPipelessText.loc.start.line`
|
|
188
|
-
3. トークンが存在するが範囲が誤っている場合、pug-lexer バージョンの問題の可能性がある
|
package/docs/maintenance.md
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# Maintenance Guide
|
|
2
|
-
|
|
3
|
-
## Commands
|
|
4
|
-
|
|
5
|
-
| Command | Description |
|
|
6
|
-
| ------------------------------------------- | ---------------------- |
|
|
7
|
-
| `yarn build --scope @markuplint/pug-parser` | Build this package |
|
|
8
|
-
| `yarn dev --scope @markuplint/pug-parser` | Watch mode build |
|
|
9
|
-
| `yarn clean --scope @markuplint/pug-parser` | Remove build artifacts |
|
|
10
|
-
| `yarn test --scope @markuplint/pug-parser` | Run tests |
|
|
11
|
-
|
|
12
|
-
## Testing
|
|
13
|
-
|
|
14
|
-
Test files follow the `*.spec.ts` naming convention:
|
|
15
|
-
|
|
16
|
-
| Test File | Coverage |
|
|
17
|
-
| ------------------------------------------------ | -------------------------------------------------------------- |
|
|
18
|
-
| `src/index.spec.ts` | PugParser integration tests (parsing Pug templates end-to-end) |
|
|
19
|
-
| `src/pug-parser/index.spec.ts` | AST optimization tests (pugParse, optimizeAST) |
|
|
20
|
-
| `src/utils/get-offset-from-line-and-col.spec.ts` | Offset calculation utility tests |
|
|
21
|
-
|
|
22
|
-
The primary testing pattern uses `nodeListToDebugMaps` for snapshot-style assertions:
|
|
23
|
-
|
|
24
|
-
```ts
|
|
25
|
-
import { nodeListToDebugMaps } from '@markuplint/parser-utils';
|
|
26
|
-
import { parser } from '@markuplint/pug-parser';
|
|
27
|
-
|
|
28
|
-
const doc = parser.parse('div.foo#bar text content');
|
|
29
|
-
const debugMaps = nodeListToDebugMaps(doc.nodeList, true);
|
|
30
|
-
expect(debugMaps).toStrictEqual([
|
|
31
|
-
// expected debug output
|
|
32
|
-
]);
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Recipes
|
|
36
|
-
|
|
37
|
-
### 1. Adding a New Pug AST Node Type
|
|
38
|
-
|
|
39
|
-
1. Read `src/types.ts` — add the new optimized type:
|
|
40
|
-
```ts
|
|
41
|
-
export type ASTNewType = PugAST.NewType & AdditionalASTData;
|
|
42
|
-
```
|
|
43
|
-
2. Add the new type to the `ASTNode` union
|
|
44
|
-
3. Read `src/pug-parser/index.ts` — add a new `case` in `optimizeAST()`:
|
|
45
|
-
```ts
|
|
46
|
-
case 'NewType': {
|
|
47
|
-
const block = optimizeAST(node.block, tokens, pug);
|
|
48
|
-
const newNode: ASTNewType = {
|
|
49
|
-
type: node.type,
|
|
50
|
-
raw,
|
|
51
|
-
offset,
|
|
52
|
-
endOffset,
|
|
53
|
-
line,
|
|
54
|
-
endLine,
|
|
55
|
-
column,
|
|
56
|
-
endColumn,
|
|
57
|
-
block,
|
|
58
|
-
filename: node.filename ?? null,
|
|
59
|
-
};
|
|
60
|
-
nodes.push(newNode);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
4. Read `src/parser.ts` — add a new `case` in `nodeize()`:
|
|
65
|
-
- For HTML-like elements: use `visitElement()` with `getNamespace()` and attributes
|
|
66
|
-
- For Pug-specific constructs: use `visitPsBlock()` with child nodes
|
|
67
|
-
5. Build: `yarn build --scope @markuplint/pug-parser`
|
|
68
|
-
6. Test: `yarn test --scope @markuplint/pug-parser`
|
|
69
|
-
|
|
70
|
-
### 2. Modifying Attribute Processing
|
|
71
|
-
|
|
72
|
-
1. Read `src/parser.ts` — the `visitAttr()` method has three paths:
|
|
73
|
-
- **Shorthand** (`#` / `.`): Uses `AttrState.BeforeValue`, sets `potentialName`
|
|
74
|
-
- **Regular**: Uses `noQuoteValueType: 'script'`
|
|
75
|
-
- **Value parsing**: Uses `scriptParser()` for type detection (Numeric, Boolean, String, Template, dynamic)
|
|
76
|
-
2. Make the change:
|
|
77
|
-
- For new shorthand syntax: add a condition before the existing `#`/`.` check
|
|
78
|
-
- For attribute name transforms: add after the `attr.name.raw.endsWith('!')` check
|
|
79
|
-
- For value type detection: modify the `scriptParser()` result switch
|
|
80
|
-
3. Use `this.updateAttr()` to set metadata: `potentialName`, `potentialValue`, `isDuplicatable`, `valueType`
|
|
81
|
-
4. Build and test: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
82
|
-
|
|
83
|
-
### 3. Updating AST Optimization
|
|
84
|
-
|
|
85
|
-
1. Read `src/pug-parser/index.ts` — the optimization pipeline:
|
|
86
|
-
- `pugParse()` — entry point: lex → parse → optimize
|
|
87
|
-
- `optimizeAST()` — recursive node enrichment
|
|
88
|
-
- `getOffsetsFromLines()` — cumulative offset lookup table
|
|
89
|
-
- `getLocationFromToken()` — token matching by line/column
|
|
90
|
-
- `getAttrs()` — attribute enrichment from lexer tokens
|
|
91
|
-
- `getEndAttributeLocation()` — tag end position including attributes
|
|
92
|
-
- `mergeTextNode()` — consecutive text node merging
|
|
93
|
-
- `getPipelessText()` — pipeless text block detection
|
|
94
|
-
- `getRawTextAndLocationEnd()` — multi-line text handling
|
|
95
|
-
- `optimizeASTOfConditionalNode()` — else-if/else chain processing
|
|
96
|
-
2. Make the change, paying attention to:
|
|
97
|
-
- Offsets must be computed from `getOffsetsFromLines()` using `offsets[line - 2]`
|
|
98
|
-
- End positions come from matching lexer tokens via `getLocationFromToken()`
|
|
99
|
-
- `raw` must be sliced from the original source: `pug.slice(offset, endOffset)`
|
|
100
|
-
- Token cloning via `structuredClone()` is required — the parser mutates the token array
|
|
101
|
-
3. Build and test: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
102
|
-
|
|
103
|
-
### 4. Modifying Inline HTML Handling
|
|
104
|
-
|
|
105
|
-
1. Read `src/parser.ts` — the `Text` case in `nodeize()`:
|
|
106
|
-
- Text with `<` or `#[` is parsed through `HtmlInPugParser`
|
|
107
|
-
- `#ps:tag-interpolation` nodes are recursively parsed by `PugParser`
|
|
108
|
-
2. To change tag interpolation syntax:
|
|
109
|
-
- Modify the `ignoreTags` in `HtmlInPugParser` constructor
|
|
110
|
-
- Update the `#ps:tag-interpolation` detection in the `Text` case
|
|
111
|
-
- Update the offset calculations for `#[` prefix and `]` suffix stripping
|
|
112
|
-
3. To change inline HTML behavior:
|
|
113
|
-
- Modify the `HtmlInPugParser` class (extends `HtmlParser`)
|
|
114
|
-
- The `offsetOffset`, `offsetLine`, `offsetColumn` context must be passed correctly
|
|
115
|
-
4. Build and test: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
116
|
-
|
|
117
|
-
### 5. Modifying the useOffset Indent Filtering
|
|
118
|
-
|
|
119
|
-
1. Read `src/pug-parser/index.ts` — the `pugParse()` function
|
|
120
|
-
2. The `useOffset` flag filters `indent` and `outdent` tokens when parsing sub-templates at non-zero offsets
|
|
121
|
-
3. To modify:
|
|
122
|
-
- Change the filter condition in the `if (useOffset)` block
|
|
123
|
-
- Consider whether other token types need filtering for the sub-template context
|
|
124
|
-
4. Build and test: `yarn build --scope @markuplint/pug-parser && yarn test --scope @markuplint/pug-parser`
|
|
125
|
-
|
|
126
|
-
## Troubleshooting
|
|
127
|
-
|
|
128
|
-
### Pug AST node has wrong offsets
|
|
129
|
-
|
|
130
|
-
**Symptom:** A Pug node's `offset`, `endOffset`, `endLine`, or `endColumn` is incorrect in the markuplint AST.
|
|
131
|
-
|
|
132
|
-
**Cause:** The `optimizeAST()` function is computing wrong offsets, or the matching lexer token is incorrect.
|
|
133
|
-
|
|
134
|
-
**Solution:**
|
|
135
|
-
|
|
136
|
-
1. Check `getOffsetsFromLines()` — verify the cumulative offset table is correct for the input
|
|
137
|
-
2. Check `getLocationFromToken()` — ensure the correct token is matched by line/column, and that `tokenType` filtering is correct
|
|
138
|
-
3. For tags with attributes, check `getEndAttributeLocation()` — verify it stops at the right token
|
|
139
|
-
4. Add debug logging: `console.log(JSON.stringify(node, null, 2))` in the relevant `optimizeAST()` case
|
|
140
|
-
|
|
141
|
-
### Tag interpolation is not parsed
|
|
142
|
-
|
|
143
|
-
**Symptom:** `#[tag content]` appears as raw text instead of being expanded into markuplint nodes.
|
|
144
|
-
|
|
145
|
-
**Cause:** The text node is not reaching the `HtmlInPugParser` path, or the `#ps:tag-interpolation` detection is failing.
|
|
146
|
-
|
|
147
|
-
**Solution:**
|
|
148
|
-
|
|
149
|
-
1. Check the `Text` case in `nodeize()` — ensure `originNode.raw.includes('#[')` evaluates to `true`
|
|
150
|
-
2. Check the `HtmlInPugParser` — verify `ignoreTags` correctly masks `#[...]`
|
|
151
|
-
3. Check the `#ps:tag-interpolation` detection — ensure `node.nodeName === '#ps:tag-interpolation'`
|
|
152
|
-
4. Check the recursive `PugParser` call — verify offset context (`offsetOffset`, `offsetLine`, `offsetColumn`) is computed correctly
|
|
153
|
-
|
|
154
|
-
### Attribute parsing fails for complex expressions
|
|
155
|
-
|
|
156
|
-
**Symptom:** A Pug attribute with a complex JavaScript value (e.g., `data-value=obj.prop + 1`) causes a parse error or incorrect AST.
|
|
157
|
-
|
|
158
|
-
**Cause:** The `scriptParser()` result is not being handled correctly for multi-token expressions.
|
|
159
|
-
|
|
160
|
-
**Solution:**
|
|
161
|
-
|
|
162
|
-
1. Check the `visitAttr()` method — the final `return` block handles multi-token expressions as `isDynamicValue: true, valueType: 'code'`
|
|
163
|
-
2. Check `scriptParser()` from `@markuplint/parser-utils` — verify it correctly tokenizes the value expression
|
|
164
|
-
3. For single-token expressions, verify the `switch (token.type)` handles the token type correctly
|
|
165
|
-
|
|
166
|
-
### Shorthand attribute has wrong potentialName
|
|
167
|
-
|
|
168
|
-
**Symptom:** `#my-id` or `.my-class` produces an attribute with the wrong `potentialName`.
|
|
169
|
-
|
|
170
|
-
**Cause:** The shorthand detection or `endOffset` recalculation is wrong.
|
|
171
|
-
|
|
172
|
-
**Solution:**
|
|
173
|
-
|
|
174
|
-
1. Check the `#`/`.` branch in `visitAttr()` — ensure `potentialName` is set to `'id'` for `#` and `'class'` for `.`
|
|
175
|
-
2. Check the `endOffset` recalculation in `nodeize()` Tag case — for shorthand attributes, `attr.offset === attr.endOffset` must be true, and `endOffset` should be `attr.offset + attr.val.length - 1`
|
|
176
|
-
3. Verify the `val` value from the Pug AST — for `#my-id`, `val` should be `"'my-id'"` (with surrounding quotes)
|
|
177
|
-
|
|
178
|
-
### Pipeless text not detected
|
|
179
|
-
|
|
180
|
-
**Symptom:** Indented text after a tag with `.` is not treated as pipeless text.
|
|
181
|
-
|
|
182
|
-
**Cause:** The `getPipelessText()` function is not finding `start-pipeless-text` / `end-pipeless-text` tokens, or the line range check is failing.
|
|
183
|
-
|
|
184
|
-
**Solution:**
|
|
185
|
-
|
|
186
|
-
1. Check the lexer output — verify that `start-pipeless-text` and `end-pipeless-text` tokens exist
|
|
187
|
-
2. Check the line range: `startPipelessText.loc.start.line < node.line && node.line < endPipelessText.loc.start.line`
|
|
188
|
-
3. If the tokens exist but the range is wrong, the issue may be in the pug-lexer version
|