use std::io; use std::io::{Read, Write}; fn main() { let mut is_in_code_block = false; let mut is_in_inline_code = false; let mut is_in_html_tag = false; let mut buffer = String::new(); if let Err(e) = io::stdin().read_to_string(&mut buffer) { panic!("{}", e); } for line in buffer.lines() { if line.is_empty() { is_in_inline_code = false; } if line.starts_with("```") { is_in_code_block = !is_in_code_block; } if is_in_code_block { is_in_inline_code = false; is_in_html_tag = false; write!(io::stdout(), "{}\n", line).unwrap(); } else { let modified_line = &mut String::new(); let mut previous_char = std::char::REPLACEMENT_CHARACTER; let mut chars_in_line = line.chars(); while let Some(possible_match) = chars_in_line.next() { // Check if inside inline code. if possible_match == '`' { is_in_inline_code = !is_in_inline_code; } // Check if inside HTML tag. if possible_match == '<' && !is_in_inline_code { is_in_html_tag = true; } if possible_match == '>' && !is_in_inline_code { is_in_html_tag = false; } // Replace with right/left apostrophe/quote. let char_to_push = if possible_match == '\'' && !is_in_inline_code && !is_in_html_tag { if (previous_char != std::char::REPLACEMENT_CHARACTER && !previous_char.is_whitespace()) || previous_char == '‘' { '’' } else { '‘' } } else if possible_match == '"' && !is_in_inline_code && !is_in_html_tag { if (previous_char != std::char::REPLACEMENT_CHARACTER && !previous_char.is_whitespace()) || previous_char == '“' { '”' } else { '“' } } else { // Leave untouched. possible_match }; modified_line.push(char_to_push); previous_char = char_to_push; } write!(io::stdout(), "{}\n", modified_line).unwrap(); } } }