Skip to content

Commit

Permalink
attr: fix multi-line comments in attributes
Browse files Browse the repository at this point in the history
fixes #74

currently only works for inline attrs as multi-line block attributes are
not implemented atm
  • Loading branch information
hellux committed Dec 14, 2024
1 parent 27a3a47 commit 27c7191
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,25 @@ impl<'s> AttributeValue<'s> {
if s.is_empty() {
return;
}
if !self.raw.is_empty() {
self.extend_raw(" ");
}
self.extend_raw(s);
}

fn extend_raw(&mut self, s: &'s str) {
match &mut self.raw {
CowStr::Borrowed(prev) => {
if prev.is_empty() {
*prev = s;
} else {
self.raw = format!("{} {}", prev, s).into();
self.raw = format!("{}{}", prev, s).into();
}
}
CowStr::Owned(ref mut prev) => {
if prev.is_empty() {
self.raw = s.into();
} else {
prev.push(' ');
prev.push_str(s);
}
}
Expand Down Expand Up @@ -765,12 +771,20 @@ impl<'s> Parser<'s> {
Key => self
.attrs
.push((AttributeKind::Pair { key: content }, "".into())),
Value | ValueQuoted | ValueContinued | Comment => {
Value | ValueQuoted | ValueContinued => {
let last = self.attrs.len() - 1;
self.attrs.0[last]
.1
.extend(&content[usize::from(matches!(st, ValueQuoted))..]);
}
Comment | CommentNewline => {
let last = self.attrs.len() - 1;
self.attrs.0[last].1.extend_raw(if matches!(st, Comment) {
content
} else {
"\n"
});
}
CommentFirst => self.attrs.push((AttributeKind::Comment, "".into())),
_ => {}
}
Expand Down Expand Up @@ -801,6 +815,7 @@ enum State {
Whitespace,
CommentFirst,
Comment,
CommentNewline,
ClassFirst,
Class,
IdentifierFirst,
Expand Down Expand Up @@ -832,9 +847,10 @@ impl State {
c if c.is_ascii_whitespace() => Whitespace,
_ => Invalid,
},
CommentFirst | Comment if c == b'%' => Whitespace,
CommentFirst | Comment if c == b'}' => Done,
CommentFirst | Comment => Comment,
CommentFirst | Comment | CommentNewline if c == b'%' => Whitespace,
CommentFirst | Comment | CommentNewline if c == b'}' => Done,
CommentFirst | Comment | CommentNewline if c == b'\n' => CommentNewline,
CommentFirst | Comment | CommentNewline => Comment,
ClassFirst if is_name(c) => Class,
ClassFirst => Invalid,
IdentifierFirst if is_name(c) => Identifier,
Expand Down Expand Up @@ -958,6 +974,15 @@ mod test {
);
}

#[test]
fn comment_newline() {
test_attr!("{%a\nb%}", [(Comment, "a\nb")], []);
test_attr!("{%\nb%}", [(Comment, "\nb")], []);
test_attr!("{%a\n%}", [(Comment, "a\n")], []);
test_attr!("{%a\n}", [(Comment, "a\n")], []);
test_attr!("{%\nb\n%}", [(Comment, "\nb\n")], []);
}

#[test]
fn escape() {
test_attr!(
Expand Down
22 changes: 22 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4167,6 +4167,28 @@ mod test {
);
}

#[test]
fn attr_inline_multiline_comment() {
test_parse!(
concat!(
"a{%a\n", //
"b\n", //
"c%}\n", //
),
(Start(Paragraph, Attributes::new()), ""),
(
Start(
Span,
[(AttributeKind::Comment, "a\nb\nc")].into_iter().collect(),
),
"",
),
(Str("a".into()), "a"),
(End(Span), "{%a\nb\nc%}"),
(End(Paragraph), ""),
);
}

#[test]
fn attr_inline_multiline_unclosed() {
test_parse!(
Expand Down

0 comments on commit 27c7191

Please sign in to comment.