(grammar) allow multiple morphemes in a cell of a grammar table

This commit is contained in:
Valentyne Stigloher 2025-04-26 13:07:48 +02:00
parent f22148ceff
commit a3d4286c19
9 changed files with 170 additions and 166 deletions

View File

@ -15,23 +15,24 @@ const variantsFromBaseConverter = await loadGrammarTableVariantsConverter();
const expandVariantsForSection = (sectionVariants: SectionDefinition['variants']): Variant[] => {
if (Array.isArray(sectionVariants)) {
return sectionVariants.map((sectionVariant) => {
const morphemeCells = sectionVariant.morphemeCells.map((morphemeCell) => {
const cells = sectionVariant.morphemeCells.map((morphemeCell) => {
if (morphemeCell === null) {
return null;
return [];
}
if (typeof morphemeCell === 'string') {
return { morpheme: morphemeCell };
return [{ morpheme: morphemeCell }];
}
return {
const morphemeDisplayDefinitions = Array.isArray(morphemeCell) ? morphemeCell : [morphemeCell];
return morphemeDisplayDefinitions.map((morphemeCell) => ({
...morphemeCell,
prefix: morphemeCell.prefix ? toMorphemeValue(morphemeCell.prefix) : undefined,
suffix: morphemeCell.suffix ? toMorphemeValue(morphemeCell.suffix) : undefined,
highlightsMorphemes: morphemeCell.highlightsMorphemes
? new Set(morphemeCell.highlightsMorphemes)
: undefined,
};
}));
});
return { ...sectionVariant, morphemeCells };
return { ...sectionVariant, cells };
});
} else {
if (Object.hasOwn(variantsFromBaseConverter, sectionVariants.type)) {
@ -45,9 +46,8 @@ const buildVariantsForSection = (
sectionVariants: SectionDefinition['variants'],
): Variant[] => {
return expandVariantsForSection(sectionVariants).filter((variant) => {
return variant.morphemeCells.some((morphemeCell) => {
return morphemeCell !== null &&
props.exampleValues.morphemeValues.getSpelling(morphemeCell.morpheme) !== undefined;
return variant.cells.flatMap((cell) => cell).some((morphemeDisplay) => {
return props.exampleValues.morphemeValues.getSpelling(morphemeDisplay.morpheme) !== undefined;
});
});
};
@ -129,20 +129,24 @@ const rowHeaderCount = computed(() => {
</th>
</template>
</template>
<td v-for="(morphemeCell, index) in variant.morphemeCells" :key="index">
<MorphemeWithPronunciation
v-if="morphemeCell !== null"
:morpheme="morphemeCell.morpheme"
:example-values
:prefix="morphemeCell.prefix"
:suffix="morphemeCell.suffix"
:highlights-morphemes="morphemeCell.highlightsMorphemes"
:examples
/>
<td v-for="(cell, index) in variant.cells" :key="index">
<template v-for="(morphemeDisplay, morphemeIndex) in cell" :key="morphemeIndex">
<template v-if="morphemeIndex > 0">
/
</template>
<MorphemeWithPronunciation
:morpheme="morphemeDisplay.morpheme"
:example-values
:prefix="morphemeDisplay.prefix"
:suffix="morphemeDisplay.suffix"
:highlights-morphemes="morphemeDisplay.highlightsMorphemes"
:examples
/>
</template>
</td>
<td
v-if="grammarTable.columnHeader.length > variant.morphemeCells.length"
:colspan="grammarTable.columnHeader.length - variant.morphemeCells.length"
v-if="grammarTable.columnHeader.length > variant.cells.length"
:colspan="grammarTable.columnHeader.length - variant.cells.length"
></td>
</tr>
</template>

View File

@ -1,4 +1,4 @@
import type { MorphemeCell, VariantsFromBaseConverter } from '~/src/language/grammarTables.ts';
import type { Cell, MorphemeDisplay, VariantsFromBaseConverter } from '~/src/language/grammarTables.ts';
const cases = ['n', 'g', 'd', 'a'];
@ -72,27 +72,27 @@ const adjectiveDeclensions: Category[] = [
const morphemesByCase = (
morphemeBase: string,
attributes: Pick<MorphemeCell, 'prefix' | 'suffix'> = {},
): MorphemeCell[] => {
return cases.map((caseAbbreviation) => ({ morpheme: `${morphemeBase}_${caseAbbreviation}`, ...attributes }));
attributes: Pick<MorphemeDisplay, 'prefix' | 'suffix'> = {},
): Cell[] => {
return cases.map((caseAbbreviation) => [{ morpheme: `${morphemeBase}_${caseAbbreviation}`, ...attributes }]);
};
export default {
'case': (sectionVariants) => {
return [{ morphemeCells: morphemesByCase(sectionVariants.base) }];
return [{ cells: morphemesByCase(sectionVariants.base) }];
},
'declension-with-case': (sectionVariants) => {
return declensions.map((declension) => ({
name: declension.name,
numerus: declension.numerus,
icon: declension.icon,
morphemeCells: morphemesByCase(`${sectionVariants.base}_${declension.abbreviation}`),
cells: morphemesByCase(`${sectionVariants.base}_${declension.abbreviation}`),
}));
},
'definiteness-with-case': (sectionVariants) => {
return definitenessCategories.map((definitenessCategory) => ({
name: definitenessCategory.name,
morphemeCells: morphemesByCase(`${definitenessCategory.abbreviation}${sectionVariants.base}`),
cells: morphemesByCase(`${definitenessCategory.abbreviation}${sectionVariants.base}`),
}));
},
'adjective-declension-with-case': (sectionVariants) => {
@ -100,7 +100,7 @@ export default {
const morphemeBase = `${sectionVariants.base}_${adjectiveDeclension.abbreviation}`;
return {
name: adjectiveDeclension.name,
morphemeCells: morphemesByCase(morphemeBase, { prefix: { spelling: '-' } }),
cells: morphemesByCase(morphemeBase, { prefix: { spelling: '-' } }),
};
});
},

View File

@ -23,6 +23,73 @@ pronouns:
- 'adjective'
- 'possessive'
- 'definitive'
grammarTables:
-
columnHeader:
-
name: 'именительный'
-
name: 'родительный'
-
name: 'дательный'
-
name: 'винительный'
-
name: 'творительный'
-
name: 'предложный'
sections:
-
variants:
-
morphemeCells:
- 'nominative'
-
-
morpheme: 'genitive'
-
morpheme: 'genitive_with_preposition'
- 'dative'
- 'accusative'
-
-
morpheme: 'instrumental'
-
morpheme: 'instrumental_with_preposition'
- 'prepositional'
-
columnHeader:
-
name: 'Окончание невозвратных глаголов в пр. в.'
-
name: 'Окончание возвратных глаголов в пр. в.'
-
name: 'Окончание кратких прилагательных'
-
name: 'Окончание прилагательных'
-
name: 'Притяжательное местоимение'
-
name: 'Определительное местоимение'
sections:
-
variants:
-
morphemeCells:
-
morpheme: 'nonreflexive_verb_past'
prefix: ''
-
morpheme: 'reflexive_verb_past'
prefix: ''
-
morpheme: 'short_adjective'
prefix: ''
-
morpheme: 'adjective'
prefix: ''
- 'possessive'
- 'definitive'
route: 'pronouns'
any: 'any'
plurals: true

View File

@ -1,67 +0,0 @@
<template>
<section>
<h2 class="h4">
<Icon v="spell-check" />
Грамматика:
</h2>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>именительный</th>
<th>родительный</th>
<th>дательный</th>
<th>винительный</th>
<th>творительный</th>
<th>предложный</th>
</tr>
</thead>
<tbody>
<tr>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="nominative" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="genitive" :counter="counter" /> / <PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="genitive_with_preposition" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="dative" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="accusative" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="instrumental" :counter="counter" /> / <PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="instrumental_with_preposition" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="prepositional" :counter="counter" /></td>
</tr>
</tbody>
</table>
</div>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Окончание невозвратных глаголов в пр. в.</th>
<th>Окончание возвратных глаголов в пр. в.</th>
<th>Окончание кратких прилагательных</th>
<th>Окончание прилагательных</th>
<th>Притяжательное местоимение</th>
<th>Определительное местоимение</th>
</tr>
</thead>
<tbody>
<tr>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="nonreflexive_verb_past" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="reflexive_verb_past" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="short_adjective" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="adjective" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="possessive" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="definitive" :counter="counter" /></td>
</tr>
</tbody>
</table>
</div>
</section>
</template>
<script>
export default {
props: {
selectedPronoun: { required: true },
counter: { required: true },
},
};
</script>

View File

@ -102,7 +102,7 @@ pronouns:
others: 'Другие формы'
othersRaw: 'другие'
or: 'или'
grammarTable: 'Таблица'
grammarTable: 'Грамматика'
pronunciation:
play: 'Включить аудио-сэмпл'

View File

@ -23,6 +23,69 @@ pronouns:
- 'adjective'
- 'possessive'
- 'definitive'
grammarTables:
-
columnHeader:
-
name: 'називний'
-
name: 'родовий'
-
name: 'давальний'
-
name: 'знахідний'
-
name: 'орудний'
-
name: 'місцевий'
sections:
-
variants:
-
morphemeCells:
- 'nominative'
-
-
morpheme: 'genitive'
-
morpheme: 'genitive_with_preposition'
- 'dative'
- 'accusative'
-
-
morpheme: 'instrumental'
-
morpheme: 'instrumental_with_preposition'
- 'prepositional'
-
columnHeader:
-
name: 'Закінчення незворотніх дієслів'
-
name: 'Закінчення зворотніх дієслів'
-
name: 'Закінчення прикметників'
-
name: 'Присвійний займенник'
-
name: 'Означальний займенник'
sections:
-
variants:
-
morphemeCells:
-
morpheme: 'nonreflexive_verb_past'
prefix: ''
-
morpheme: 'reflexive_verb_past'
prefix: ''
-
morpheme: 'adjective'
prefix: ''
- 'possessive'
- 'definitive'
route: 'pronouns'
any: 'будь-які'
plurals: true

View File

@ -1,65 +0,0 @@
<template>
<section>
<h2 class="h4">
<Icon v="spell-check" />
Граматика:
</h2>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>називний</th>
<th>родовий</th>
<th>давальний</th>
<th>знахідний</th>
<th>орудний</th>
<th>місцевий</th>
</tr>
</thead>
<tbody>
<tr>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="nominative" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="genitive" :counter="counter" /> / <PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="genitive_with_preposition" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="dative" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="accusative" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="instrumental" :counter="counter" /> / <PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="instrumental_with_preposition" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="prepositional" :counter="counter" /></td>
</tr>
</tbody>
</table>
</div>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Закінчення незворотніх дієслів</th>
<th>Закінчення зворотніх дієслів</th>
<th>Закінчення прикметників</th>
<th>Присвійний займенник</th>
<th>Означальний займенник</th>
</tr>
</thead>
<tbody>
<tr>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="nonreflexive_verb_past" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="reflexive_verb_past" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="adjective" :counter="counter" prepend="" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="possessive" :counter="counter" /></td>
<td><PronounsMorphemeWithPronunciation :pronoun="selectedPronoun" morpheme="definitive" :counter="counter" /></td>
</tr>
</tbody>
</table>
</div>
</section>
</template>
<script>
export default {
props: {
selectedPronoun: { required: true },
counter: { required: true },
},
};
</script>

View File

@ -76,7 +76,7 @@ pronouns:
others: 'Інші форми'
othersRaw: 'інші'
or: 'або'
grammarTable: 'Таблиця'
grammarTable: 'Граматика'
null:
header:
avoiding: 'Уникнення ґендерних форм'

View File

@ -20,7 +20,7 @@ export interface SectionDefinition {
export interface VariantDefinition {
name?: string;
morphemeCells: (string | MorphemeCellDefinition | null)[];
morphemeCells: (string | MorphemeCellDefinition | MorphemeCellDefinition[] | null)[];
}
export interface VariantsFromBaseDefinition {
@ -41,10 +41,12 @@ export interface Variant {
name?: string;
numerus?: 'singular' | 'plural';
icon?: string;
morphemeCells: (MorphemeCell | null)[];
cells: Cell[];
}
export interface MorphemeCell {
export type Cell = MorphemeDisplay[];
export interface MorphemeDisplay {
morpheme: string;
highlightsMorphemes?: Set<string>;
prefix?: MorphemeValue;