import { SYMBOLS, parse, isScope, isMacro, getTail, getText, getUnmatched, isCollection } from './core.js' const schemaTCE = ` macros primitive match number string section pos number tail content string unmatched position number options parameter1 number parameter2 string literal unmatched string unmatched primitive root title string options options collection subsection section list - string array collection section collection collection2 unmatched collection ` function head(line) { return line.split(' ')[0] } function tail(line) { return line.split(' ').slice(1).join(' ') } function chain(...macroNames) { return (args) => { for (const macroName of macroNames) { if (args.macros[macroName]) args.entry = args.macros[macroName](args) } return args.entry } } const schema = { macros: { tail({ entry }) { return [head(entry[0]), tail(entry[0])] }, string({ entry }) { return [entry[0], entry[1].toString()] }, number({ entry }) { const num = +entry[1] if (isNaN(num) || entry[1] === '') return entry return [entry[0], num] }, primitive(args) { const num = macros.number(args) return num !== undefined ? num : macros.string(args) }, scope({ addScope, head, tail, entry }, definition) { return addScope({ definition, head, tail, entry }) }, section: isScope({ [SYMBOLS.TAIL]: getTail('pos', isMacro('number')), [SYMBOLS.UNMATCHED]: getText('content', isMacro('string')), position: isMacro('number') }), options: isScope({ parameter1: isMacro('number'), parameter2: isMacro('string'), unmatched: isMacro('string'), [SYMBOLS.UNMATCHED]: getUnmatched(isMacro('any')), }), any(args) { const macro = args.macros[args.head] if (macro) return macro(args) const numResult = args.macros.number(args) if (numResult !== undefined) return numResult args.tail = args.entry return args.macros.string(args) }, }, root: { // Move tail into value position and cast it to string. title: chain('tail', 'string'), // options: isMacro('options'), // subsection: isMacro('section'), // list: isScope({ // '-': isMacro('string') // }), // collection: isScope({ // section: isCollection(isMacro('section')) // }), // collection2: isScope({ // [SYMBOLS.UNMATCHED]: getUnmatched(isMacro('any')) // }) } } const lines = [ `title Example`, `options`, ` parameter1 30`, ` parameter2 Enim eu id anim minim reprehenderit nostrud eu amet deserunt ea ut do cupidatat ea.`, `options`, ` parameter1 0`, ` parameter2 Esse incididunt et est adipisicing eiusmod aliqua enim ea aliqua id enim.`, `subsection`, ` position 1`, ` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`, `subsection 2`, ` position 2`, ` Aute deserunt incididunt ad in sint adipisicing est officia velit pariatur ipsum deserunt quis nulla.`, ` Ea dolore in aliquip fugiat anim adipisicing amet aute tempor et deserunt est duis sint.`, `list`, ` - item 1`, ` - item 2`, `collection`, ` section`, ` lorem ipsum 1`, ` section`, ` lorem ipsum 2`, `collection2`, ` section`, ` position 3`, ` Laborum aute anim occaecat occaecat pariatur tempor proident magna sit magna non non.`, ` list`, ` 1`, ` 2` ] async function main() { console.dir(await parse(lines, schema), { depth: null }) } main()