initial import
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
### Elvish
|
||||
|
||||
> The Elvish tongue flows like a river and pools upon the lips like sweetest wine. -- Anwin am Vakaralithien
|
||||
|
||||
Elvish is an ornate, multisyllabic language featuring a complex and nuanced set
|
||||
of vowel sounds that can take non-native speakers decades to master. Surnames
|
||||
are typically derived from place names; the more noble the name, the more
|
||||
baroque its construction.
|
||||
|
||||
*Aaclysmior uewhön fyaeiath nöagefniath iedyglion ryavies, eamwien acyöe, uëstr udrocrem!*
|
||||
|
||||
**Elvish Names:**
|
||||
* Afydyioth um Envyien
|
||||
* Wjillias am Aofll
|
||||
* Anyir um Edyoieth
|
||||
|
||||
**Noble Elvish Names:**
|
||||
* Uebs Sviiies um Udjsmierios
|
||||
* Nytyuia Oudryhn um Ioltier
|
||||
* Emyea Whonoel an Ofyediar
|
||||
@@ -0,0 +1,7 @@
|
||||
"""
|
||||
Elvish
|
||||
"""
|
||||
from .base import Language
|
||||
from .names import Name, NobleName
|
||||
|
||||
__all__ = [Language, Name, NobleName]
|
||||
@@ -0,0 +1,129 @@
|
||||
from language import types
|
||||
|
||||
from .rules import rules
|
||||
|
||||
vowels = types.WeightedSet(
|
||||
("a", 1.0),
|
||||
("e", 1.0),
|
||||
("i", 0.3),
|
||||
("o", 0.8),
|
||||
("u", 0.7),
|
||||
("y", 0.3),
|
||||
("j", 0.05),
|
||||
("ä", 0.1),
|
||||
("ë", 0.1),
|
||||
("ö", 0.1),
|
||||
("ü", 0.1),
|
||||
)
|
||||
consonants = types.WeightedSet(
|
||||
("b", 0.5),
|
||||
("c", 0.3),
|
||||
("d", 0.3),
|
||||
("f", 0.4),
|
||||
("g", 0.3),
|
||||
("h", 0.5),
|
||||
("k", 0.05),
|
||||
("l", 1.0),
|
||||
("m", 1.0),
|
||||
("n", 1.0),
|
||||
("p", 0.5),
|
||||
("r", 1.0),
|
||||
("s", 1.0),
|
||||
("t", 0.7),
|
||||
("v", 0.3),
|
||||
("w", 0.2),
|
||||
("y", 0.3),
|
||||
) + types.equal_weights(
|
||||
[
|
||||
"ch",
|
||||
"cl",
|
||||
"cr",
|
||||
"cw",
|
||||
"cy",
|
||||
"dh",
|
||||
"dj",
|
||||
"dr",
|
||||
"dw",
|
||||
"dy",
|
||||
"fl",
|
||||
"fn",
|
||||
"fr",
|
||||
"fw",
|
||||
"fy",
|
||||
"gl",
|
||||
"ll",
|
||||
"ly",
|
||||
"ml",
|
||||
"mw",
|
||||
"my",
|
||||
"ny",
|
||||
"rh",
|
||||
"ry",
|
||||
"sh",
|
||||
"sl",
|
||||
"sm",
|
||||
"sn",
|
||||
"st",
|
||||
"sv",
|
||||
"sw",
|
||||
"sy",
|
||||
"th",
|
||||
"tr",
|
||||
"tw",
|
||||
"ty",
|
||||
"vy",
|
||||
"wh",
|
||||
"wr",
|
||||
"wy",
|
||||
"yh",
|
||||
]
|
||||
)
|
||||
|
||||
suffixes = types.equal_weights(
|
||||
[
|
||||
"a",
|
||||
"i",
|
||||
"e",
|
||||
"t",
|
||||
"s",
|
||||
"m",
|
||||
"n",
|
||||
"l",
|
||||
"r",
|
||||
"d",
|
||||
"a",
|
||||
"th",
|
||||
"ss",
|
||||
"ieth",
|
||||
"ies",
|
||||
"ier",
|
||||
"ien",
|
||||
"iath",
|
||||
"ias",
|
||||
"iar",
|
||||
"ian",
|
||||
"ioth",
|
||||
"ios",
|
||||
"ior",
|
||||
"ion",
|
||||
],
|
||||
weight=1.0,
|
||||
)
|
||||
|
||||
Language = types.Language(
|
||||
name="elvish",
|
||||
vowels=vowels,
|
||||
consonants=consonants,
|
||||
prefixes=None,
|
||||
suffixes=suffixes,
|
||||
syllables=types.SyllableSet(
|
||||
(types.Syllable(template="vowel|consonant") * 3, 0.4),
|
||||
(types.Syllable(template="vowel|consonant") * 3, 0.5),
|
||||
(types.Syllable(template="vowel|consonant") * 4, 1.0),
|
||||
(types.Syllable(template="vowel|consonant") * 5, 0.5),
|
||||
(types.Syllable(template="vowel|consonant") * 6, 0.1),
|
||||
(types.Syllable(template="vowel|consonant") * 7, 0.1),
|
||||
),
|
||||
rules=rules,
|
||||
minimum_grapheme_count=3,
|
||||
)
|
||||
@@ -0,0 +1,77 @@
|
||||
from language import defaults, types
|
||||
from language.languages.elvish import Language
|
||||
from language.languages.elvish.base import suffixes
|
||||
|
||||
PlaceName = types.NameGenerator(
|
||||
language=Language,
|
||||
syllables=types.SyllableSet(
|
||||
(types.Syllable(template="vowel,vowel|consonant,vowel|consonant"), 1.0),
|
||||
(types.Syllable(template="consonant,vowel|consonant,vowel|consonant"), 0.3),
|
||||
),
|
||||
templates=types.NameSet(
|
||||
(types.NameTemplate("affix,name"), 1.0),
|
||||
),
|
||||
affixes=types.WeightedSet(("el", 1.0)),
|
||||
adjectives=defaults.adjectives,
|
||||
suffixes=suffixes,
|
||||
)
|
||||
|
||||
|
||||
class ElvishNameGenerator(types.NameGenerator):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
language=Language,
|
||||
syllables=Language.syllables,
|
||||
templates=types.NameSet(
|
||||
(types.NameTemplate("name,affix,surname"), 1.0),
|
||||
),
|
||||
affixes=types.equal_weights(["am", "an", "al", "um"], weight=1.0, blank=False),
|
||||
adjectives=defaults.adjectives,
|
||||
titles=defaults.titles,
|
||||
suffixes=suffixes,
|
||||
)
|
||||
self.language.minimum_grapheme_count = 2
|
||||
self.place_generator = PlaceName
|
||||
|
||||
def get_surname(self) -> str:
|
||||
return self.place_generator.name()[0]["name"][0]
|
||||
|
||||
|
||||
class NobleElvishNameGenerator(types.NameGenerator):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
language=Language,
|
||||
syllables=Language.syllables,
|
||||
templates=types.NameSet(
|
||||
(types.NameTemplate("name,name,affix,surname"), 1.0),
|
||||
),
|
||||
affixes=types.equal_weights(["am", "an", "al", "um"], weight=1.0, blank=False),
|
||||
adjectives=defaults.adjectives,
|
||||
titles=defaults.titles,
|
||||
)
|
||||
self.language.minimum_grapheme_count = 2
|
||||
self.place_generator = PlaceName
|
||||
self.suffixes = types.equal_weights(
|
||||
[
|
||||
"ieth",
|
||||
"ies",
|
||||
"ier",
|
||||
"ien",
|
||||
"iath",
|
||||
"ias",
|
||||
"iar",
|
||||
"ian",
|
||||
"ioth",
|
||||
"ios",
|
||||
"ior",
|
||||
"ion",
|
||||
],
|
||||
1.0,
|
||||
)
|
||||
|
||||
def get_surname(self) -> str:
|
||||
return self.place_generator.name()[0]["name"][0] + self.suffixes.random()
|
||||
|
||||
|
||||
Name = ElvishNameGenerator()
|
||||
NobleName = NobleElvishNameGenerator()
|
||||
@@ -0,0 +1,109 @@
|
||||
import logging
|
||||
import re
|
||||
|
||||
from language.types import Language
|
||||
|
||||
logger = logging.getLogger("elvish-rules")
|
||||
|
||||
permitted_starting_clusters = [
|
||||
"ch",
|
||||
"cl",
|
||||
"cr",
|
||||
"cw",
|
||||
"cy",
|
||||
"dh",
|
||||
"dj",
|
||||
"dr",
|
||||
"dw",
|
||||
"dy",
|
||||
"fl",
|
||||
"fn",
|
||||
"fr",
|
||||
"fw",
|
||||
"fy",
|
||||
"gl",
|
||||
"ll",
|
||||
"ly",
|
||||
"ml",
|
||||
"mw",
|
||||
"my",
|
||||
"ny",
|
||||
"rh",
|
||||
"ry",
|
||||
"sh",
|
||||
"sl",
|
||||
"sm",
|
||||
"sn",
|
||||
"st",
|
||||
"sv",
|
||||
"sw",
|
||||
"sy",
|
||||
"th",
|
||||
"tr",
|
||||
"tw",
|
||||
"ty",
|
||||
"vy",
|
||||
"wh",
|
||||
"wr",
|
||||
"wy",
|
||||
"yh",
|
||||
]
|
||||
|
||||
|
||||
def cannot_start_with_two_consonants(language: Language, word: str) -> bool:
|
||||
found = re.compile(r"(^[bcdfghklmnpqrstvwxz]{2})").search(word)
|
||||
if not found:
|
||||
return True
|
||||
|
||||
first, second = found.group(1)
|
||||
if first == second and first != "l":
|
||||
logger.debug(f"{word} starts with a repeated consonant.")
|
||||
return False
|
||||
|
||||
if found.group(1) not in permitted_starting_clusters:
|
||||
logger.debug("f{word} cannot start with {first}{second}")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def too_many_vowels(language: Language, word: str) -> bool:
|
||||
found = re.compile(r"[" + "".join(language.vowels.members) + "]{4}").findall(word)
|
||||
if found == []:
|
||||
return True
|
||||
logger.debug(f"{word} has too many contiguous vowels: {found}")
|
||||
return False
|
||||
|
||||
|
||||
def too_many_consonants(language: Language, word: str) -> bool:
|
||||
found = re.compile(r"[bcdfghklmnprstvw]{3}").findall(word)
|
||||
if found == []:
|
||||
return True
|
||||
logger.debug(f"{word} has too many contiguous consonants: {found}")
|
||||
return False
|
||||
|
||||
|
||||
def cannot_have_just_repeated_vowels(language: Language, word: str) -> bool:
|
||||
if len(word) == 1:
|
||||
return True
|
||||
uniq = {letter for letter in word}
|
||||
if len(uniq) > 1:
|
||||
return True
|
||||
logger.debug(f"{word} consists of only one repeated letter.")
|
||||
return False
|
||||
|
||||
|
||||
def must_have_a_vowel(language: Language, word: str) -> bool:
|
||||
for vowel in language.vowels.members:
|
||||
if vowel in word:
|
||||
return True
|
||||
logger.debug(f"{word} does not contain a vowel.")
|
||||
return False
|
||||
|
||||
|
||||
rules = {
|
||||
must_have_a_vowel,
|
||||
too_many_vowels,
|
||||
too_many_consonants,
|
||||
cannot_have_just_repeated_vowels,
|
||||
cannot_start_with_two_consonants,
|
||||
}
|
||||
Reference in New Issue
Block a user