Skip to content
Snippets Groups Projects
Commit 18ca201a authored by marihachi's avatar marihachi
Browse files

update

* implement url
parent 8bee369b
No related branches found
No related tags found
No related merge requests found
import peg from 'pegjs';
import { MfmNode } from './mfm-node';
import { MfmNode } from './util';
const parser: peg.Parser = require('./parser');
export function parse(input: string): MfmNode[] {
......
{
const {
createNode,
mergeText
} = require('./mfm-node');
mergeText,
setConsumeCount,
consumeDynamically
} = require('./util');
function applyParser(input, startRule) {
let parseFunc = peg$parse;
......@@ -12,8 +14,6 @@
// emoji
const emojiRegex = require('twemoji-parser/dist/lib/regex').default;
let emojiLoop = 0;
const anchoredEmojiRegex = RegExp(`^(?:${emojiRegex.source})`);
/**
......@@ -26,23 +26,12 @@
const result = anchoredEmojiRegex.exec(src);
if (result != null) {
emojiLoop = result[0].length; // length(utf-16 byte length) of emoji sequence.
setConsumeCount(result[0].length); // length(utf-16 byte length) of emoji sequence.
return true;
}
return false;
}
/**
* this is the process when the input is consumed as emojis.
*/
function forwardUnicodeEmoji() {
const forwarding = (emojiLoop > 0);
if (forwarding) {
emojiLoop--;
}
return forwarding;
}
}
//
......@@ -167,6 +156,7 @@ inline
/ inlineCode
/ mathInline
/ hashtag
/ url
/ text
// inline: emoji
......@@ -185,7 +175,7 @@ emojiName
// NOTE: if the text matches one of the emojis, it will count the length of the emoji sequence and consume it.
unicodeEmoji
= &{ return matchUnicodeEmoji(); } (&{ return forwardUnicodeEmoji(); } .)+
= &{ return matchUnicodeEmoji(); } (&{ return consumeDynamically(); } .)+
{
return createNode('emoji', { emoji: text() });
}
......@@ -222,14 +212,6 @@ small
return createNode('small', { }, mergeText(content));
}
// inline: strike
strike
= "~~" content:(!("~" / LF) i:inline { return i; })+ "~~"
{
return createNode('strike', { }, mergeText(content));
}
// inline: italic
italic
......@@ -248,6 +230,14 @@ italic
return createNode('italic', { }, parsedContent);
}
// inline: strike
strike
= "~~" content:(!("~" / LF) i:inline { return i; })+ "~~"
{
return createNode('strike', { }, mergeText(content));
}
// inline: inlineCode
inlineCode
......@@ -287,6 +277,36 @@ hashtagBracketPair
hashtagChar
= ![ \t.,!?'"#:\/\[\]【】()「」] CHAR
// inline: URL
url
= "<" url:urlFormat ">"
{
return createNode('url', { url: url });
}
/ url:urlFormat
{
return createNode('url', { url: url });
}
urlFormat
= "http" "s"? "://" urlContent
{
return text();
}
urlContent
= urlContentPart+
urlContentPart
= urlBracketPair
/ [.,] &urlContentPart // last char is neither "." nor ",".
/ [a-z0-9/:%#@$&?!~=+-]i
urlBracketPair
= "(" urlContentPart* ")"
/ "[" urlContentPart* "]"
// inline: text
text
......
......@@ -61,3 +61,39 @@ export function mergeText(trees: MfmNode[], recursive?: boolean): MfmNode[] {
return createNode(tree.type, tree.props, recursive ? mergeText(tree.children) : tree.children);
});
}
//
// dynamic consuming
//
/*
1. If you want to consume 3 chars, call the setConsumeCount.
```
setConsumeCount(3);
```
2. And the rule to consume the input is as below:
```
rule = (&{ return consumeDynamically(); } .)+
```
*/
let consumeCount = 0;
/**
* set the length of dynamic consuming.
*/
export function setConsumeCount(count: number) {
consumeCount = count;
}
/**
* consume the input and returns matching result.
*/
export function consumeDynamically() {
const matched = (consumeCount > 0);
if (matched) {
consumeCount--;
}
return matched;
}
......@@ -2,7 +2,7 @@ import assert from 'assert';
import { parse, parsePlain } from '../built/index';
import { createNode } from '../built/mfm-node';
import {
TEXT, EMOJI, UNI_EMOJI, HASHTAG
TEXT, EMOJI, UNI_EMOJI, HASHTAG, N_URL
} from './node';
describe('text', () => {
......@@ -35,3 +35,15 @@ describe('hashtag', () => {
assert.deepStrictEqual(parse(input), output);
});
});
describe('url', () => {
it('basic', () => {
const input = 'official instance: https://misskey.io/@ai.';
const output = [
TEXT('official instance: '),
N_URL('https://misskey.io/@ai'),
TEXT('.')
];
assert.deepStrictEqual(parse(input), output);
});
});
......@@ -4,3 +4,4 @@ export const TEXT = (value: string) => createNode('text', { text: value });
export const EMOJI = (name: string) => createNode('emoji', { name: name });
export const UNI_EMOJI = (value: string) => createNode('emoji', { emoji: value });
export const HASHTAG = (value: string) => createNode('hashtag', { hashtag: value });
export const N_URL = (value: string) => createNode('url', { url: value });
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