Skip to content

Commit c8ce79a

Browse files
committed
repl glossing
1 parent 32b5676 commit c8ce79a

File tree

8 files changed

+78
-12
lines changed

8 files changed

+78
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ will turn out as
226226
- [ ] Better cache
227227
- [ ] `translator`: Automatic translation according to gloss
228228
- [x] Evolve each form (with affixes)
229-
- [ ] Match-up forms and glosses
229+
- [x] Match-up forms and glosses
230230
- [ ] Better cache
231231
- [ ] `book`: Generate a grammar/lexicon reference with less boilerplate
232232
- [x] Conlang-to-English lexicon, with entries, affixes and templates:

pyconlang/ipa.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

pyconlang/repl.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from cmd import Cmd
22
from dataclasses import dataclass, field
33
from operator import attrgetter
4-
from typing import Callable
4+
from typing import Callable, Tuple
55

66
from prompt_toolkit import PromptSession
77
from prompt_toolkit.history import FileHistory
@@ -12,6 +12,8 @@
1212
from .errors import show_exception
1313
from .evolve.types import Evolved
1414
from .translate import Translator
15+
from .types import Form
16+
from .unicode import center, length
1517

1618
HISTORY_PATH = PYCONLANG_PATH / "repl.history"
1719

@@ -115,6 +117,24 @@ def do_s(self, line: str) -> None:
115117
"""
116118
self.do_simple(line)
117119

120+
def do_gloss(self, line: str) -> None:
121+
"""
122+
Translates and glosses the translation.
123+
"""
124+
125+
def pair_width(pair: Tuple[Evolved, Form]) -> int:
126+
return 2 + max(length(pair[0].modern), length(str(pair[1])))
127+
128+
gloss = self.translator.gloss_string(line)
129+
print(" ".join(center(pair[0].modern, pair_width(pair), " ") for pair in gloss))
130+
print(" ".join(center(str(pair[1]), pair_width(pair), " ") for pair in gloss))
131+
132+
def do_g(self, line: str) -> None:
133+
"""
134+
See gloss.
135+
"""
136+
return self.do_gloss(line)
137+
118138

119139
def run(command: str = "") -> None:
120140
session = ReplSession()

pyconlang/translate.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from dataclasses import dataclass, field
2-
from typing import List, Mapping
2+
from typing import List, Mapping, Sequence, Tuple
33

44
from .evolve import Evolver
55
from .evolve.types import Evolved
@@ -17,10 +17,15 @@ class Translator:
1717
def evolve(self, form: Form) -> Evolved:
1818
return self.evolver.evolve_single(self.lexicon.resolve(form))
1919

20+
def resolve_and_evolve(self, forms: Sequence[Form]) -> List[Evolved]:
21+
return self.evolver.evolve([self.lexicon.resolve(form) for form in forms])
22+
2023
def evolve_string(self, string: str) -> List[Evolved]:
21-
return self.evolver.evolve(
22-
[self.lexicon.resolve(form) for form in parse_sentence(string)]
23-
)
24+
return self.resolve_and_evolve(parse_sentence(string))
25+
26+
def gloss_string(self, string: str) -> Sequence[Tuple[Evolved, Form]]:
27+
forms = parse_sentence(string)
28+
return list(zip(self.resolve_and_evolve(forms), forms))
2429

2530
def evolve_entry(self, entry: Entry) -> List[Evolved]:
2631
return [

pyconlang/types.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@
99
class Rule:
1010
name: str
1111

12+
def __str__(self) -> str:
13+
return f"@{self.name}"
14+
1215

1316
@dataclass(eq=True, frozen=True)
1417
class Canonical:
1518
name: str
1619

20+
def __str__(self) -> str:
21+
return f"<{self.name}>"
22+
1723

1824
@dataclass(eq=True, frozen=True)
1925
class Proto:
@@ -25,6 +31,9 @@ def era_name(self) -> Optional[str]:
2531
return None
2632
return self.era.name
2733

34+
def __str__(self) -> str:
35+
return f"*{self.form}{self.era or ''}"
36+
2837

2938
@dataclass(eq=True, frozen=True)
3039
class TemplateName:
@@ -76,6 +85,21 @@ def from_form(cls, form: "Form") -> "Compound":
7685
case _:
7786
return Compound(form)
7887

88+
def __str__(self) -> str:
89+
return (
90+
"".join(
91+
affix.name + "."
92+
for affix in self.affixes
93+
if affix.type == AffixType.PREFIX
94+
)
95+
+ str(self.stem)
96+
+ "".join(
97+
"." + affix.name
98+
for affix in self.affixes
99+
if affix.type == AffixType.SUFFIX
100+
)
101+
)
102+
79103

80104
Form = Union[SimpleForm, Compound]
81105

pyconlang/unicode.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from wcwidth import wcswidth
2+
3+
PRIMARY_STRESS = "\u02c8"
4+
5+
6+
def remove_primary_stress(word: str) -> str:
7+
return word.replace(PRIMARY_STRESS, "")
8+
9+
10+
def length(string: str) -> int:
11+
return wcswidth(string)
12+
13+
14+
def center(string: str, width: int, fill_char: str = " ") -> str:
15+
diff = max(0, width - length(string))
16+
add_left = int(diff / 2)
17+
add_right = int((diff + 1) / 2)
18+
19+
return fill_char * add_left + string + fill_char * add_right

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ dependencies = [
1717
"click==8.1.3",
1818
"toml==0.10.2",
1919
"pyparsing==3.0.9",
20-
"unidecode==1.3.4"
20+
"unidecode==1.3.4",
21+
"wcwidth==0.2.5 "
2122
]
2223
dynamic = ["version"]
2324

stubs/wcwidth/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def wcswidth(string: str) -> int:
2+
...

0 commit comments

Comments
 (0)