| 124 | * @returns The text with the interpolated variables |
| 125 | */ |
| 126 | export function replaceVariables (engine: VisualNovelEngine, statement: string): string { |
| 127 | let newStatement = translate (engine, statement); |
| 128 | |
| 129 | const matches = newStatement.match (/{{\S+?}}/g); |
| 130 | |
| 131 | if (matches === null) { |
| 132 | return newStatement; |
| 133 | } |
| 134 | |
| 135 | for (const match of matches) { |
| 136 | const path = match.replace ('{{', '').replace ('}}', '').split ('.'); |
| 137 | |
| 138 | let data: unknown = engine.storage (); |
| 139 | |
| 140 | for (let j = 0; j < path.length; j++) { |
| 141 | const name = path[j]; |
| 142 | if (typeof data === 'object' && data !== null && name in data) { |
| 143 | data = (data as Record<string, unknown>)[name]; |
| 144 | } else { |
| 145 | FancyError.show ('engine:storage:variable_not_found', { |
| 146 | variable: match, |
| 147 | statement: newStatement, |
| 148 | partNotFound: name, |
| 149 | availableVariables: typeof data === 'object' && data !== null ? Object.keys (data) : [] |
| 150 | }); |
| 151 | |
| 152 | // TODO: Is an empty string correct here? |
| 153 | return ''; |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | newStatement = newStatement.replace (match, String(data)); |
| 158 | } |
| 159 | |
| 160 | return replaceVariables (engine, newStatement); |
| 161 | } |
| 162 | |
| 163 | export function translations (engine: VisualNovelEngine, object: string | Record<string, Record<string, string>> | null = null): Record<string, string> | Record<string, Record<string, string>> | undefined { |
| 164 | if (object === null) { |