mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-02-02 23:38:41 +08:00
79 lines
2.6 KiB
Rust
79 lines
2.6 KiB
Rust
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();
|
||
}
|
||
}
|
||
}
|