,
entitiesOffset = 0,
offset = 0,
length = text.length,
): string {
if (!text) return text
if (!entities.length || entities.length === entitiesOffset) {
return HtmlMessageEntityParser.escape(text)
.replace(/\n/g, '
')
.replace(/ {2,}/g, (match) => {
return ' '.repeat(match.length)
})
}
const end = offset + length
const html: string[] = []
let lastOffset = 0
for (let i = entitiesOffset; i < entities.length; i++) {
const entity = entities[i]
if (entity.offset >= end) break
let entOffset = entity.offset
let length = entity.length
if (entOffset < 0) {
length += entOffset
entOffset = 0
}
let relativeOffset = entOffset - offset
if (relativeOffset > lastOffset) {
// add missing plain text
html.push(HtmlMessageEntityParser.escape(text.substring(lastOffset, relativeOffset)))
} else if (relativeOffset < lastOffset) {
length -= lastOffset - relativeOffset
relativeOffset = lastOffset
}
if (length <= 0 || relativeOffset >= end || relativeOffset < 0) {
continue
}
let skip = false
const substr = text.substr(relativeOffset, length)
if (!substr) continue
const type = entity._
let entityText
if (type === 'messageEntityPre') {
entityText = substr
} else {
entityText = this._unparse(substr, entities, i + 1, offset + relativeOffset, length)
}
switch (type) {
case 'messageEntityBold':
case 'messageEntityItalic':
case 'messageEntityUnderline':
case 'messageEntityStrike':
case 'messageEntityCode':
case 'messageEntityBlockquote':
case 'messageEntitySpoiler':
{
const tag = (
{
messageEntityBold: 'b',
messageEntityItalic: 'i',
messageEntityUnderline: 'u',
messageEntityStrike: 's',
messageEntityCode: 'code',
messageEntityBlockquote: 'blockquote',
messageEntitySpoiler: 'spoiler',
} as const
)[type]
html.push(`<${tag}>${entityText}${tag}>`)
}
break
case 'messageEntityPre':
html.push(
`${
this._syntaxHighlighter && entity.language ?
this._syntaxHighlighter(entityText, entity.language) :
entityText
}
`,
)
break
case 'messageEntityEmail':
html.push(`${entityText}`)
break
case 'messageEntityUrl':
html.push(`${entityText}`)
break
case 'messageEntityTextUrl':
html.push(`${entityText}`)
break
case 'messageEntityMentionName':
html.push(`${entityText}`)
break
default:
skip = true
break
}
lastOffset = relativeOffset + (skip ? 0 : length)
}
html.push(HtmlMessageEntityParser.escape(text.substr(lastOffset)))
return html.join('')
}
}