const { colors } = require('../formatting.json')
const { normalize } = require('../utility')
const colormap = Object.fromEntries(colors.map(color => [color.name, color.rgb]))
const colorcodemap = Object.fromEntries(colors.map(color => [color.code, color.rgb]))
const reservedCharacters = {
'"': '"',
"'": ''',
'&': '&',
'<': '<',
'>': '>'
}
function htmlStringify (text, { lang = {} } = {}) {
text = normalize(text)
let string = ''
if (text.text != null) string += preprocessText(text.text)
else if (text.translate != null) {
let format
if (Object.hasOwn(lang, text.translate)) format = lang[text.translate]
else if (text.fallback != null) format = text.fallback
else format = text.translate
const _with = text.with || []
let i = 0
string += preprocessText(format).replace(/%(?:(\d+)\$)?(s|%)/g, (g0, g1) => {
if (g0 === '%%') return '%'
const idx = g1 ? parseInt(g1) : i++
if (_with[idx]) {
return htmlStringify(_with[idx], { lang })
}
return ''
})
}
else if (text.selector != null) string += preprocessText(text.selector)
else if (text.keybind) {
// TODO
}
if (text.extra) {
for (const extra of text.extra) {
string += htmlStringify(extra, { lang })
}
}
if (text.color) {
const rgb = text.color[0] === '#' ? parseInt(text.color.substring(1), 16) : colormap[text.color]
if (rgb) string = `${string}`
}
// formatting
if (text.bold) string = `${string}`
if (text.italic) string = `${string}`
if (text.underlined) string = `${string}`
if (text.strikethrough) string = `${string}`
if (text.obfuscated) string = ``
return string
}
function preprocessText (input) {
let string = ''
let closing = ''
for (let i = 0; i < input.length; i++) {
const c = input[i]
// Emulate Minecraft's section sign escape sequences
if (c === '§') {
if ((i + 1) >= input.length) break // For trailing section signs, append nothing
const code = input.substring(i, i + 2)
i++
const hex = colorcodemap[code]
if (hex) {
string += closing
string += ``
closing = ''
continue
}
if (code === '§r') {
string += closing
closing = ''
continue
}
if (code === '§l') { string += ''; closing += '' }
else if (code === '§o') { string += ''; closing += '' }
else if (code === '§n') { string += ''; closing += '' }
else if (code === '§m') { string += ''; closing += '' }
else if (code === '§k') { string += '' }
continue // Do not append the escape sequence itself to the string
}
else if (reservedCharacters[c]) string += reservedCharacters[c]
else if (c === '\n') string += '
'
else string += c
}
string += closing
return string
}
module.exports = htmlStringify