mirror of
https://activitypub.software/TransFem-org/sfm-js
synced 2024-11-25 07:25:13 +00:00
🐱
This commit is contained in:
parent
0a78a1b404
commit
28841ea930
2 changed files with 89 additions and 84 deletions
88
src/index.ts
88
src/index.ts
|
@ -1,5 +1,6 @@
|
||||||
import peg from 'pegjs';
|
import peg from 'pegjs';
|
||||||
import { MfmNode } from './node';
|
import { MfmNode } from './node';
|
||||||
|
import { stringifyNode, stringifyTree } from './util';
|
||||||
const parser: peg.Parser = require('./parser');
|
const parser: peg.Parser = require('./parser');
|
||||||
|
|
||||||
export function parse(input: string): MfmNode[] {
|
export function parse(input: string): MfmNode[] {
|
||||||
|
@ -12,95 +13,14 @@ export function parsePlain(input: string): MfmNode[] {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nodeStringify(node: MfmNode): string {
|
export function toString(tree: MfmNode[]): string
|
||||||
switch(node.type) {
|
|
||||||
// block
|
|
||||||
case 'quote': {
|
|
||||||
return toString(node.children).split('\n').map(line => `>${line}`).join('\n');
|
|
||||||
}
|
|
||||||
case 'search': {
|
|
||||||
return node.props.content;
|
|
||||||
}
|
|
||||||
case 'blockCode': {
|
|
||||||
return `\`\`\`${ node.props.lang ?? '' }\n${ node.props.code }\n\`\`\``;
|
|
||||||
}
|
|
||||||
case 'mathBlock': {
|
|
||||||
return `\\[\n${ node.props.formula }\n\\]`;
|
|
||||||
}
|
|
||||||
case 'center': {
|
|
||||||
return `<center>${ toString(node.children) }</center>`;
|
|
||||||
}
|
|
||||||
// inline
|
|
||||||
case 'emoji': {
|
|
||||||
if (node.props.name) {
|
|
||||||
return `:${ node.props.name }:`;
|
|
||||||
}
|
|
||||||
else if (node.props.emoji) {
|
|
||||||
return node.props.emoji;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 'bold': {
|
|
||||||
return `**${ toString(node.children) }**`;
|
|
||||||
}
|
|
||||||
case 'small': {
|
|
||||||
return `<small>${ toString(node.children) }</small>`;
|
|
||||||
}
|
|
||||||
case 'italic': {
|
|
||||||
return `<i>${ toString(node.children) }</i>`;
|
|
||||||
}
|
|
||||||
case 'strike': {
|
|
||||||
return `~~${ toString(node.children) }~~`;
|
|
||||||
}
|
|
||||||
case 'inlineCode': {
|
|
||||||
return `\`${ node.props.code }\``;
|
|
||||||
}
|
|
||||||
case 'mathInline': {
|
|
||||||
return `\\(${ node.props.formula }\\)`;
|
|
||||||
}
|
|
||||||
case 'mention': {
|
|
||||||
return node.props.acct;
|
|
||||||
}
|
|
||||||
case 'hashtag': {
|
|
||||||
return `#${ node.props.hashtag }`;
|
|
||||||
}
|
|
||||||
case 'url': {
|
|
||||||
return node.props.url;
|
|
||||||
}
|
|
||||||
case 'link': {
|
|
||||||
const prefix = node.props.silent ? '?' : '';
|
|
||||||
return `${ prefix }[${ toString(node.children) }](${ node.props.url })`;
|
|
||||||
}
|
|
||||||
case 'fn': {
|
|
||||||
const argFields = Object.keys(node.props.args).map(key => {
|
|
||||||
const value = node.props.args[key];
|
|
||||||
if (value === true) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return `${ key }=${ value }`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const args = (argFields.length > 0) ? '.' + argFields.join(',') : '';
|
|
||||||
return `[${ node.props.name }${ args } ${ toString(node.children) }]`;
|
|
||||||
}
|
|
||||||
case 'text': {
|
|
||||||
return node.props.text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error('unknown mfm node');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toString(nodes: MfmNode[]): string
|
|
||||||
export function toString(node: MfmNode): string
|
export function toString(node: MfmNode): string
|
||||||
export function toString(node: MfmNode | MfmNode[]): string {
|
export function toString(node: MfmNode | MfmNode[]): string {
|
||||||
if (Array.isArray(node)) {
|
if (Array.isArray(node)) {
|
||||||
return node.map(n => nodeStringify(n)).join('');
|
return stringifyTree(node);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nodeStringify(node);
|
return stringifyNode(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
85
src/util.ts
85
src/util.ts
|
@ -71,6 +71,91 @@ export function mergeText(trees: MfmNode[] | undefined, recursive?: boolean): Mf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stringifyNode(node: MfmNode): string {
|
||||||
|
switch(node.type) {
|
||||||
|
// block
|
||||||
|
case 'quote': {
|
||||||
|
return stringifyTree(node.children).split('\n').map(line => `>${line}`).join('\n');
|
||||||
|
}
|
||||||
|
case 'search': {
|
||||||
|
return node.props.content;
|
||||||
|
}
|
||||||
|
case 'blockCode': {
|
||||||
|
return `\`\`\`${ node.props.lang ?? '' }\n${ node.props.code }\n\`\`\``;
|
||||||
|
}
|
||||||
|
case 'mathBlock': {
|
||||||
|
return `\\[\n${ node.props.formula }\n\\]`;
|
||||||
|
}
|
||||||
|
case 'center': {
|
||||||
|
return `<center>${ stringifyTree(node.children) }</center>`;
|
||||||
|
}
|
||||||
|
// inline
|
||||||
|
case 'emoji': {
|
||||||
|
if (node.props.name) {
|
||||||
|
return `:${ node.props.name }:`;
|
||||||
|
}
|
||||||
|
else if (node.props.emoji) {
|
||||||
|
return node.props.emoji;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'bold': {
|
||||||
|
return `**${ stringifyTree(node.children) }**`;
|
||||||
|
}
|
||||||
|
case 'small': {
|
||||||
|
return `<small>${ stringifyTree(node.children) }</small>`;
|
||||||
|
}
|
||||||
|
case 'italic': {
|
||||||
|
return `<i>${ stringifyTree(node.children) }</i>`;
|
||||||
|
}
|
||||||
|
case 'strike': {
|
||||||
|
return `~~${ stringifyTree(node.children) }~~`;
|
||||||
|
}
|
||||||
|
case 'inlineCode': {
|
||||||
|
return `\`${ node.props.code }\``;
|
||||||
|
}
|
||||||
|
case 'mathInline': {
|
||||||
|
return `\\(${ node.props.formula }\\)`;
|
||||||
|
}
|
||||||
|
case 'mention': {
|
||||||
|
return node.props.acct;
|
||||||
|
}
|
||||||
|
case 'hashtag': {
|
||||||
|
return `#${ node.props.hashtag }`;
|
||||||
|
}
|
||||||
|
case 'url': {
|
||||||
|
return node.props.url;
|
||||||
|
}
|
||||||
|
case 'link': {
|
||||||
|
const prefix = node.props.silent ? '?' : '';
|
||||||
|
return `${ prefix }[${ stringifyTree(node.children) }](${ node.props.url })`;
|
||||||
|
}
|
||||||
|
case 'fn': {
|
||||||
|
const argFields = Object.keys(node.props.args).map(key => {
|
||||||
|
const value = node.props.args[key];
|
||||||
|
if (value === true) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return `${ key }=${ value }`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const args = (argFields.length > 0) ? '.' + argFields.join(',') : '';
|
||||||
|
return `[${ node.props.name }${ args } ${ stringifyTree(node.children) }]`;
|
||||||
|
}
|
||||||
|
case 'text': {
|
||||||
|
return node.props.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('unknown mfm node');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stringifyTree(tree: MfmNode[]): string {
|
||||||
|
return tree.map(n => stringifyNode(n)).join('');
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// dynamic consuming
|
// dynamic consuming
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue