Skip to content

Commit

Permalink
feat: parse to map (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
trim21 authored Jan 13, 2023
1 parent 01acc1f commit dece9b6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 2 deletions.
32 changes: 31 additions & 1 deletion __test__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as url from 'node:url';
import yaml from 'js-yaml';
import { describe, test, expect } from '@jest/globals';

import { parse, stringify } from '../src';
import { parse, parseToMap, stringify, WikiArrayItem, WikiItem } from '../src';

const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

Expand Down Expand Up @@ -86,3 +86,33 @@ describe('Wiki stringify', () => {
});
}
});

describe('parse map', () => {
const item = new WikiItem('A', '', 'array');

item.values = [new WikiArrayItem(undefined, 'b'), new WikiArrayItem(undefined, 'c')];

const expected = { type: '', data: new Map([['A', item]]) };

test('should merge keys', () => {
const o = parseToMap(`{{Infobox
|A= b
| A=c
}}
`);

expect(o).toEqual(expected);
});

test('should merge previous array keys', () => {
const o = parseToMap(`{{Infobox
|A= {
[b]
}
| A=c
}}
`);

expect(o).toEqual(expected);
});
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
"lint-staged": {
"*.{md,js,jsx,ts,tsx,json,yml,yaml}": [
"prettier --ignore-path ./.prettierignore --write"
],
"*.{js,ts}": [
"eslint --fix"
]
},
"files": [
Expand Down
21 changes: 20 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,32 @@ import {
WikiSyntaxError,
} from './error';
import { prefix, suffix } from './shared';
import type { Wiki, WikiItemType } from './types';
import type { Wiki, WikiItemType, WikiMap } from './types';
import { WikiArrayItem, WikiItem } from './types';

export * from './types';
export * from './error';
export { stringify } from './stringify';

/** 解析 wiki 文本,以 `Map` 类型返回解析结果。 会合并重复出现的 key */
export function parseToMap(s: string): WikiMap {
const w = parse(s);

const data = new Map<string, WikiItem>();

for (const item of w.data) {
const previous = data.get(item.key);
if (!previous) {
data.set(item.key, item);
continue;
}

previous.push(item);
}

return { type: w.type, data };
}

export function parse(s: string): Wiki {
const wiki: Wiki = {
type: '',
Expand Down
28 changes: 28 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ export interface Wiki {
data: WikiItem[];
}

/** JS 的 map 会按照插入顺序排序 */
export interface WikiMap {
type: string;
data: Map<string, WikiItem>;
}

export type WikiItemType = 'array' | 'object';

export class WikiArrayItem {
Expand Down Expand Up @@ -36,4 +42,26 @@ export class WikiItem {
}
}
}

private convertToArray() {
if (this.array) {
return;
}

this.array = true;
this.values ??= [];

this.values.push(new WikiArrayItem(undefined, this.value));
this.value = undefined;
}

push(item: WikiItem) {
this.convertToArray();

if (item.array) {
this.values?.push(...(item.values ?? []));
} else {
this.values?.push(new WikiArrayItem(undefined, item.value));
}
}
}

0 comments on commit dece9b6

Please sign in to comment.