Skip to content
2 changes: 1 addition & 1 deletion ui/src/xmlEditor/StandAloneOXTED.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export function StandAloneOXTED({ editorConfig }: IProps): ReactElement {
) : (
<div className="container mx-auto">
<FileLoader accept="text/xml" onLoad={readFile} />
<FileLoader accept="text/json" onLoad={readDict} text="Wörterbuch hochladen"/>
<FileLoader accept="application/JSON" onLoad={readDict} text="Wörterbuch hochladen"/>
</div>
)}
</div>
Expand Down
19 changes: 12 additions & 7 deletions ui/src/xmlEditor/hur/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, Set<string>> = new Map();

Expand All @@ -30,16 +30,18 @@ export function annotateHurrianWord(node: XmlElementNode): void {
delete node.attributes.firstAnalysisIsPlaceholder;
}
const mrps: Map<string, string> = getMrps(node);
const analyses: Set<string> = new Set(mrps.values());
const analyses: Set<string> = 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;
}
Expand All @@ -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;
}
Expand All @@ -89,5 +94,5 @@ export function getDictionary(): { [key: string]: string[] } {
}

export function upgradeDictionary(object: { [key: string]: string[] }): void {
updateDictionary(dictionary, object);
updateAndValidateDictionary(dictionary, object);
}
12 changes: 2 additions & 10 deletions ui/src/xmlEditor/hur/glossProvider.ts
Original file line number Diff line number Diff line change
@@ -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<string, Set<string>> = new Map();
Expand Down Expand Up @@ -47,20 +47,12 @@ export function retrieveGloss(word: string, pos: string): Set<string> | 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);
}

export function upgradeGlosses(object: {[key: string]: string[]}): void
{
updateDictionary(glosses, object);
updateGlossesLexicon(glosses, object);
}
2 changes: 1 addition & 1 deletion ui/src/xmlEditor/hur/glossUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
51 changes: 51 additions & 0 deletions ui/src/xmlEditor/hur/morphologicalAnalysisValidator.ts
Original file line number Diff line number Diff line change
@@ -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(' @ ');
}
10 changes: 9 additions & 1 deletion ui/src/xmlEditor/hur/segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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][]
Expand Down
16 changes: 11 additions & 5 deletions ui/src/xmlEditor/hur/splitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
27 changes: 26 additions & 1 deletion ui/src/xmlEditor/hur/utility.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isValid, normalize } from './morphologicalAnalysisValidator';

export function convertDictionary(dictionary: Map<string, Set<string>>): { [key: string]: string[] } {
const object: { [key: string]: string[] } = {};
for (const [key, value] of dictionary) {
Expand All @@ -6,7 +8,7 @@ export function convertDictionary(dictionary: Map<string, Set<string>>): { [key:
return object;
}

export function updateDictionary(dictionary: Map<string, Set<string>>, object: { [key: string]: string[] }): void {
export function updateGlossesLexicon(dictionary: Map<string, Set<string>>, object: { [key: string]: string[] }): void {
for (const [key, values] of Object.entries(object)) {
const currSet = dictionary.get(key);
if (currSet === undefined) {
Expand All @@ -18,4 +20,27 @@ export function updateDictionary(dictionary: Map<string, Set<string>>, object: {
}
}
}
}

export function updateAndValidateDictionary(dictionary: Map<string, Set<string>>, object: { [key: string]: string[] }): void {
for (const [key, values] of Object.entries(object)) {
const currSet = dictionary.get(key);
if (currSet === undefined) {
const newSet: Set<string> = 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));
}
}
}
}
}