Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert a tabbed tree to JSON in JavaScript?

I've looked around for an answer, but I think this is a kind of weird question. How would I convert, as a text file using tabs for spacing, this:

parent
    child
    child
parent
    child
        grandchild
        grandhcild

to

{
"name" : "parent",
"children" : [
    {"name" : "child"},
    {"name" : "child"},
]
},
{
"name" : "parent",
"children" : [
    {
    "name" : "child",
    "children" : [
        {"name" : "grandchild"},
        {"name" : "grandchild"},
        {"name" : "grandchild"},
    ]
    },
]
}

JSON probably isn't perfect, but hopefully makes my point clear.

like image 523
user1114864 Avatar asked Jan 09 '14 21:01

user1114864


2 Answers

i've had the same problem. Here is the solution:

function node(title,lvl){
    var children = [],
        parent = null;
    return {
        title:title,
        children:children,
        lvl:()=>lvl==undefined?-1:lvl,
        parent:()=>parent, //as a function to prevent circular reference when parse to JSON
        setParent:p=>{parent=p},
        appendChildren: function(c){
            children.push(c); 
            c.setParent(this);
            return this
        },
    }
}
function append_rec(prev,curr) {
    if(typeof(curr)=='string'){ //in the recursive call it's a object
        curr = curr.split('    ');//or tab (\t)
        curr = node(curr.pop(),curr.length);
    }
    if(curr.lvl()>prev.lvl()){//curr is prev's child
        prev.appendChildren(curr);
    }else if(curr.lvl()<prev.lvl()){
        append_rec(prev.parent(),curr) //recursive call to find the right parent level
    }else{//curr is prev's sibling
        prev.parent().appendChildren(curr);
    }

    return curr;
}

root = node('root');

var txt = 
`parent
    child
    child
parent
    child
        grandchild
        grandhcild`;
        
txt.toString().split('\n').reduce(append_rec,root); 

console.log(JSON.stringify(root.children,null,3));
like image 99
Francisco Sobrinho Avatar answered Sep 29 '22 18:09

Francisco Sobrinho


I've just implemented this feature for the tabdown markup language — it does exactly what you sought for. https://github.com/antyakushev/tabdown

Usage is pretty simple:

var lines = data.toString().split('\n');
var tree = tabdown.parse(lines);
console.log(tree.toString());

You can also use the parse function outside of node.js, it does not depend on any modules.

like image 40
Anton Yakushev Avatar answered Sep 29 '22 18:09

Anton Yakushev