add translated string support

This commit is contained in:
danhanson committed 2026-09-06 05:28:53 -05:00
1 parent 451e38cad4
commit 9fc72cf891
6 files changed
+7956 -7501

No files matched your search

+13 -2
View File
@@ -30,6 +30,9 @@ function spaced(separator, keyword, ...args) {
return seq(separator, keyword, ...args);
}
/** Django's string constant, which takes any escape but a line break. */
const STRING = /"(?:[^"\\]|\\[^\n])*"|'(?:[^'\\]|\\[^\n])*'/;
const django = grammar({
name: "django",
extras: ($) => [/[ \t]/],
@@ -72,12 +75,20 @@ const django = grammar({
filter_expression: ($) =>
seq($.filter, repeat(seq(token.immediate("|"), $.filter))),
value: ($) => choice($.literal, $.variable_attribute),
literal: ($) => seq(choice($.number, $.string), $._after_literal),
literal: ($) =>
seq(choice($.number, $.string, $.translated_string), $._after_literal),
// digits, with single underscores allowed between them, as Python's
// int() and float() accept ("1_000") and Django's Variable relies on
number: ($) =>
/[-+]?(?:[0-9](?:_?[0-9])*(?:\.(?:[0-9](?:_?[0-9])*)?)?|\.[0-9](?:_?[0-9])*)(?:[eE][0-9](?:_?[0-9])*)?/,
string: ($) => /"(?:[^"\\]|\\[^\n])*"|'(?:[^'\\]|\\[^\n])*'/,
string: ($) => STRING,
/**
* A string to translate at render time. Django matches "_(" and ")" as
* part of the constant itself, so nothing may come between them and the
* string: "_( 'a' )" is a syntax error there, not a translated literal.
*/
translated_string: ($) =>
seq("_(", alias(token.immediate(STRING), $.string), token.immediate(")")),
attribute: ($) => /[a-zA-Z0-9][a-zA-Z0-9_]*(?:\.[a-zA-Z0-9][a-zA-Z0-9_]*)*/,
variable_attribute: ($) =>
seq($.identifier, optional(seq(token.immediate("."), $.attribute))),
+2
View File
@@ -34,6 +34,8 @@ variable: (identifier) @variable.parameter
("}}")
("#}")
("%}")
("_(")
(")")
(",")] @punctuation
(number) @number
+32
View File
@@ -127,6 +127,10 @@
{
"type": "SYMBOL",
"name": "string"
},
{
"type": "SYMBOL",
"name": "translated_string"
}
]
},
@@ -144,6 +148,34 @@
"type": "PATTERN",
"value": "\"(?:[^\"\\\\]|\\\\[^\\n])*\"|'(?:[^'\\\\]|\\\\[^\\n])*'"
},
"translated_string": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "_("
},
{
"type": "ALIAS",
"content": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "\"(?:[^\"\\\\]|\\\\[^\\n])*\"|'(?:[^'\\\\]|\\\\[^\\n])*'"
}
},
"named": true,
"value": "string"
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": ")"
}
}
]
},
"attribute": {
"type": "PATTERN",
"value": "[a-zA-Z0-9][a-zA-Z0-9_]*(?:\\.[a-zA-Z0-9][a-zA-Z0-9_]*)*"
+27
View File
@@ -657,6 +657,10 @@
{
"type": "string",
"named": true
},
{
"type": "translated_string",
"named": true
}
]
}
@@ -1018,6 +1022,21 @@
]
}
},
{
"type": "translated_string",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "string",
"named": true
}
]
}
},
{
"type": "url_block",
"named": true,
@@ -1230,6 +1249,10 @@
"type": "%}",
"named": false
},
{
"type": ")",
"named": false
},
{
"type": ",",
"named": false
@@ -1262,6 +1285,10 @@
"type": ">=",
"named": false
},
{
"type": "_(",
"named": false
},
{
"type": "add:",
"named": false
+7833 -7499
View File
File diff suppressed because it is too large. Load diff
+49
View File
@@ -274,3 +274,52 @@ Template Variable Attribute Beginning With Underscore
(ERROR)
==================
Template Variable Translated String
==================
{{ _("Hello") }}
---
(template
(content)
(template_variable
(filtered_value
(value
(literal
(translated_string
(string))))))
(content))
==================
Template Variable Translated String With Filter
==================
{{ _('Hello')|upper }}
---
(template
(content)
(template_variable
(filtered_value
(value
(literal
(translated_string
(string))))
(filter_expression
(filter))))
(content))
==================
Template Variable Translated String With Spaces
:error
==================
{{ _( "Hello" ) }}
---
(ERROR)