Implemented a new span to trim leading whitespace.
Through my experiements I have concluded that DustJS trims whitespace at the front of a line. To handle this, I implement a new parser that matches a newline followed by any amount of whitespace. This should allow me to trim whitespace at the head of the line because spans start immediately after a tag is closed. So, for example: ``` {foo} bar {/foo} ``` Would be: ``` {foo}\n bar{/foo} ^ ^ \____/ span ``` So while there is no magical "start of line" detector like in regular expressions, the first start of a line in a span will always be preceded with a newline character except for the opening of the document. For handling the opening of the document I am already trimming the whitespace in the `template()` parser.
This commit is contained in:
parent
31029bf50b
commit
b8e8f19724
@ -88,6 +88,11 @@ pub struct Span<'a> {
|
|||||||
pub contents: &'a str,
|
pub contents: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct NewSpan<'a> {
|
||||||
|
pub contents: Vec<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Container<'a> {
|
pub struct Container<'a> {
|
||||||
pub path: Path<'a>,
|
pub path: Path<'a>,
|
||||||
@ -475,6 +480,34 @@ fn filter(i: &str) -> IResult<&str, Filter> {
|
|||||||
)(i)
|
)(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whitespace at the beginning of lines is ignored so inside a span
|
||||||
|
/// we are matching a newline character followed by as much contiguous
|
||||||
|
/// whitespace as possible, all of which will be thrown away by other
|
||||||
|
/// parsers.
|
||||||
|
fn span_end_of_line(i: &str) -> IResult<&str, (&str, &str)> {
|
||||||
|
tuple((line_ending, multispace0))(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn span_line(i: &str) -> IResult<&str, &str> {
|
||||||
|
verify(
|
||||||
|
take_until_parser_matches(alt((
|
||||||
|
tag("{"),
|
||||||
|
line_ending,
|
||||||
|
recognize(all_consuming(eof_whitespace)),
|
||||||
|
))),
|
||||||
|
|s: &str| s.len() > 0,
|
||||||
|
)(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Any text that is not a Dust element
|
||||||
|
fn new_span(i: &str) -> IResult<&str, NewSpan> {
|
||||||
|
let (remaining, lines) = preceded(
|
||||||
|
opt(span_end_of_line),
|
||||||
|
many1(terminated(span_line, opt(span_end_of_line))),
|
||||||
|
)(i)?;
|
||||||
|
Ok((remaining, NewSpan { contents: lines }))
|
||||||
|
}
|
||||||
|
|
||||||
/// Any text that is not a Dust element
|
/// Any text that is not a Dust element
|
||||||
fn span(i: &str) -> IResult<&str, Span> {
|
fn span(i: &str) -> IResult<&str, Span> {
|
||||||
let (remaining, body) = verify(
|
let (remaining, body) = verify(
|
||||||
@ -620,6 +653,74 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_span_end_of_line() {
|
||||||
|
assert_eq!(
|
||||||
|
super::span_end_of_line("\n \t \n\nfoo"),
|
||||||
|
Ok(("foo", ("\n", " \t \n\n")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_span_line() {
|
||||||
|
assert_eq!(
|
||||||
|
super::span_line("this is just some text"),
|
||||||
|
Ok(("", "this is just some text"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::span_line("this is just some text {~lb}"),
|
||||||
|
Ok(("{~lb}", "this is just some text "))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::span_line("{~lb}"),
|
||||||
|
Err(Error(("{~lb}", ErrorKind::Verify)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_span() {
|
||||||
|
assert_eq!(
|
||||||
|
super::new_span("this is just some text"),
|
||||||
|
Ok((
|
||||||
|
"",
|
||||||
|
NewSpan {
|
||||||
|
contents: vec!["this is just some text"]
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::new_span("this is just some text {~lb}"),
|
||||||
|
Ok((
|
||||||
|
"{~lb}",
|
||||||
|
NewSpan {
|
||||||
|
contents: vec!["this is just some text "]
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::new_span("{~lb}"),
|
||||||
|
Err(Error(("{~lb}", ErrorKind::Verify)))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::new_span("this is \t \n\n \t \n \t multiline text\n {foo}"),
|
||||||
|
Ok((
|
||||||
|
"{foo}",
|
||||||
|
NewSpan {
|
||||||
|
contents: vec!["this is \t ", "multiline text"]
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::new_span("\n leading whitespace"),
|
||||||
|
Ok((
|
||||||
|
"",
|
||||||
|
NewSpan {
|
||||||
|
contents: vec!["leading whitespace"]
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_section_mismatched_paths() {
|
fn test_section_mismatched_paths() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
Loading…
Reference in New Issue
Block a user