fix(markdown-parser): handle interpolation inside links

This commit is contained in:
alina 🌸 2024-05-30 00:07:47 +03:00
parent e081fddbc2
commit 41a3575805
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
2 changed files with 94 additions and 45 deletions

View file

@ -146,6 +146,9 @@ function parse(
let insidePre = false let insidePre = false
let insideLink = false let insideLink = false
let insideLinkUrl = false
let pendingLinkUrl = ''
function feed(text: string) { function feed(text: string) {
const len = text.length const len = text.length
let pos = 0 let pos = 0
@ -154,7 +157,11 @@ function parse(
const c = text[pos] const c = text[pos]
if (c === '\\') { if (c === '\\') {
if (insideLinkUrl) {
pendingLinkUrl += text[pos + 1]
} else {
result += text[pos + 1] result += text[pos + 1]
}
pos += 2 pos += 2
continue continue
} }
@ -220,19 +227,29 @@ function parse(
} }
pos += 2 pos += 2
let url = '' insideLink = false
insideLinkUrl = true
while (pos < text.length && text[pos] !== ')') { stacks.link.push(ent)
url += text[pos++] continue
} }
pos += 1 // ) if (insideLinkUrl) {
pos += 1
if (pos > text.length) { if (c !== ')') {
throw new Error('Malformed LINK entity, expected )') // not ended yet
pendingLinkUrl += c
continue
} }
if (url.length) { const ent = stacks.link.pop()!
let url = pendingLinkUrl
pendingLinkUrl = ''
insideLinkUrl = false
if (!url.length) continue
ent.length = result.length - ent.offset ent.length = result.length - ent.offset
let m = url.match(MENTION_REGEX) let m = url.match(MENTION_REGEX)
@ -242,8 +259,7 @@ function parse(
const accessHash = m[2] const accessHash = m[2]
if (accessHash) { if (accessHash) {
(ent as tl.Mutable<tl.RawInputMessageEntityMentionName>)._ = (ent as tl.Mutable<tl.RawInputMessageEntityMentionName>)._ = 'inputMessageEntityMentionName'
'inputMessageEntityMentionName'
;(ent as tl.Mutable<tl.RawInputMessageEntityMentionName>).userId = { ;(ent as tl.Mutable<tl.RawInputMessageEntityMentionName>).userId = {
_: 'inputUser', _: 'inputUser',
userId, userId,
@ -262,9 +278,7 @@ function parse(
;(ent as tl.Mutable<tl.RawMessageEntityTextUrl>).url = url ;(ent as tl.Mutable<tl.RawMessageEntityTextUrl>).url = url
} }
entities.push(ent) entities.push(ent)
}
insideLink = false
continue continue
} }
@ -395,6 +409,19 @@ function parse(
if (typeof it === 'boolean' || !it) return if (typeof it === 'boolean' || !it) return
if (insideLinkUrl) {
if (typeof it === 'string' || typeof it === 'number') {
pendingLinkUrl += it
} else if (Long.isLong(it)) {
pendingLinkUrl += it.toString(10)
} else {
// ignore the entity, only use text
pendingLinkUrl += it.text
}
return
}
if (typeof it === 'string' || typeof it === 'number') { if (typeof it === 'string' || typeof it === 'number') {
result += it result += it
} else if (Long.isLong(it)) { } else if (Long.isLong(it)) {

View file

@ -514,6 +514,11 @@ describe('MarkdownMessageEntityParser', () => {
test(md_`${'**plain**'}`, [], '**plain**') test(md_`${'**plain**'}`, [], '**plain**')
}) })
it('should handle numbers/Longs', () => {
test(md_`${1234567890}`, [], '1234567890')
test(md_`${Long.fromString('1234567890')}`, [], '1234567890')
})
it('should skip falsy values', () => { it('should skip falsy values', () => {
test(md_`some text ${null} more text ${false}`, [], 'some text more text ') test(md_`some text ${null} more text ${false}`, [], 'some text more text ')
}) })
@ -579,6 +584,23 @@ describe('MarkdownMessageEntityParser', () => {
) )
}) })
it('should interpolate inside links', () => {
test(
md_`[${'link'}](${'https'}://example.com/\\)${'foo'}/bar/${'baz'}?foo=bar&baz=${'egg'})`,
[
createEntity('messageEntityTextUrl', 0, 4, {
url: 'https://example.com/)foo/bar/baz?foo=bar&baz=egg',
}),
],
'link',
)
test(
md_`[emoji](tg://emoji?id=${Long.fromNumber(123123)})`,
[createEntity('messageEntityCustomEmoji', 0, 5, { documentId: Long.fromNumber(123123) })],
'emoji',
)
})
it('should process MessageEntity', () => { it('should process MessageEntity', () => {
test( test(
md_`**bold ${new MessageEntity(createEntity('messageEntityItalic', 0, 11), 'bold italic')} more bold**`, md_`**bold ${new MessageEntity(createEntity('messageEntityItalic', 0, 11), 'bold italic')} more bold**`,