Spaces:
Running
Running
File size: 2,279 Bytes
6556bb5 ee12ee4 6556bb5 ee12ee4 001aa75 ee12ee4 6556bb5 ee12ee4 6556bb5 ee12ee4 6556bb5 ee12ee4 6556bb5 ee12ee4 6556bb5 ee12ee4 b784e3e 001aa75 ee12ee4 6556bb5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/**
* Indicates position of spans of text inside the string.
* (for visual applications only, no semantic sense here.)
*/
interface Span {
type: string;
start: number;
end: number;
}
interface SpanTag {
span: Span;
tag: "start" | "end";
}
class Displacy {
static sortSpans(spans: Span[]) {
spans.sort((a, b) => { /// `a` should come first when the result is < 0
if (a.start === b.start) {
return b.end - a.end; /// CAUTION.
}
return a.start - b.start;
});
// Check existence of **strict overlapping**
spans.forEach((s, i) => {
if (i < spans.length - 1) {
const sNext = spans[i+1];
if (s.start < sNext.start && s.end > sNext.start) {
console.log("ERROR", "Spans: strict overlapping");
}
}
});
}
/**
* Render a text string and its entity spans
*
* *see displacy-ent.js*
* see https://github.com/explosion/displacy-ent/issues/2
*/
static render(text: string, spans: Span[]): string {
this.sortSpans(spans);
const tags: { [index: number]: SpanTag[] } = {};
const __addTag = (i: number, s: Span, tag: "start" | "end") => {
if (Array.isArray(tags[i])) {
tags[i].push({ span: s, tag: tag });
} else {
tags[i] = [{ span: s, tag: tag }];
}
};
for (const s of spans) {
__addTag(s.start, s, "start");
__addTag(s.end, s, "end");
}
// console.log(JSON.stringify(tags)); // todo remove
let out = {
__content: "",
append(s: string) {
this.__content += s;
}
};
let offset = 0;
const indexes = Object.keys(tags).map(k => parseInt(k, 10)).sort((a, b) => a - b); /// CAUTION
for (const i of indexes) {
const spanTags = tags[i];
// console.log(i, spanTags); // todo remove
if (i > offset) {
out.append(text.slice(offset, i));
}
offset = i;
for (const sT of spanTags) {
if (sT.tag === "start") {
out.append(`<mark data-entity="${ sT.span.type.toLowerCase() }" data-index="${ (<any>sT.span).index }">`);
const singleScore = (<any>sT.span).singleScore;
if (singleScore) {
out.append(`<span class="single-score">${ singleScore.toFixed(3) }</span>`);
}
} else {
out.append(`</mark>`);
}
}
}
out.append(text.slice(offset, text.length));
return out.__content;
}
}
|