diff options
| author | Alon Levy <alon@pobox.com> | 2014-12-16 17:37:42 +0200 |
|---|---|---|
| committer | Alon Levy <alon@pobox.com> | 2014-12-16 17:37:42 +0200 |
| commit | ade19de410e0a789a921ec1666b278b2a64176d6 (patch) | |
| tree | c4c54b106de93609ca7bb70a20fd4be696715dbe /src/textanalysis.js | |
| parent | c7d026b1d504323a8c61d51b726e5e8d2337fc4b (diff) | |
moving files around after repository merger
Diffstat (limited to 'src/textanalysis.js')
| -rw-r--r-- | src/textanalysis.js | 501 |
1 files changed, 0 insertions, 501 deletions
diff --git a/src/textanalysis.js b/src/textanalysis.js deleted file mode 100644 index 830c16c1..00000000 --- a/src/textanalysis.js +++ /dev/null @@ -1,501 +0,0 @@ -"use strict"; - -define(['rz_core', 'model/core', 'model/util', 'model/diff', 'rz_bus', 'consts'], -function(rz_core, model_core, model_util, model_diff, rz_bus, consts) { - -var typeindex = 0; -var nodetypes = consts.nodetypes; -var typeStack = []; - -var lastnode; - -var sugg = {}, // suggestions for autocompletion of node names - suggestions_options = new Bacon.Bus(); // TODO: Property: same as bus, but with initial value - -var ANALYSIS_NODE_START = 'ANALYSIS_NODE_START'; -var ANALYSIS_NODE = 'ANALYSIS_NODE' -var ANALYSIS_LINK = 'ANALYSIS_LINK'; - -function selectedType() -{ - return nodetypes[typeindex]; -} - -function autoSuggestAddName(name) -{ - /* note that name can contain spaces - this is ok. We might want to limit this though? */ - sugg[name] = 1; - suggestions_options.push(sugg); -} - -/* up_to_two_renames: - * - * allow one letter or 'new node' to anything changes */ -function up_to_two_renames(graph, old_name, new_name) -{ - var not_one_letter = false; - var k; - /* Allowed renames: - * no change - * s1 is substring of s2 - * older (s1) node being 'new node' - */ - function allowed_rename(s1, s2) - { - return (s1 == s2 || - s1 == 'new node' || - s1.substr(0, s2.length) == s2 || - s2.substr(0, s1.length) == s1); - } - - if (old_name.length != new_name.length) { - console.log('bug: up_to_two_renames: not equal inputs'); - return; - } - if (old_name.length > 2) { - console.log('bug: up_to_two_renames: input length 2 < ' + old_name.length); - return; - } - if (old_name.length == 2) { - if (allowed_rename(old_name[0], new_name[1]) && - allowed_rename(old_name[1], new_name[0])) { - old_name = [old_name[1], old_name[0]]; - } else { - if (!allowed_rename(old_name[0], new_name[0]) || - !allowed_rename(old_name[1], new_name[1])) { - not_one_letter = true; - } - } - } - if (not_one_letter) { - console.log('bug: up_to_two_renames: not one letter changes'); - console.log(old_name); - console.log(new_name); - return; - } - for (k = 0 ; k < old_name.length ; ++k) { - graph.editNameByName(old_name[k], new_name[k]); - } -} - -// TODO: add escape char, i.e. r"bla\"bla" -> ['bla"bla'] -function tokenize(text, node_token, quote) -{ - var segment = [], - subsegment = [], - sentence = [], - quoteword; - var j; - - segment = text.split(node_token); - for (j = 0; j < segment.length; j++) { - if (j !== 0) sentence.push(node_token); - subsegment = segment[j].split(" "); - if (subsegment.length === 0) { - sentence.push(" "); - } - for (var k = 0; k < subsegment.length; k++) { - if (subsegment[k] !== " " && subsegment[k] !== "") { - if (subsegment[k].charAt(0) === quote) { - quoteword = ""; - do { - quoteword += subsegment[k] + ' '; - if(subsegment[k].charAt(subsegment[k].length-1) !== quote)k++; - } while (k < subsegment.length && subsegment[k].charAt(subsegment[k].length - 1) !== quote); - if (subsegment[k] && subsegment[k]!==quoteword.replace(/ /g, "")) { - quoteword += subsegment[k]; - } - sentence.push(quoteword.replace(new RegExp(quote, 'g'), "")); - } else { - sentence.push(subsegment[k]); - } - } - } - } - return sentence; -} - -/* - * textAnalyser - * - * Input: - * @newtext - new sentence - * @finalize - is this an intermediate editing state or are we editing the graph - * - * Output: - * none - * - * Side effect: - * updating graph (global) - * - * Implementation notes: - * There is no well defined grammer. The translation goes from obvious to not - * so much for more complex sentences involving more than two nodes (two '#' - * marks). - * - */ -var textAnalyser = function (newtext, finalize) { - var sentence, - token_set_new_node_names = [], // token set representing new node names - token_set_new_link_names = [], // token set representing new link names - linkindex = 0, - nodeindex = 0, - orderStack = [], - and_count = 0, - prefix = "", - m, - word, - completeSentence, - typesetter, starGraph, - n, - link_hash = {}, - yell_bug = false, // TODO: fix both issues - NODE = "NODE", - LINK = "LINK", - START = "START", - ret = model_diff.new_topo_diff(); - - function addNode(name, type, state) { - if (type === undefined) { - console.log('bug: textanalyser.addNode of type undefined'); - } - var node = model_core.create_node_from_spec( - {'name':name, - 'type':type, - 'state':state}); - - ret.node_set_add.push(node); - } - - function __addLink(src, dst, name, state) { - if (!src || !dst) { - if (yell_bug) { - console.log('bug - adding link (' + src + ', ' + dst + ')'); - } - return; - } - if (link_hash[src] && link_hash[src][dst]) { - if (yell_bug) { - console.log('bug - adding link twice (' + src + ', ' + dst + ')'); - } - return; - } - if (!link_hash[src]) { - link_hash[src] = {}; - } - link_hash[src][dst] = 1; - - var link = {'__src': src, '__dst':dst, 'name':name, 'state':state}; // can't use model_core.create_link_from_spec as src,dst are only names - ret.link_set_add.push(link); - } - - function apply_conjugator_link_logic(link, drop_conjugator_links){ - if (drop_conjugator_links && link.name && (link.name.replace(/ /g,"") === "and")) { - link.state = "temp"; - } - } - - if (newtext.indexOf('#') == -1 || finalize) { - lastnode = null; - } - - //Sentence Sequencing - //Build the words and cuts the main elements - sentence = tokenize(newtext, '#', '"'); - - // build new node,link arrays in order of appearance - for (m = 0; m < sentence.length; m++) { - switch (sentence[m]) { - case "#": - orderStack.push(START); - break; - case "and": - case "+": - case ",": - case "&": - sentence[m] = "and"; - and_count++; - //orderStack.push("AND"); - default: - if (orderStack[orderStack.length - 1] === START) { - orderStack.push(NODE); - token_set_new_node_names.push(sentence[m]); - linkindex++; - } else if (orderStack[orderStack.length - 1] === NODE) { - orderStack.push(LINK); - if (!token_set_new_link_names[linkindex]) { - token_set_new_link_names[linkindex] = sentence[m] + " "; - } else { - token_set_new_link_names[linkindex] += sentence[m] + " "; - } - } else { - if (!token_set_new_link_names[linkindex]) { - token_set_new_link_names[linkindex] = sentence[m] + " "; - } else { - token_set_new_link_names[linkindex] += sentence[m] + " "; - } - } - if (token_set_new_node_names.length === 0) { - prefix += (prefix.length > 0 ? ' ' : '') + sentence[m]; - } - break; - } - } - - starGraph = (token_set_new_link_names.length - and_count) >= 3 || - ((token_set_new_link_names.length - and_count >= 1) && - token_set_new_link_names.length > 2 && - orderStack.length > 1 && - orderStack[orderStack.length - 1] != NODE); - - //PREFIX not null case - put complete sentence in first link. - if (prefix && !starGraph) { - token_set_new_link_names[1] = prefix + " " + token_set_new_node_names[0] + - (token_set_new_link_names[1] !== undefined || token_set_new_node_names[1] !== undefined ? - " " : "") - + (token_set_new_link_names[1] !== undefined ? token_set_new_link_names[1] : "") - + (token_set_new_node_names[1] !== undefined ? token_set_new_node_names[1] : ""); - } - - //WRITE COMPLETE SENTENCE - linkindex = 0; - nodeindex = 0; - word = ""; - completeSentence = prefix.length > 0 ? String(prefix) + " " : ""; - for (m = 0; m < orderStack.length; m++) { - if (orderStack[m] === NODE) { - word += " (" + token_set_new_node_names[nodeindex] + ") "; - completeSentence += token_set_new_node_names[nodeindex] + " "; - nodeindex++; - } else if (orderStack[m] === LINK) { - word += " -->" + token_set_new_link_names[nodeindex] + " --> "; - completeSentence += token_set_new_link_names[nodeindex]; - } - } - completeSentence = completeSentence.trim(); - - //REBUILD GRAPH - linkindex = 0; - nodeindex = 0; - - //CHANGE TO PERMANENT STATE AND UPDATE SUGGESTIONLIST - typesetter = ""; - if (finalize === true) { - typesetter = "perm"; - for (n = 0; n < token_set_new_node_names.length; n++) { - autoSuggestAddName(token_set_new_node_names[n]); - } - } else { - typesetter = "temp"; - } - - //ADD SURROUNDING BUBBLE - if (orderStack.length > 0) { - addNode("", "bubble","temp"); - } - - //0-N ORDER STACK - for (m = 0; m < orderStack.length - 1; m++) { - switch (orderStack[m]) { - case START: - if (!typeStack[nodeindex]) { - typeStack[nodeindex] = selectedType(); - } - break; - case NODE: - addNode(token_set_new_node_names[nodeindex], typeStack[nodeindex], typesetter); - if (!starGraph && nodeindex > 0) { - __addLink(token_set_new_node_names[nodeindex - 1], - token_set_new_node_names[nodeindex], - token_set_new_link_names[linkindex], typesetter); - } - nodeindex++; - break; - case LINK: - linkindex++; - break; - } - } - - //FINAL N ORDER - switch (orderStack[orderStack.length - 1]) { - case START: - typeStack[nodeindex] = selectedType(); - addNode("new node", typeStack[nodeindex], "temp"); - if (!starGraph && nodeindex > 0) { - __addLink(token_set_new_node_names[nodeindex - 1], "new node", - token_set_new_link_names[linkindex], "temp"); - and_connect("new node"); - } - ret.state = ANALYSIS_NODE_START; - break; - case NODE: - typeStack[nodeindex] = selectedType(); - addNode(token_set_new_node_names[nodeindex], typeStack[nodeindex], typesetter); - if (!starGraph && nodeindex > 0) { - __addLink(token_set_new_node_names[nodeindex - 1], - token_set_new_node_names[nodeindex], - token_set_new_link_names[linkindex], typesetter); - and_connect(token_set_new_node_names[nodeindex]); - } - ret.state = ANALYSIS_NODE_START; - break; - case LINK: - linkindex++; - addNode("new node", selectedType(), "temp"); - if (!starGraph) { - __addLink(token_set_new_node_names[nodeindex - 1], "new node", token_set_new_link_names[linkindex], "temp"); - and_connect("new node"); - } - ret.state = ANALYSIS_LINK; - break; - } - - //EXTERNAL AND CONNECTION CHECKING - function and_connect(node) { - var verb; - for(var x=0;x<token_set_new_link_names.length;x++){ - if(token_set_new_link_names[x])if(token_set_new_link_names[x].replace(/ /g,"")!=="and"){ - verb = token_set_new_link_names[x]; - for(var y=0; y<x ;y++){ - __addLink(token_set_new_node_names[y], node, verb, typesetter); - for(var z=x; z<token_set_new_node_names.length ;z++){ - __addLink(token_set_new_node_names[y], token_set_new_node_names[z], verb, typesetter); - } - } - } - } - } - - /*console.log(sentence); - console.log(completeSentence); - console.log(orderStack);*/ - - //STAR CASE - if (starGraph) { - addNode(completeSentence, "chainlink", typesetter); - for (n = 0; n < token_set_new_node_names.length; n++) { - __addLink(token_set_new_node_names[n], completeSentence, "", typesetter); - } - } - - ret.drop_conjugator_links = and_count < linkindex; - - ret.applyToGraph = function(graph, backend_commit) { - window.ret = ret; - - /* - * generate fitered node set who: - * - are not name-present in graph - * - are not of type 'bubble' - */ - var n_set = ret.node_set_add.filter(function(node) { - return false == graph.hasNodeByNameAndNotState(node.name, "temp") - && node.type !== 'bubble'; - }), - link_set = ret.link_set_add.map( - function (link) { - return [link.__src, link.__dst]; - }), - comp = graph.compareSubset('temp', n_set, link_set); - - if (false == finalize && comp.graph_same) { - if (comp.old_name && comp.new_name) { - up_to_two_renames(graph, comp.old_name, comp.new_name); - } - } else { - // REINITIALISE GRAPH (DUMB BUT IT WORKS) - graph.removeNodes(function(n){ return "temp" == n.state; }); - graph.removeLinks("temp"); - - ret.for_each_node_add(function (node) { - if (true == finalize && node.state == 'temp') { - console.log('bug: temp node creation on finalize'); - } else { - if (!finalize) { - lastnode = graph.addNode(node); - } else { - graph.addNode(node); - } - } - }); - } - ret.for_each_link_add(function (link) { - if (false == finalize || link.name !== 'and') { - apply_conjugator_link_logic(link, ret.drop_conjugator_links); - graph.addLinkByName(link.__src, - link.__dst, - link.name, - link.state); - } - }); - - if (!finalize) { - graph.markRelated(token_set_new_node_names); - } else { - graph.removeRelated(); - } - - if (finalize && backend_commit) { - // broadcast diff: - // - finalize? - // - broadcast_diff requested by caller - var topo_diff = model_util.adapt_format_write_topo_diff(ret.nodes, ret.links); - var diff_set = model_diff.new_diff_set(); - diff_set.add_diff_obj(topo_diff); - graph.commit_diff_set(diff_set); - } - - // UPDATE GRAPH ONCE - rz_core.update_view__graph(!finalize && comp.graph_same); - }; - - if (finalize) { - typeStack = []; - } - - return ret; -}; - -function init(graph) -{ - function onNodeAdded(diff) { - if (!diff || !diff.nodes || !diff.nodes.added) { - return; - } - for (var k in diff.nodes.added) { - var node = diff.nodes[k]; - autoSuggestAddName(node.name.toLowerCase()); - } - } - function toLowerCase(n) { - return n.toLowerCase(); - } - function onSuggestedNameAdd(names) { - names.map(toLowerCase).forEach(autoSuggestAddName); - } - graph.diffBus.onValue(onNodeAdded); - rz_bus.names.onValue(onSuggestedNameAdd); -} - -return { - init:init, - textAnalyser:textAnalyser, - suggestions_options: suggestions_options, - ANALYSIS_NODE_START:ANALYSIS_NODE_START, - ANALYSIS_NODE: ANALYSIS_NODE, - ANALYSIS_LINK:ANALYSIS_LINK, - - //for the external arrow-type changer - lastnode: function() { return lastnode; }, - - selected_type_next: function() { - typeindex = (typeindex + 1) % 5; - return selectedType(); - }, - selected_type_prev: function() { - typeindex = (typeindex + 4) % 5; - return selectedType(); - } -}; -}); |
