1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const textNode = (text, target) =>{ if(text.length){ target.push({type:'TEXT', text}); return ''; } };
const elementNode = (input, cursor, text, stack, stacks) =>{ const char = input[cursor++]; let isBreak = false; if(char === '<'){ text = textNode(text, stack.tag.children); if(input[cursor++] != '/'){ let name = input.substr(cursor -1, cursor = input.indexOf('>', cursor)); const isClose = input[cursor] === '/'; if(isClose){ name = name.substr(0, name.length - 1); } const tag = {name, type:'NODE', children: isClose ? null:[]}; cursor++; stack.tag.children.push(tag); if(!isClose){ stacks.push({tag, back: stack}); isBreak = true; } }else if(stack.tag.name == input.substring(cursor, input.indexOf('>',cursor))){ stack = stack.back; } }else{ text += char; } return {cursor, text, isBreak} };
const parser = input =>{ const result ={tag:{type:'ROOT', children:[]}, stacks=[]}; let cursor = 0, stack = result; do{ let text = ''; while (cursor < input.length){ const v = elementNode(input, cursor, text, stack, stacks); ({cursor, text} = v); if(v.isBreak) break; } }while (stack = stacks.pop()) return result; };
|