| use std::io; |
| use std::io::prelude::*; |
| |
| fn main() { |
| write_md(remove_hidden_lines(&read_md())); |
| } |
| |
| fn read_md() -> String { |
| let mut buffer = String::new(); |
| match io::stdin().read_to_string(&mut buffer) { |
| Ok(_) => buffer, |
| Err(error) => panic!("{error}"), |
| } |
| } |
| |
| fn write_md(output: String) { |
| print!("{output}"); |
| } |
| |
| fn remove_hidden_lines(input: &str) -> String { |
| let mut resulting_lines = vec![]; |
| let mut within_codeblock = false; |
| |
| for line in input.lines() { |
| if line.starts_with("```") { |
| within_codeblock = !within_codeblock; |
| } |
| |
| if !within_codeblock || (!line.starts_with("# ") && line != "#") { |
| resulting_lines.push(line) |
| } |
| } |
| |
| resulting_lines.join("\n") |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use crate::remove_hidden_lines; |
| |
| #[test] |
| fn hidden_line_in_code_block_is_removed() { |
| let input = r#" |
| In this listing: |
| |
| ``` |
| fn main() { |
| # secret |
| } |
| ``` |
| |
| you can see that... |
| "#; |
| let output = remove_hidden_lines(input); |
| |
| let desired_output = r#" |
| In this listing: |
| |
| ``` |
| fn main() { |
| } |
| ``` |
| |
| you can see that... |
| "#; |
| |
| assert_eq!(output, desired_output); |
| } |
| |
| #[test] |
| fn headings_arent_removed() { |
| let input = r#" |
| # Heading 1 |
| "#; |
| let output = remove_hidden_lines(input); |
| |
| let desired_output = r#" |
| # Heading 1 |
| "#; |
| |
| assert_eq!(output, desired_output); |
| } |
| } |