Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions Rules/Languages/pl/SharedRules/general.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@
# cannot be determined, which falls through to the genitive - the form
# Polish uses with unknown or large quantities.
- Coefficient: "IfThenElse($MRowForCoefficient, number($MRowForCoefficient/*[1][self::m:mn]), 0)"
# The 'per-fraction' rule speaks the denominator after the preposition "na",
# which governs the accusative: "na godzinę", not "na godzina". Only feminine
# nouns change form, so AccusativeCase holds just those; a missing entry
# means the accusative equals the nominative (as for "na litr", "na mol").
# The second test covers a denominator raised to a power, as in m/s^2, where
# the unit's parent is the 'power' element rather than the fraction itself.
- IsFractionDenominator: "(parent::m:fraction and preceding-sibling::*) or
(parent::m:power and parent::*[parent::m:fraction and preceding-sibling::*])"
- IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and
not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)"
- Prefix: "''"
Expand Down Expand Up @@ -339,7 +347,9 @@
if: "$Prefix = ''"
then:
- test:
- if: "$IsSingular"
- if: "$IsSingular and $IsFractionDenominator and DefinitionValue($Word, 'Speech', 'AccusativeCase') != ''"
then: [x: "DefinitionValue($Word, 'Speech', 'AccusativeCase')"]
- else_if: "$IsSingular"
# HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base
then: [x: "$Word"]
- else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''"
Expand All @@ -353,7 +363,9 @@
- x: "$Prefix"
- ct: "-"
- test:
- if: "$IsSingular"
- if: "$IsSingular and $IsFractionDenominator and DefinitionValue($Word, 'Speech', 'AccusativeCase') != ''"
then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'AccusativeCase'))"]
- else_if: "$IsSingular"
# HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base
then: [x: "concat('\uF8FE', $Word)"]
- else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''"
Expand Down
42 changes: 42 additions & 0 deletions Rules/Languages/pl/definitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,48 @@
"łyżka stołowa": "łyżki stołowe"
}

- AccusativeCase: {
# Accusative singular, used after the preposition "na" in the
# 'per-fraction' rule: "62 mile na godzinę", not "na godzina".
# Only feminine nouns differ from the nominative, so masculine and
# neuter names are deliberately absent - a missing entry means
# "the form does not change" (na litr, na mol, na metr).
# An adjective agrees with its noun (milę kwadratową), while a
# dependent noun keeps its own case (uncję płynu, minutę łuku).
"atmosfera": "atmosferę",
"baryłka": "baryłkę",
"drachma": "drachmę",
"drachma płynu": "drachmę płynu",
"dyna": "dynę",
"godzina": "godzinę",
"jednostka astronomiczna": "jednostkę astronomiczną",
"jednostka masy atomowej": "jednostkę masy atomowej",
"kaloria": "kalorię",
"kandela": "kandelę",
"kwarta": "kwartę",
"mila": "milę",
"mila kwadratowa": "milę kwadratową",
"mila na galon": "milę na galon",
"mila na godzinę": "milę na godzinę",
"minuta": "minutę",
"minuta łuku": "minutę łuku",
"pinta": "pintę",
"rupia": "rupię",
"sekunda": "sekundę",
"sekunda łuku": "sekundę łuku",
"stopa": "stopę",
"stopa deskowa": "stopę deskową",
"stopa kwadratowa": "stopę kwadratową",
"stopa sześcienna": "stopę sześcienną",
"tesla": "teslę",
"tona": "tonę",
"uncja": "uncję",
"uncja płynu": "uncję płynu",
"uncja trojańska": "uncję trojańską",
"łyżeczka": "łyżeczkę",
"łyżka stołowa": "łyżkę stołową"
}

- PluralGenitive: {
# Genitive plural - after 5 and above, and after 12-14, 112-114.
# Polish inflects the noun according to the numeral, so a single plural
Expand Down
1 change: 1 addition & 0 deletions tests/Languages/pl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
mod pl;
mod number_sets;
mod unit_plurals;
mod preposition_case;

// Tests mirrored from the English suite, with expected speech localized to Polish.
mod ClearSpeak {
Expand Down
2 changes: 1 addition & 1 deletion tests/Languages/pl/ClearSpeak/mfrac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn frac_with_units() -> Result<()> {
</mfrac>
</mrow>
</math>";
test("pl", "ClearSpeak", expr, "62 mile na godzina")?;
test("pl", "ClearSpeak", expr, "62 mile na godzinę")?;
return Ok(());

}
Expand Down
8 changes: 4 additions & 4 deletions tests/Languages/pl/SimpleSpeak/mfrac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ fn frac_with_units() -> Result<()> {
</mfrac>
</mrow>
</math>";
test("pl", "SimpleSpeak", expr, "62 mile na godzina")?;
test("pl", "SimpleSpeak", expr, "62 mile na godzinę")?;
return Ok(());

}
Expand All @@ -181,7 +181,7 @@ fn singular_frac_with_units() -> Result<()> {
</mfrac>
</mrow>
</math>";
test("pl", "SimpleSpeak", expr, "1 galon na mila")?;
test("pl", "SimpleSpeak", expr, "1 galon na milę")?;
return Ok(());

}
Expand All @@ -198,7 +198,7 @@ fn number_in_numerator_with_units() -> Result<()> {
<mi intent=':unit'>mi</mi>
</mfrac>
</math>";
test("pl", "SimpleSpeak", expr, "3 galony na mila")?;
test("pl", "SimpleSpeak", expr, "3 galony na milę")?;
return Ok(());

}
Expand All @@ -212,7 +212,7 @@ fn units_with_powers() -> Result<()> {
<msup> <mi intent=':unit'>s</mi><mn>2</mn> </msup>
</mfrac>
</math>";
test("pl", "SimpleSpeak", expr, "3 metry na sekunda do kwadratu")?;
test("pl", "SimpleSpeak", expr, "3 metry na sekundę do kwadratu")?;
return Ok(());

}
Expand Down
71 changes: 71 additions & 0 deletions tests/Languages/pl/preposition_case.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/// Polish prepositions govern case: the denominator of a unit fraction is spoken
/// after "na", which requires the accusative - "na godzinę", not "na godzina".
use crate::common::*;
use anyhow::Result;

/// Feminine denominators: these are the ones whose form actually changes.
#[test]
fn per_fraction_feminine_denominator() -> Result<()> {
let expr = r#"<math>
<mn>62</mn><mfrac><mi intent=":unit">mi</mi><mi intent=":unit">hr</mi></mfrac><mo>,</mo>
<mn>5</mn><mfrac><mi intent=":unit">m</mi><mi intent=":unit">s</mi></mfrac><mo>,</mo>
<mn>2</mn><mfrac><mi intent=":unit">km</mi><mi intent=":unit">hr</mi></mfrac><mo>,</mo>
<mn>7</mn><mfrac><mi intent=":unit">rad</mi><mi intent=":unit">min</mi></mfrac><mo>,</mo>
<mn>3</mn><mfrac><mi intent=":unit">J</mi><mi intent=":unit">t</mi></mfrac>
</math>"#;
test("pl", "SimpleSpeak", expr, "62 mile na godzinę, przecinek; 5 metrów na sekundę, przecinek; 2 kilo-metry na godzinę; przecinek; 7 radianów na minutę, przecinek; 3 dżule na tonę")?;
Ok(())
}

/// Masculine and neuter denominators must NOT change: their accusative already
/// equals the nominative. This is the negative control for the change.
#[test]
fn per_fraction_masculine_denominator_unchanged() -> Result<()> {
let expr = r#"<math>
<mn>3</mn><mfrac><mi intent=":unit">g</mi><mi intent=":unit">l</mi></mfrac><mo>,</mo>
<mn>1</mn><mfrac><mi intent=":unit">J</mi><mi intent=":unit">mol</mi></mfrac><mo>,</mo>
<mn>5</mn><mfrac><mi intent=":unit">N</mi><mi intent=":unit">m</mi></mfrac><mo>,</mo>
<mn>2</mn><mfrac><mi intent=":unit">V</mi><mi intent=":unit">A</mi></mfrac>
</math>"#;
test("pl", "SimpleSpeak", expr, "3 gramy na litr, przecinek; 1 dżul na mol, przecinek; 5 niutonów na metr, przecinek; 2 wolty na amper")?;
Ok(())
}

/// A unit standing on its own keeps the nominative - the accusative must not
/// leak outside the fraction denominator.
#[test]
fn standalone_unit_stays_nominative() -> Result<()> {
let expr = r#"<math>
<mn>1</mn><mi intent=":unit">hr</mi><mo>,</mo>
<mn>1</mn><mi intent=":unit">s</mi><mo>,</mo>
<mn>1</mn><mi intent=":unit">t</mi><mo>,</mo>
<mn>1</mn><mi intent=":unit">min</mi>
</math>"#;
test("pl", "SimpleSpeak", expr, "1 godzina, przecinek; 1 sekunda, przecinek; 1 tona, przecinek; 1 minuta")?;
Ok(())
}

/// Multi-word feminine units: the adjective agrees, a dependent noun does not.
#[test]
fn per_fraction_multiword_denominator() -> Result<()> {
let expr = r#"<math>
<mn>3</mn><mfrac><mi intent=":unit">g</mi><mi intent=":unit">sq ft</mi></mfrac><mo>,</mo>
<mn>2</mn><mfrac><mi intent=":unit">m</mi><mi intent=":unit">arcmin</mi></mfrac>
</math>"#;
test("pl", "SimpleSpeak", expr, "3 gramy na stopę kwadratową; przecinek; 2 metry na minutę łuku")?;
Ok(())
}

/// A denominator raised to a power, as in m/s^2: the unit's parent is the
/// 'power' element, not the fraction, so this needs its own test.
#[test]
fn per_fraction_denominator_with_power() -> Result<()> {
let expr = r#"<math>
<mfrac>
<mrow><mn>3</mn><mi intent=":unit">m</mi></mrow>
<msup><mi intent=":unit">s</mi><mn>2</mn></msup>
</mfrac>
</math>"#;
test("pl", "SimpleSpeak", expr, "3 metry na sekundę do kwadratu")?;
Ok(())
}