Created sketchy translation formatter script
Compares a translation file to a EN version to place translations on matching line numbers and matches up comments.
This commit is contained in:
parent
f65ff3a9a8
commit
86a00a59d4
|
@ -1,12 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Activity text strings.
|
||||||
|
* Is used for all the text within activity logs & notifications.
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/**
|
|
||||||
* Activity text strings.
|
|
||||||
* Is used for all the text within activity logs & notifications.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
'page_create' => 'created page',
|
'page_create' => 'created page',
|
||||||
'page_create_notification' => 'Page Successfully Created',
|
'page_create_notification' => 'Page Successfully Created',
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Validation Lines
|
||||||
|
* The following language lines contain the default error messages used by
|
||||||
|
* the validator class. Some of these rules have multiple versions such
|
||||||
|
* as the size rules. Feel free to tweak each of these messages here.
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
// Standard laravel validation lines
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Validation Language Lines
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following language lines contain the default error messages used by
|
|
||||||
| the validator class. Some of these rules have multiple versions such
|
|
||||||
| as the size rules. Feel free to tweak each of these messages here.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'accepted' => 'The :attribute must be accepted.',
|
'accepted' => 'The :attribute must be accepted.',
|
||||||
'active_url' => 'The :attribute is not a valid URL.',
|
'active_url' => 'The :attribute is not a valid URL.',
|
||||||
'after' => 'The :attribute must be a date after :date.',
|
'after' => 'The :attribute must be a date after :date.',
|
||||||
|
@ -75,34 +70,13 @@ return [
|
||||||
'unique' => 'The :attribute has already been taken.',
|
'unique' => 'The :attribute has already been taken.',
|
||||||
'url' => 'The :attribute format is invalid.',
|
'url' => 'The :attribute format is invalid.',
|
||||||
|
|
||||||
/*
|
// Custom validation lines
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Custom Validation Language Lines
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here you may specify custom validation messages for attributes using the
|
|
||||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
|
||||||
| specify a specific custom language line for a given attribute rule.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'custom' => [
|
'custom' => [
|
||||||
'password-confirm' => [
|
'password-confirm' => [
|
||||||
'required_with' => 'Password confirmation required',
|
'required_with' => 'Password confirmation required',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
// Custom validation attributes
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Custom Validation Attributes
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following language lines are used to swap attribute place-holders
|
|
||||||
| with something more reader friendly such as E-Mail Address instead
|
|
||||||
| of "email". This simply helps us make messages a little cleaner.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'attributes' => [],
|
'attributes' => [],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a language file in the same way as the EN equivalent.
|
||||||
|
* Matches the line numbers of translated content.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$args = array_slice($argv, 1);
|
||||||
|
|
||||||
|
if (count($args) < 2) {
|
||||||
|
errorOut("Please provide a language code as the first argument and a translation file name as the second (./format.php fr activities)");
|
||||||
|
}
|
||||||
|
|
||||||
|
$lang = formatLang($args[0]);
|
||||||
|
$fileName = explode('.', $args[1])[0];
|
||||||
|
|
||||||
|
$enLines = loadLangFileLines('en', $fileName);
|
||||||
|
$langContent = loadLang($lang, $fileName);
|
||||||
|
$enContent = loadLang('en', $fileName);
|
||||||
|
|
||||||
|
// Calculate the longest top-level key length
|
||||||
|
$longestKeyLength = longestKey($enContent);
|
||||||
|
|
||||||
|
// Start formatted content
|
||||||
|
$formatted = [];
|
||||||
|
$mode = 'header';
|
||||||
|
$arrayKeys = [];
|
||||||
|
|
||||||
|
foreach($enLines as $index => $line) {
|
||||||
|
$trimLine = trim($line);
|
||||||
|
if ($mode === 'header') {
|
||||||
|
$formatted[$index] = $line;
|
||||||
|
if (str_replace(' ', '', $trimLine) === 'return[') $mode = 'body';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mode === 'body') {
|
||||||
|
$matches = [];
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
if (strpos($trimLine, '//') === 0) {
|
||||||
|
$formatted[$index] = "\t" . $trimLine;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrays
|
||||||
|
$arrayStartMatch = preg_match('/^\'(.*)\'\s+?=>\s+?\[(\],)?\s*?$/', $trimLine, $matches);
|
||||||
|
$arrayEndMatch = preg_match('/]\s*,\s*$/', $trimLine);
|
||||||
|
$indent = count($arrayKeys) + 1;
|
||||||
|
if ($arrayStartMatch === 1) {
|
||||||
|
$arrayKeys[] = $matches[1];
|
||||||
|
$formatted[$index] = str_repeat(" ", $indent * 4) . str_pad("'{$matches[1]}'", $longestKeyLength) . "=> [";
|
||||||
|
if ($arrayEndMatch !== 1) continue;
|
||||||
|
}
|
||||||
|
if ($arrayEndMatch === 1) {
|
||||||
|
unsetArrayByKeys($langContent, $arrayKeys);
|
||||||
|
$key = array_pop($arrayKeys);
|
||||||
|
if (isset($formatted[$index])) {
|
||||||
|
$formatted[$index] .= '],';
|
||||||
|
} else {
|
||||||
|
$formatted[$index] = str_repeat(" ", ($indent-1) * 4) . "],";
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translation
|
||||||
|
$translationMatch = preg_match('/^\'(.*)\'\s+?=>\s+?\'(.*)?\'.+?$/', $trimLine, $matches);
|
||||||
|
if ($translationMatch === 1) {
|
||||||
|
$key = $matches[1];
|
||||||
|
$keys = array_merge($arrayKeys, [$key]);
|
||||||
|
$langVal = getTranslationByKeys($langContent, $keys);
|
||||||
|
if (empty($langVal)) continue;
|
||||||
|
|
||||||
|
$keyPad = $longestKeyLength;
|
||||||
|
if (count($arrayKeys) === 0) {
|
||||||
|
unset($langContent[$key]);
|
||||||
|
} else {
|
||||||
|
$keyPad = longestKey(getTranslationByKeys($enContent, $arrayKeys));
|
||||||
|
}
|
||||||
|
|
||||||
|
$formatted[$index] = formatTranslationLine($key, $langVal, $indent, $keyPad);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill missing lines
|
||||||
|
$arraySize = max(array_keys($formatted));
|
||||||
|
$formatted = array_replace(array_fill(0, $arraySize, ''), $formatted);
|
||||||
|
|
||||||
|
// Add remaining translations
|
||||||
|
$langContent = array_filter($langContent, function($item) {
|
||||||
|
return !is_null($item) && !empty($item);
|
||||||
|
});
|
||||||
|
if (count($langContent) > 0) {
|
||||||
|
$formatted[] = '';
|
||||||
|
$formatted[] = "\t// Unmatched";
|
||||||
|
}
|
||||||
|
foreach ($langContent as $key => $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
$formatted[] = formatTranslationArray($key, $value);
|
||||||
|
} else {
|
||||||
|
$formatted[] = formatTranslationLine($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add end line
|
||||||
|
$formatted[] = '];';
|
||||||
|
$formatted = implode("\n", $formatted);
|
||||||
|
|
||||||
|
writeLangFile($lang, $fileName, $formatted);
|
||||||
|
|
||||||
|
function formatTranslationLine(string $key, string $value, int $indent = 1, int $keyPad = 1) {
|
||||||
|
$escapedValue = str_replace("'", "\\'", $value);
|
||||||
|
return str_repeat(" ", $indent * 4) . str_pad("'{$key}'", $keyPad, ' ') ."=> '{$escapedValue}',";
|
||||||
|
}
|
||||||
|
|
||||||
|
function longestKey(array $array) {
|
||||||
|
$top = 0;
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
$keyLen = strlen($key);
|
||||||
|
$top = max($top, $keyLen);
|
||||||
|
}
|
||||||
|
return $top + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTranslationArray(string $key, array $array) {
|
||||||
|
$arrayPHP = var_export($array, true);
|
||||||
|
return " '{$key}' => {$arrayPHP},";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTranslationByKeys(array $translations, array $keys) {
|
||||||
|
$val = $translations;
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$val = $val[$key] ?? '';
|
||||||
|
if ($val === '') return '';
|
||||||
|
}
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unsetArrayByKeys(array &$input, array $keys) {
|
||||||
|
$val = &$input;
|
||||||
|
$lastIndex = count($keys) - 1;
|
||||||
|
foreach ($keys as $index => &$key) {
|
||||||
|
if ($index === $lastIndex && is_array($val)) {
|
||||||
|
unset($val[$key]);
|
||||||
|
}
|
||||||
|
if (!is_array($val)) return;
|
||||||
|
$val = &$val[$key] ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeLangFile(string $lang, string $fileName, string $content) {
|
||||||
|
$path = __DIR__ . "/{$lang}/{$fileName}.php";
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
errorOut("Expected translation file '{$path}' does not exist");
|
||||||
|
}
|
||||||
|
file_put_contents($path, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadLangFileLines(string $lang, string $fileName) {
|
||||||
|
$path = __DIR__ . "/{$lang}/{$fileName}.php";
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
errorOut("Expected translation file '{$path}' does not exist");
|
||||||
|
}
|
||||||
|
$lines = explode("\n", file_get_contents($path));
|
||||||
|
return array_map(function($line) {
|
||||||
|
return trim($line, "\r");
|
||||||
|
}, $lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadLang(string $lang, string $fileName) {
|
||||||
|
$path = __DIR__ . "/{$lang}/{$fileName}.php";
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
errorOut("Expected translation file '{$path}' does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileData = include($path);
|
||||||
|
return $fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatLang($lang) {
|
||||||
|
$langParts = explode('_', strtoupper($lang));
|
||||||
|
$langParts[0] = strtolower($langParts[0]);
|
||||||
|
return implode('_', $langParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dd($content) {
|
||||||
|
print_r($content);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function info($text) {
|
||||||
|
echo "\e[34m" . $text . "\e[0m\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorOut($text) {
|
||||||
|
echo "\e[31m" . $text . "\e[0m\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
Loading…
Reference in New Issue