New kwic view
diff --git a/public/translatehtml.js b/public/translatehtml.js
new file mode 100644
index 0000000..4a1f4c6
--- /dev/null
+++ b/public/translatehtml.js
@@ -0,0 +1,147 @@
+var cleanRegex = /^([^\/]+?\/)?[^\:]+?\:/;
+var splitRegex = /^(.+?):([^:]+?)$/;
+
+// SnippetTree constructor
+function SnippetTree (obj) {
+ this.children = [];
+ this.data = obj;
+
+ // Replace title
+ this.cleanTitle = function (title) {
+ return title.replace(cleanRegex, "");
+ };
+
+ // Add new child to tree
+ this.addChild = function (childData) {
+ var c = new SnippetTree (childData);
+ this.children.push(c);
+ return c;
+ };
+
+ // Recursively parse children
+ this.parseChildren = function (children) {
+ for (var i in children) {
+ var c = children[i];
+ if (c.nodeType === 1) {
+ if (c.getAttribute("title")) {
+ var title = this.cleanTitle(c.getAttribute("title"));
+ var childTree = this.addChild({ type : title });
+ if (c.hasChildNodes())
+ childTree.parseChildren(c.childNodes);
+ }
+ else if (c.hasChildNodes())
+ this.parseChildren(c.childNodes);
+ }
+ else if (c.nodeType === 3)
+ if (c.nodeValue.match(/[-a-z0-9]/i)) {
+ this.addChild({
+ type : "leaf",
+ word : c.nodeValue
+ });
+ };
+ };
+ return this;
+ };
+};
+
+
+// SnippetTable constructor
+function SnippetTable (obj) {
+ this.info = [];
+ this.overall = {};
+ this.pos = 0;
+ this.load = function (children) {
+ for (var i in children) {
+ var c = children[i];
+
+ // element with title
+ if (c.nodeType === 1) {
+ if (c.getAttribute("title")) {
+ if (splitRegex.exec(c.getAttribute("title"))) {
+
+ // Create object on position unless it exists
+ if (!this.info[this.pos]) {
+ this.info[this.pos] = {};
+ };
+
+ // Fill position with info
+ this.info[this.pos][RegExp.$1] = RegExp.$2;
+ this.overall[RegExp.$1] = 1;
+ };
+ };
+
+ // depth search
+ if (c.hasChildNodes())
+ this.load(c.childNodes);
+ }
+
+ // Leaf node - store string on position and go to next string
+ else if (c.nodeType === 3)
+ if (c.nodeValue.match(/[-a-z0-9]/i))
+ this.info[this.pos++]["-s"] = c.nodeValue;
+ };
+ return this;
+ };
+};
+
+
+// Make tree from snippet
+function translateTree (snippet) {
+ var html = document.createElement("tree");
+ html.innerHTML = snippet;
+ return new SnippetTree({ type : "ROOT" }).parseChildren(html.childNodes);
+};
+
+
+// Make table from snippet
+function translateTable (snippet) {
+ // Create wrapper element
+ var html = document.createElement("table");
+ html.innerHTML = snippet;
+
+ // Create table object and load data from HTML
+ var info = new SnippetTable();
+ info.load(html.childNodes);
+
+ // Sort keys
+ var overallArray = [];
+ for (i in info.overall) {
+ overallArray.push(i);
+ };
+ overallArray.sort();
+
+ // Create HTML based on info
+ var d = document;
+ var table = d.createElement('table');
+ var tr = d.createElement('tr');
+ table.appendChild(tr);
+ var th = d.createElement('th');
+ tr.appendChild(th);
+
+ // Header line with surface strings
+ for (i in info.info) {
+ th = d.createElement('th');
+ tr.appendChild(th);
+ th.appendChild(d.createTextNode(info.info[i]["-s"]));
+ };
+
+ // Annotations
+ for (i in overallArray) {
+ i = overallArray[i];
+
+ tr = d.createElement('tr');
+ table.appendChild(tr);
+ th = d.createElement('th');
+ tr.appendChild(th);
+ th.appendChild(d.createTextNode(i));
+ for (t in info.info) {
+ var td = d.createElement('td');
+ tr.appendChild(td);
+ if (info.info[t][i] !== undefined)
+ td.appendChild(d.createTextNode(info.info[t][i]));
+ };
+ };
+
+ // return HTML object
+ return table;
+};