import { html, type TreeAdapterTypeMap, type TreeAdapter } from 'parse5'; function createFragmentContext( tagName: string | undefined, treeAdapter: TreeAdapter ): T['element'] | null { if (!tagName) { return null; } let namespace = html.NS.HTML; const parts = tagName.split(' '); if (parts.length > 1) { tagName = parts[1]; if (parts[0] === 'svg') { namespace = html.NS.SVG; } else if (parts[0] === 'math') { namespace = html.NS.MATHML; } } return treeAdapter.createElement(tagName, namespace, []); } export interface DatFile { input: string; expected: string; expectedErrors: string[]; disableEntitiesDecoding: boolean; lineNum: number; scriptingEnabled: boolean; fragmentContext: T['element'] | null; } export function parseDatFile(testSet: string, treeAdapter: TreeAdapter): DatFile[] { const testDescrs: Record[] = []; let curDirective = ''; let curDescr: Record = {}; for (const [idx, line] of testSet.split(/\r?\n/).entries()) { if (line === '#data') { curDescr = { '#line': idx + 1 }; testDescrs.push(curDescr); } if (line[0] === '#') { curDirective = line; curDescr[curDirective] = []; } else { (curDescr[curDirective] as string[]).push(line); } } return testDescrs.map((descr) => { const fragmentContextTagName = (descr['#document-fragment'] as string[] | undefined)?.[0]; return { input: (descr['#data'] as string[]).join('\n'), expected: (descr['#document'] as string[]).join('\n'), expectedErrors: descr['#new-errors'] || [], disableEntitiesDecoding: !!descr['#disable-html-entities-decoding'], lineNum: descr['#line'], scriptingEnabled: !descr['#script-off'], fragmentContext: createFragmentContext(fragmentContextTagName, treeAdapter), } as DatFile; }); }