mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-03 11:07:00 -04:00
(nouns) resolve first declension in a consistent manner
This commit is contained in:
parent
a6a890fb10
commit
2d49b722c7
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { loadNounsData } from '~/src/data.ts';
|
||||
import { symbolsByNumeri } from '~/src/nouns.ts';
|
||||
import { resolveDeclensionByCase, symbolsByNumeri } from '~/src/nouns.ts';
|
||||
import type { NounClass, NounConvention, NounWord, Numerus } from '~/src/nouns.ts';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
@ -36,10 +36,17 @@ const word = computed((): NounWord | undefined => {
|
||||
declension: template.value.declension,
|
||||
};
|
||||
});
|
||||
|
||||
const declensionByCase = computed(() => {
|
||||
if (word.value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return resolveDeclensionByCase(word.value, props.numerus, nounsData);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="word" class="mb-3">
|
||||
<div v-if="word && declensionByCase" class="mb-3">
|
||||
<h5 class="h6">
|
||||
{{ symbolsByNumeri[numerus] }} <T>nouns.{{ numerus }}</T>
|
||||
</h5>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { loadNounsData } from '~/src/data.ts';
|
||||
import type { NounConvention, NounStemKey } from '~/src/nouns.ts';
|
||||
import { resolveFirstDeclension } from '~/src/nouns.ts';
|
||||
import type { NounConvention, NounWord } from '~/src/nouns.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
nounConvention: WithKey<NounConvention>;
|
||||
@ -14,16 +15,18 @@ if (nounsData === undefined) {
|
||||
|
||||
const template = props.nounConvention.templates.t1;
|
||||
|
||||
const stems: Record<NounStemKey, string> = {
|
||||
default: 'Arbeit',
|
||||
flucht: 'Arbeits',
|
||||
partizip: 'Arbeit',
|
||||
};
|
||||
const stems = nounsData.classes!.t1.exampleStems;
|
||||
|
||||
const stem = computed(() => {
|
||||
return stems[template.stem ?? 'default'];
|
||||
});
|
||||
|
||||
const word = computed((): NounWord => ({
|
||||
spelling: stem.value + template.suffix,
|
||||
convention: props.nounConvention.key,
|
||||
declension: template.declension,
|
||||
}));
|
||||
|
||||
const declension = nounsData.declensions?.[template.declension];
|
||||
|
||||
const singularExample = computed(() => {
|
||||
@ -31,7 +34,7 @@ const singularExample = computed(() => {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return `${props.nounConvention.morphemes.article_n ?? ''} ${stem.value}${template.suffix}${declension.singular.n}`;
|
||||
return resolveFirstDeclension(word.value, 'singular', nounsData);
|
||||
});
|
||||
|
||||
const pluralExample = computed(() => {
|
||||
@ -39,7 +42,7 @@ const pluralExample = computed(() => {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return `die ${stem.value}${template.suffix}${declension.plural.n}`;
|
||||
return resolveFirstDeclension(word.value, 'plural', nounsData);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { loadNounsData } from '~/src/data.ts';
|
||||
import { capitalise } from '~/src/helpers.ts';
|
||||
import type { Numerus, NounWord, NounCaseKey } from '~/src/nouns.ts';
|
||||
import { getFirstDeclension, resolveArticles, resolveDeclensionByCase } from '~/src/nouns.ts';
|
||||
import type { NounConvention, Numerus, NounWord } from '~/src/nouns.ts';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
word: NounWord;
|
||||
@ -16,47 +17,24 @@ const props = withDefaults(defineProps<{
|
||||
|
||||
const nounsData = await loadNounsData();
|
||||
|
||||
const declensionByCase = computed((): Record<NounCaseKey, string[]> | undefined => {
|
||||
if (props.word.declension === undefined) {
|
||||
const nounConvention = computed((): WithKey<NounConvention> | undefined => {
|
||||
if (props.word.convention === undefined || nounsData.conventions === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof props.word.declension === 'string') {
|
||||
return nounsData.declensions?.[props.word.declension]?.[props.numerus];
|
||||
}
|
||||
return props.word.declension[props.numerus];
|
||||
});
|
||||
|
||||
const nounConvention = computed(() => {
|
||||
if (props.word.convention === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return { ...nounsData.conventions?.[props.word.convention], key: props.word.convention };
|
||||
return { ...nounsData.conventions[props.word.convention], key: props.word.convention };
|
||||
});
|
||||
|
||||
const articles = computed(() => {
|
||||
if (nounConvention.value === undefined) {
|
||||
return {};
|
||||
}
|
||||
return Object.fromEntries(Object.entries(nounsData.classExample?.[props.numerus] ?? {})
|
||||
.map(([caseAbbreviation, article]) => {
|
||||
const resolvedArticle = article.replace(/\{([^}]+)}/, (_match, morpheme) => {
|
||||
const value = nounConvention.value?.morphemes?.[morpheme];
|
||||
if (value === undefined) {
|
||||
return '';
|
||||
}
|
||||
return typeof value === 'string' ? value : value.spelling;
|
||||
});
|
||||
return [caseAbbreviation, resolvedArticle];
|
||||
}));
|
||||
return resolveArticles(nounConvention.value, props.numerus, nounsData);
|
||||
});
|
||||
|
||||
const declensionByCase = computed(() => resolveDeclensionByCase(props.word, props.numerus, nounsData));
|
||||
|
||||
const firstDeclension = computed(() => {
|
||||
if (nounsData.cases === undefined) {
|
||||
return props.word.spelling;
|
||||
}
|
||||
const caseAbbreviation = Object.keys(nounsData.cases)[0];
|
||||
const ending = declensionByCase.value?.[caseAbbreviation][0] ?? '';
|
||||
return `${articles.value[caseAbbreviation] ?? ''}${props.word.spelling}${ending}`;
|
||||
return getFirstDeclension(props.word, nounsData, articles.value, declensionByCase.value);
|
||||
});
|
||||
|
||||
const visible = ref(props.open);
|
||||
|
@ -3,14 +3,14 @@ import SQL from 'sql-template-strings';
|
||||
|
||||
import { getLocale, loadConfig, loadNounsData, loadTranslator } from '~/server/data.ts';
|
||||
import { registerLocaleFont } from '~/server/localeFont.ts';
|
||||
import { buildNoun, displayWord, parseNounRow } from '~/server/nouns.ts';
|
||||
import { buildNoun, parseNounRow } from '~/server/nouns.ts';
|
||||
import type { NounRow } from '~/server/nouns.ts';
|
||||
import {
|
||||
availableGenders,
|
||||
availableNumeri,
|
||||
iconUnicodesByGender,
|
||||
longIdentifierByGender,
|
||||
numeri,
|
||||
numeri, resolveFirstDeclension,
|
||||
symbolsByNumeri,
|
||||
} from '~/src/nouns.ts';
|
||||
|
||||
@ -100,7 +100,7 @@ export default defineEventHandler(async (event) => {
|
||||
const symbol = symbolsByNumeri[numerus];
|
||||
noun.words[gender]?.[numerus]?.forEach((word) => {
|
||||
context.fillText(
|
||||
`${symbol} ${displayWord(word, numerus, nounsData)}`,
|
||||
`${symbol} ${resolveFirstDeclension(word, numerus, nounsData)}`,
|
||||
column * (width - 2 * padding) / genders.length + padding,
|
||||
padding * 2.5 + i * 48,
|
||||
);
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
loadTranslator,
|
||||
} from '~/server/data.ts';
|
||||
import { getInclusiveEntries } from '~/server/inclusive.ts';
|
||||
import { buildNoun, displayWord, getNounEntries } from '~/server/nouns.ts';
|
||||
import { buildNoun, getNounEntries } from '~/server/nouns.ts';
|
||||
import { rootDir } from '~/server/paths.ts';
|
||||
import { getSourcesEntries } from '~/server/sources.ts';
|
||||
import { getTermsEntries } from '~/server/terms.ts';
|
||||
@ -27,6 +27,7 @@ import { Day } from '~/src/calendar/helpers.ts';
|
||||
import { getUrlForLocale } from '~/src/domain.ts';
|
||||
import forbidden from '~/src/forbidden.ts';
|
||||
import { clearLinkedText, buildImageUrl } from '~/src/helpers.ts';
|
||||
import { resolveFirstDeclension } from '~/src/nouns.ts';
|
||||
import type { Numerus } from '~/src/nouns.ts';
|
||||
import parseMarkdown from '~/src/parseMarkdown.ts';
|
||||
import { normaliseQuery, validateQuery } from '~/src/search.ts';
|
||||
@ -638,7 +639,9 @@ const kinds: SearchKind[] = [
|
||||
.map((wordsByNumerus) => {
|
||||
return Object.entries(wordsByNumerus)
|
||||
.flatMap(([numerus, words]) => {
|
||||
return words.map((word) => displayWord(word, numerus as Numerus, nounsData));
|
||||
return words.map((word) => {
|
||||
return resolveFirstDeclension(word, numerus as Numerus, nounsData);
|
||||
});
|
||||
})
|
||||
.join(', ');
|
||||
})
|
||||
|
@ -10,7 +10,7 @@ import { loadWords, Noun } from '~/src/classes.ts';
|
||||
import type { NounRaw } from '~/src/classes.ts';
|
||||
import { clearKey } from '~/src/helpers.ts';
|
||||
import { addWordsFromClassInstance } from '~/src/nouns.ts';
|
||||
import type { Numerus, NounWord, NounsData } from '~/src/nouns.ts';
|
||||
import type { NounsData } from '~/src/nouns.ts';
|
||||
import type { User } from '~/src/user.ts';
|
||||
|
||||
export interface NounRow {
|
||||
@ -59,17 +59,6 @@ const parseNounRowWithAuthor = (nounRow: NounRowWithAuthor, isGranted: IsGranted
|
||||
return noun;
|
||||
};
|
||||
|
||||
export const displayWord = (word: NounWord, numerus: Numerus, nounsData: NounsData): string => {
|
||||
if (!nounsData.declensions || !nounsData.cases) {
|
||||
return word.spelling;
|
||||
}
|
||||
|
||||
const declension = typeof word.declension === 'string' ? nounsData.declensions[word.declension] : word.declension;
|
||||
const firstCaseAbbreviation = Object.keys(nounsData.cases)[0];
|
||||
const endings = declension?.[numerus]?.[firstCaseAbbreviation];
|
||||
return `${word.spelling}${endings?.[0] ?? ''}`;
|
||||
};
|
||||
|
||||
export const addVersions = async (
|
||||
db: Database,
|
||||
isGranted: IsGrantedFn,
|
||||
|
61
src/nouns.ts
61
src/nouns.ts
@ -117,6 +117,67 @@ export interface NounDeclension {
|
||||
plural?: Record<NounCaseKey, string[]>;
|
||||
}
|
||||
|
||||
export const resolveDeclensionByCase = (
|
||||
word: NounWord,
|
||||
numerus: Numerus,
|
||||
nounsData: NounsData,
|
||||
): Record<NounCaseKey, string[]> | undefined => {
|
||||
if (word.declension === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof word.declension === 'string') {
|
||||
return nounsData.declensions?.[word.declension]?.[numerus];
|
||||
}
|
||||
return word.declension[numerus];
|
||||
};
|
||||
|
||||
export const resolveArticles = (
|
||||
nounConvention: NounConvention,
|
||||
numerus: Numerus,
|
||||
nounsData: NounsData,
|
||||
): Record<NounCaseKey, string> => {
|
||||
return Object.fromEntries(Object.entries(nounsData.classExample?.[numerus] ?? {})
|
||||
.map(([caseAbbreviation, article]) => {
|
||||
const resolvedArticle = article.replace(/\{([^}]+)}/, (_match, morpheme) => {
|
||||
const value = nounConvention.morphemes?.[morpheme];
|
||||
if (value === undefined) {
|
||||
return '';
|
||||
}
|
||||
return typeof value === 'string' ? value : value.spelling;
|
||||
});
|
||||
if (resolvedArticle.trim().length === 0) {
|
||||
return [caseAbbreviation, ''];
|
||||
}
|
||||
return [caseAbbreviation, resolvedArticle];
|
||||
}));
|
||||
};
|
||||
|
||||
export const getFirstDeclension = (
|
||||
word: NounWord,
|
||||
nounsData: NounsData,
|
||||
articles: Record<NounCaseKey, string>,
|
||||
declensionByCase: Record<NounCaseKey, string[]> | undefined,
|
||||
): string => {
|
||||
if (nounsData.cases === undefined) {
|
||||
return word.spelling;
|
||||
}
|
||||
const caseAbbreviation = Object.keys(nounsData.cases)[0];
|
||||
const ending = declensionByCase?.[caseAbbreviation][0] ?? '';
|
||||
return `${articles[caseAbbreviation] ?? ''}${word.spelling}${ending}`;
|
||||
};
|
||||
|
||||
export const resolveFirstDeclension = (word: NounWord, numerus: Numerus, nounsData: NounsData) => {
|
||||
let articles;
|
||||
if (word.convention !== undefined && nounsData.conventions !== undefined) {
|
||||
const nounConvention = nounsData.conventions[word.convention];
|
||||
articles = resolveArticles(nounConvention, numerus, nounsData);
|
||||
} else {
|
||||
articles = {};
|
||||
}
|
||||
const declensionByCase = resolveDeclensionByCase(word, numerus, nounsData);
|
||||
return getFirstDeclension(word, nounsData, articles, declensionByCase);
|
||||
};
|
||||
|
||||
export interface NounDeclensionsByFirstCase {
|
||||
singular: Record<string, NounDeclensionKey>;
|
||||
plural: Record<string, NounDeclensionKey>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user