Home > Back-end >  Parsing recursive json, from markdown AST
Parsing recursive json, from markdown AST

Time:04-22

Recursive functions are not my forté, and im pretty sure thats what is needed here.

I have a nested json object, which represents a nested checklist It is autogenerated from markdown using mdast-util-gfm-task-list-item

* AAA
    * BBB
* CCC
    * [x] DDD
        * [ ] EEE
        * FFF
    {
    "type": "root",
    "children": [
        {
            "type": "list",
            "ordered": false,
            "start": null,
            "spread": false,
            "children": [
                {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                        {
                            "type": "paragraph",
                            "children": [
                                {
                                    "type": "text",
                                    "value": "AAA"
                                }
                            ]
                        },
                        {
                            "type": "list",
                            "ordered": false,
                            "start": null,
                            "spread": false,
                            "children": [
                                {
                                    "type": "listItem",
                                    "spread": false,
                                    "checked": null,
                                    "children": [
                                        {
                                            "type": "paragraph",
                                            "children": [
                                                {
                                                    "type": "text",
                                                    "value": "BBB"
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                        {
                            "type": "paragraph",
                            "children": [
                                {
                                    "type": "text",
                                    "value": "CCC"
                                }
                            ]
                        },
                        {
                            "type": "list",
                            "ordered": false,
                            "start": null,
                            "spread": false,
                            "children": [
                                {
                                    "type": "listItem",
                                    "spread": false,
                                    "checked": null,
                                    "children": [
                                        {
                                            "type": "paragraph",
                                            "children": [
                                                {
                                                    "type": "text",
                                                    "value": "DDD"
                                                }
                                            ]
                                        },
                                        {
                                            "type": "list",
                                            "ordered": false,
                                            "start": null,
                                            "spread": false,
                                            "children": [
                                                {
                                                    "type": "listItem",
                                                    "spread": false,
                                                    "checked": null,
                                                    "children": [
                                                        {
                                                            "type": "paragraph",
                                                            "children": [
                                                                {
                                                                    "type": "text",
                                                                    "value": "EEE"
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                },
                                                {
                                                    "type": "listItem",
                                                    "spread": false,
                                                    "checked": null,
                                                    "children": [
                                                        {
                                                            "type": "paragraph",
                                                            "children": [
                                                                {
                                                                    "type": "text",
                                                                    "value": "FFF"
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

I need to manipulate it to be in the following, more consise format:

{
    "type" : "list",
    "data" : {
        "style" : "unordered",
        "items" : [
            {
              "content": "AAA",
              "checked" : null
              "items": [
                {
                  "content": "BBB",
                  "checked" : null
                  "items": []
                }
              ]
            },
            {
              "content": "CCC",
              "checked" : null
              "items": [
                {
                  "content": "DDD",
                  "checked": true,
                  "items": [
                      {
                        "content": "EEE",
                        "checked": false,
                        "items": []
                      },
                      {
                        "content": "FFF",
                        "checked": null,
                         "items": []
                      }
                   ]
                },
              ]
            }
        ]
    }
}

Any help greatly appreciated - I have been banging my head against the wall for a couple of hours now.

CodePudding user response:

I think I am pretty close here but haven't been able to finish it off:

function transform(data) {
  const {type} = data;
  if (type === "root") {
    return transform(data.children[0]);
  } else if (type === "list") {
    return {
      type,
      data: {
        style: data.ordered ? "ordered" : "unordered",
        items: data.children.map(child => transform(child))
      }
    }
  } else if (type === "listItem") {
    return {
      type,
      checked: data.checked,
      content: data.children[0].children[0].value,
      items: data.children.filter(child => child.type === "list").map(child => transform(child))
    }
  }
  return data;
}

// Pass your data in here as fromData
const toData = transform(fromData);

// toData would then be the new format

CodePudding user response:

Thanks @jimTheDev

I also recived some assistance on another forum, and both answers were useful. In the end, I have sucssfully produced the following function, which works almost perfectly for my use case.

let ast_to_ejs = (input) => {
    const { type, children } = input;
    if (type === "root") {
      const data = {};
      data.style = input.ordered ? 'ordered' : 'unordered';
      data.items = children.map(ast_to_ejs);
      return { type: 'list', data };
  
    } else if (type === 'list') {
       return children.map(ast_to_ejs);
  
    } else if (type === 'listItem') {
      const checked = input.checked;
      const content = children[0].children[0].value;
       const items = children[1] ? ast_to_ejs(children[1]) : [];
       return { content, checked, items };
     }
};
  • Related