This commit is contained in:
marihachi 2021-03-27 22:09:18 +09:00
parent ffa45abfd8
commit 57e687efa2
2 changed files with 48 additions and 5 deletions

View file

@ -2,6 +2,11 @@ export type MfmNode = MfmBlock | MfmInline;
export type MfmBlock = MfmQuote | MfmSearch | MfmCodeBlock | MfmMathBlock | MfmCenter; export type MfmBlock = MfmQuote | MfmSearch | MfmCodeBlock | MfmMathBlock | MfmCenter;
const blockTypes: MfmNode['type'][] = [ 'quote', 'search', 'blockCode', 'mathBlock', 'center' ];
export function isMfmBlock(node: MfmNode): node is MfmBlock {
return blockTypes.includes(node.type);
}
export type MfmQuote = { export type MfmQuote = {
type: 'quote'; type: 'quote';
props?: { }; props?: { };

View file

@ -1,4 +1,4 @@
import { MfmNode } from './node'; import { isMfmBlock, MfmNode } from './node';
export function createNode(type: string, props?: Record<string, any>, children?: MfmNode[]): MfmNode { export function createNode(type: string, props?: Record<string, any>, children?: MfmNode[]): MfmNode {
const node: any = { type }; const node: any = { type };
@ -45,7 +45,7 @@ export function stringifyNode(node: MfmNode): string {
switch(node.type) { switch(node.type) {
// block // block
case 'quote': { case 'quote': {
return stringifyTree(node.children).split('\n').map(line => `>${line}`).join('\n'); return stringifyTree(node.children).split('\n').map(line => `> ${line}`).join('\n');
} }
case 'search': { case 'search': {
return node.props.content; return node.props.content;
@ -57,7 +57,7 @@ export function stringifyNode(node: MfmNode): string {
return `\\[\n${ node.props.formula }\n\\]`; return `\\[\n${ node.props.formula }\n\\]`;
} }
case 'center': { case 'center': {
return `<center>${ stringifyTree(node.children) }</center>`; return `<center>\n${ stringifyTree(node.children) }\n</center>`;
} }
// inline // inline
case 'emoji': { case 'emoji': {
@ -122,8 +122,46 @@ export function stringifyNode(node: MfmNode): string {
throw new Error('unknown mfm node'); throw new Error('unknown mfm node');
} }
export function stringifyTree(tree: MfmNode[]): string { enum stringifyState {
return tree.map(n => stringifyNode(n)).join(''); none = 0,
inline,
block
};
export function stringifyTree(nodes: MfmNode[]): string {
let dest: MfmNode[] = [];
let state: stringifyState = stringifyState.none;
for (const node of nodes) {
// 文脈に合わせて改行を追加する。
// none -> inline : No
// none -> block : No
// inline -> inline : No
// inline -> block : Yes
// block -> inline : Yes
// block -> block : Yes
let pushLf: boolean = true;
if (isMfmBlock(node)) {
if (state == stringifyState.none) {
pushLf = false;
}
state = stringifyState.block;
}
else {
if (state == stringifyState.none || state == stringifyState.inline) {
pushLf = false;
}
state = stringifyState.inline;
}
if (pushLf) {
dest.push(createNode('text', { text: '\n' }));
}
dest.push(node);
}
return dest.map(n => stringifyNode(n)).join('');
} }
// //