PronounsPage/components/nouns/NounsClassExample.vue
2025-07-27 23:43:57 +02:00

73 lines
2.2 KiB
Vue

<script setup lang="ts">
import { NounDeclension } from '~/src/classes.ts';
import { loadNounsData } from '~/src/data.ts';
import type { NounClass, NounConvention } from '~/src/nouns.ts';
const props = defineProps<{
nounClass: NounClass & { key: string };
nounConvention: NounConvention;
plural?: boolean;
}>();
const nounsData = await loadNounsData();
if (nounsData === undefined) {
throw new Error('nounsData is undefined');
}
const template = computed(() => props.nounConvention.templates[props.nounClass.key]);
const stem = computed(() => {
if (!template.value) {
return undefined;
}
return props.nounClass.exampleStems[template.value.stem ?? 'default'];
});
const numerus = computed(() => {
return !props.plural ? 'singular' : 'plural';
});
const declension = computed(() => {
if (!template.value || !stem.value) {
return undefined;
}
const declension = nounsData.declensions?.[template.value.declension];
if (declension?.[numerus.value] === undefined || nounsData.classExample?.[numerus.value] === undefined) {
return undefined;
}
const entries = Object.entries(declension[numerus.value] ?? {}).map(([caseAbbreviation, declensionSuffix]) => {
const article = nounsData.classExample?.[numerus.value][caseAbbreviation]
.replace(/\{([^}]+)}/, (_match, morpheme) => {
const value = props.nounConvention.morphemes[morpheme];
if (value === undefined) {
return '';
}
return typeof value === 'string' ? value : value.spelling;
}) ?? '';
return [
caseAbbreviation.toUpperCase() + (props.plural ? '_pl' : ''),
article + stem.value + template.value.suffix + declensionSuffix,
];
});
return new NounDeclension(Object.fromEntries(entries));
});
</script>
<template>
<div v-if="declension" class="mb-3">
<h5 class="h6">
<template v-if="!plural">
<T>nouns.singular</T>
</template>
<template v-else>
<T>nouns.plural</T>
</template>
</h5>
<NounsDeclension word="" :template="declension" open :plural />
</div>
</template>