Skip to content

Commit ea71012

Browse files
Fix conflicts in attribute/keyword parsing
1 parent 8873e3d commit ea71012

File tree

9 files changed

+10317
-23695
lines changed

9 files changed

+10317
-23695
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "tree-sitter-htmldjango"
33
description = "htmldjango grammar for the tree-sitter parsing library"
4-
version = "0.1.1"
4+
version = "1.0.0"
55
keywords = ["incremental", "parsing", "htmldjango"]
66
categories = ["parsing", "text-editors"]
77
repository = "https://github.com/interdependence/tree-sitter-htmldjango"

grammar.js

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
module.exports = grammar({
22
name: "htmldjango",
33

4-
// Handle whitespace explicitly
5-
extras: $ => [],
4+
word: $ => $._identifier,
65

76
rules: {
87
template: $ => repeat(
@@ -13,16 +12,39 @@ module.exports = grammar({
1312
$._expression,
1413
$._statement,
1514
$._comment,
16-
$.content,
17-
/\s+/
15+
$.content
1816
),
1917

2018
// General rules
21-
keyword: $ => choice("on", "off", "with", "as", "silent", "only", "from", "random", "by"),
19+
keyword: $ => token(seq(
20+
choice(
21+
"on",
22+
"off",
23+
"with",
24+
"as",
25+
"silent",
26+
"only",
27+
"from",
28+
"random",
29+
"by"
30+
),
31+
/\s/
32+
)),
33+
keyword_operator: $ => token(seq(
34+
choice(
35+
"and",
36+
"or",
37+
"not",
38+
"in",
39+
"not in",
40+
"is",
41+
"is not"
42+
),
43+
/\s/
44+
)),
2245
operator: $ => choice("==", "!=", "<", ">", "<=", ">="),
23-
keyword_operator: $ => choice("and", "or", "not", "in", "not in", "is", "is not"),
24-
number: $ => repeat1(/[0-9]/),
25-
boolean: $ => choice("True", "False"),
46+
number: $ => /[0-9]+/,
47+
boolean: $ => token(seq(choice("True", "False"), /\s/)),
2648
string: $ => seq(
2749
choice(
2850
seq("'", repeat(/[^']/), "'"),
@@ -31,24 +53,23 @@ module.exports = grammar({
3153
repeat(seq("|", $.filter))
3254
),
3355

34-
_word: $ => repeat1(/[A-Za-z0-9_]/),
35-
_ws: $ => repeat1(" "),
56+
_identifier: $ => /\w+/,
3657

3758
// Expressions
38-
_expression: $ => seq("{{", optional($._ws), $.variable, optional($._ws), "}}"),
59+
_expression: $ => seq("{{", $.variable, "}}"),
3960

4061
variable: $ => seq($.variable_name, repeat(seq("|", $.filter))),
4162
// Django variables cannot start with an "_", can contain one or more words separated by a "."
42-
variable_name: $ => seq(repeat1(/[A-Za-z]/), optional($._word), repeat(seq(".", $._word))),
43-
63+
variable_name: $ => /[a-zA-Z](\w+)?((\.?\w)+)?/,
64+
4465
filter: $ => seq($.filter_name, optional(seq(":", choice($.filter_argument, $._quoted_filter_argument)))),
45-
filter_name: $ => $._word,
46-
filter_argument: $ => seq($._word, repeat(seq(".", $._word))),
66+
filter_name: $ => $._identifier,
67+
filter_argument: $ => seq($._identifier, repeat(seq(".", $._identifier))),
4768
_quoted_filter_argument: $ => choice(
4869
seq("'", alias(repeat(/[^']/), $.filter_argument), "'"),
4970
seq('"', alias(repeat(/[^"]/), $.filter_argument), '"')
5071
),
51-
72+
5273
// Statements
5374
// unpaired type {% tag %}
5475
// paired type {% tag %}..{% endtag %}
@@ -57,8 +78,7 @@ module.exports = grammar({
5778
alias($.if_statement, $.paired_statement),
5879
alias($.for_statement, $.paired_statement),
5980
alias($.filter_statement, $.paired_statement),
60-
$.unpaired_statement,
61-
$.detatched_end_statement
81+
$.unpaired_statement
6282
),
6383

6484
paired_statement: $ => {
@@ -73,13 +93,13 @@ module.exports = grammar({
7393
];
7494

7595
return choice(...tag_names.map((tag_name) => seq(
76-
"{%", $._ws, alias(tag_name + " ", $.tag_name), optional($._ws), repeat($._attribute), "%}",
96+
"{%", alias(tag_name, $.tag_name), repeat($._attribute), "%}",
7797
repeat($._node),
78-
"{%", $._ws, "end", alias(tag_name + " ", $.tag_name), optional($._ws), repeat($._attribute), alias("%}", $.end_paired_statement))));
98+
"{%", alias("end" + tag_name, $.tag_name), repeat($._attribute), alias("%}", $.end_paired_statement))));
7999
},
80100

81101
if_statement: $ => seq(
82-
"{%", $._ws, alias("if ", $.tag_name), optional($._ws), repeat($._attribute), "%}",
102+
"{%", alias("if", $.tag_name), repeat($._attribute), "%}",
83103
repeat($._node),
84104
repeat(prec.left(seq(
85105
alias($.elif_statement, $.branch_statement),
@@ -89,30 +109,28 @@ module.exports = grammar({
89109
alias($.else_statement, $.branch_statement),
90110
repeat($._node),
91111
)),
92-
"{%", $._ws, "end", alias("if ", $.tag_name), optional($._ws), alias("%}", $.end_paired_statement)
112+
"{%", alias("endif", $.tag_name), alias("%}", $.end_paired_statement)
93113
),
94-
elif_statement: $ => seq("{%", $._ws, alias("elif ", $.tag_name), optional($._ws), repeat($._attribute), "%}"),
95-
else_statement: $ => seq("{%", $._ws, alias("else ", $.tag_name), optional($._ws), "%}"),
114+
elif_statement: $ => seq("{%", alias("elif", $.tag_name), repeat($._attribute), "%}"),
115+
else_statement: $ => seq("{%", alias("else", $.tag_name), "%}"),
96116

97117
for_statement: $ => seq(
98-
"{%", $._ws, alias("for ", $.tag_name), optional($._ws), repeat($._attribute), "%}",
118+
"{%", alias("for", $.tag_name), repeat($._attribute), "%}",
99119
repeat($._node),
100120
optional(seq(
101121
alias($.empty_statement, $.branch_statement),
102122
repeat($._node),
103123
)),
104-
"{%", $._ws, "end", alias("for ", $.tag_name), optional($._ws), alias("%}", $.end_paired_statement)
124+
"{%", alias("endfor", $.tag_name), alias("%}", $.end_paired_statement)
105125
),
106-
empty_statement: $ => seq("{%", $._ws, alias("empty ", $.tag_name), optional($._ws), repeat($._attribute), "%}"),
126+
empty_statement: $ => seq("{%", alias("empty", $.tag_name), repeat($._attribute), "%}"),
107127

108128
filter_statement: $ => seq(
109-
"{%", $._ws, alias("filter ", $.tag_name), optional($._ws), $.filter, repeat(seq("|", $.filter)), $._ws, "%}",
129+
"{%", alias("filter", $.tag_name), $.filter, repeat(seq("|", $.filter)), "%}",
110130
repeat($._node),
111-
"{%", $._ws, "end", alias("filter ", $.tag_name), optional($._ws), alias("%}", $.end_paired_statement)
131+
"{%", alias("endfilter", $.tag_name), alias("%}", $.end_paired_statement)
112132
),
113-
114-
unpaired_statement: $ => seq("{%", $._ws, alias($._word, $.tag_name), $._ws, repeat($._attribute), "%}"),
115-
detatched_end_statement: $ => seq("{%", $._ws, "end", alias($._word, $.tag_name), $._ws, repeat($._attribute), "%}"),
133+
unpaired_statement: $ => seq("{%", alias($._identifier, $.tag_name), repeat($._attribute), "%}"),
116134

117135
_attribute: $ => seq(
118136
choice(
@@ -124,11 +142,7 @@ module.exports = grammar({
124142
$.string,
125143
$.variable
126144
),
127-
choice(
128-
$._ws,
129-
seq(optional($._ws), ",", optional($._ws)),
130-
seq(optional($._ws), "=", optional($._ws))
131-
)
145+
optional(choice(",", "="))
132146
),
133147

134148
// Comments
@@ -140,10 +154,10 @@ module.exports = grammar({
140154
),
141155
unpaired_comment: $ => seq("{#", repeat(/.|\s/), repeat(seq(alias($.unpaired_comment, ""), repeat(/.|\s/))), "#}"),
142156
paired_comment: $ => seq(
143-
alias("{%", ""), $._ws, "comment", optional(seq($._ws, $._word)), $._ws, alias("%}", ""),
157+
alias("{%", ""), "comment", optional($._identifier), alias("%}", ""),
144158
repeat(/.|\s/),
145159
repeat(seq(alias($.paired_comment, ""), repeat(/.|\s/))),
146-
alias("{%", ""), $._ws, "endcomment", $._ws, alias("%}", "")
160+
alias("{%", ""), "endcomment", alias("%}", "")
147161
),
148162

149163
// All other content

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tree-sitter-htmldjango",
3-
"version": "0.1.1",
3+
"version": "1.0.0",
44
"description": "A tree-sitter grammar for the Django template language",
55
"main": "bindings/node",
66
"scripts": {

queries/highlights.scm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
] @tag
1313

1414
[
15-
"end"
1615
(tag_name)
1716
] @function
1817

0 commit comments

Comments
 (0)