2
2
mirror of https://github.com/Thream/website.git synced 2024-07-21 09:28:32 +02:00
website/components/Emoji/emojiPlugin.tsx

64 lines
1.9 KiB
TypeScript
Raw Normal View History

2021-10-24 05:19:39 +02:00
import visit from 'unist-util-visit'
import { Plugin, Transformer } from 'unified'
import { Node } from 'unist'
import { EmojiSet } from 'emoji-mart'
export const emojiSet: EmojiSet = 'twitter'
export const emojiRegex = /:\+1:|:-1:|:[\w-]+:/
export const isStringWithOnlyOneEmoji = (value: string): boolean => {
const result = emojiRegex.exec(value)
return result != null && result.input === result[0]
}
const extractText = (string: string, start: number, end: number): Node => {
const startLine = string.slice(0, start).split('\n')
const endLine = string.slice(0, end).split('\n')
return {
type: 'text',
value: string.slice(start, end),
position: {
start: {
line: startLine.length,
column: startLine[startLine.length - 1].length + 1
},
end: {
line: endLine.length,
column: endLine[endLine.length - 1].length + 1
}
}
}
}
export const emojiPlugin: Plugin = () => {
const transformer: Transformer = (tree) => {
visit(tree, 'text', (node, position, parent) => {
if (typeof node.value !== 'string') {
return
}
const definition: Node[] = []
let lastIndex = 0
const match = emojiRegex.exec(node.value)
if (match != null) {
const value = match[0]
if (match.index !== lastIndex) {
definition.push(extractText(node.value, lastIndex, match.index))
}
definition.push({ type: 'emoji', value })
lastIndex = match.index + value.length
if (lastIndex !== node.value.length) {
definition.push(extractText(node.value, lastIndex, node.value.length))
}
if (parent != null) {
const last = parent.children.slice(position + 1)
parent.children = parent.children.slice(0, position)
parent.children = parent.children.concat(definition)
parent.children = parent.children.concat(last)
}
}
})
}
return transformer
}