프로그래밍/Js

ES6+ html parser 재귀함수

소행성왕자 2018. 11. 23. 08:45
log = (...args)=>{
console.log(args.join(' '));
}


/*
const input = " ppppp <div> a <a>bbb</a> cc <img/> dddd</div>";
cursor = 1;
const idx = input.indexOf('<', cursor);
console.log('cursor:'+cursor);
console.log('idx:'+idx);
const text = input.substring(cursor,idx);
console.log(text);
*/




const textNode = (input, cursor, curr) => {
const idx = input.indexOf('<',cursor);
curr.tag.children.push({
type:'text', text:input.substring(cursor,idx)
});
return idx;
};


const elementNode = (input,cursor,idx,curr,stack) => {

let name, isClose;
if(input[idx - 1] === '/') { // <img/>
name = input.substring(cursor+1, idx-1);
isClose = true;
}
else {
name = input.substring(cursor+1, idx)
isClose = false;
}
const tag = {name, type:'node', children:[]};
curr.tag.children.push(tag);
if(!isClose) {
stack.push({tag, back:curr});
return true;
}
return false;
}


const parser = input => {

input = input.trim();
const result = {name:'ROOT', type:'node', children:[]};
const stack = [{tag:result}];
let curr, i=0, j=input.length;

while(curr = stack.pop()) {
while( i<j ) {
const cursor = i;
if( input[cursor] === '<' ) {
console.log(' >>>');
const idx = input.indexOf('>',cursor);
i = idx + 1;

if(input[cursor + 1] === '/') {
curr = curr.back;
}
else {
if(elementNode(input,cursor,idx,curr,stack)) {
break;
}
}
}
else { // text
i = textNode(input, cursor, curr);
}
}
}

return result;
};

console.log('-----------', parser(`<div>
a
<aa>bbbbb</aa>
ccc
<img/>
dddd
</div>
`));


'프로그래밍 > Js' 카테고리의 다른 글

JavaScript Lexical Grammar  (0) 2021.10.21
ES6+ 2차원배열 foreach  (0) 2018.11.23
async await promise 예제  (0) 2018.11.21
ES6+ SYNC, ASYNC (block, non-block)  (0) 2018.11.21
ES6+ blocking 과 non-blicking (time slice)  (0) 2018.11.21