fs-walle-react-ts/src/LexAccessors.tsx

253 lines
6.7 KiB
TypeScript

import * as _ from 'lodash';
function simpleAccessor(lens: string, def: string = '') {
return {
get: (li: any) => {
let val = _.get<any>(li, lens, def);
return val;
},
set: (li: any, value: string) => {
let lexItem = _.cloneDeep(li);
let ret = _.set<any>(lexItem, lens, value);
return ret;
}
};
}
function simpleAttrAccessor(attrPred: any) {
let { attribVal, attribKey, pred, lens } = attrPred;
let def = (value: any) => ({ _: value, $: { [attribKey]: attribVal } });
return {
get: (li: any) => {
let allProps = _.get<any>(li, lens, def(''));
let prop = _.filter<any>(allProps, (m) => {
return pred(m);
});
let mcls = _.get<any>(prop, '[0]._', '');
return mcls;
},
set: (li: any, value: string) => {
let lexItem = _.cloneDeep(li);
let allProps = _.get<any>(lexItem, lens, []);
if (allProps.length > 0) {
let prop = _.filter<any>(allProps, (m) => {
return pred(m);
});
_.set(prop, '[0]._', value);
} else {
_.set(lexItem, lens, [def(value)]);
}
return lexItem;
}
};
}
function listAttrAccessor(attrPred: any) {
let { pred, lens } = attrPred;
return {
get: (li: any) => {
let def: any = [];
let morphProps = _.get<any>(li, lens, def);
let morphExps = _.filter<any>(morphProps, (m) => {
return pred(m);
});
let mEs = morphExps.map((me) => {
return _.get<any>(me, '_', me);
});
return mEs;
},
set: (li: any, value: any) => {
let lexItem = _.cloneDeep(li);
let allProps = _.get<any>(lexItem, lens, []);
if (allProps.length > 0) {
let keepProps = _.filter<any>(allProps, (m) => {
return !pred(m);
});
_.set(lexItem, lens, _.concat(keepProps, value));
} else {
_.set(lexItem, lens, value);
}
return lexItem;
}
};
}
function propListAttrAccessor(attrPred: any) {
let { attribKey, pred, lens } = attrPred;
return {
get: (li: any) => {
let def: any = [];
let morphProps = _.get<any>(li, lens, def);
let morphExps = _.filter<any>(morphProps, (m) => {
return pred(m);
});
let mEs = morphExps.map((me) => {
let value = _.get<any>(me, '_', me);
let key = _.get<any>(me, '$.' + attribKey, '');
return { value, key };
});
return mEs;
},
set: (li: any, value: any) => {
let lexItem = _.cloneDeep(li);
let allProps = _.get<any>(lexItem, lens, []);
let setValue = value.map((v: any) => {
let ret = {};
_.set(ret, '$.form', v.key);
_.set(ret, '_', v.value);
return ret;
});
if (allProps.length > 0) {
let keepProps = _.filter<any>(allProps, (m) => {
return !pred(m);
});
_.set(lexItem, lens, _.concat(keepProps, setValue));
} else {
_.set(lexItem, lens, setValue);
}
return lexItem;
}
};
}
const attrPredGen = (lens: string, key: string, val: string, comp: any) => {
const pred = (m: any) => comp(_.get<any>(m, '$.' + key, ''), val);
return { lens, attribKey: key, attribVal: val, pred };
};
const fieldMetaMap = {
label: {
type: 'text',
...simpleAccessor('label[0]'),
},
unl: { type: 'text', ...simpleAccessor('unl[0]'), },
synset: { type: 'text', ...simpleAccessor('lexprops[0].wnsynset[0]'), },
guid: { type: 'text', ...simpleAccessor('guid[0]'), },
pos: { type: 'select', ...simpleAccessor('pos[0]'), },
image: { type: 'preview', ...simpleAccessor('image[0]'), },
relations: { type: 'text', ...simpleAccessor('relations[0]'), },
frame: {
type: 'select',
...simpleAttrAccessor(attrPredGen(
'syntacticprops[0].property',
'id',
'frame',
_.isEqual
)),
},
cat: {
type: 'select',
...simpleAttrAccessor(attrPredGen(
'uiprops[0].property',
'id',
'cat',
_.isEqual
)),
},
subcat: {
type: 'select',
...simpleAttrAccessor(attrPredGen(
'uiprops[0].property',
'id',
'subcat',
_.isEqual
)),
},
morphclass: {
type: 'select',
...simpleAttrAccessor(attrPredGen(
'lexprops[0].morphology[0].morph',
'form',
'morphclass',
_.isEqual
))
},
morphexceptions: {
type: 'proplist',
...propListAttrAccessor(attrPredGen(
'lexprops[0].morphology[0].morph',
'form',
'morphclass',
_.negate(_.isEqual)
))
},
stats: { type: 'text', ...simpleAccessor('stats[0].property[0]._'), },
lang: {
type: 'select',
options: ['en', 'es'], ...simpleAccessor('$.id', 'en'),
},
syntacticprops: {
type: 'list',
...listAttrAccessor(attrPredGen(
'syntacticprops[0].property',
'id',
'frame',
_.negate(_.isEqual)
))
},
groups: {
type: 'list',
...listAttrAccessor(attrPredGen(
'groups[0].property',
'id',
'frame',
_.negate(_.isEqual)
))
},
};
function getSelectOptions(field: string, entries: any) {
let allOpts = entries.map((q: any) => {
return fieldMetaMap[field].get(q);
});
switch (fieldMetaMap[field].type) {
case 'select':
return _.uniq(allOpts);
case 'list':
return _.uniq(_.flatten(allOpts));
case 'proplist':
return _.uniq(_.map(_.flatten(allOpts), (v) => _.get<any>(v, 'key')));
default:
return [];
}
}
export const xmlToEntries = (xmlData: any) => {
let allEntries = _.chain(xmlData)
.get<any>('document.lexicon[0].item')
.flatMap((o: any) => _.chain(o)
.get<any>('entry')
.map((p: any) => _.chain(p)
.get<any>('lang[0]')
.set('guid[0]', o.$.guid)
.value())
.value()
)
.value();
let langReducer = ((result: any, q: any) => {
let lang = fieldMetaMap.lang.get(q);
(result[lang] || (result[lang] = [])).push(q);
return result;
});
let langEntries = _.reduce(allEntries, langReducer, {});
let langs = _.keys(langEntries);
let selectableFields = ['select', 'list', 'proplist'];
let selectFields = _.fromPairs(langs.map((lang) => {
let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => {
return _.includes(selectableFields, fieldMetaMap[s].type);
}).map((s) => {
let entries = _.get<any>(langEntries, lang, 'en');
// let allOpts = entries.map((q: any) => {
// return fieldMetaMap[s].get(q);
// });
// let select = _.isEqual(fieldMetaMap[s].type, 'select');
// let selectOptions = select ? _.uniq(allOpts) : _.uniq(_.flatten(allOpts));
return [s, getSelectOptions(s, entries)];
}));
return [lang, langOpts];
}));
return ({
allEntries, selectFields, fieldMetaMap
});
};