diff --git a/src/mfm/parser.ts b/src/mfm/parser.ts index 480d59075..e9174a99f 100644 --- a/src/mfm/parser.ts +++ b/src/mfm/parser.ts @@ -29,6 +29,26 @@ function makeNodeWithChildren(name: string, children: Node[], props?: any): Node return _makeNode(name, children, props); } +function getTrailingPosition(x: string): number { + let pendingBracket = 0; + const end = x.split('').findIndex(char => { + if (char == ')') { + if (pendingBracket > 0) { + pendingBracket--; + return false; + } else { + return true; + } + } else if (char == '(') { + pendingBracket++; + return false; + } else { + return false; + } + }); + return end > 0 ? end : x.length; +} + const newline = P((input, i) => { if (i == 0 || input[i] == '\n' || input[i - 1] == '\n') { return P.makeSuccess(i, null); @@ -113,23 +133,7 @@ const mfm = P.createLanguage({ const match = text.match(/^#([^\s\.,!\?#]+)/i); if (!match) return P.makeFailure(i, 'not a hashtag'); let hashtag = match[1]; - let pendingBracket = 0; - const end = hashtag.split('').findIndex(char => { - if (char == ')') { - if (pendingBracket > 0) { - pendingBracket--; - return false; - } else { - return true; - } - } else if (char == '(') { - pendingBracket++; - return false; - } else { - return false; - } - }); - if (end > 0) hashtag = hashtag.substr(0, end); + hashtag = hashtag.substr(0, getTrailingPosition(hashtag)); if (hashtag.match(/^[0-9]+$/)) return P.makeFailure(i, 'not a hashtag'); if (!['\n', ' ', '(', null, undefined].includes(input[i - 1])) return P.makeFailure(i, 'require space before "#"'); return P.makeSuccess(i + ('#' + hashtag).length, makeNode('hashtag', { hashtag: hashtag })); @@ -264,23 +268,7 @@ const mfm = P.createLanguage({ const match = text.match(/^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.,=\+\-]+/); if (!match) return P.makeFailure(i, 'not a url'); let url = match[0]; - let pendingBracket = 0; - const end = url.split('').findIndex(char => { - if (char == ')') { - if (pendingBracket > 0) { - pendingBracket--; - return false; - } else { - return true; - } - } else if (char == '(') { - pendingBracket++; - return false; - } else { - return false; - } - }); - if (end > 0) url = url.substr(0, end); + url = url.substr(0, getTrailingPosition(url)); if (url.endsWith('.')) url = url.substr(0, url.lastIndexOf('.')); if (url.endsWith(',')) url = url.substr(0, url.lastIndexOf(',')); return P.makeSuccess(i + url.length, url);