(input: string)
| 71 | const TAB = 0x09 |
| 72 | |
| 73 | export function parse(input: string) { |
| 74 | input = input.replaceAll('\r\n', '\n') |
| 75 | |
| 76 | let ast: ValueAstNode[] = [] |
| 77 | |
| 78 | let stack: (ValueFunctionNode | null)[] = [] |
| 79 | |
| 80 | let parent = null as ValueFunctionNode | null |
| 81 | |
| 82 | let buffer = '' |
| 83 | |
| 84 | let peekChar |
| 85 | |
| 86 | for (let i = 0; i < input.length; i++) { |
| 87 | let currentChar = input.charCodeAt(i) |
| 88 | |
| 89 | switch (currentChar) { |
| 90 | // Current character is a `\` therefore the next character is escaped, |
| 91 | // consume it together with the next character and continue. |
| 92 | case BACKSLASH: { |
| 93 | buffer += input[i] + input[i + 1] |
| 94 | i++ |
| 95 | break |
| 96 | } |
| 97 | |
| 98 | // Typically for math operators, they have to have spaces around them. But |
| 99 | // there are situations in `theme(colors.red.500/10)` where we use `/` |
| 100 | // without spaces. Let's make sure this is a separate word as well. |
| 101 | case SLASH: { |
| 102 | // 1. Handle everything before the separator as a word |
| 103 | // Handle everything before the closing paren as a word |
| 104 | if (buffer.length > 0) { |
| 105 | let node = word(buffer) |
| 106 | if (parent) { |
| 107 | parent.nodes.push(node) |
| 108 | } else { |
| 109 | ast.push(node) |
| 110 | } |
| 111 | buffer = '' |
| 112 | } |
| 113 | |
| 114 | // 2. Track the `/` as a word on its own |
| 115 | let node = word(input[i]) |
| 116 | if (parent) { |
| 117 | parent.nodes.push(node) |
| 118 | } else { |
| 119 | ast.push(node) |
| 120 | } |
| 121 | |
| 122 | break |
| 123 | } |
| 124 | |
| 125 | // Space and commas are bundled into separators |
| 126 | // |
| 127 | // E.g.: |
| 128 | // |
| 129 | // ```css |
| 130 | // foo(bar, baz) |
no test coverage detected