| 492 | |
| 493 | let _mdParser = new MDParser(); |
| 494 | function parseMarkdown(input:string):{text: string, spans: MDSpan[]} { |
| 495 | let parsed = _mdParser.parse(input); |
| 496 | let walker = parsed.walker(); |
| 497 | var cur:commonmark.NodeWalkingStep; |
| 498 | var text:string[] = []; |
| 499 | var pos = 0; |
| 500 | var lastLine = 1; |
| 501 | var spans:MDSpan[] = []; |
| 502 | var context:{node: commonmark.Node, start: number}[] = []; |
| 503 | while(cur = walker.next()) { |
| 504 | let node = cur.node; |
| 505 | if(cur.entering) { |
| 506 | while(node.sourcepos && node.sourcepos[0][0] > lastLine) { |
| 507 | lastLine++; |
| 508 | pos++; |
| 509 | text.push("\n"); |
| 510 | } |
| 511 | if(node.type !== "text") { |
| 512 | context.push({node, start: pos}); |
| 513 | } |
| 514 | if(node.type == "text" || node.type == "code_block" || node.type == "code") { |
| 515 | text.push(node.literal); |
| 516 | pos += node.literal.length; |
| 517 | } |
| 518 | if(node.type == "softbreak") { |
| 519 | text.push("\n"); |
| 520 | pos += 1; |
| 521 | lastLine++; |
| 522 | } |
| 523 | if(node.type == "code_block") { |
| 524 | let start = context[context.length - 1].start; |
| 525 | spans.push([start, pos, node]); |
| 526 | lastLine = node.sourcepos[1][0] + 1; |
| 527 | } |
| 528 | if(node.type == "code") { |
| 529 | let start = context[context.length - 1].start; |
| 530 | spans.push([start, pos, node]); |
| 531 | } |
| 532 | } else { |
| 533 | let info = context.pop(); |
| 534 | if(!info) throw new Error("Invalid context stack while parsing markdown"); |
| 535 | if(node.type == "emph" || node.type == "strong" || node.type == "link") { |
| 536 | spans.push([info.start, pos, node]); |
| 537 | } else if(node.type == "heading" || node.type == "item") { |
| 538 | spans.push([info.start, info.start, node]); |
| 539 | } |
| 540 | } |
| 541 | } |
| 542 | return {text: text.join(""), spans}; |
| 543 | } |
| 544 | |
| 545 | export class Change implements CodeMirror.EditorChange { |
| 546 | type:string = "range"; |