#!/bin/sh
# A locale is brought level with en_US in two halves, its short strings
# and its public and help wiki pages, and both halves drift unseen until
# someone reads a screen in that language. This measures the drift so
# the gaps are named before any of them is translated, and so a finished
# translation can be shown to have closed them.
#
# sh devlog/devscripts/check_locale.sh <locale-tag>
#
# For src/locale/<tag>/configure.ini it reports keys missing against
# en_US, keys left empty, and values whose markers differ in count from
# the English: %s placeholders, %% signs, {1}-style slots, escaped
# quotes, HTML entities, wiki {{ }} braces and HTML tags. A value with
# a different count breaks or garbles the line it fills. It also reports
# emoji picker names given the same text twice, since the picker uses
# those names as array keys and a repeated name hides an emoji.
#
# For src/configs/PublicHelpPages.php it lists each English public and
# help page that has no page in the locale, either under the same name
# or as the target a same-named alias page points at.
#
# Each problem is printed on its own line, and the last line gives how
# many of each kind there were, so the numbers say what is left to do.
# It exits non-zero when anything is reported.
if [ -z "$1" ]; then
echo "check_locale: name a locale tag, such as de"
exit 2
fi
tag="$1"
dir=$(echo "$tag" | tr "-" "_")
if [ ! -f "src/locale/$dir/configure.ini" ]; then
echo "check_locale: no src/locale/$dir/configure.ini here"
exit 2
fi
php -d error_reporting=-1 -- "$tag" <<'EOP'
<?php
namespace seekquarry\yioop\configs;
$tag = $argv[1];
$counts = ["keys missing" => 0, "keys empty" => 0,
"values whose markers differ from English" => 0,
"emoji names given twice" => 0, "public pages with no page" => 0,
"help pages with no page" => 0, "aliases pointing at no page" => 0];
$english = parse_ini_file("src/locale/en_US/configure.ini", true,
INI_SCANNER_RAW)["strings"];
$ini = "src/locale/" . str_replace("-", "_", $tag) . "/configure.ini";
$parsed = parse_ini_file($ini, true,
INI_SCANNER_RAW);
if ($parsed === false) {
echo "check_locale: $ini does not parse, so " .
"every key counts as missing\n";
}
$local = $parsed["strings"] ?? [];
$markers = ['%s' => '/%s/', '%%' => '/%%/', 'slot' => '/\{[0-9]\}/',
'quote' => '/\\\\"/', 'entity' => '/&[a-z]+;/', 'braces' => '/\{\{|\}\}/',
'tag' => '/<[^>]+>/'];
$emoji_names = [];
foreach ($english as $key => $english_value) {
if (!array_key_exists($key, $local)) {
echo "missing: $key\n";
$counts["keys missing"]++;
continue;
}
$value = $local[$key];
if ($value === "" && $english_value !== "") {
echo "empty: $key\n";
$counts["keys empty"]++;
continue;
}
foreach ($markers as $marker => $pattern) {
$english_count = preg_match_all($pattern, $english_value);
$local_count = preg_match_all($pattern, $value);
if ($english_count != $local_count) {
echo "markers $marker ($english_count vs $local_count): $key\n";
$counts["values whose markers differ from English"]++;
}
}
if (strncmp($key, "emojipicker_helper_", 19) == 0) {
$emoji_names[$value][] = $key;
}
}
foreach ($emoji_names as $value => $keys) {
if (count($keys) > 1) {
echo "emoji name repeated \"$value\": " . implode(" ", $keys) .
"\n";
$counts["emoji names given twice"]++;
}
}
require "src/configs/PublicHelpPages.php";
/* A locale folder is named with an underscore, as el_GR, while the wiki
pages are filed under the tag with a hyphen, as el-GR. */
$page_tag = str_replace("_", "-", $tag);
foreach (["public" => $public_pages, "help" => $help_pages] as
$kind => $pages) {
$local_pages = $pages[$page_tag] ?? [];
foreach (array_keys($pages["en-US"] ?? []) as $name) {
if (!isset($local_pages[$name])) {
echo "no $kind page: " . urldecode($name) . "\n";
$counts["$kind pages with no page"]++;
continue;
}
if (preg_match('/^page_alias=(\S+)$/m', $local_pages[$name],
$match) && !isset($local_pages[trim($match[1])])) {
echo "alias to nothing, $kind page: " . urldecode($name) . "\n";
$counts["aliases pointing at no page"]++;
}
}
}
echo "check_locale: $tag has " . count($local) . " of " . count($english) .
" English keys.\n";
foreach ($counts as $kind => $count) {
echo " $count $kind\n";
}
exit(array_sum($counts) > 0 ? 1 : 0);
EOP