pter 0.1.0

Plain Text Email Renderer — convert HTML email bodies into readable markdown
Documentation
/// Normalize whitespace in the final markdown output.
///
/// - Collapse runs of 3+ newlines into 2 (one blank line)
/// - Trim leading/trailing whitespace
/// - Remove trailing whitespace from each line
pub fn normalize(input: &str) -> String {
    let mut result = String::with_capacity(input.len());
    let mut consecutive_newlines = 0u32;

    for ch in input.chars() {
        if ch == '\n' {
            consecutive_newlines += 1;
            if consecutive_newlines <= 2 {
                result.push('\n');
            }
        } else {
            consecutive_newlines = 0;
            result.push(ch);
        }
    }

    // Trim trailing whitespace from each line
    let lines: Vec<&str> = result.lines().map(|l| l.trim_end()).collect();
    let joined = lines.join("\n");
    joined.trim().to_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn collapse_excessive_newlines() {
        assert_eq!(normalize("a\n\n\n\nb"), "a\n\nb");
    }

    #[test]
    fn preserve_single_blank_line() {
        assert_eq!(normalize("a\n\nb"), "a\n\nb");
    }

    #[test]
    fn trim_trailing_whitespace() {
        assert_eq!(normalize("hello   \nworld  "), "hello\nworld");
    }

    #[test]
    fn trim_outer_whitespace() {
        assert_eq!(normalize("\n\nhello\n\n"), "hello");
    }

    #[test]
    fn empty_input() {
        assert_eq!(normalize(""), "");
    }
}