Skip to content

Commit

Permalink
feat: implement getJsonPathForNode (#13)
Browse files Browse the repository at this point in the history
* feat: introduce getJsonPathForNode

* revert: yarn.lock

* refactor: remove "!" clobbers

* chore: bump deps

* chore: remove no longer required types def

* feat: update types
  • Loading branch information
P0lip authored Jul 26, 2019
1 parent 484058f commit 2a50bb7
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 187 deletions.
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,26 @@
},
"dependencies": {
"js-yaml": "^3.13",
"lodash": ">=4.17.5",
"lodash": "^4.17.15",
"mdast-util-to-string": "~1.0",
"remark-frontmatter": "~1.3",
"remark-parse": "~6.0",
"remark-stringify": "~6.0",
"unified": "~7.1",
"remark-parse": "~7.0.0",
"remark-stringify": "~7.0.1",
"unified": "~8.3.2",
"unist-util-select": "~2.0"
},
"devDependencies": {
"@stoplight/scripts": "~5.1",
"@stoplight/types": "^9",
"@stoplight/types": "^9.1.2",
"@types/jest": "^24.0",
"@types/js-yaml": "3.12.1",
"@types/lodash": "^4.14",
"@types/lodash": "^4.14.136",
"@types/unist": "2.0.3",
"jest": "^24.8",
"ts-jest": "^24.0.2",
"tslint": "^5.17",
"tslint": "^5.18.0",
"tslint-config-stoplight": "^1.2.0",
"typescript": "3.5.2"
"typescript": "3.5.3"
},
"lint-staged": {
"*.{ts,tsx}$": [
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/getJsonPathForNode.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as fs from 'fs';
import { join } from 'path';
import { IParagraph, IStrong } from '../ast-types/mdast';
import { getJsonPathForNode } from '../getJsonPathForNode';
import { parseWithPointers } from '../parseWithPointers';

const FIXTURES_DIR = join(__dirname, '../reader/__tests__/fixtures/markdown/');

const basic = fs.readFileSync(join(FIXTURES_DIR, 'basic.md'), 'utf-8');

describe('getJsonPathForNode', () => {
describe('basic fixture', () => {
const result = parseWithPointers(basic);

it('generates correct json path for heading', () => {
expect(getJsonPathForNode(result.data, result.data.children[0])).toEqual(['children', 0]);
});

it('generates correct json path for strong node in paragraph', () => {
expect(getJsonPathForNode(result.data, (result.data.children[1] as IParagraph).children[3])).toEqual([
'children',
1,
'children',
3,
]);
});

it('generates correct json path for nested emphasis node', () => {
expect(
getJsonPathForNode(result.data, ((result.data.children[1] as IParagraph).children[7] as IStrong).children[1]),
).toEqual(['children', 1, 'children', 7, 'children', 1]);
});
});
});
36 changes: 36 additions & 0 deletions src/getJsonPathForNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { JsonPath } from '@stoplight/types';
import * as Unist from 'unist';

export const getJsonPathForNode = (root: Unist.Parent, node: Unist.Node): JsonPath | void => {
const path: JsonPath = [];
findNode(root, node, path);
return path;
};

function findNode(root: Unist.Parent | Unist.Node, node: Unist.Node, path: JsonPath): Unist.Node | undefined {
if (node.position === undefined || root.position === undefined) return;

if (
node.position.start.line === root.position.start.line &&
node.position.end.line === root.position.end.line &&
node.position.start.column === root.position.start.column &&
node.position.end.column === root.position.end.column
) {
return node;
}

if (node.position.start.line >= root.position.start.line && node.position.end.line <= root.position.end.line) {
const { children } = root;
if (Array.isArray(children)) {
for (let i = 0; i < children.length; i++) {
const item = findNode(children[i], node, path);
if (item) {
path.unshift('children', i);
return findNode(item, node, path);
}
}
}
}

return;
}
8 changes: 4 additions & 4 deletions src/parse.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import remarkParse, { IParseOpts } from 'remark-parse';
import remarkParse, { RemarkParseOptions } from 'remark-parse';
import unified from 'unified';
import * as Unist from 'unist';
const frontmatter = require('remark-frontmatter');

const defaultOpts: IParseOpts = {
const defaultOpts: Partial<RemarkParseOptions> = {
commonmark: true,
gfm: true,
};

const defaultProcessor = unified()
.use(remarkParse)
.use<RemarkParseOptions[]>(remarkParse)
.use(frontmatter, ['yaml']);

export const parse = (
input: string,
opts: IParseOpts = defaultOpts,
opts: Partial<RemarkParseOptions> = defaultOpts,
processor: unified.Processor = defaultProcessor,
): Unist.Node => {
// return the parsed remark ast
Expand Down
4 changes: 2 additions & 2 deletions src/parseWithPointers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IParseOpts } from 'remark-parse';
import { RemarkParseOptions } from 'remark-parse';
import * as unified from 'unified';
import * as Unist from 'unist';

Expand All @@ -7,7 +7,7 @@ import { MarkdownParserResult } from './types';

export const parseWithPointers = (
value: string,
opts?: IParseOpts,
opts?: Partial<RemarkParseOptions>,
processor?: unified.Processor,
): MarkdownParserResult => {
const tree = parse(value, opts, processor) as Unist.Parent;
Expand Down
15 changes: 0 additions & 15 deletions src/remark-parse.d.ts

This file was deleted.

31 changes: 0 additions & 31 deletions src/remark-stringify.d.ts

This file was deleted.

8 changes: 4 additions & 4 deletions src/stringify.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import remarkStringify, { IStringifyOpts } from 'remark-stringify';
import remarkStringify, { RemarkStringifyOptions } from 'remark-stringify';
import unified from 'unified';
import { Node } from 'unist';
const frontmatter = require('remark-frontmatter');

const defaultOpts: IStringifyOpts = {
const defaultOpts: Partial<RemarkStringifyOptions> = {
commonmark: true,
gfm: true,
};

const defaultProcessor = unified()
.use(remarkStringify)
.use<RemarkStringifyOptions[]>(remarkStringify)
.use(frontmatter, ['yaml']);

export const stringify = (
tree: Node,
opts: IStringifyOpts = defaultOpts,
opts: Partial<RemarkStringifyOptions> = defaultOpts,
processor: unified.Processor = defaultProcessor,
) => {
return processor()
Expand Down
Loading

0 comments on commit 2a50bb7

Please sign in to comment.