diff --git a/src/__tests__/flatToMdast.spec.ts b/src/__tests__/flatToMdast.spec.ts new file mode 100644 index 00000000..b7944fc5 --- /dev/null +++ b/src/__tests__/flatToMdast.spec.ts @@ -0,0 +1,261 @@ +import {flatToMdast} from '../flatToMdast'; + +describe('structure', () => { + it('exists', () => { + expect(typeof flatToMdast).toBe('function'); + }); + + it('single root', () => { + const flat = { + nodes: [ + { + type: 'root', + } + ] + }; + const mdast = flatToMdast(flat as any); + + expect(mdast).toEqual({ + type: 'root', + children: [], + }); + }); + + it('doc 1', () => { + const flat = { + nodes: [ + { + type: 'root', + children: [1], + }, + { + type: 'paragraph', + children: [2], + }, + { + type: 'text', + value: 'foo', + }, + ], + contents: [], + definitions: {}, + footnotes: {}, + }; + const mdast = flatToMdast(flat as any); + + expect(mdast).toEqual({ + type: 'root', + children: [ + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'foo', + }, + ], + }, + ], + }); + }); + + it('doc 2', () => { + const flat = { + nodes: [ + { + type: 'root', + children: [1, 3], + }, + { + type: 'heading', + children: [2], + depth: 1, + }, + { + type: 'text', + value: 'Title', + }, + { + type: 'heading', + children: [4], + depth: 2, + }, + { + type: 'text', + value: 'Subtitle', + }, + ], + contents: [1, 3], + definitions: {}, + footnotes: {}, + }; + const mdast = flatToMdast(flat as any); + + expect(mdast).toEqual({ + type: 'root', + children: [ + { + type: 'heading', + depth: 1, + children: [ + { + type: 'text', + value: 'Title', + }, + ], + }, + { + type: 'heading', + depth: 2, + children: [ + { + type: 'text', + value: 'Subtitle', + }, + ], + }, + ], + }); + }); + + it('doc 3', () => { + const flat = { + nodes: [ + { + type: 'root', + children: [1], + }, + { + type: 'paragraph', + children: [2], + }, + { + type: 'linkReference', + children: [3], + identifier: 'click', + referenceType: 'full', + }, + { + type: 'text', + value: 'Click me', + }, + { + type: 'definition', + identifier: 'click', + title: null, + url: 'https://github.com/', + }, + ], + contents: [], + definitions: { + click: 4, + }, + footnotes: {}, + }; + const mdast = flatToMdast(flat as any); + + expect(mdast).toEqual({ + type: 'root', + children: [ + { + type: 'paragraph', + children: [ + { + type: 'linkReference', + children: [ + { + type: 'text', + value: 'Click me', + }, + ], + identifier: 'click', + referenceType: 'full', + }, + ], + }, + { + type: 'definition', + identifier: 'click', + title: null, + url: 'https://github.com/', + }, + ], + }); + }); + + it('doc 4', () => { + const flat = { + nodes: [ + { + type: 'root', + children: [1], + }, + { + type: 'paragraph', + children: [2, 3], + }, + { + type: 'text', + value: 'Hello', + }, + { + type: 'footnoteReference', + value: 'gg', + }, + { + type: 'footnoteDefinition', + children: [5], + identifier: 'gg', + }, + { + type: 'paragraph', + children: [6], + }, + { + type: 'text', + value: 'world!', + }, + ], + contents: [], + definitions: {}, + footnotes: { + gg: 4, + }, + }; + const mdast = flatToMdast(flat as any); + + expect(mdast).toEqual({ + type: 'root', + children: [ + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'Hello', + }, + { + type: 'footnoteReference', + value: 'gg', + }, + ], + }, + { + type: 'footnoteDefinition', + identifier: 'gg', + children: [ + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'world!' + }, + ], + }, + ], + }, + ], + }); + }); +}); diff --git a/src/flatToMdast.ts b/src/flatToMdast.ts new file mode 100644 index 00000000..ea54f798 --- /dev/null +++ b/src/flatToMdast.ts @@ -0,0 +1,26 @@ +import {FlatToMdast, Flat} from './types'; +import {IRoot, TAnyToken, TBlockToken} from 'md-mdast/lib/types'; + +export const flatToMdast: FlatToMdast = (flat: Flat) => { + const traverse: (index: number) => IRoot | TAnyToken = (index) => { + const node: any = {...flat.nodes[index]}; + if (node.children) node.children = node.children.map(traverse); + return node; + }; + + const mdast = traverse(0) as IRoot; + if (!mdast.children) mdast.children = []; + + if (flat.definitions instanceof Object) { + Object.values(flat.definitions).forEach(index => { + mdast.children.push(traverse(index) as TBlockToken); + }); + } + if (flat.footnotes instanceof Object) { + Object.values(flat.footnotes).forEach(index => { + mdast.children.push(traverse(index) as TBlockToken); + }); + } + + return mdast; +}; diff --git a/src/types.ts b/src/types.ts index 5d999850..7e7f9ef8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,3 +18,4 @@ export interface Flat { } export type MdastToFlat = (mdast: IRoot | TAnyToken) => Flat; +export type FlatToMdast = (flat: Flat) => IRoot | TAnyToken;