Skip to content

Commit

Permalink
Add indent filter (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
Spiegie committed Nov 27, 2022
1 parent 4d4eae8 commit b0b18c3
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
50 changes: 50 additions & 0 deletions minijinja/src/filters.rs
Expand Up @@ -754,6 +754,56 @@ mod builtins {
})
}

/// indents Value with spaces
///
/// The first optional parameter to the filter can be set to `true` to
/// indent the first line. The parameter defaults to false.
/// the second optional parameter to the filter can be set to `true`
/// to indent blank lines. The parameter defaults to false.
/// This filter is useful, if you want to template yaml-files
///
/// ```jinja
/// example:
/// config:
/// {{ global_conifg|indent(2) }} #does not indent first line
/// {{ global_config|indent(2,true) }} #indent whole Value with two spaces
/// {{ global_config|indent(2,true,true)}} #indent whole Value and all Blank Lines value
/// ```
#[cfg_attr(docsrs, doc(cfg(all(feature = "builtins"))))]
pub fn indent(
mut value: String,
width: usize,
indent_first_line: Option<bool>,
indent_blank_lines: Option<bool>,
) -> String {
fn strip_trailing_newline(input: &mut String) {
if let Some(stripped) = input.strip_suffix(&['\r', '\n'][..]) {
input.truncate(stripped.len());
}
}

strip_trailing_newline(&mut value);

let mut output: String = String::new();
let mut iterator = value.split('\n');
if !indent_first_line.unwrap_or(false) {
output.push_str(iterator.next().unwrap());
output.push('\n');
}
for line in iterator {
if line.is_empty() {
if indent_blank_lines.unwrap_or(false) {
output.push_str(&" ".repeat(width));
}
} else {
output.push_str(format!("{}{}", " ".repeat(width), line).as_str());
}
output.push('\n');
}
strip_trailing_newline(&mut output);
output
}

/// URL encodes a value.
///
/// If given a map it encodes the parameters into a query set, otherwise it
Expand Down
50 changes: 50 additions & 0 deletions minijinja/tests/test_filters.rs
@@ -0,0 +1,50 @@
#![cfg(feature = "builtins")]
use minijinja::filters::indent;

#[test]
fn test_indent_one_empty_line() {
let teststring = String::from("\n");
assert_eq!(indent(teststring, 2, None, None), String::from(""));
}

#[test]
fn test_indent_one_line() {
let teststring = String::from("test\n");
assert_eq!(indent(teststring, 2, None, None), String::from("test"));
}

#[test]
fn test_indent() {
let teststring = String::from("test\ntest1\n\ntest2\n");
assert_eq!(
indent(teststring, 2, None, None),
String::from("test\n test1\n\n test2")
);
}

#[test]
fn test_indent_with_indented_first_line() {
let teststring = String::from("test\ntest1\n\ntest2\n");
assert_eq!(
indent(teststring, 2, Some(true), None),
String::from(" test\n test1\n\n test2")
);
}

#[test]
fn test_indent_with_indented_blank_line() {
let teststring = String::from("test\ntest1\n\ntest2\n");
assert_eq!(
indent(teststring, 2, None, Some(true)),
String::from("test\n test1\n \n test2")
);
}

#[test]
fn test_indent_with_all_indented() {
let teststring = String::from("test\ntest1\n\ntest2\n");
assert_eq!(
indent(teststring, 2, Some(true), Some(true)),
String::from(" test\n test1\n \n test2")
);
}

0 comments on commit b0b18c3

Please sign in to comment.