use crate::core::environment::RunSignal;
use crate::core::{Element, Environment};
use crate::error::Result;
use crate::template::{TModel, TemplateTransformModel};
use std::collections::HashMap;
pub struct NormalizeNewlinesTransform;
impl TemplateTransformModel for NormalizeNewlinesTransform {
fn transform_with_body(
&self,
env: &mut Environment,
_params: &HashMap<String, TModel>,
body: &[Element],
) -> Result<RunSignal> {
let (signal, captured) = env.capture(|e| e.run(body))?;
env.emit(&normalize_newlines_text(&captured))?;
Ok(signal)
}
}
pub fn normalize_newlines_text(s: &str) -> String {
let mut out = String::new();
let mut first = true;
let mut line_start = 0;
let b = s.as_bytes();
let mut i = 0;
while i <= b.len() {
let eol_len = if i == b.len() {
0
} else if b[i] == b'\n' {
1
} else if b[i] == b'\r' {
if i + 1 < b.len() && b[i + 1] == b'\n' {
2
} else {
1
}
} else {
0
};
if eol_len == 0 {
i += 1;
continue;
}
let line = &s[line_start..i];
if first {
first = false;
if line.is_empty() {
i += eol_len;
line_start = i;
continue;
}
}
out.push_str(line);
out.push('\n');
i += eol_len;
line_start = i;
}
if line_start < b.len() {
let line = &s[line_start..];
if first {
if !line.is_empty() {
out.push_str(line);
out.push('\n');
}
} else {
out.push_str(line);
out.push('\n');
}
}
out
}