git.schokokeks.org
Repositories
Help
Report an Issue
fs-draft.git
Code
Commits
Branches
Tags
Suche
Strukturansicht:
06d17a2
Branches
Tags
master
midgard
vorlage
fs-draft.git
source
vorlage
fsdraft.ts
fast perfekt
Christian Fraß
commited
06d17a2
at 2018-08-24 15:59:38
fsdraft.ts
Blame
History
Raw
type int = number; /** * @author kcf */ const configuration = { "replace_fs_umlauts": false, "target": "eng", }; /** * @author kcf */ function mark( core, classes ) { const contains = ((list, entry) => (list.indexOf(entry) >= 0)); if (configuration["replace_fs_umlauts"]) { if ( contains(classes, "lang_flk") && ! contains(classes, "type_letter") ) { core = ( core .replace(new RegExp("ö", "g"), "oy") .replace(new RegExp("ü", "g"), "uy") ); } } return ('<span class="' + classes.join(" ") + '">' + core + '</span>'); } /** * @author kcf */ function format_single( type, language ) { return ( function (piece) { return mark(piece, [type, "lang_" + language]); } ); } /** * @author kcf */ function format_list( type, language ) { return ( function (pieces) { return ( ((pieces === undefined) || (pieces === null) || (pieces.length <= 0)) ? "?" : pieces.map(format_single(type, language)).join(", ") ); } ); } /** * @author kcf */ function format_correlation( type, language_from = "flk", language_to = null ) { if (language_to === null) language_to = configuration["target"]; return ( function (source) { let output = ""; output += format_list(type, language_from)(source[language_from]); output += " ~ "; output += format_list(type, language_to)(source[language_to]); return output; } ); } /** * @author fenris */ function objvals( objekt : {[key : string] : any} ) : Array<any> { return Object.keys(objekt).map(key => objekt[key]); } /** * @author fenris */ function merge<typ_element>( liste_x : Array<typ_element>, liste_y : Array<typ_element>, ordnung : (x : typ_element, y : typ_element)=>boolean ) : Array<typ_element> { if (liste_x.length <= 0) { return liste_y; } else if (liste_y.length <= 0) { return liste_x; } else { return ( ordnung(liste_x[0], liste_y[0]) ? ([liste_x[0]].concat(merge(liste_x.slice(1), liste_y, ordnung))) : ([liste_y[0]].concat(merge(liste_x, liste_y.slice(1), ordnung))) ); } } /** * @author fenris */ function mergesort<typ_element>( liste : Array<typ_element>, ordnung : (x : typ_element, y : typ_element)=>boolean ) : Array<typ_element> { if (liste.length <= 1) { return liste; } else { let n : int = <int>(Math.floor(liste.length/2)); return merge( mergesort(liste.slice(0, n), ordnung), mergesort(liste.slice(n), ordnung), ordnung ); } } /** * @author fenris */ function order_list<typ_element>( liste : Array<typ_element>, kollation : (x : typ_element, y : typ_element)=>boolean = ((x, y) => (x === y)) ) : (x : typ_element, y : typ_element)=>boolean { return ( (x, y) => { let i : int = liste["findIndex"]((element) => kollation(x, element)); let j : int = liste["findIndex"]((element) => kollation(y, element)); return (i <= j); } ); } /** * @author fenris */ function order_lex( ordnungen : Array<(x : any, y : any)=>boolean> ) : (x : Array<any>, y : Array<any>)=>boolean { return ( (x, y) => { if ( (ordnungen.length <= 0) || (x.length <= 0) || (y.length <= 0) ) { return true; } else { let le : boolean = ordnungen[0](x[0], y[0]); let ge : boolean = ordnungen[0](y[0], x[0]); if (le && !ge) { return true; } else if (!le && ge) { return false; } else { return order_lex(ordnungen.slice(1))(x.slice(1), y.slice(1)); } } } ); } /** * @author fenris */ function kollation_satz( kollationen : {[name : string] : (x : any, y : any)=>boolean}, satz_x : {[namen : string] : any}, satz_y : {[namen : string] : any}, namen : Array<string> ) : boolean { return ( namen.every( (name) => kollationen[name](satz_x[name], satz_y[name]) ) ); } /** * @author fenris */ function sammeln( kollationen : {[name : string] : (x : any, y : any)=>boolean}, ordnungen : {[name : string] : (x : any, y : any)=>boolean}, daten : Array<{[name : string] : any}>, namen : Array<string> ) : Array<{[name : string] : any}> { let liste : Array<{[name : string] : any}> = []; // Heraussuchen daten .forEach( (satz_urspruenglich) => { let satz_neu : {[name : string] : any} = {}; namen.forEach(name => {satz_neu[name] = satz_urspruenglich[name];}); let vorhanden : boolean = liste.some((satz_alt) => kollation_satz(kollationen, satz_alt, satz_neu, namen)); if (! vorhanden) { liste.push(satz_neu); } } ); // Sortieren liste = mergesort<{[name : string] : any}>( liste, (x, y) => { let x_ : Array<any> = namen.map(name => x[name]); let y_ : Array<any> = namen.map(name => y[name]); let ordnung : (x : any, y : any)=>boolean = order_lex(namen.map((name) => ordnungen[name])); return ordnung(x_, y_); } ); return liste; } /** * @author fenris */ function anzeigen( { "daten": daten, "spalten": namen, "kollationen": kollationen = {}, "ordnungen": ordnungen = {}, "sortierung_propagieren": sortierung_propagieren = true, } : { daten : Array<{[name : string] : any}>; spalten : Array<string>; kollationen ?: {[name : string] : (x : any, y : any)=>boolean}; ordnungen ?: {[name : string] : (x : any, y : any)=>boolean}; sortierung_propagieren ?: boolean; } ) : {meta : any; data : Array<{[name : string] : any}>;} { // Kollationen und Ordnungen vervollständigen { namen .forEach( (name) => { // Kollation ergänzen if (! kollationen.hasOwnProperty(name)) { kollationen[name] = ((x, y) => (x === y)); } // Ordnung ergänzen if (! ordnungen.hasOwnProperty(name)) { ordnungen[name] = (sortierung_propagieren ? ((x, y) => false) : ((x, y) => (x <= y))); } } ); } const werte : Array<{[name : string] : any}> = sammeln(kollationen, ordnungen, daten, namen); /* let meta = { "x": {}, "y": {}, }; werte.forEach((satz, nummer) => {let name : string = ("y" + nummer.toFixed(0)); meta.y[name] = satz;}); werte_waagerecht.forEach((satz, nummer) => {let name : string = ("x" + nummer.toFixed(0)); meta.x[name] = satz;}); */ return { "meta": null, "data": werte, }; } /* +------+------+------+ | xA | xB | xC | +------+------+------+ | a2 | b1 | c3 | | a1 | b1 | c0 | | a1 | b3 | c2 | | a2 | b2 | c4 | | a1 | b2 | c1 | | a2 | b4 | c5 | +------+------+------+ +------+------+------+------+------+ | xA | xB:b1| xB:b2| xB:b3| xB:b4| +------+------+------+------+------+ | a1 | c0 | c1 | c2 | -- | | a2 | c3 | c4 | -- | c5 | +------+------+------+------+------+ */ /** * @author fenris */ function anordnen( { "daten": daten, "senkrecht": namen_senkrecht, "waagerecht": namen_waagerecht, "kollationen": kollationen = {}, "ordnungen": ordnungen = {}, "feldsatz_kuerzen": feldsatz_kuerzen = true, "sortierung_propagieren": sortierung_propagieren = true, } : { daten : Array<{[name : string] : any}>; waagerecht : Array<string>; senkrecht : Array<string>; kollationen ?: {[name : string] : (x : any, y : any)=>boolean}; ordnungen ?: {[name : string] : (x : any, y : any)=>boolean}; feldsatz_kuerzen ?: boolean; sortierung_propagieren ?: boolean; } ) : {meta : {x : {[name : string] : any}; y : {[name : string] : any};}; data : Array<{[name : string] : any}>;} { // Kollationen und Ordnungen vervollständigen { ([].concat(namen_senkrecht).concat(namen_waagerecht)) .forEach( (name) => { // Kollation ergänzen if (! kollationen.hasOwnProperty(name)) { kollationen[name] = ((x, y) => (x === y)); } // Ordnung ergänzen if (! ordnungen.hasOwnProperty(name)) { ordnungen[name] = (sortierung_propagieren ? ((x, y) => false) : ((x, y) => (x <= y))); } } ); } const werte_senkrecht : Array<{[name : string] : any}> = sammeln(kollationen, ordnungen, daten, namen_senkrecht); const werte_waagerecht : Array<{[name : string] : any}> = sammeln(kollationen, ordnungen, daten, namen_waagerecht); let meta = { "x": {}, "y": {}, }; werte_senkrecht.forEach((satz, nummer) => {let name : string = ("y" + nummer.toFixed(0)); meta.y[name] = satz;}); werte_waagerecht.forEach((satz, nummer) => {let name : string = ("x" + nummer.toFixed(0)); meta.x[name] = satz;}); let data : Array<{[name : string] : any}> = ( Object.keys(meta.y) .map( (label_senkrecht) => { let satz_senkrecht : {[name : string] : any} = meta.y[label_senkrecht]; let satz_ergebnis : {[name : string] : any} = {}; // Kopf { let name : string = "_"; satz_ergebnis[name] = label_senkrecht; } // Rumpf { Object.keys(meta.x) .forEach( (label_waagerecht) => { let satz_waagerecht : {[name : string] : any} = meta.x[label_waagerecht]; let saetze_feld : Array<{[name : string] : any}> = ( daten .filter( (satz_urspruenglich) => ( kollation_satz(kollationen, satz_urspruenglich, satz_senkrecht, namen_senkrecht) && kollation_satz(kollationen, satz_urspruenglich, satz_waagerecht, namen_waagerecht) ) ) .map( (satz_urspruenglich) => { let satz_neu : {[name : string] : any} = {}; Object.keys(satz_urspruenglich) .forEach( (name) => { if ( ! feldsatz_kuerzen || ( namen_senkrecht.every((name_) => (name !== name_)) && namen_waagerecht.every((name_) => (name !== name_)) ) ) { satz_neu[name] = satz_urspruenglich[name]; } } ); return satz_neu; } ) ); satz_ergebnis[label_waagerecht] = saetze_feld; } ); } return satz_ergebnis; } ) ); return { "meta": meta, "data": data, }; } /** * @author fenris */ function xmlwrap( name : string, kern : string, att : string = "" ) : string { return (("<" + name + att + ">") + kern + ("</" + name + ">") + "\n"); } /** * @author fenris */ function htmltable( titel : Array<string>, daten : Array<Array<string>>, classes : Array<string> = [], _2d : boolean = false, ) : string { return ( xmlwrap( "table", ( // kopf xmlwrap( "thead", xmlwrap( "tr", ( titel .map( (titel_) => xmlwrap("th", titel_) ) .join("") ) ) ) + // rumpf xmlwrap( "tbody", ( daten .map( (satz) => xmlwrap( "tr", satz.map( (feld, nummer) => ( (_2d && (nummer === 0)) ? xmlwrap("th", feld) : xmlwrap("td", feld) ) ) .join("") ) ) .join("") ) ) ), (" class=\"" + classes.join(" ") + "\"") ) ); } /** * @author kcf */ export function definieren( ) : any { return { "name": "fsdraft", "befehle": [ { "name": "fsdraft-mark", "funktion": (args) => (wert) => { let classes = args; return mark(wert, classes); } }, { "name": "fsdraft-correlation", "funktion": (args) => (wert) => { let type = args.shift(); return format_correlation(type)(wert); } }, { "name": "fsdraft-table-1d", "funktion": (args) => (wert) => { let namen_ : string = ( (args.length > 0) ? args.shift() : null ); let namen : Array<string> = namen_.split("/"); let tabelle : {meta : any; data : Array<{[name : string] : any}>;} = anzeigen( { "daten": wert, "spalten": namen, } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( namen ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz).map( (label) => ( JSON.stringify(satz[label]) ) ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], false ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); }, }, { "name": "fsdraft-table-2d", "funktion": (args) => (wert) => { let senkrecht_ : string = ( (args.length > 0) ? args.shift() : null ); let waagerecht_ : string = ( (args.length > 0) ? args.shift() : null ); let senkrecht : Array<string> = ( (senkrecht_ !== null) ? senkrecht_.split("/") : [] ); let waagerecht : Array<string> = ( (waagerecht_ !== null) ? waagerecht_.split("/") : [] ); let tabelle : {meta : any; data : any;} = anordnen( { "daten": wert, "senkrecht": senkrecht, "waagerecht": waagerecht, } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( [""].concat( Object.keys(tabelle.meta.x).map( (label) => ( // JSON.stringify(tabelle.meta.x[label]) objvals(tabelle.meta.x[label]).join("/") ) ) ) ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz).map( (label) => ( (label === "_") // ? JSON.stringify(tabelle.meta.y[satz[label]]) ? objvals(tabelle.meta.y[satz[label]]).join("/") : JSON.stringify(satz[label]) /* : ( satz[label] .filter(x => (x["language_id"] === "flk")) .map(x => x["words"].join(", ")) .join("; ") ) */ ) ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], true ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); } }, { "name": "fsdraft-macro-phonology_and_orthography", "funktion": (args) => (wert) => { let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": [ "IPA-sound", "Latin letter Representation", "Runic Representation", "Folksprak Example", "English Example", ], "rumpf": ( wert .map( (eintrag) => { const format_repr : (repr : string, type : string)=>string = (repr, type) => { let repr_ : string = repr; let regexp : RegExp = (new RegExp("'([^']*)'", "g")); while (true) { let matching : any = regexp.exec(repr); if (matching === null) { break; } else { repr_ = repr_.replace(matching[0], mark(matching[1], ["type_" + type, "lang_flk"])); } } return repr_; }; const format_example : (word : string, language_id : string)=>string = (word, language_id) => { if (word == null) { return "--"; } else { let word_ : string = word; { let regexp : RegExp = (new RegExp("'([^']*)'", "g")); while (true) { let matching : any = regexp.exec(word); if (matching === null) { break; } else { word_ = word_.replace(matching[0], mark(matching[1], ["type_word", "lang_" + language_id])); } } } { let regexp : RegExp = (new RegExp("_([^_]*)_", "g")); while (true) { let matching : any = regexp.exec(word); if (matching === null) { break; } else { word_ = word_.replace(matching[0], "<u>" + matching[1] + "</u>"); } } } return word_; } }; let ipa : string = mark(eintrag["ipa"], ["ipa"]); let latin : string = format_repr(eintrag["latin"], "letter"); let runic : string = format_repr(eintrag["runic"], "rune"); let example_source : string = format_example(eintrag["examples"]["flk"], "flk"); let example_target : string = format_example(eintrag["examples"][configuration["target"]], configuration["target"]); return [ ipa, latin, runic, example_source, example_target, ]; } ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], false ); return (tabelle__); } }, { "name": "fsdraft-macro-principles", "funktion": (args) => (wert) => { let tabelle : {meta : any; data : any;} = anordnen( { "daten": wert, "senkrecht": [ "transition_id", ], "waagerecht": [ "language_id", ], "feldsatz_kuerzen": false, } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( [].concat( Object.keys(tabelle.meta.x) .map( (label) => ( // JSON.stringify(tabelle.meta.x[label]) objvals(tabelle.meta.x[label]).join("/") ) ) ) ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz) .filter( (label) => (label !== "_") ) .map( (label) => { if (label === "_") { return objvals(tabelle.meta.y[satz[label]]).join("/") } else { let head = satz[label][0]; if (head !== undefined) { return ( ( (head["phones"].length <= 0) ? "?" : ( head["phones"] .map( (phone) => ( mark(phone, ["type_letter", "lang_" + head["language_id"]]) ) ) .join( ", " ) ) ) + "<br/>" + ( (head["examples"][0] != undefined) ? ("[" + mark(head["examples"][0], ["type_word", "lang_" + head["language_id"]]) + "]") : "" ) ); } else { return "?"; } } } ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], false ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); } }, { "name": "fsdraft-macro-personal_pronouns", "funktion": (args) => (wert) => { let tabelle : {meta : any; data : any;} = anordnen( { "daten": wert, "senkrecht": [ "count_id", "person_id", "gender_id", ], "waagerecht": [ "type_id", "case_id", ], } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( [""].concat( Object.keys(tabelle.meta.x) .map( (label) => ( objvals(tabelle.meta.x[label]).join("/") ) ) ) ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz) .map( (label) => { if (label === "_") { return objvals(tabelle.meta.y[satz[label]]).join("/") } else { let language_from : string = "flk"; let language_to : string = configuration["target"]; let source : {[language_id : string] : Array<string>} = {}; satz[label].forEach((eintrag) => {source[eintrag["language_id"]] = eintrag["words"];}); return format_correlation("type_word", language_from, language_to)(source); } } ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], true ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); } }, { "name": "fsdraft-macro-correlatives", "funktion": (args) => (wert) => { let tabelle : {meta : any; data : any;} = anordnen( { "daten": wert, "senkrecht": [ "domain_id", ], "waagerecht": [ "type_id", ], } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( [""].concat( Object.keys(tabelle.meta.x) .map( (label) => ( objvals(tabelle.meta.x[label]).join("/") ) ) ) ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz) .map( (label) => { if (label === "_") { return objvals(tabelle.meta.y[satz[label]]).join("/") } else { let language_from : string = "flk"; let language_to : string = configuration["target"]; let source : {[language_id : string] : Array<string>} = {}; satz[label].forEach((eintrag) => {source[eintrag["language_id"]] = eintrag["words"];}); return format_correlation("type_word", language_from, language_to)(source); } } ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], true ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); } }, { "name": "fsdraft-macro-adpositions", "funktion": (args) => (wert) => { let tabelle : {meta : any; data : any;} = anordnen( { "daten": wert, "senkrecht": [ "situation_id", ], "waagerecht": [ "type_id", "reference_id", ], } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( [""].concat( Object.keys(tabelle.meta.x) .map( (label) => ( objvals(tabelle.meta.x[label]).join("/") ) ) ) ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz) .map( (label) => { if (label === "_") { return objvals(tabelle.meta.y[satz[label]]).join("/") } else { let language_from : string = "flk"; let language_to : string = configuration["target"]; let source : {[language_id : string] : Array<string>} = {}; satz[label].forEach((eintrag) => {source[eintrag["language_id"]] = eintrag["words"];}); return format_correlation("type_word", language_from, language_to)(source); } } ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], true ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); } }, { "name": "fsdraft-macro-declension", "funktion": (args) => (wert) => { let tabelle : {meta : any; data : any;} = anordnen( { "daten": wert, "senkrecht": [ "count_id", "definiteness_id", ], "waagerecht": [ "case_id", ], } ); let tabelle_ : {kopf : Array<string>; rumpf : Array<Array<string>>;} = { "kopf": ( [""].concat( Object.keys(tabelle.meta.x) .map( (label) => ( objvals(tabelle.meta.x[label]).join("/") ) ) ) ), "rumpf": tabelle.data.map( (satz) => ( Object.keys(satz) .map( (label) => { if (label === "_") { return objvals(tabelle.meta.y[satz[label]]).join("/") } else { let language_from : string = "flk"; let language_to : string = configuration["target"]; let source : {[language_id : string] : Array<string>} = {}; satz[label].forEach((eintrag) => {source[eintrag["language_id"]] = eintrag["words"];}); return format_correlation("type_word", language_from, language_to)(source); } } ) ) ), }; let tabelle__ : string = htmltable( tabelle_.kopf, tabelle_.rumpf, ["datatable"], true ); let style : string = ""; // xmlwrap("style", "th,td {font-family: monospace; font-size: 0.875em;}"); return (style + tabelle__); } }, ], }; }