blob: 515a78f007f94e6b2879335049e2502e857e08e3 [file] [log] [blame]
Nils Diewalde8518f82015-03-18 22:41:49 +00001/**
2 * Make annotations visible.
3 *
4 * @author Nils Diewald
5 */
6/*
7 - Scroll with a static left legend.
8 - Highlight (at least mark as bold) the match
9 - Scroll to match vertically per default
10 */
11var KorAP = KorAP || {};
12
13(function (KorAP) {
14 "use strict";
15
16 KorAP._AvailableRE = new RegExp("^([^\/]+?)\/([^=]+?)(?:=(spans|rels|tokens))?$");
17 KorAP._TermRE = new RegExp("^([^\/]+?)(?:\/([^:]+?))?:(.+?)$");
18 KorAP._matchTerms = ["corpusID", "docID", "textID"];
19
20 // API requests
21 KorAP.API = KorAP.API || {};
22 KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () { return {} };
23
24 KorAP.MatchInfo = {
25
26 /**
27 * Create a new annotation object.
28 * Expects an array of available foundry/layer=type terms.
29 * Supported types are 'spans', 'tokens' and 'rels'.
30 */
31 create : function (match, available) {
32 if (arguments.length < 2)
33 throw new Error("Missing parameters");
34
35 return Object.create(KorAP.MatchInfo)._init(match, available);
36 },
37
38 _init : function (match, available) {
39 this._match = KorAP.Match.create(match);
40 this._available = {
41 tokens : [],
42 spans : [],
43 rels : []
44 };
45 for (var i = 0; i < available.length; i++) {
46 var term = available[i];
47 // Create info layer objects
48 try {
49 var layer = KorAP.InfoLayer.create(term);
50 this._available[layer.type].push(layer);
51 }
52 catch (e) {
53 continue;
54 };
55 };
56 return this;
57 },
58
59
60 /**
61 * Return a list of parseable tree annotations.
62 */
63 getSpans : function () {
64 return this._available.spans;
65 },
66
67
68 /**
69 * Return a list of parseable token annotations.
70 */
71 getTokens : function () {
72 return this._available.tokens;
73 },
74
75
76 /**
77 * Return a list of parseable relation annotations.
78 */
79 getRels : function () {
80 return this._available.rels;
81 },
82
83
84 getTable : function (tokens) {
85 var focus = [];
86
87 // Get all tokens
88 if (tokens === undefined) {
89 focus = this.getTokens();
90 }
91
92 // Get only some tokens
93 else {
94
95 // Push newly to focus array
96 for (var i = 0; i < tokens.length; i++) {
97 var term = tokens[i];
98 try {
99 // Create info layer objects
100 var layer = KorAP.InfoLayer.create(term);
101 layer.type = "tokens";
102 focus.push(layer);
103 }
104 catch (e) {
105 continue;
106 };
107 };
108 };
109
110 // No tokens chosen
111 if (focus.length == 0)
112 return;
113
114 // Get info (may be cached)
115 var matchResponse = KorAP.API.getMatchInfo(
116 this._match,
117 { 'spans' : true, 'layer' : focus }
118 );
119
120 // Get snippet from match info
121 if (matchResponse["snippet"] !== undefined) {
122 this._table = KorAP.InfoTable.create(matchResponse["snippet"]);
123 return this._table;
124 };
125
126 return null;
127 }
128
129 /*
130 // Parse snippet for table visualization
131 getTree : function (foundry, layer) {
132 },
133 */
134 };
135
136 KorAP.Match = {
137 create : function (match) {
138 return Object.create(KorAP.Match)._init(match);
139 },
140 _init : function (match) {
141 for (var i in KorAP._matchTerms) {
142 var term = KorAP._matchTerms[i];
143 if (match[term] !== undefined) {
144 this[term] = match[term];
145 }
146 else {
147 this[term] = undefined;
148 }
149 };
150 return this;
151 },
152 };
153
154 /**
155 *
156 * Alternatively pass a string as <tt>base/s=span</tt>
157 *
158 * @param foundry
159 */
160 KorAP.InfoLayer = {
161 create : function (foundry, layer, type) {
162 return Object.create(KorAP.InfoLayer)._init(foundry, layer, type);
163 },
164 _init : function (foundry, layer, type) {
165 if (foundry === undefined)
166 throw new Error("Missing parameters");
167
168 if (layer === undefined) {
169 if (KorAP._AvailableRE.exec(foundry)) {
170 this.foundry = RegExp.$1;
171 this.layer = RegExp.$2;
172 this.type = RegExp.$3;
173 }
174 else {
175 throw new Error("Missing parameters");
176 };
177 }
178 else {
179 this.foundry = foundry;
180 this.layer = layer;
181 this.type = type;
182 };
183
184 if (this.type === undefined)
185 this.type = 'tokens';
186
187 return this;
188 }
189 };
190
191
192 KorAP.InfoTable = {
193 create : function (snippet) {
194 return Object.create(KorAP.InfoTable)._init(snippet);
195 },
196 _init : function (snippet) {
197 // Create html for traversal
198 var html = document.createElement("div");
199 html.innerHTML = snippet;
200
201 this._pos = 0;
202 this._token = [];
203 this._info = [];
204 this._foundry = [];
205 this._layer = [];
206
207 // Parse the snippet
208 this._parse(html.childNodes);
209
210 this._layer = undefined;
211 this._foundry = undefined;
212
213 html.innerHTML = '';
214 return this;
215 },
216
217 length : function () {
218 return this._pos;
219 },
220
221 getToken : function (pos) {
222 if (pos === undefined)
223 return this._token;
224 return this._token[pos];
225 },
226
227 getValue : function (pos, foundry, layer) {
228 return this._info[pos][foundry + '/' + layer]
229 },
230
231 getLayerPerFoundry : function (foundry) {
232 return this._foundry[foundry]
233 },
234
235 getFoundryPerLayer : function (layer) {
236 return this._layer[layer];
237 },
238
239 // Parse the snippet
240 _parse : function (children) {
241
242 // Get all children
243 for (var i in children) {
244 var c = children[i];
245
246 // Create object on position unless it exists
247 if (this._info[this._pos] === undefined)
248 this._info[this._pos] = {};
249
250 // Store at position in foundry/layer as array
251 var found = this._info[this._pos];
252
253 // Element with title
254 if (c.nodeType === 1) {
255 if (c.getAttribute("title") &&
256 KorAP._TermRE.exec(c.getAttribute("title"))) {
257
258 // Fill position with info
259 var foundry, layer, value;
260 if (RegExp.$2) {
261 foundry = RegExp.$1;
262 layer = RegExp.$2;
263 }
264 else {
265 foundry = "base";
266 layer = RegExp.$1
267 };
268
269 value = RegExp.$3;
270
271 if (found[foundry + "/" + layer] === undefined)
272 found[foundry + "/" + layer] = [];
273
274 // Push value to foundry/layer at correct position
275 found[foundry + "/" + layer].push(RegExp.$3);
276
277 // Set foundry
278 if (!this._foundry[foundry])
279 this._foundry[foundry] = {};
280 this._foundry[foundry][layer] = 1;
281
282 // Set layer
283 if (!this._layer[layer])
284 this._layer[layer] = {};
285 this._layer[layer][foundry] = 1;
286 };
287
288 // depth search
289 if (c.hasChildNodes())
290 this._parse(c.childNodes);
291 }
292
293 // Leaf node - store string on position and go to next string
294 else if (c.nodeType === 3) {
295 if (c.nodeValue.match(/[a-z0-9]/i))
296 this._token[this._pos++] = c.nodeValue;
297 };
298 };
299
300 delete this._info[this._pos];
301 },
302 element : function () {
303 var ce = document.createElement;
304 // First the legend table
305 /*
306 var table = ce('table');
307 var row = ce('tr');
308 table.appendChild(tr);
309 */
310 }
311 };
312
313
314 /*
315 KorAP.InfoFoundryLayer = {};
316 KorAP.InfoTree = {};
317 KorAP.InfoTable = {};
318 */
319}(this.KorAP));