Skip to content

Commit a4a0d06

Browse files
committed
fix: fix attribute name starts with Jinja tag (fix #46)
1 parent ccace3f commit a4a0d06

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

markup_fmt/src/parser.rs

+36-11
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,13 @@ impl<'s> Parser<'s> {
645645
Language::Jinja => {
646646
self.skip_ws();
647647
let result = if matches!(self.chars.peek(), Some((_, '{'))) {
648-
self.parse_jinja_tag_or_block(None, &mut Parser::parse_attr)
648+
let mut chars = self.chars.clone();
649+
chars.next();
650+
if let Some((_, '{')) = chars.next() {
651+
self.parse_native_attr().map(Attribute::Native)
652+
} else {
653+
self.parse_jinja_tag_or_block(None, &mut Parser::parse_attr)
654+
}
649655
} else {
650656
self.parse_native_attr().map(Attribute::Native)
651657
};
@@ -663,13 +669,26 @@ impl<'s> Parser<'s> {
663669

664670
fn parse_attr_name(&mut self) -> PResult<&'s str> {
665671
if matches!(self.language, Language::Jinja | Language::Vento) {
666-
let Some((start, _)) = self
667-
.chars
668-
.next_if(|(_, c)| is_attr_name_char(*c) && *c != '{')
669-
else {
672+
let Some((start, mut end)) = (match self.chars.peek() {
673+
Some((i, '{')) => {
674+
let start = *i;
675+
let mut chars = self.chars.clone();
676+
chars.next();
677+
if let Some((_, '{')) = chars.next() {
678+
let end =
679+
start + self.parse_mustache_interpolation()?.0.len() + "{{}}".len() - 1;
680+
Some((start, end))
681+
} else {
682+
None
683+
}
684+
}
685+
Some((_, c)) if is_attr_name_char(*c) => {
686+
self.chars.next().map(|(start, _)| (start, start))
687+
}
688+
_ => None,
689+
}) else {
670690
return Err(self.emit_error(SyntaxErrorKind::ExpectAttrName));
671691
};
672-
let mut end = start;
673692

674693
while let Some((i, c)) = self.chars.peek() {
675694
if is_attr_name_char(*c) && *c != '{' {
@@ -679,11 +698,17 @@ impl<'s> Parser<'s> {
679698
let i = *i;
680699
let mut chars = self.chars.clone();
681700
chars.next();
682-
if chars.next_if(|(_, c)| *c != '%').is_some() {
683-
end = i;
684-
self.chars.next();
685-
} else {
686-
break;
701+
match chars.next() {
702+
Some((_, '%')) => {
703+
break;
704+
}
705+
Some((_, '{')) => {
706+
end += self.parse_mustache_interpolation()?.0.len() + "{{}}".len();
707+
}
708+
_ => {
709+
end = i;
710+
self.chars.next();
711+
}
687712
}
688713
} else {
689714
break;

markup_fmt/tests/fmt/jinja/attributes/tag-or-block-as-attr.jinja

+11
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,14 @@
8383
<li class="nav-internal-link--dropdown--separator">{{ subentry.name }}</li>
8484
{% endif %}
8585
{% endfor %}
86+
87+
<picture
88+
{% for key, val in attributes.items %}
89+
{{ key }}{{ key }}="{{ val }}"
90+
data-{{ key }}{{ key }}="{{ val }}"
91+
{{ key }}-{{ key }}="{{ val }}"
92+
data-{{ key }}-{{ key }}="{{ val }}"
93+
{{ key }}="{{ val }}"
94+
data-{{ key }}="{{ val }}"
95+
{% endfor %}
96+
></picture>

markup_fmt/tests/fmt/jinja/attributes/tag-or-block-as-attr.snap

+12
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,15 @@ source: markup_fmt/tests/fmt.rs
140140
<li class="nav-internal-link--dropdown--separator">{{ subentry.name }}</li>
141141
{% endif %}
142142
{% endfor %}
143+
144+
<picture
145+
{% for key, val in attributes.items %}
146+
{{ key }}{{ key }}="{{ val }}"
147+
data-{{ key }}{{ key }}="{{ val }}"
148+
{{ key }}-{{ key }}="{{ val }}"
149+
data-{{ key }}-{{ key }}="{{ val }}"
150+
{{ key }}="{{ val }}"
151+
data-{{ key }}="{{ val }}"
152+
{% endfor %}
153+
>
154+
</picture>

0 commit comments

Comments
 (0)