diff options
author | RenΓ© Kijewski <kijewski@library.vetmed.fu-berlin.de> | 2023-04-03 18:34:33 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2023-05-31 17:29:22 +0200 |
commit | fe5d350f50ebc73300456c618dd265cc43a8f05a (patch) | |
tree | 62248a4f9a1137a1bbae114172f3eebfb0fa5032 | |
parent | a3ff30a5eaca6ffcf82dd152affef4725acf0aa8 (diff) | |
download | askama-fe5d350f50ebc73300456c618dd265cc43a8f05a.tar.gz askama-fe5d350f50ebc73300456c618dd265cc43a8f05a.tar.bz2 askama-fe5d350f50ebc73300456c618dd265cc43a8f05a.zip |
Allow delimiters with arbitrary length
-rw-r--r-- | askama_derive/src/config.rs | 110 | ||||
-rw-r--r-- | book/src/configuration.md | 4 |
2 files changed, 96 insertions, 18 deletions
diff --git a/askama_derive/src/config.rs b/askama_derive/src/config.rs index cf22a72..f01bd65 100644 --- a/askama_derive/src/config.rs +++ b/askama_derive/src/config.rs @@ -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) @@ -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] diff --git a/book/src/configuration.md b/book/src/configuration.md index 2311e7d..740160b 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -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: |