Add German IPA support (wiki-pronunciation-dict + epitran)
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 33s
CI / test-go-edu-search (push) Successful in 29s
CI / test-python-klausur (push) Failing after 2m12s
CI / test-python-agent-core (push) Successful in 15s
CI / test-nodejs-website (push) Successful in 17s

Hybrid approach mirroring English IPA:
- Primary: wiki-pronunciation-dict (636k entries, CC-BY-SA, Wiktionary)
- Fallback: epitran rule-based G2P (MIT license)

IPA modes now use language-appropriate dictionaries:
- auto/en: English IPA (Britfone + eng_to_ipa)
- de: German IPA (wiki-pronunciation-dict + epitran)
- all: EN column gets English IPA, other columns get German IPA
- none: disabled

Frontend shows CC-BY-SA attribution when German IPA is active.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-25 22:18:20 +01:00
parent a73ddce43d
commit f860eb66e6
7 changed files with 637123 additions and 34 deletions

View File

@@ -22,6 +22,7 @@ interface GridToolbarProps {
const IPA_LABELS: Record<IpaMode, string> = {
auto: 'IPA: Auto',
en: 'IPA: nur EN',
de: 'IPA: nur DE',
all: 'IPA: Alle',
none: 'IPA: Aus',
}
@@ -93,16 +94,26 @@ export function GridToolbar({
</button>
{/* IPA mode */}
<select
value={ipaMode}
onChange={(e) => onIpaModeChange(e.target.value as IpaMode)}
className="px-2 py-1.5 text-xs rounded-md border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400"
title="Lautschrift (IPA): Auto = nur bei erkannten englischen Woertern, Alle = fuer alle Vokabeln, Aus = keine"
>
{(Object.keys(IPA_LABELS) as IpaMode[]).map((m) => (
<option key={m} value={m}>{IPA_LABELS[m]}</option>
))}
</select>
<div className="flex items-center gap-1">
<select
value={ipaMode}
onChange={(e) => onIpaModeChange(e.target.value as IpaMode)}
className="px-2 py-1.5 text-xs rounded-md border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400"
title="Lautschrift (IPA): Auto = nur erkannte EN-Woerter, DE = deutsches IPA (Wiktionary), Alle = EN + DE, Aus = keine"
>
{(Object.keys(IPA_LABELS) as IpaMode[]).map((m) => (
<option key={m} value={m}>{IPA_LABELS[m]}</option>
))}
</select>
{(ipaMode === 'de' || ipaMode === 'all') && (
<span
className="text-[9px] text-gray-400 dark:text-gray-500 cursor-help"
title="DE-Lautschrift: Wiktionary (CC-BY-SA 4.0) + epitran (MIT). EN-Lautschrift: Britfone (MIT) + eng_to_ipa (MIT)."
>
CC-BY-SA
</span>
)}
</div>
{/* Syllable mode */}
<select

View File

@@ -14,7 +14,7 @@ export interface GridEditorState {
selectedZone: number | null
}
export type IpaMode = 'auto' | 'all' | 'en' | 'none'
export type IpaMode = 'auto' | 'all' | 'de' | 'en' | 'none'
export type SyllableMode = 'auto' | 'all' | 'de' | 'en' | 'none'
export function useGridEditor(sessionId: string | null) {