Skip to content

Commit

Permalink
Allow delimiters with arbitrary length
Browse files Browse the repository at this point in the history
  • Loading branch information
Kijewski authored and djc committed May 31, 2023
1 parent a3ff30a commit fe5d350
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 18 deletions.
110 changes: 94 additions & 16 deletions askama_derive/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,34 @@ impl<'a> TryFrom<RawSyntax<'a>> for Syntax<'a> {
comment_end: raw.comment_end.unwrap_or(default.comment_end),
};

if syntax.block_start.len() != 2
|| syntax.block_end.len() != 2
|| syntax.expr_start.len() != 2
|| syntax.expr_end.len() != 2
|| syntax.comment_start.len() != 2
|| syntax.comment_end.len() != 2
{
return Err("length of delimiters must be two".into());
for s in [
syntax.block_start,
syntax.block_end,
syntax.expr_start,
syntax.expr_end,
syntax.comment_start,
syntax.comment_end,
] {
if s.len() < 2 {
return Err(
format!("delimiters must be at least two characters long: {s:?}").into(),
);
} else if s.chars().any(|c| c.is_whitespace()) {
return Err(format!("delimiters may not contain white spaces: {s:?}").into());
}
}

let bs = syntax.block_start.as_bytes()[0];
let be = syntax.block_start.as_bytes()[1];
let cs = syntax.comment_start.as_bytes()[0];
let ce = syntax.comment_start.as_bytes()[1];
let es = syntax.expr_start.as_bytes()[0];
let ee = syntax.expr_start.as_bytes()[1];
if !((bs == cs && bs == es) || (be == ce && be == ee)) {
return Err(format!("bad delimiters block_start: {}, comment_start: {}, expr_start: {}, needs one of the two characters in common", syntax.block_start, syntax.comment_start, syntax.expr_start).into());
for (s1, s2) in [
(syntax.block_start, syntax.expr_start),
(syntax.block_start, syntax.comment_start),
(syntax.expr_start, syntax.comment_start),
] {
if s1.starts_with(s2) || s2.starts_with(s1) {
return Err(format!(
"a delimiter may not be the prefix of another delimiter: {s1:?} vs {s2:?}",
)
.into());
}
}

Ok(syntax)
Expand Down Expand Up @@ -452,6 +462,74 @@ mod tests {
assert_eq!(bar.comment_end, default_syntax.comment_end);
}

#[cfg(feature = "config")]
#[test]
fn longer_delimiters() {
let raw_config = r#"
[[syntax]]
name = "emoji"
block_start = "👉🙂👉"
block_end = "👈🙃👈"
expr_start = "🤜🤜"
expr_end = "🤛🤛"
comment_start = "👎_(ツ)_👎"
comment_end = "👍:D👍"
[general]
default_syntax = "emoji"
"#;

let config = Config::new(raw_config, None).unwrap();
assert_eq!(config.default_syntax, "emoji");

let foo = config.syntaxes.get("emoji").unwrap();
assert_eq!(foo.block_start, "👉🙂👉");
assert_eq!(foo.block_end, "👈🙃👈");
assert_eq!(foo.expr_start, "🤜🤜");
assert_eq!(foo.expr_end, "🤛🤛");
assert_eq!(foo.comment_start, "👎_(ツ)_👎");
assert_eq!(foo.comment_end, "👍:D👍");
}

#[cfg(feature = "config")]
#[test]
fn illegal_delimiters() {
let raw_config = r#"
[[syntax]]
name = "too_short"
block_start = "<"
"#;
let config = Config::new(raw_config, None);
assert_eq!(
config.unwrap_err().msg,
r#"delimiters must be at least two characters long: "<""#,
);

let raw_config = r#"
[[syntax]]
name = "contains_ws"
block_start = " {{ "
"#;
let config = Config::new(raw_config, None);
assert_eq!(
config.unwrap_err().msg,
r#"delimiters may not contain white spaces: " {{ ""#,
);

let raw_config = r#"
[[syntax]]
name = "is_prefix"
block_start = "{{"
expr_start = "{{$"
comment_start = "{{#"
"#;
let config = Config::new(raw_config, None);
assert_eq!(
config.unwrap_err().msg,
r#"a delimiter may not be the prefix of another delimiter: "{{" vs "{{$""#,
);
}

#[cfg(feature = "toml")]
#[should_panic]
#[test]
Expand Down
4 changes: 2 additions & 2 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ The following keys can currently be used to customize template syntax:
* `expr_start`, defaults to `{{`
* `expr_end`, defaults to `}}`

Values must be 2 characters long and start delimiters must all start with the same
character. If a key is omitted, the value from the default syntax is used.
Values must be at least two characters long.
If a key is omitted, the value from the default syntax is used.

Here is an example of a custom escaper:

Expand Down

0 comments on commit fe5d350

Please sign in to comment.