Repository: typst/typst
File: crates/typst/src/layout/inline/mod.rs (Rust)

Code before:
        return false;
    }

    // If there's a trimmed out space, we needn't repeat the hyphen. That's the case of a text like
    // "... kebab é a -melhor- comida que existe", where the hyphens are a kind of emphasis marker.
    if pred_line.trimmed.end != pred_line.end {
        return false;
    }

    // The hyphen should repeat only in the languages that requires that feature.
    // For more information see the discussion at https://github.com/typst/typst/issues/3235
    if let Some(Item::Text(shape)) = pred_line.last.as_ref() {
        match shape.lang.as_str() {
            // Lower Sorbian: see https://dolnoserbski.de/ortografija/psawidla/K3
            //
            // Czech: see https://prirucka.ujc.cas.cz/?id=164
            //
            // Croatian: see http://pravopis.hr/pravilo/spojnica/68/
            //
            // Polish: see https://www.ortograf.pl/zasady-pisowni/lacznik-zasady-pisowni
            //
            // Portuguese: see Base XX of "Acordo Ortográfico da Língua Portuguesa de 1990"
            // https://www2.senado.leg.br/bdsf/bitstream/handle/id/508145/000997415.pdf
            //
            // Slovak: see https://www.zones.sk/studentske-prace/gramatika/10620-pravopis-rozdelovanie-slov/
            "dsb" | "cs" | "hr" | "pl" | "pt" | "sk" => true,
            // In Spanish the hyphen is required only if the word next to hyphen isn't capitalized.
            //
            // See § 4.1.1.1.2.e on the "Ortografía de la lengua española"
            // https://www.rae.es/ortografía/como-signo-de-división-de-palabras-a-final-de-línea
            "es" => pred_line.bidi.text[pred_line.end..]
                .chars()
                .next()
                .map(|c| !c.is_uppercase())
                .unwrap_or(false),
            _ => false,
        }
    } else {
        false
    }
}


Review comment (suggestion):
You can match directly on the `Lang::..` constants instead. That's less prone to typos.

Code after:
        '\u{60C}' | '\u{6D4}' => 0.4,

        _ => 0.0,
    }
}

/// Whether the hyphen should repeat at the start of the next line.
fn should_repeat_hyphen(pred_line: &Line) -> bool {
    // If the predecessor line does not end with a Dash::HardHyphen, we shall
    // not place a hyphen at the start of the next line.
    if pred_line.dash != Some(Dash::HardHyphen) {
        return false;
    }

    // If there's a trimmed out space, we needn't repeat the hyphen. That's the
    // case of a text like "...kebab é a -melhor- comida que existe", where the
    // hyphens are a kind of emphasis marker.
    if pred_line.trimmed.end != pred_line.end {
        return false;
    }

    // The hyphen should repeat only in the languages that require that feature.
    // For more information see the discussion at https://github.com/typst/typst/issues/3235
    let Some(Item::Text(shape)) = pred_line.last.as_ref() else { return false };

    match shape.lang {
        // - Lower Sorbian: see https://dolnoserbski.de/ortografija/psawidla/K3
        // - Czech: see https://prirucka.ujc.cas.cz/?id=164
        // - Croatian: see http://pravopis.hr/pravilo/spojnica/68/
        // - Polish: see https://www.ortograf.pl/zasady-pisowni/lacznik-zasady-pisowni
        // - Portuguese: see https://www2.senado.leg.br/bdsf/bitstream/handle/id/508145/000997415.pdf (Base XX)
        // - Slovak: see https://www.zones.sk/studentske-prace/gramatika/10620-pravopis-rozdelovanie-slov/
        Lang::LOWER_SORBIAN
        | Lang::CZECH
        | Lang::CROATIAN
        | Lang::POLISH
        | Lang::PORTUGUESE
        | Lang::SLOVAK => true,
        // In Spanish the hyphen is required only if the word next to hyphen is
        // not capitalized. Otherwise, the hyphen must not be repeated.
        //
        // See § 4.1.1.1.2.e on the "Ortografía de la lengua española"
        // https://www.rae.es/ortografía/como-signo-de-división-de-palabras-a-final-de-línea
        Lang::SPANISH => pred_line.bidi.text[pred_line.end..]
            .chars()
            .next()
            .map(|c| !c.is_uppercase())
            .unwrap_or(false),
        _ => false,
    }
}