Skip to content

Commit

Permalink
feat: 🎸 add replace() function
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Feb 25, 2019
1 parent a791b0d commit 76c78ac
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/__tests__/flatToMdast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ describe('structure', () => {
nodes: [
{
type: 'root',
}
]
},
],
};
const mdast = flatToMdast(flat as any);

Expand Down Expand Up @@ -249,7 +249,7 @@ describe('structure', () => {
children: [
{
type: 'text',
value: 'world!'
value: 'world!',
},
],
},
Expand Down
135 changes: 135 additions & 0 deletions src/__tests__/replace.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import {create} from 'md-mdast';
import {mdastToFlat} from '../mdastToFlat';
import {replace} from '../replace';

describe('structure', () => {
it('exists', () => {
expect(typeof replace).toBe('function');
});

it('merges nodes', () => {
const parser = create();
const mdast1 = parser.tokenizeBlock('1\n' + '\n' + 'here\n' + '\n' + '4\n');
const mdast2 = parser.tokenizeBlock('3\n' + '\n' + '4\n');
const flat1 = mdastToFlat(mdast1!);
const flat2 = mdastToFlat(mdast2!);
const merged = replace(flat1, 3, flat2);

expect(merged).toMatchObject({
nodes: [
{type: 'root', children: [1, 3, 5], idx: 0},
{type: 'paragraph', children: [2], idx: 1},
{type: 'text', value: '1', idx: 2},
{type: 'portal', original: {type: 'paragraph', children: [4], idx: 3}, children: [7]},
{type: 'text', value: 'here', idx: 4},
{type: 'paragraph', children: [6], idx: 5},
{type: 'text', value: '4', idx: 6},
{type: 'root', children: [8, 10], idx: 7},
{type: 'paragraph', children: [9], idx: 8},
{type: 'text', value: '3', idx: 9},
{type: 'paragraph', children: [11], idx: 10},
{type: 'text', value: '4', idx: 11},
],
contents: [],
definitions: {},
footnotes: {},
});
});

it('merges metadata', () => {
const parser = create();
const mdast1 = parser.tokenizeBlock(`
# Click [here][link1] world![^foot]
merge here
[^foot]: This is footnote 1
[link1]: http://google.com
`);
const mdast2 = parser.tokenizeBlock(`
## [what][gg]?[^note]
[gg]: mailto:gg@bets.com
[^note]: is dis...
`);
const flat1 = mdastToFlat(mdast1!);
const flat2 = mdastToFlat(mdast2!);
const merged = replace(flat1, 7, flat2);

expect(merged).toMatchObject({
nodes: [
{type: 'root', children: [1, 7], idx: 0},
{
type: 'heading',
children: [2, 3, 5, 6],
depth: 1,
idx: 1,
},
{type: 'text', value: 'Click ', idx: 2},
{
type: 'linkReference',
children: [4],
identifier: 'link1',
referenceType: 'full',
idx: 3,
},
{type: 'text', value: 'here', idx: 4},
{type: 'text', value: ' world', idx: 5},
{
type: 'imageReference',
identifier: '^foot',
referenceType: 'shortcut',
alt: '^foot',
idx: 6,
},
{
type: 'portal',
idx: 7,
original: {type: 'paragraph', children: [8], idx: 7},
children: [13],
},
{type: 'text', value: 'merge here', idx: 8},
{
type: 'footnoteDefinition',
children: [10],
identifier: 'foot',
idx: 9,
},
{type: 'paragraph', children: [11], idx: 10},
{type: 'text', value: 'This is footnote 1', idx: 11},
{
type: 'definition',
identifier: 'link1',
title: null,
url: 'http://google.com',
idx: 12,
},
{type: 'root', children: [14], idx: 13},
{type: 'heading', children: [15, 17, 18], depth: 2, idx: 14},
{
type: 'linkReference',
children: [16],
identifier: 'gg',
referenceType: 'full',
idx: 15,
},
{type: 'text', value: 'what', idx: 16},
{type: 'text', value: '?', idx: 17},
{type: 'footnoteReference', value: 'note', idx: 18},
{
type: 'definition',
identifier: 'gg',
title: null,
url: 'mailto:gg@bets.com',
idx: 19,
},
{type: 'footnoteDefinition', children: [21], identifier: 'note', idx: 20},
{type: 'paragraph', children: [22], idx: 21},
{type: 'text', value: 'is dis…', idx: 22},
],
contents: [1, 14],
definitions: {link1: 12, gg: 19},
footnotes: {foot: 9, note: 20},
});
});
});
4 changes: 2 additions & 2 deletions src/flatToMdast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ export const flatToMdast: FlatToMdast = (flat: Flat) => {
if (!mdast.children) mdast.children = [];

if (flat.definitions instanceof Object) {
Object.values(flat.definitions).forEach(index => {
Object.values(flat.definitions).forEach((index) => {
mdast.children.push(traverse(index) as TBlockToken);
});
}
if (flat.footnotes instanceof Object) {
Object.values(flat.footnotes).forEach(index => {
Object.values(flat.footnotes).forEach((index) => {
mdast.children.push(traverse(index) as TBlockToken);
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './mdastToFlat';
export * from './flatToMdast';
export * from './replace';
45 changes: 45 additions & 0 deletions src/replace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {Flat} from './types';

export const replace = (into: Flat, at: number, what: Flat): Flat => {
const mergeIdx = into.nodes.length;
const merged: Flat = {
nodes: [...into.nodes],
contents: [...into.contents],
definitions: {...into.definitions},
footnotes: {...into.footnotes},
};

const replacedNode = merged.nodes[at];
merged.nodes[at] = {
type: 'portal',
idx: at,
original: replacedNode,
children: [mergeIdx],
} as any;

// APPEND NODES.
for (const node of what.nodes) {
const newNode: any = {
...node,
idx: node.idx + mergeIdx,
};

if (newNode.children) {
newNode.children = newNode.children.map((idx) => idx + mergeIdx);
}
merged.nodes.push(newNode);
}

// MERGE METADATA.
for (const idx of what.contents) {
merged.contents.push(idx + mergeIdx);
}
Object.keys(what.definitions).forEach(
(identifier) => (merged.definitions[identifier] = what.definitions[identifier] + mergeIdx),
);
Object.keys(what.footnotes).forEach(
(identifier) => (merged.footnotes[identifier] = what.footnotes[identifier] + mergeIdx),
);

return merged;
};
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface FlatFootnotes {
[id: string]: number;
}

export type TNode = (IRoot | TAnyToken) & {idx: number, children?: number[]};
export type TNode = (IRoot | TAnyToken) & {idx: number; children?: number[]};

export interface Flat {
nodes: TNode[];
Expand Down

0 comments on commit 76c78ac

Please sign in to comment.