Skip to content

Commit

Permalink
Merge branch 'develop' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
marihachi committed Apr 3, 2021
2 parents bec95d8 + 044acbf commit 1cd5b06
Show file tree
Hide file tree
Showing 6 changed files with 670 additions and 644 deletions.
58 changes: 58 additions & 0 deletions src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import peg from 'pegjs';
import { MfmNode, MfmPlainNode } from './node';
import { stringifyNode, stringifyTree } from './util';

const parser: peg.Parser = require('./parser');

export function parse(input: string): MfmNode[] {
const nodes = parser.parse(input, { startRule: 'fullParser' });
return nodes;
}

export function parsePlain(input: string): MfmPlainNode[] {
const nodes = parser.parse(input, { startRule: 'plainParser' });
return nodes;
}

export function toString(tree: MfmNode[]): string
export function toString(node: MfmNode): string
export function toString(node: MfmNode | MfmNode[]): string {
if (Array.isArray(node)) {
return stringifyTree(node);
}
else {
return stringifyNode(node);
}
}

export function inspect(tree: MfmNode[], action: (node: MfmNode) => void): void {
for (const node of tree) {
action(node);
if (node.children != null) {
inspect(node.children, action);
}
}
}

export function extract(nodes: MfmNode[], type: (MfmNode['type'] | MfmNode['type'][])): MfmNode[] {
function predicate(node: MfmNode, type: (MfmNode['type'] | MfmNode['type'][])): boolean {
if (Array.isArray(type)) {
return (type.some(i => i == node.type));
}
else {
return (type == node.type);
}
}

const dest = [] as MfmNode[];
for (const node of nodes) {
if (predicate(node, type)) {
dest.push(node);
}
if (node.children != null) {
dest.push(...extract(node.children, type));
}
}

return dest;
}
64 changes: 7 additions & 57 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,10 @@
import peg from 'pegjs';
import { MfmNode, MfmPlainNode } from './node';
import { stringifyNode, stringifyTree } from './util';
const parser: peg.Parser = require('./parser');

export function parse(input: string): MfmNode[] {
const nodes = parser.parse(input, { startRule: 'fullParser' });
return nodes;
}

export function parsePlain(input: string): MfmPlainNode[] {
const nodes = parser.parse(input, { startRule: 'plainParser' });
return nodes;
}

export function toString(tree: MfmNode[]): string
export function toString(node: MfmNode): string
export function toString(node: MfmNode | MfmNode[]): string {
if (Array.isArray(node)) {
return stringifyTree(node);
}
else {
return stringifyNode(node);
}
}

export function inspect(tree: MfmNode[], action: (node: MfmNode) => void): void {
for (const node of tree) {
action(node);
if (node.children != null) {
inspect(node.children, action);
}
}
}

export function extract(nodes: MfmNode[], type: (MfmNode['type'] | MfmNode['type'][])): MfmNode[] {
function predicate(node: MfmNode, type: (MfmNode['type'] | MfmNode['type'][])): boolean {
if (Array.isArray(type)) {
return (type.some(i => i == node.type));
}
else {
return (type == node.type);
}
}

const dest = [] as MfmNode[];
for (const node of nodes) {
if (predicate(node, type)) {
dest.push(node);
}
if (node.children != null) {
dest.push(...extract(node.children, type));
}
}

return dest;
}
export {
parse,
parsePlain,
toString,
inspect,
extract
} from './api';

export { NodeType } from './node';

Expand Down
58 changes: 58 additions & 0 deletions test/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import assert from 'assert';
import { extract, inspect, parse, toString } from '../built/index';
import {
TEXT, CENTER, FN, UNI_EMOJI, MENTION, EMOJI_CODE, HASHTAG, N_URL, BOLD, SMALL, ITALIC, STRIKE, QUOTE, MATH_BLOCK, SEARCH, CODE_BLOCK, LINK
} from './node';

describe('API', () => {
describe('toString', () => {
it('basic', () => {
const input =
`before
<center>
Hello [tada everynyan! 🎉]
I'm @ai, A bot of misskey!
https://github.com/syuilo/ai
</center>
after`;
assert.strictEqual(toString(parse(input)), input);
});
});

describe('inspect', () => {
it('replace text', () => {
const input = 'good morning [tada everynyan!]';
const result = parse(input);
inspect(result, node => {
if (node.type == 'text') {
node.props.text = node.props.text.replace(/good morning/g, 'hello');
}
});
assert.strictEqual(toString(result), 'hello [tada everynyan!]');
});
});

describe('extract', () => {
it('basic', () => {
const nodes = parse('@hoge @piyo @bebeyo');
const expect = [
MENTION('hoge', null, '@hoge'),
MENTION('piyo', null, '@piyo'),
MENTION('bebeyo', null, '@bebeyo')
];
assert.deepStrictEqual(extract(nodes, 'mention'), expect);
});

it('nested', () => {
const nodes = parse('abc:hoge:[tada 123 @hoge :foo:]:piyo:');
const expect = [
EMOJI_CODE('hoge'),
EMOJI_CODE('foo'),
EMOJI_CODE('piyo')
];
assert.deepStrictEqual(extract(nodes, 'emojiCode'), expect);
});
});
});
Loading

0 comments on commit 1cd5b06

Please sign in to comment.