import request from "../services/request" interface Aoml { [key: string]: string | number, name: string; start: string; end: string; remove: number; talking: number; color: string; } const aomlParser = (text: string) => { const parsed: {[key: string]: Aoml}= {} let currentHeader = '' for (const line of text.split(/\r?\n/)) { if (line === '') { currentHeader = '' continue; } const content = line.split(' = ') const contentName = content[0] const contentValue = content[1] if (currentHeader === '') { currentHeader = contentName parsed[currentHeader] = { color: contentValue } as Aoml } else { const contentKey = contentName.split('_')[1] parsed[currentHeader][contentKey] = contentValue } } return parsed } const mlConfig = (AO_HOST: string) => { const defaultUrl = `${AO_HOST}themes/default/chat_config.ini` const aomlParsed: Promise<{ [key: string]: Aoml }> = request(defaultUrl).then((data) => aomlParser(data)); const createIdentifiers = async () => { const identifiers = new Map() for (const [ruleName, value] of Object.entries(await aomlParsed)) { if (value.start && value.end) { identifiers.set(value.start, value) identifiers.set(value.end, value) } } return identifiers } const createStartIdentifiers = async () => { const startingIdentifiers = new Set() for (const [ruleName, value] of Object.entries(await aomlParsed)) { if (value?.start && value?.end) { startingIdentifiers.add(value.start) } } return startingIdentifiers } const applyMarkdown = async (text: string, defaultColor: string) => { const identifiers = await createIdentifiers() const startIdentifiers = await createStartIdentifiers() const closingStack = [] const colorStack = [] // each value in output will be an html element const output: HTMLSpanElement[] = [] for (const letter of text) { const currentSelector = document.createElement('span') const currentIdentifier = identifiers.get(letter) const currentClosingLetter = closingStack[closingStack.length - 1] const keepChar = Number(currentIdentifier?.remove) === 0 if (currentClosingLetter === letter) { const r = colorStack[colorStack.length - 1][0] const g = colorStack[colorStack.length - 1][1] const b = colorStack[colorStack.length - 1][2] const currentColor = `color: rgb(${r},${g},${b});` currentSelector.setAttribute('style', currentColor) closingStack.pop() colorStack.pop() if (keepChar) { currentSelector.innerHTML = letter } } else if (startIdentifiers.has(letter)) { const color = identifiers.get(letter).color.split(',') const r = color[0] const g = color[1] const b = color[2] colorStack.push([r, g, b]) closingStack.push(currentIdentifier.end) const currentColor = `color: rgb(${r},${g},${b});` currentSelector.setAttribute('style', currentColor) if (keepChar) { currentSelector.innerHTML = letter } } else { currentSelector.innerHTML = letter if (colorStack.length === 0) { currentSelector.className = `text_${defaultColor}` } else { const r = colorStack[colorStack.length - 1][0] const g = colorStack[colorStack.length - 1][1] const b = colorStack[colorStack.length - 1][2] const currentColor = `color: rgb(${r},${g},${b});` currentSelector.setAttribute('style', currentColor) } } output.push(currentSelector) } return output } return { applyMarkdown } } export default mlConfig