aboutsummaryrefslogtreecommitdiff
path: root/webAO/utils/aoml.ts
blob: 898d8fbb5ee7da8edb69f926839234860b276fa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import request from "../services/request"

interface Aoml {
    name: string;
    start: string;
    end: string;
    remove: number;
    talking: number;
    color: string;
}
const aomlParser = (text: string) => {
    let 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) => {
    const defaultUrl = `${AO_HOST}themes/default/chat_config.ini`
    let aomlParsed: {[key: string]: Aoml} = {}

    request(defaultUrl).then((data) => {
            aomlParsed = aomlParser(data)
        }
    );

    const createIdentifiers = () => {
        const identifiers = new Map<string, Aoml>()
        for (const [ruleName, value] of Object.entries(aomlParsed)) {
            if (identifiers.has(value.start)) {
                throw new Error()
            } 
            else if (value.start && value.end) {
                identifiers.set(value.start, value)
                identifiers.set(value.end, value)
            }

            
        }
        return identifiers
    }
    const createStartIdentifiers = () => {
        const startingIdentifiers = new Set<string>()
        for (const [ruleName, value] of Object.entries(aomlParsed)) {
            if (value?.start && value?.end) {
                startingIdentifiers.add(value.start)
            }   
        }
        return startingIdentifiers
    }

    const applyMarkdown = (text: string, defaultColor: string) => {
        const identifiers = createIdentifiers()
        const startIdentifiers = createStartIdentifiers()
        const closingStack = []
        const colorStack = []
        // each value in output will be an html element
        let output: HTMLSpanElement[] = []
        for (const letter of text) {
            let currentSelector = document.createElement('span')
            let currentIdentifier = identifiers.get(letter)
            const currentClosingLetter = closingStack[closingStack.length-1]
            const keepChar = Number(currentIdentifier?.remove) === 0
            console.log(startIdentifiers)
            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 if (currentClosingLetter === letter) {
                if (colorStack.length === 0) {
                    currentSelector.className = `test_${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)
                }
                closingStack.pop()
                colorStack.pop()
                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