use super::Replacer;
use regex::Regex;
use std::sync::LazyLock;
static SINGLE_QUOTES: LazyLock<Replacer> = LazyLock::new(|| Replacer::RegexSurround {
regex: Regex::new(r"`(.*?)'").unwrap(),
begin: "\u{2018}",
end: "\u{2019}",
});
static DOUBLE_QUOTES: LazyLock<Replacer> = LazyLock::new(|| Replacer::RegexSurround {
regex: Regex::new(r"``(.*?)''").unwrap(),
begin: "\u{201c}",
end: "\u{201d}",
});
static LOW_DOUBLE_QUOTES: LazyLock<Replacer> =
LazyLock::new(|| Replacer::RegexSurround {
regex: Regex::new(r",,(.*?)''").unwrap(),
begin: "\u{201e}",
end: "\u{201d}",
});
static HORIZONTAL_ELLIPSIS: LazyLock<Replacer> =
LazyLock::new(|| Replacer::RegexReplace {
regex: Regex::new(r"(?:^|[^\.])(?<repl>(\.\.|\. \. )\.)(?:[^\.]|$)").unwrap(),
replacement: "\u{2026}",
});
pub fn substitute(text: &mut String) {
let mut buffer = String::new();
debug!("Performing typography substitutions");
macro_rules! replace {
($replacer:expr) => {
$replacer.replace(text, &mut buffer)
};
}
replace!(DOUBLE_QUOTES);
replace!(LOW_DOUBLE_QUOTES);
replace!(SINGLE_QUOTES);
replace!(HORIZONTAL_ELLIPSIS);
}
#[cfg(test)]
const TEST_CASES: [(&str, &str); 21] = [
(
"John laughed. ``You'll never defeat me!''\n``That's where you're wrong...''",
"John laughed. “You'll never defeat me!”\n“That's where you're wrong…”",
),
(
",,あんたは馬鹿です!''\n``Ehh?''\n,,本当!''\n[[footnoteblock]]",
"„あんたは馬鹿です!”\n“Ehh?”\n„本当!”\n[[footnoteblock]]",
),
(
"**ENTITY MAKES DRAMATIC MOTION** . . . ",
"**ENTITY MAKES DRAMATIC MOTION** … ",
),
("Whales... they are cool", "Whales… they are cool"),
("Whales ... they are cool", "Whales … they are cool"),
("Whales. . . they are cool", "Whales… they are cool"),
("Whales . . . they are cool", "Whales … they are cool"),
("...why would you think that?", "…why would you think that?"),
(
"... why would you think that?",
"… why would you think that?",
),
(
". . .why would you think that?",
"…why would you think that?",
),
(
". . . why would you think that?",
"… why would you think that?",
),
("how could you...", "how could you…"),
("how could you ...", "how could you …"),
("how could you. . .", "how could you…"),
("how could you . . .", "how could you …"),
(". . .. ....", ". . .. ...."),
("... . . . . . .", "… … …"),
(".... ..", ".... .."),
("..........", ".........."),
("... ... ...", "… … …"),
("... . . . ...", "… … …"),
];
#[test]
fn regexes() {
let _ = &*SINGLE_QUOTES;
let _ = &*DOUBLE_QUOTES;
let _ = &*LOW_DOUBLE_QUOTES;
let _ = &*HORIZONTAL_ELLIPSIS;
}
#[test]
fn test_substitute() {
use super::test::test_substitution;
test_substitution("typography", substitute, &TEST_CASES);
}