Nertivia-Client/src/utils/markdown-it-plugins/replaceCustomEmoji.js

92 lines
No EOL
2 KiB
JavaScript

import config from "@/config.js";
/* 58: ':' */
/* 60: '<' */
/* 62: '>' */
function render_custom_emoji(tokens, idx) {
return ':3'
}
function parseUntil(state, fromPos, until) {
let max = state.posMax
let found = false
let oldPos = state.pos
// let start = nameStart + 1
state.pos = fromPos
let end = -1
while(state.pos++ < max) {
let marker = state.src.charCodeAt(state.pos)
if(marker === until) {
found = true;
break;
}
}
if(found) {
end = state.pos
}
state.pos = oldPos
return end
}
function parseEmojiName(state, nameStart) {
return parseUntil(state, nameStart, 58)
}
function replace_custom_emoji(state, silent) {
let pos = state.pos
let max = state.posMax
// if begins with <
if (state.src.charCodeAt(pos) !== 60) { return false; }
pos += 1
// if the next character is not ':' then it's not a custom emoji
if(state.src.charCodeAt(pos) !== 58) { return false; }
// parse the emoji name
let nameStart = pos + 1
let nameEnd = parseEmojiName(state, nameStart)
// parser failed to find another ':', so it's not a valid emoji
if(nameEnd < 0 || nameEnd - nameStart <= 1) { return false; }
let emojiName = state.src.slice(nameStart, nameEnd)
pos = nameEnd + 1
// parse until '>'
let idStart = pos
let idEnd = parseUntil(state, idStart, 62)
if(idEnd < 0 || idEnd - idStart <= 1) { return false; }
let emojiID = state.src.slice(idStart, idEnd)
if(!silent) {
state.pos = idStart
state.posMax = idEnd
let token = state.push('custom_emoji_open', 'img', 1);
token.attrs = [[ 'src', `${config.domain}/files/${emojiID}` ]]
// state.md.inline.tokenize(state)
}
state.pos = idEnd + 1
state.posMax = max
return true
}
export default function custom_emoji_plugin(md, opts) {
md.renderer.rules.custom_emoji_open = (tokens, idx) => {
let token = tokens[idx]
return `<${md.utils.escapeHtml(token.tag)} class="emoji" src=${md.utils.escapeHtml(token.attrs.find(([name]) => name === 'src')[1])} />`
}
md.inline.ruler.push('custom_emoji', replace_custom_emoji)
}