Add alternative smartquotes (#1631)

This commit is contained in:
T0mstone 2023-07-06 13:52:24 +02:00 committed by GitHub
parent 07553cbe71
commit 46a6f92bf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 6 deletions

View File

@ -598,7 +598,11 @@ fn collect<'a>(
if SmartQuoteElem::enabled_in(styles) {
let lang = TextElem::lang_in(styles);
let region = TextElem::region_in(styles);
let quotes = Quotes::from_lang(lang, region);
let quotes = Quotes::from_lang(
lang,
region,
SmartQuoteElem::alternative_in(styles),
);
let peeked = iter.peek().and_then(|child| {
let child = if let Some((child, _)) = child.to_styled() {
child

View File

@ -42,6 +42,19 @@ pub struct SmartQuoteElem {
/// ```
#[default(true)]
pub enabled: bool,
/// Whether to use alternative quotes.
///
/// Does nothing for languages that don't have alternative quotes.
///
/// ```example
/// #set text(lang: "de")
/// #set smartquote(alternative: true)
///
/// "Das ist in anderen Anführungszeichen."
/// ```
#[default(false)]
pub alternative: bool,
}
/// State machine for smart quote substitution.
@ -135,17 +148,25 @@ impl<'s> Quotes<'s> {
/// Norwegian.
///
/// For unknown languages, the English quotes are used.
pub fn from_lang(lang: Lang, region: Option<Region>) -> Self {
pub fn from_lang(lang: Lang, region: Option<Region>, alternative: bool) -> Self {
let region = region.as_ref().map(Region::as_str);
let low_high = ("", "", "", "");
let (single_open, single_close, double_open, double_close) = match lang.as_str() {
"de" if matches!(region, Some("CH" | "LI")) => ("", "", "«", "»"),
"cs" | "da" | "de" | "et" | "is" | "lt" | "lv" | "sk" | "sl" => {
("", "", "", "")
}
"de" if matches!(region, Some("CH" | "LI")) => match alternative {
false => ("", "", "«", "»"),
true => low_high,
},
"cs" | "da" | "de" | "sk" | "sl" if alternative => ("", "", "»", "«"),
"cs" | "da" | "de" | "et" | "is" | "lt" | "lv" | "sk" | "sl" => low_high,
"fr" | "ru" if alternative => return Self::default(),
"fr" => ("\u{00A0}", "\u{00A0}", "«\u{00A0}", "\u{00A0}»"),
"fi" | "sv" if alternative => ("", "", "»", "»"),
"bs" | "fi" | "sv" => ("", "", "", ""),
"es" if matches!(region, Some("ES") | None) => ("", "", "«", "»"),
"hu" | "pl" | "ro" => ("", "", "", ""),
"no" | "nb" | "nn" if alternative => low_high,
"ru" | "no" | "nb" | "nn" | "ua" => ("", "", "«", "»"),
_ if lang.dir() == Dir::RTL => ("", "", "", ""),
_ => return Self::default(),