diff --git a/ui/src/xmlEditor/StandAloneOXTED.tsx b/ui/src/xmlEditor/StandAloneOXTED.tsx index 3a8ad469..cceda81c 100644 --- a/ui/src/xmlEditor/StandAloneOXTED.tsx +++ b/ui/src/xmlEditor/StandAloneOXTED.tsx @@ -156,7 +156,7 @@ export function StandAloneOXTED({ editorConfig }: IProps): ReactElement { ) : (
- +
)} diff --git a/ui/src/xmlEditor/hur/dictionary.ts b/ui/src/xmlEditor/hur/dictionary.ts index a6592589..bcd0b364 100644 --- a/ui/src/xmlEditor/hur/dictionary.ts +++ b/ui/src/xmlEditor/hur/dictionary.ts @@ -2,11 +2,11 @@ import { XmlElementNode } from 'simple_xml'; import { getText, getMrps } from './xmlUtilities'; import { makeBoundTranscription } from './transcribe'; import { makeStandardAnalyses } from './standardAnalysis'; -import { logGlosses } from './glossProvider'; import { setGlosses, saveGloss } from './glossUpdater'; import { MorphologicalAnalysis, writeMorphAnalysisValue } from '../../model/morphologicalAnalysis'; -import { convertDictionary, updateDictionary } from './utility'; +import { convertDictionary, updateAndValidateDictionary } from './utility'; +import { isValid, normalize } from './morphologicalAnalysisValidator'; const dictionary: Map> = new Map(); @@ -30,16 +30,18 @@ export function annotateHurrianWord(node: XmlElementNode): void { delete node.attributes.firstAnalysisIsPlaceholder; } const mrps: Map = getMrps(node); - const analyses: Set = new Set(mrps.values()); + const analyses: Set = new Set( + Array.from(mrps.values()).map((an: string) => an.replaceAll(' ', '')) + ); let i: number; if (mrps.size > 0) { - i = Math.max(...Array.from(mrps.keys()).map(parseInt)); + i = Math.max(...Array.from(mrps.keys()).map(num => parseInt(num, 10))); } else { i = 0; } for (const analysis of possibilities) { - if (!analyses.has(analysis)) { + if (!analyses.has(analysis.replaceAll(' ', ''))) { i++; node.attributes['mrp' + i.toString()] = analysis; } @@ -59,12 +61,15 @@ export function annotateHurrianWord(node: XmlElementNode): void { node.attributes.firstAnalysisIsPlaceholder = 'true'; } } - logGlosses(); setGlosses(node); } } export function updateHurrianDictionary(node: XmlElementNode, number: number, value: string): void { + if (!isValid(value)) { + return; + } + value = normalize(value, false); if (number === 1) { delete node.attributes.firstAnalysisIsPlaceholder; } @@ -89,5 +94,5 @@ export function getDictionary(): { [key: string]: string[] } { } export function upgradeDictionary(object: { [key: string]: string[] }): void { - updateDictionary(dictionary, object); + updateAndValidateDictionary(dictionary, object); } diff --git a/ui/src/xmlEditor/hur/glossProvider.ts b/ui/src/xmlEditor/hur/glossProvider.ts index 85733632..f3da9c7d 100644 --- a/ui/src/xmlEditor/hur/glossProvider.ts +++ b/ui/src/xmlEditor/hur/glossProvider.ts @@ -1,4 +1,4 @@ -import {convertDictionary, updateDictionary} from './utility'; +import {convertDictionary, updateGlossesLexicon} from './utility'; //Dieses Modul kann Bedeutungen von Stämmen speichern und nachschlagen. const glosses: Map> = new Map(); @@ -47,14 +47,6 @@ export function retrieveGloss(word: string, pos: string): Set | null } } -export function logGlosses(): void -{ - for(const [key, value] of glosses) - { - console.log(key + ' -> ' + Array.from(value).sort().join('; ')); - } -} - export function getGlosses(): {[key: string]: string[]} { return convertDictionary(glosses); @@ -62,5 +54,5 @@ export function getGlosses(): {[key: string]: string[]} export function upgradeGlosses(object: {[key: string]: string[]}): void { - updateDictionary(glosses, object); + updateGlossesLexicon(glosses, object); } diff --git a/ui/src/xmlEditor/hur/glossUpdater.ts b/ui/src/xmlEditor/hur/glossUpdater.ts index 231bab0d..9eea1c8d 100644 --- a/ui/src/xmlEditor/hur/glossUpdater.ts +++ b/ui/src/xmlEditor/hur/glossUpdater.ts @@ -7,7 +7,7 @@ import {getStem} from './splitter'; function getPos(template: string): string { - if (template === 'noun' || template === 'indecl') + if (template === 'noun' || template === 'indecl' || template === '') { return template; } diff --git a/ui/src/xmlEditor/hur/morphologicalAnalysisValidator.ts b/ui/src/xmlEditor/hur/morphologicalAnalysisValidator.ts new file mode 100644 index 00000000..14713354 --- /dev/null +++ b/ui/src/xmlEditor/hur/morphologicalAnalysisValidator.ts @@ -0,0 +1,51 @@ +export function isValid(analysis: string): boolean { + const fields: string[] = analysis.split('@').map(field => field.trim()); + if (fields.length !== 5) { + return false; + } + const gloss = fields[1]; + const morphTag = fields[2]; + if (gloss === '' || morphTag === '') { + return false; + } + return true; +} +function normalizeOption(option: string): string { + if (option.startsWith('-')) { + return option.substring(1); + } + return option; +} +function normalizePairs(pairs: string[], unify: boolean): string[][] { + let result: string[][] = pairs.map((option: string) => option.split('→').map(s => s.trim())); + if (unify) { + result = result.filter((pair: string[]) => pair[1] !== ''); + } + return result; +} +function normalizeMorphTag(morphTag: string, unify: boolean): string { + if (morphTag.startsWith('{') && morphTag.endsWith('}')) { + const options: string[][] = normalizePairs(morphTag + .substring(1, morphTag.length - 1) + .replaceAll(' ', '') + .replaceAll('\n', '') + .split('}{'), unify); + if (unify && options.length === 1) { + return normalizeOption(options[0][1].trim()); + } + else { + return '{' + options + .map((pair: string[]) => pair[0] + ' → ' + normalizeOption(pair[1])) + .join('}{') + + '}'; + } + } else { + return normalizeOption(morphTag); + } +} +export function normalize(analysis: string, unify: boolean): string { + const fields: string[] = analysis.split('@').map(field => field.trim()); + const morphTag = fields[2]; + fields[2] = normalizeMorphTag(morphTag, unify); + return fields.join(' @ '); +} \ No newline at end of file diff --git a/ui/src/xmlEditor/hur/segment.ts b/ui/src/xmlEditor/hur/segment.ts index ae5de373..db906713 100644 --- a/ui/src/xmlEditor/hur/segment.ts +++ b/ui/src/xmlEditor/hur/segment.ts @@ -3,6 +3,14 @@ import {patterns, firstEnclitics} from './patterns'; const indecl = new Set(['tiššan', 'ḫenni']); +function postprocessSegmentation(segmentation: string): string { + segmentation = segmentation.replace('-=', '='); + if (segmentation.endsWith('-')) { + return segmentation.substring(0, segmentation.length - 1); + } + return segmentation; +} + function joinSegments(groups: string[], firstEnclitic: number) { const morphs = groups @@ -12,7 +20,7 @@ function joinSegments(groups: string[], firstEnclitic: number) .slice(firstEnclitic) .filter((enclitic: string | undefined) => enclitic !== undefined).join('='); const segmented = enclitics === '' ? morphs : morphs + '=' + enclitics; - return segmented; + return postprocessSegmentation(segmented); } export function segment(word: string): [string, string][] diff --git a/ui/src/xmlEditor/hur/splitter.ts b/ui/src/xmlEditor/hur/splitter.ts index 68a9d413..cf8e8ff2 100644 --- a/ui/src/xmlEditor/hur/splitter.ts +++ b/ui/src/xmlEditor/hur/splitter.ts @@ -14,20 +14,26 @@ export function getStem(segmentation: string): string { return segmentation.substring(0, i); } -export function getGrammaticalMorphemes(segmentation: string): string { - const i: number = findBoundary(segmentation); +function basicGetGrammaticalMorphemes(segmentation: string, i: number): string { if (i == segmentation.length) { - return ''; + return '-'; } else { + if (segmentation[i] === '=') { + return '-' + segmentation.substring(i); + } return segmentation.substring(i); } } +export function getGrammaticalMorphemes(segmentation: string): string { + const i: number = findBoundary(segmentation); + return basicGetGrammaticalMorphemes(segmentation, i); +} + export function getStemAndGrammaticalMorphemes(segmentation: string): [string, string] { const i: number = findBoundary(segmentation); const stem: string = segmentation.substring(0, i); - const grammaticalMorphemes = - i == segmentation.length ? '' : segmentation.substring(i); + const grammaticalMorphemes = basicGetGrammaticalMorphemes(segmentation, i); return [stem, grammaticalMorphemes]; } diff --git a/ui/src/xmlEditor/hur/utility.ts b/ui/src/xmlEditor/hur/utility.ts index 12f24e2b..b5419398 100644 --- a/ui/src/xmlEditor/hur/utility.ts +++ b/ui/src/xmlEditor/hur/utility.ts @@ -1,3 +1,5 @@ +import { isValid, normalize } from './morphologicalAnalysisValidator'; + export function convertDictionary(dictionary: Map>): { [key: string]: string[] } { const object: { [key: string]: string[] } = {}; for (const [key, value] of dictionary) { @@ -6,7 +8,7 @@ export function convertDictionary(dictionary: Map>): { [key: return object; } -export function updateDictionary(dictionary: Map>, object: { [key: string]: string[] }): void { +export function updateGlossesLexicon(dictionary: Map>, object: { [key: string]: string[] }): void { for (const [key, values] of Object.entries(object)) { const currSet = dictionary.get(key); if (currSet === undefined) { @@ -18,4 +20,27 @@ export function updateDictionary(dictionary: Map>, object: { } } } +} + +export function updateAndValidateDictionary(dictionary: Map>, object: { [key: string]: string[] }): void { + for (const [key, values] of Object.entries(object)) { + const currSet = dictionary.get(key); + if (currSet === undefined) { + const newSet: Set = new Set(); + for (const value of values) { + if (isValid(value)) { + newSet.add(normalize(value, true)); + } + } + if (newSet.size > 0) { + dictionary.set(key, newSet); + } + } else { + for (const value of values) { + if (isValid(value)) { + currSet.add(normalize(value, true)); + } + } + } + } } \ No newline at end of file