Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at 87b736ef368a36cd6d4ebbcb18d2b4b30dc67f6d 86 lines 2.4 kB view raw
1import {Tree, NodeProp} from "@lezer/common" 2import {parser as html} from "@lezer/html" 3import ist from "ist" 4import {parser, parseCode} from "../dist/index.js" 5 6let full = parser.configure(parseCode({ 7 codeParser(str) { return !str || str == "html" ? html : null }, 8 htmlParser: html.configure({dialect: "noMatch"}) 9})) 10 11function findMounts(tree: Tree) { 12 let result = [] 13 for (let cur = tree.cursor(); cur.next();) { 14 let mount = cur.tree?.prop(NodeProp.mounted) 15 if (mount) result.push({at: cur.from, mount}) 16 } 17 return result 18} 19 20function test(doc: string, ...nest: [string, ...number[]][]) { 21 return () => { 22 let tree = full.parse(doc), mounts = findMounts(tree) 23 ist(mounts.length, nest.length) 24 nest.forEach(([repr, ...ranges], i) => { 25 let {mount, at} = mounts[i] 26 ist(mount.tree.toString(), "Document(" + repr + ")") 27 ist(mount.overlay!.map(r => (r.from + at) + "," + (r.to + at)).join(), ranges.join()) 28 }) 29 } 30} 31 32describe("Code parsing", () => { 33 it("parses HTML blocks", test(` 34Paragraph 35 36<div id=x> 37 Hello &amp; goodbye 38</div>`, ["Element(OpenTag(StartTag,TagName,Attribute(AttributeName,Is,UnquotedAttributeValue),EndTag),Text,EntityReference,Text,CloseTag(StartCloseTag,TagName,EndTag))", 12, 51])) 39 40 it("parses inline HTML", test( 41 `Paragraph with <em>inline tags</em> in it.`, 42 ["Element(OpenTag(StartTag,TagName,EndTag))", 15, 19], 43 ["CloseTag(StartCloseTag,TagName,EndTag)", 30, 35])) 44 45 it("parses indented code", test(` 46Paragraph. 47 48 <!doctype html> 49 Hi 50`, ["DoctypeDecl,Text", 17, 33, 37, 39])) 51 52 it("parses fenced code", test(` 53Okay 54 55~~~ 56<p> 57 Hey 58</p> 59~~~`, ["Element(OpenTag(StartTag,TagName,EndTag),Text,CloseTag(StartCloseTag,TagName,EndTag))", 11, 25])) 60 61 it("allows gaps in fenced code", test(` 62- >~~~ 63 ><!doctype html> 64 >yay 65 > ~~~`, ["DoctypeDecl,Text", 11, 27, 30, 33])) 66 67 it("passes fenced code info", test(` 68~~~html 69&raquo; 70~~~ 71 72~~~python 73False 74~~~`, ["EntityReference", 9, 16])) 75 76 it("can parse disjoint ranges", () => { 77 let tree = parser.parse(`==foo\n==\n==ba==r\n==`, undefined, 78 [{from: 2, to: 6}, {from: 8, to: 9}, {from: 11, to: 13}, {from: 15, to: 17}]) 79 ist(tree.toString(), "Document(Paragraph,Paragraph)") 80 ist(tree.length, 15) 81 ist(tree.topNode.firstChild!.from, 0) 82 ist(tree.topNode.firstChild!.to, 3) 83 ist(tree.topNode.lastChild!.from, 9) 84 ist(tree.topNode.lastChild!.to, 14) 85 }) 86})