|
/* TODO: Differentiate between Node and Text */ |
|
|
|
function Tree(data, parent /* Tree */) { |
|
this.data = data; |
|
this.parent = parent; |
|
this.children = []; |
|
} |
|
Tree.prototype.addChild = function addChild(child) { |
|
const last = this.children[this.children.length - 1]; |
|
// Collapse string nodes |
|
if (last && 'string' === typeof child && 'string' === typeof last.data) { |
|
last.data += child; |
|
return last; |
|
} |
|
const node = new Tree(child, this); |
|
this.children.push(node); |
|
return node; |
|
}; |
|
|
|
function DOMBuilder() { |
|
this.root = new Tree(); |
|
this.current = this.root; |
|
} |
|
DOMBuilder.prototype.startMark = function startMark(attributes) { |
|
this.current = this.current.addChild({ attributes }); |
|
return this; |
|
}; |
|
DOMBuilder.prototype.endMark = function endMark() { |
|
this.current = this.current.parent; // pop! |
|
return this; |
|
}; |
|
DOMBuilder.prototype.addText = function addText(text) { |
|
this.current.addChild(text); |
|
return this; |
|
}; |
|
DOMBuilder.prototype.toNode = function toNode() { |
|
// console.dir(this.current); |
|
return this.current; |
|
}; |
|
|
|
const markdown = `Lorem ipsum dolor amet twee shaman salvia, helvetica coloring book direct trade copper mug food truck kitsch DIY. Edison bulb snackwave blue bottle meggings hoodie, beard listicle hexagon wolf jean shorts migas 8-bit dreamcatcher. La croix snackwave woke marfa, messenger bag af kitsch next level authentic you probably haven't heard of them pinterest everyday carry. Cronut yuccie offal, cray plaid meditation tote bag master cleanse 90's microdosing hoodie bespoke. Artisan actually keytar blue bottle quinoa taxidermy beard. Raw denim polaroid thundercats biodiesel enamel pin messenger bag mixtape pok pok woke ugh drinking vinegar. |
|
Seitan waistcoat kickstarter everyday carry PBR&B church-key. Helvetica poke trust fund air plant, pug authentic fanny pack glossier keffiyeh hell of chillwave. Readymade street art synth, try-hard actually meh squid blue bottle cray affogato shaman beard sartorial green juice sustainable. Neutra kitsch vegan, knausgaard master cleanse thundercats blog sustainable coloring book aesthetic iPhone tumeric cronut drinking vinegar. Ennui live-edge 3 wolf moon migas retro small batch. |
|
Retro yr deep v af, kinfolk hoodie knausgaard normcore taxidermy sustainable brunch mustache polaroid four dollar toast raw denim. Listicle af ennui pinterest messenger bag jianbing roof party heirloom vice stumptown. Bushwick scenester fingerstache narwhal, vice banjo viral drinking vinegar craft beer flannel woke kitsch franzen synth next level. Disrupt snackwave knausgaard VHS artisan taiyaki, umami trust fund kinfolk lomo. Stumptown la croix tattooed kogi. Kitsch street art master cleanse williamsburg hammock, pabst hell of migas meditation brooklyn hoodie chambray everyday carry.`; |
|
|
|
const annotations = [ |
|
{ |
|
id: '1', |
|
range: { |
|
start: { |
|
line: 1, |
|
column: 127 |
|
}, |
|
end: { |
|
line: 1, |
|
column: 127 + 129 |
|
} |
|
} |
|
}, |
|
{ |
|
id: '2', |
|
range: { |
|
start: { |
|
line: 1, |
|
column: 256 |
|
}, |
|
end: { |
|
line: 1, |
|
column: 468 |
|
} |
|
} |
|
}, |
|
{ |
|
id: '3', |
|
range: { |
|
start: { |
|
line: 1, |
|
column: 353 |
|
}, |
|
end: { |
|
line: 2, |
|
column: 118 |
|
} |
|
} |
|
} |
|
]; |
|
|
|
function documentOrder(a, b) { |
|
if (a.range.start.line > b.range.start.line) return true; |
|
if (a.range.start.line === b.range.start.line) { |
|
return a.range.start.column > b.range.start.column; |
|
} |
|
return false; |
|
} |
|
|
|
function inScope(annotations, line) { |
|
//console.dir(annotations); |
|
return annotations |
|
.filter(a => a.range.start.line <= line && line <= a.range.end.line) |
|
.sort(documentOrder); |
|
} |
|
|
|
function Line(line, annotations) { |
|
const builder = new DOMBuilder(); |
|
|
|
for (let column = 0; column < line.length; column++) { |
|
builder.addText(line[column]); |
|
} |
|
return builder.toNode(); |
|
} |
|
|
|
console.dir( |
|
markdown |
|
.split(/\n/) |
|
.map((line, index) => Line(line, inScope(annotations, index + 1))) |
|
); |