Skip to content

Instantly share code, notes, and snippets.

@amit08255
Created October 2, 2022 12:28
Show Gist options
  • Save amit08255/dc049ef05935c7f7c66b72bc8c010640 to your computer and use it in GitHub Desktop.
Save amit08255/dc049ef05935c7f7c66b72bc8c010640 to your computer and use it in GitHub Desktop.
Markdown to hierarchy based on heading
const getLines = (val:string) => val.split(/\r?\n/);

const getHeadingLevel = (val: string) => {
    const tokenizer = /(#{1,6})\s*(.+)(?:\n+|$)/gm;

    const token = tokenizer.exec(val);

    if (token && token[1]) {
        return token;
    }

    return [null, null, null];
};

const processLines = (lines:string[]) => {
    const parents = [{
        title: null, description: '', level: 0, children: [],
    }];
    let lastParent = parents[0];

    lines.forEach((h) => {
        const [_, levelType, text] = getHeadingLevel(h);

        if (levelType) {
            const level = levelType.length;

            while (level && level <= parents[parents.length - 1].level) {
                parents.pop();
            }
            const hobj = {
                title: text, description: '', level, children: [],
            };
            lastParent = hobj;
            parents[parents.length - 1].children.push(hobj);
            parents.push(hobj);
        } else {
            lastParent.description = `${lastParent.description}\n${h}`.trim();
        }
    });
    return parents[0].children;
};

const parseEditorText = (val: string) => {
    const lines = getLines(val);
    return processLines(lines);
};

export default parseEditorText;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment