Skip to content

Add Luxembourgish language support - #134

Merged
allenap merged 2 commits into
masterfrom
lang-luxembourgish
Aug 9, 2026
Merged

Add Luxembourgish language support#134
allenap merged 2 commits into
masterfrom
lang-luxembourgish

Conversation

@allenap

@allenap allenap commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Adds Luxembourgish (Lëtzebuergesch) as a third language, behind a non-default lang-luxembourgish feature and selected with --language luxembourgish. It follows the pattern established by Turkish – a distinct type implementing Generator, duplicated rather than abstracted – but it's the first generator to need two things English and Turkish didn't.

Gender agreement. Every noun is masculine, feminine, or neuter, and an attributive adjective agrees with it in the articleless strong nominative: masculine -en (groussen Hond), feminine bare (grouss Kaz), neuter -t (grousst Haus). Irregulars are common enough – héichhéijen, guttgudden, routrouden – that each adjective carries all three forms as data rather than deriving them, so a wrong irregular is a fixable line in a text file rather than a bug in a morphology engine. generate_into picks the noun first, even though it's emitted last, because the noun fixes the gender.

The Eifeler Regel. A final -n or -nn drops before a word beginning with anything other than n, d, t, z, h or a vowel. This is applied at the join, which is what the "Generator owns the whole buffer" design was for:

$ petname --language luxembourgish --words 2
grousse-mupp     # -n elided before m
groussen-hond    # -n kept before h
grouss-kaz       # feminine is bare

$ petname --language luxembourgish --words 3
ganz-schéint-haus

The separator plays no part – the rule is about the sounds either side of the join – and the last word of a name is phrase-final, so it always keeps its -n.

Word lists need a native-speaker pass

words/luxembourgish/* are best-effort seed lists authored by a non-native speaker. The genders in particular, and a handful of adjective forms, want review; the file headers say so. Two guard rails make that curation safer:

  • A unit test lints the built-in adjective data – the masculine must end in -n, and the neuter is the feminine plus -t except after a stem-final -t/-d. Real exceptions go in an IRREGULAR_NEUTER const. This already caught one bad entry (rouden:rout:routt).
  • The luxembourgish! macro now rejects entries that contradict each other rather than silently keeping the first, e.g. noun 'kaz' appears twice with different genders: Feminine and Masculine.

The one open linguistic question is whether adjectival -nn really reduces all the way (ronn + birro-bir). The documented rule says final -n and -nn both go, and that's what's implemented, but it's the first thing worth checking with a native speaker. It's a one-line change if the answer is no.

Second commit

Apply --letters to Turkish emphatic adjective forms is an unrelated pre-existing bug found while reviewing the Luxembourgish equivalent: Petnames::retain judged a Turkish adjective by its base form alone, so --letters 6 could still emit çırılçıplak (11 characters). It's kept as a separate commit and can be split into its own PR if preferred.

Verification

cargo fmt --check; cargo clippy --workspace --all-features --all-targets -D warnings; the full test suite; cargo hack --workspace --feature-powerset test (321 test binaries, 0 failures); scripts/doc; and scripts/semver-checks, which reports no semver update required – everything here is additive, so this is a minor bump when released.

allenap added 2 commits August 9, 2026 10:35
Gated behind a new `lang-luxembourgish` feature and selected with `--language
luxembourgish`. Luxembourgish is the first generator to need grammatical gender
and join-time sandhi:

- Nouns carry a gender (m/f/n) and adjectives carry all three agreeing forms, so
  nothing is derived at runtime and the irregulars – héich -> héijen, gutt ->
  gudden – are plain data.
- The Eifeler Regel drops a final -n/-nn at each join unless the next word
  begins with n, d, t, z, h or a vowel.

The word lists are best-effort seed lists awaiting native-speaker review. To
keep curation honest, a unit test lints the built-in adjective forms and the
`luxembourgish!` macro rejects entries that contradict one another, so a slip
fails the build rather than showing up in generated names.
`Petnames::retain` judged an adjective by its base form alone, so an emphatic
form like `kıpkırmızı` (10 characters) could still be emitted under `--letters
6`. Drop an emphatic that fails the predicate on its own, which keeps the base
adjective in play rather than discarding both.
@allenap
allenap merged commit 0e4bc6c into master Aug 9, 2026
5 checks passed
@allenap
allenap deleted the lang-luxembourgish branch August 9, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant