PronounsPage/components/ExampleItem.vue
2025-04-22 14:29:10 +02:00

68 lines
2.2 KiB
Vue

<script setup lang="ts">
import type { Example, ExampleValues } from '~/src/language/examples.ts';
const props = defineProps<{
example: Example;
exampleValues: ExampleValues;
showPronunciation?: boolean;
}>();
const config = useConfig();
const startsWithArabicLetter = /^[\u0621-\u064A]/;
const endsWithArabicLetter = /[\u0621-\u064A]$/;
const zeroWidthJoiner = '\u200d';
const getContent = (index: number): string | undefined => {
return props.example.getSpelling(index, props.exampleValues);
};
const getPrepend = (index: number): string => {
if (getContent(index)?.match(startsWithArabicLetter) &&
index > 0 && getContent(index - 1)?.match(endsWithArabicLetter)) {
return zeroWidthJoiner;
}
return '';
};
const getAppend = (index: number): string => {
if (getContent(index)?.match(endsWithArabicLetter) &&
index < props.example.parts.length - 1 && getContent(index + 1)?.match(startsWithArabicLetter)) {
return zeroWidthJoiner;
}
return '';
};
const processedExampleParts = computed(() => {
return props.example.parts.map((part, index) => {
const spelling = getPrepend(index) + getContent(index) + getAppend(index);
if (typeof part === 'string') {
return spelling;
}
switch (part.type) {
case 'morpheme':
return { type: 'morpheme', spelling, morpheme: part.morpheme } as const;
case 'noun':
return { type: 'noun', spelling } as const;
}
});
});
const pronunciation = computed(() => {
if (!props.showPronunciation) {
return undefined;
}
return props.example.toPronunciationString(config, props.exampleValues);
});
</script>
<template>
<template v-for="(part, index) in processedExampleParts" :key="index">
<Spelling v-if="typeof part === 'string'" :text="part" />
<strong v-else>
<Morpheme v-if="part.type === 'morpheme'" :morpheme="part.morpheme" :spelling="part.spelling" />
<Spelling v-else :text="part.spelling" />
</strong>
</template>
<slot></slot>
<Pronunciation v-if="pronunciation" :pronunciation />
</template>