I have JSON representing some content in a text editor. Here's a sample:
{ "type": "doc", "content": [ { "type": "paragraph", "content": [ { "type": "text", "marks": [ { "type": "bold" } ], "text": "Testing" }, { "type": "text", "text": " " }, { "type": "text", "marks": [ { "type": "strike" } ], "text": "Testing " }, { "type": "text", "marks": [ { "type": "strike" }, { "type": "underline" } ], "text": "Testing" }, { "type": "text", "marks": [ { "type": "strike" } ], "text": " Testing" } ] }, { "type": "paragraph" }, { "type": "paragraph", "content": [ { "type": "text", "marks": [ { "type": "bold" } ], "text": "Testing " }, { "type": "text", "marks": [ { "type": "bold" }, { "type": "italic" }, { "type": "strike" } ], "text": "Testing" }, { "type": "text", "marks": [ { "type": "bold" } ], "text": " Testing" } ] }, { "type": "paragraph" } ] }
It's good because I can safely turn it into html, however instead of having nested values for styles, it represents this styling in a marks
sub-array.
What I would prefer if to store the data already nested with respect to it's natural hierarchy.
So instead of:
{
"type":"text",
"marks": [{ "type": "bold" }, { "type": "italic" }],
"text": "Testing"
}
I'd like to have something that more accurately represents the resulting HTML:
{
"type" : "bold",
"content" : [{
"type" : "italic",
"content":[{
"type" : "text",
"text" : "Testing"
}]
}]
}
I've tried various ways of parsing the json and storing it like below, but I think I'm missing somethign fundamental about how javascript works with objects, because the changes aren't being made.
I've done various iteration of the function below, over each marks
array in the json.
item = {type:type, text:text}
marks.forEach((mark)=>{
let newObj = {content:[], type:mark.type}
item = newObj.content.push(item)
});
Some extra background information, this is the json generated by the tiptap wysiwyg editor, which is based on prosemirror. I can't use the normal html export because I'm doing special stuff to the data. Any help would be greatly appreciated.
EDIT : Dacre Denny came up with an answer using reduceRight()
which answered the first part of the problem. However, the function below still returns the original object unchanged.
const content = editorContent.content
function parseContent (arr) {
arr.forEach((item)=>{
// Check if item contains another array of items, and then iterate
over that one too.
if(item.content){
parseContent(item.content)
}
if(item.marks){
//Extract values from item
// THis is the correct function
const processContent = ({ marks, text }) =>
marks.reduceRight((acc, mark) => ({ type: mark.type, content: [acc]
}), {
type: "text",
text: text
});
item = processContent({ text:item.text, marks:item.marks })
}
})
}
parseContent(content)
return content
//