5 * Format a language file in the same way as the EN equivalent.
6 * Matches the line numbers of translated content.
9 $args = array_slice($argv, 1);
11 if (count($args) < 2) {
12 errorOut("Please provide a language code as the first argument and a translation file name as the second (./format.php fr activities)");
15 $lang = formatLang($args[0]);
16 $fileName = explode('.', $args[1])[0];
18 $enLines = loadLangFileLines('en', $fileName);
19 $langContent = loadLang($lang, $fileName);
20 $enContent = loadLang('en', $fileName);
22 // Calculate the longest top-level key length
23 $longestKeyLength = longestKey($enContent);
25 // Start formatted content
30 foreach($enLines as $index => $line) {
31 $trimLine = trim($line);
32 if ($mode === 'header') {
33 $formatted[$index] = $line;
34 if (str_replace(' ', '', $trimLine) === 'return[') $mode = 'body';
37 if ($mode === 'body') {
41 if (strpos($trimLine, '//') === 0) {
42 $formatted[$index] = "\t" . $trimLine;
47 $arrayStartMatch = preg_match('/^\'(.*)\'\s+?=>\s+?\[(\],)?\s*?$/', $trimLine, $matches);
48 $arrayEndMatch = preg_match('/]\s*,\s*$/', $trimLine);
49 $indent = count($arrayKeys) + 1;
50 if ($arrayStartMatch === 1) {
51 $arrayKeys[] = $matches[1];
52 $formatted[$index] = str_repeat(" ", $indent * 4) . str_pad("'{$matches[1]}'", $longestKeyLength) . "=> [";
53 if ($arrayEndMatch !== 1) continue;
55 if ($arrayEndMatch === 1) {
56 unsetArrayByKeys($langContent, $arrayKeys);
57 $key = array_pop($arrayKeys);
58 if (isset($formatted[$index])) {
59 $formatted[$index] .= '],';
61 $formatted[$index] = str_repeat(" ", ($indent-1) * 4) . "],";
67 $translationMatch = preg_match('/^\'(.*)\'\s+?=>\s+?\'(.*)?\'.+?$/', $trimLine, $matches);
68 if ($translationMatch === 1) {
70 $keys = array_merge($arrayKeys, [$key]);
71 $langVal = getTranslationByKeys($langContent, $keys);
72 if (empty($langVal)) continue;
74 $keyPad = $longestKeyLength;
75 if (count($arrayKeys) === 0) {
76 unset($langContent[$key]);
78 $keyPad = longestKey(getTranslationByKeys($enContent, $arrayKeys));
81 $formatted[$index] = formatTranslationLine($key, $langVal, $indent, $keyPad);
89 $arraySize = max(array_keys($formatted));
90 $formatted = array_replace(array_fill(0, $arraySize, ''), $formatted);
92 // Add remaining translations
93 $langContent = array_filter($langContent, function($item) {
94 return !is_null($item) && !empty($item);
96 if (count($langContent) > 0) {
98 $formatted[] = "\t// Unmatched";
100 foreach ($langContent as $key => $value) {
101 if (is_array($value)) {
102 $formatted[] = formatTranslationArray($key, $value);
104 $formatted[] = formatTranslationLine($key, $value);
110 $formatted = implode("\n", $formatted);
112 writeLangFile($lang, $fileName, $formatted);
114 function formatTranslationLine(string $key, string $value, int $indent = 1, int $keyPad = 1) {
115 $escapedValue = str_replace("'", "\\'", $value);
116 return str_repeat(" ", $indent * 4) . str_pad("'{$key}'", $keyPad, ' ') ."=> '{$escapedValue}',";
119 function longestKey(array $array) {
121 foreach ($array as $key => $value) {
122 $keyLen = strlen($key);
123 $top = max($top, $keyLen);
128 function formatTranslationArray(string $key, array $array) {
129 $arrayPHP = var_export($array, true);
130 return " '{$key}' => {$arrayPHP},";
133 function getTranslationByKeys(array $translations, array $keys) {
134 $val = $translations;
135 foreach ($keys as $key) {
136 $val = $val[$key] ?? '';
137 if ($val === '') return '';
142 function unsetArrayByKeys(array &$input, array $keys) {
144 $lastIndex = count($keys) - 1;
145 foreach ($keys as $index => &$key) {
146 if ($index === $lastIndex && is_array($val)) {
149 if (!is_array($val)) return;
150 $val = &$val[$key] ?? [];
154 function writeLangFile(string $lang, string $fileName, string $content) {
155 $path = __DIR__ . "/{$lang}/{$fileName}.php";
156 if (!file_exists($path)) {
157 errorOut("Expected translation file '{$path}' does not exist");
159 file_put_contents($path, $content);
162 function loadLangFileLines(string $lang, string $fileName) {
163 $path = __DIR__ . "/{$lang}/{$fileName}.php";
164 if (!file_exists($path)) {
165 errorOut("Expected translation file '{$path}' does not exist");
167 $lines = explode("\n", file_get_contents($path));
168 return array_map(function($line) {
169 return trim($line, "\r");
173 function loadLang(string $lang, string $fileName) {
174 $path = __DIR__ . "/{$lang}/{$fileName}.php";
175 if (!file_exists($path)) {
176 errorOut("Expected translation file '{$path}' does not exist");
179 $fileData = include($path);
183 function formatLang($lang) {
184 $langParts = explode('_', strtoupper($lang));
185 $langParts[0] = strtolower($langParts[0]);
186 return implode('_', $langParts);
189 function dd($content) {
194 function info($text) {
195 echo "\e[34m" . $text . "\e[0m\n";
198 function errorOut($text) {
199 echo "\e[31m" . $text . "\e[0m\n";