Skip to content
Snippets Groups Projects
Commit 027edb46 authored by marihachi's avatar marihachi
Browse files

Merge branch 'develop' into master

parents d238c1da e412bcd1
No related branches found
Tags v0.15.0
No related merge requests found
......@@ -54,9 +54,15 @@ npm run build
```
### Use the interactive CLI parser
full parser:
```
npm run parse
```
plain parser:
```
npm run parse-plain
```
## License
This software is released under the [MIT License](LICENSE).
{
"name": "mfm-js",
"version": "0.15.0",
"version": "0.15.1",
"description": "An MFM parser implementation with PEG.js",
"main": "./built/index.js",
"types": "./built/index.d.ts",
......
import peg from 'pegjs';
import { MfmNode, MfmPlainNode } from './node';
import { stringifyNode, stringifyTree } from './util';
import { stringifyNode, stringifyTree, inspectOne } from './util';
const parser: peg.Parser = require('./parser');
......@@ -37,13 +37,17 @@ export function toString(node: MfmNode | MfmNode[]): string {
/**
* Inspects the MfmNode tree.
*/
export function inspect(nodes: MfmNode[], action: (node: MfmNode) => void): void {
for (const node of nodes) {
action(node);
if (node.children != null) {
inspect(node.children, action);
export function inspect(node: MfmNode, action: (node: MfmNode) => void): void
export function inspect(nodes: MfmNode[], action: (node: MfmNode) => void): void
export function inspect(node: (MfmNode | MfmNode[]), action: (node: MfmNode) => void): void {
if (Array.isArray(node)) {
for (const n of node) {
inspectOne(n, action);
}
}
else {
inspectOne(node, action);
}
}
/**
......
......@@ -85,15 +85,26 @@ block
// block: quote
quote
= lines:quoteLine+
= head:quoteMultiLine tails:quoteMultiLine+
{
const children = applyParser(lines.join('\n'), 'fullParser');
const children = applyParser([head, ...tails].join('\n'), 'fullParser');
return QUOTE(children);
}
/ line:quoteLine
{
const children = applyParser(line, 'fullParser');
return QUOTE(children);
}
quoteMultiLine
= quoteLine / quoteEmptyLine
quoteLine
= BEGIN ">" _? text:$(CHAR+) END { return text; }
quoteEmptyLine
= BEGIN ">" _? END { return ''; }
// block: search
search
......
......@@ -147,6 +147,15 @@ export function stringifyTree(nodes: MfmNode[]): string {
return dest.map(n => stringifyNode(n)).join('');
}
export function inspectOne(node: MfmNode, action: (node: MfmNode) => void) {
action(node);
if (node.children != null) {
for (const child of node.children) {
inspectOne(child, action);
}
}
}
//
// dynamic consuming
//
......
......@@ -32,6 +32,17 @@ after`;
});
assert.strictEqual(mfm.toString(result), 'hello [tada everynyan!]');
});
it('replace text (one item)', () => {
const input = 'good morning [tada everyone!]';
const result = mfm.parse(input);
mfm.inspect(result[1], node => {
if (node.type == 'text') {
node.props.text = node.props.text.replace(/one/g, 'nyan');
}
});
assert.strictEqual(mfm.toString(result), 'good morning [tada everynyan!]');
});
});
describe('extract', () => {
......
......@@ -89,6 +89,26 @@ describe('FullParser', () => {
];
assert.deepStrictEqual(mfm.parse(input), output);
});
it('複数行の引用ブロックでは空行を含めることができる', () => {
const input = `
> abc
>
> 123
`;
const output = [
QUOTE([
TEXT('abc\n\n123')
])
];
assert.deepStrictEqual(mfm.parse(input), output);
});
it('1行の引用ブロックを空行にはできない', () => {
const input = `> `;
const output = [
TEXT('> ')
];
assert.deepStrictEqual(mfm.parse(input), output);
});
});
describe('search', () => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment