import * as ValueParser from '../value-parser'
import { addWhitespaceAroundMathOperators } from './math-operators'
export function decodeArbitraryValue(input: string): string {
if (input.indexOf('(') === -1) {
return convertUnderscoresToWhitespace(input)
}
let ast = ValueParser.parse(input)
recursivelyDecodeArbitraryValues(ast)
input = ValueParser.toCss(ast)
input = addWhitespaceAroundMathOperators(input)
return input
}
function convertUnderscoresToWhitespace(input: string, skipUnderscoreToSpace = false) {
let output = ''
for (let i = 0; i < input.length; i++) {
let char = input[i]
if (char === '\\' && input[i + 1] === '_') {
output += '_'
i += 1
}
else if (char === '_' && !skipUnderscoreToSpace) {
output += ' '
}
else {
output += char
}
}
return output
}
function recursivelyDecodeArbitraryValues(ast: ValueParser.ValueAstNode[]) {
for (let node of ast) {
switch (node.kind) {
case 'function': {
if (node.value === 'url' || node.value.endsWith('_url')) {
node.value = convertUnderscoresToWhitespace(node.value)
break
}
if (
node.value === 'var' ||
node.value.endsWith('_var') ||
node.value === 'theme' ||
node.value.endsWith('_theme')
) {
node.value = convertUnderscoresToWhitespace(node.value)
for (let i = 0; i < node.nodes.length; i++) {
if (i == 0 && node.nodes[i].kind === 'word') {
node.nodes[i].value = convertUnderscoresToWhitespace(node.nodes[i].value, true)
continue
}
recursivelyDecodeArbitraryValues([node.nodes[i]])
}
break
}
node.value = convertUnderscoresToWhitespace(node.value)
recursivelyDecodeArbitraryValues(node.nodes)
break
}
case 'separator':
case 'word': {
node.value = convertUnderscoresToWhitespace(node.value)
break
}
default:
never(node)
}
}
}
function never(value: never): never {
throw new Error(`Unexpected value: ${value}`)
}