teams:i18n:translation-check
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
teams:i18n:translation-check [2015-07-27 08:13] – Automatic update: 4 problems in 3 languages. schplrtz.au | teams:i18n:translation-check [2023-11-05 09:16] (current) – more than 2.5 year with nothing to report. DW translation has checks too. This page and the checks are no more needed. Stopping my daily checks. schplurtz | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== DokuWiki PHP translation checks ===== | ||
- | |||
- | This page shows the result of checks on translation strings. The results | ||
- | are presented language by language. All languages are tested but only those with troubles are reported. | ||
- | |||
- | Every day, the test is run. This page is updated only when there is something new to report. | ||
- | |||
- | Last report date : 2015-07-27T04: | ||
- | |||
- | |||
- | **Explanation for translators: | ||
- | |||
- | DokuWiki sometimes uses a function called [[phpfn> | ||
- | |||
- | The most common format string is a simple '' | ||
- | |||
- | When translating a string it is important to **leave the format strings intact**. They have to appear exactly as in the original. If a string contains several format strings, **order does matter**. Make sure the logical order of words or numbers to be inserted are the same as in the original. | ||
- | |||
- | |||
- | |||
- | ===== ka ===== | ||
- | |||
- | ! ./ | ||
- | ! ./ | ||
- | < | ||
- | - | ||
- | + $lang[subscr_style_list]=list of changed pages since last email (every %.2f days) | ||
- | - | ||
- | </ | ||
- | |||
- | ===== zh ===== | ||
- | |||
- | ! ./ | ||
- | ! ./ | ||
- | < | ||
- | - | ||
- | </ | ||
- | |||
- | ===== zh-tw ===== | ||
- | |||
- | ! ./ | ||
- | ! ./ | ||
- | < | ||
- | - | ||
- | </ | ||
- | |||
- | ===== summary ===== | ||
- | |||
- | There were 4 problems in 3 languages. | ||
- | |||
- | ------------------ | ||
- | Report generated in 12.992762088776 seconds. | ||
- | |||
- | ===== technical details ===== | ||
- | |||
- | * percent test 1\\ This test checks that there are as many '' | ||
- | * non existing arg test\\ Translators may change the order of argument using '' | ||
- | * percent test 2\\ checks that each %thing in translation has a corresponding %samething in english, in the correct order and that each %thing in english has a corresponding %samething in translation. | ||
- | * supernumerary translations\\ This test detects 3 possible errors : | ||
- | - Old translations that remain in locale files but that are no more needed. Those unneeded strings are just useless, not harmful at all. They should be removed anyway. | ||
- | - Typo in the translation key name. For example, if a translator types '' | ||
- | - Misplaced translation key. For example '' | ||
- | |||
- | ===== script code ===== | ||
- | |||
- | This page was produced with the following php code. This page is automagically updated by an ugly daily cron job of mine. Any change in the script below will stop the automatic updates. | ||
- | |||
- | <code php checklanguage.php> | ||
- | #! / | ||
- | <?php | ||
- | /* | ||
- | * checklanguage.php simple checks on english dokuwiki texts and their translations | ||
- | * Copyright (C) 2011, 2013 Schplurtz le Déboulonné < | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | */ | ||
- | /* | ||
- | This script runs some automated tests on dokuwiki translation strings. | ||
- | |||
- | It checks printf format strings. Current code is a mess but detects | ||
- | many problems. | ||
- | |||
- | / | ||
- | */ | ||
- | # ADJUST TO THE BASE OF YOUR DW. no other thing need be changed... | ||
- | $base_english=dirname(__FILE__); | ||
- | $base_tr=$base_english; | ||
- | |||
- | $vu=array( ' | ||
- | |||
- | $debug_log = false; // if true, get log and function call in /tmp/log. function l() | ||
- | $timestart=0; | ||
- | if( function_exists( ' | ||
- | |||
- | # get all langs | ||
- | exec( 'cd ' | ||
- | # get all english PHP language files | ||
- | exec( 'cd ' | ||
- | pageheader(); | ||
- | $npbfound=0; | ||
- | foreach( $langdirs as $language ) { | ||
- | l( " | ||
- | foreach( $english_files as $en_fi ) { | ||
- | l( " | ||
- | $fen = $base_english . '/' | ||
- | $tr_fi = str_replace( ' | ||
- | $ftr = $base_tr . '/' | ||
- | if( !file_exists( $ftr ) ) | ||
- | /* nothing to check if no translation exists */ | ||
- | continue; | ||
- | l( "found file $ftr" ); | ||
- | $lang=array(); | ||
- | include( $fen ); | ||
- | l( " | ||
- | $org=$lang; | ||
- | include( $ftr ); | ||
- | l( " | ||
- | $npbfound += chklang( $org, $lang, $en_fi, $tr_fi ); | ||
- | } | ||
- | } | ||
- | summary( $npbfound ); | ||
- | pagefooter(); | ||
- | |||
- | function chklang( &$en, &$tr, $prenfi, $prtrfi, $strkeys='' | ||
- | l( " | ||
- | $ntrouble=0; | ||
- | global $language; | ||
- | $vukeys=array(); | ||
- | foreach( $en as $k =>$v ) { | ||
- | if( is_array( $v ) ) { | ||
- | $ntrouble += chklang( $v, $tr[$k], $prenfi, $prtrfi, $strkeys.' | ||
- | continue; | ||
- | } | ||
- | |||
- | // FIXME: preg_match english once and cache result in global array ? | ||
- | // Can't use substr_count( $v, % ). It could match %thing that are not format. | ||
- | preg_match_all( '/ | ||
- | preg_match_all( '/ | ||
- | /* | ||
- | * we have the full %thing in $nen[0] and $ntr[0], | ||
- | | ||
- | | ||
- | * $ntr[0] is necessarily an array : if no % in translation, | ||
- | * detects the situation and we don't get here... | ||
- | * example | ||
- | * Given this string : | ||
- | | ||
- | * we have this in $ntr array. | ||
- | * Array | ||
- | * ( | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | * ) | ||
- | */ | ||
- | |||
- | // test number 1 : same count of % sign in both strings | ||
- | $pen = count( $nen[0] ); | ||
- | $ptr = count( $ntr[0] ); | ||
- | if( $pen != $ptr ) { | ||
- | prestart($language, | ||
- | echo | ||
- | ($pen - $ptr) < 0 ? '- ' : '+ ', | ||
- | ' | ||
- | ($pen - $ptr) > 0 ? '- ' : '+ ', | ||
- | ' | ||
- | $ntrouble++; | ||
- | continue; | ||
- | } | ||
- | // no need to continue if no % in English string. | ||
- | if( !$pen ) | ||
- | continue; | ||
- | |||
- | // Since order can be set by translator, set order for each format. we'll need that | ||
- | order_fmt( $nen ); | ||
- | order_fmt( $ntr ); | ||
- | $expectargen=max( $nen[1] ); | ||
- | $expectargtr=max( $ntr[1] ); | ||
- | |||
- | // and test 2 : check translator don't want to print a non existing arg. | ||
- | if( $expectargtr > $expectargen ) { | ||
- | prestart($language, | ||
- | headkeypb( $vukeys, $strkeys, $k, $v, $tr[$k] ); | ||
- | echo | ||
- | ' | ||
- | ' | ||
- | printf( "%4d ' | ||
- | foreach( $ntr[1] as $k2 => $v2 ) { | ||
- | if( $v2 > $expectargen ) { | ||
- | echo ' | ||
- | ' | ||
- | | ||
- | | ||
- | } | ||
- | } | ||
- | continue; | ||
- | } | ||
- | if( min( $ntr[1] ) < 1 ) { //weird. Should never happen | ||
- | prestart($language, | ||
- | headkeypb( $vukeys, $strkeys, $k, $v, $tr[$k] ); | ||
- | echo | ||
- | ' | ||
- | ' | ||
- | | ||
- | | ||
- | if( $v2 < 1 ) { | ||
- | echo ' | ||
- | ' | ||
- | printf( " | ||
- | $ntrouble++; | ||
- | } | ||
- | } | ||
- | continue; | ||
- | } | ||
- | |||
- | // test #? ... Test all args are used : | ||
- | /* '%3s %2s' => arg 1 never printed... */ | ||
- | foreach( range( 1, $expectargen ) as $argnum ) { | ||
- | if( !array_key_exists( $argnum, $ntr[3] ) ) { | ||
- | prestart($language, | ||
- | headkeypb( $vukeys, $strkeys, $k, $v, $tr[$k] ); | ||
- | echo ' | ||
- | } | ||
- | } | ||
- | // test 3 check that each %thing in translation has a matching %samething in original | ||
- | /* FIXME: undefined indexes when english is "%s %d" and tr is "%1$s %1$s" */ | ||
- | $orderpb=false; | ||
- | foreach( $ntr[1] as $i2 => $v2 ) { | ||
- | if( !array_key_exists( $ntr[1][$i2], | ||
- | continue; | ||
- | if( $ntr[2][$i2] != $nen[2][$nen[3][$ntr[1][$i2]]] ) { | ||
- | $ntrouble++; | ||
- | $orderpb=true; | ||
- | prestart($language, | ||
- | headkeypb( $vukeys, $strkeys, $k, $v, $tr[$k] ); | ||
- | echo ' | ||
- | ' | ||
- | } | ||
- | } | ||
- | if( $orderpb ) | ||
- | continue; | ||
- | // and vice versa | ||
- | foreach( $nen[1] as $i2 => $v2 ) { | ||
- | if( !array_key_exists( $nen[1][$i2], | ||
- | continue; | ||
- | if( $nen[2][$i2] != $ntr[2][$ntr[3][$nen[1][$i2]]] ) { | ||
- | $ntrouble++; | ||
- | $orderpb=true; | ||
- | prestart($language, | ||
- | headkeypb( $vukeys, $strkeys, $k, $v, $tr[$k] ); | ||
- | echo ' | ||
- | ' | ||
- | } | ||
- | } | ||
- | if( $orderpb ) | ||
- | continue; | ||
- | } | ||
- | // things to do only once per language file | ||
- | if( '' | ||
- | // test n : supernumerary translations | ||
- | if( count( $diff=array_diff_key( $tr, $en ) ) ) { | ||
- | preend($language, | ||
- | fileheader($language, | ||
- | echo "Those translations are present in $language but not in original English\n"; | ||
- | prestart($language, | ||
- | foreach( $diff as $k => $v ) { | ||
- | echo ' | ||
- | $ntrouble++; | ||
- | } | ||
- | preend($language, | ||
- | } | ||
- | filefooter( $language, $prenfi, $prtrfi); | ||
- | } | ||
- | l( " | ||
- | return $ntrouble; | ||
- | } | ||
- | function headkeypb( & | ||
- | if( array_key_exists( $k, $vukeys ) ) | ||
- | return; | ||
- | $vukeys[$k]=1; | ||
- | echo | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | } | ||
- | |||
- | function summary( $ntrouble ) { | ||
- | global $vu, $timestart; | ||
- | echo " | ||
- | if( $ntrouble ) { | ||
- | $nlang = count( $vu[' | ||
- | printf( "There %s %d problem%s in %d language%s.\n", | ||
- | ($ntrouble > 1) ? ' | ||
- | $ntrouble, | ||
- | ($ntrouble > 1) ? ' | ||
- | $nlang, | ||
- | ($nlang > 1) ? ' | ||
- | ); | ||
- | } | ||
- | else { | ||
- | echo 'No problem found.', | ||
- | ' | ||
- | echo " | ||
- | } | ||
- | if ($timestart) { | ||
- | echo " | ||
- | echo " | ||
- | } | ||
- | } | ||
- | function pageheader() { | ||
- | ?> | ||
- | ====== DokuWiki PHP translation checks ===== | ||
- | |||
- | This page shows the result of checks on translation strings. The results | ||
- | are presented language by language. All languages are tested but only those with troubles are reported. | ||
- | |||
- | Every day, the test is run. This page is updated only when there is something new to report. | ||
- | |||
- | Last report date : <?php echo date( ' | ||
- | |||
- | |||
- | **Explanation for translators: | ||
- | |||
- | DokuWiki sometimes uses a function called [[phpfn> | ||
- | |||
- | The most common format string is a simple '' | ||
- | |||
- | When translating a string it is important to **leave the format strings intact**. They have to appear exactly as in the original. If a string contains several format strings, **order does matter**. Make sure the logical order of words or numbers to be inserted are the same as in the original. | ||
- | |||
- | |||
- | <?php | ||
- | } | ||
- | function pagefooter() { | ||
- | ?> | ||
- | |||
- | ===== technical details ===== | ||
- | |||
- | * percent test 1\\ This test checks that there are as many '' | ||
- | * non existing arg test\\ Translators may change the order of argument using '' | ||
- | * percent test 2\\ checks that each %thing in translation has a corresponding %samething in english, in the correct order and that each %thing in english has a corresponding %samething in translation. | ||
- | * supernumerary translations\\ This test detects 3 possible errors : | ||
- | - Old translations that remain in locale files but that are no more needed. Those unneeded strings are just useless, not harmful at all. They should be removed anyway. | ||
- | - Typo in the translation key name. For example, if a translator types '' | ||
- | - Misplaced translation key. For example '' | ||
- | |||
- | ===== script code ===== | ||
- | |||
- | This page was produced with the following php code. This page is automagically updated by an ugly daily cron job of mine. Any change in the script below will stop the automatic updates. | ||
- | |||
- | <?php | ||
- | /* | ||
- | * must break </ code> in 2 pieces otherwise it is not possible to | ||
- | * self-include this file in doku page | ||
- | */ | ||
- | echo '<', | ||
- | readfile( __FILE__ ); | ||
- | echo '</', | ||
- | } | ||
- | |||
- | function langheader( $language ) { | ||
- | l( " | ||
- | global $vu; | ||
- | if( !array_key_exists( $language, $vu[' | ||
- | $vu[' | ||
- | echo " | ||
- | l( " | ||
- | } | ||
- | } | ||
- | function fileheader( $language, $en_file, $tr_file ) { | ||
- | global $vu; | ||
- | langheader( $language ); | ||
- | l( " | ||
- | if( !array_key_exists( $tr_file, $vu[' | ||
- | l( " | ||
- | $vu[' | ||
- | echo | ||
- | "\n! ", | ||
- | '! ', | ||
- | } | ||
- | } | ||
- | function prestart( $language, $en_file, $tr_file ) { | ||
- | global $vu; | ||
- | fileheader( $language, $en_file, $tr_file ); | ||
- | l( " | ||
- | if( !array_key_exists( $tr_file, $vu[' | ||
- | l( " | ||
- | $vu[' | ||
- | echo '< | ||
- | } | ||
- | } | ||
- | function preend( $language, $en_file, $tr_file ) { | ||
- | global $vu; | ||
- | l( " | ||
- | if( array_key_exists( $tr_file, $vu[' | ||
- | echo '<', | ||
- | l( " | ||
- | unset( $vu[' | ||
- | } | ||
- | } | ||
- | function filefooter( $language, $en_file, $tr_file ) { | ||
- | global $vu; | ||
- | preend( $language, $en_file, $tr_file ); | ||
- | l( " | ||
- | } | ||
- | function langfooter() { | ||
- | return; | ||
- | } | ||
- | function l( $s ) { | ||
- | global $debug_log; | ||
- | if( ! $debug_log ) return; | ||
- | file_put_contents( '/ | ||
- | } | ||
- | /* | ||
- | * fills in numbering info of format string. | ||
- | * adds a reverse index array so it is easy to find | ||
- | * the original format knowing the translated format even | ||
- | * when there are printf %order$ thing in both strings | ||
- | | ||
- | * printf( '%3$s %2$s %s %s %5$s %s', 1, 2, 3, 4, 5 ); | ||
- | * => 3 2 1 2 5 3 | ||
- | */ | ||
- | function order_fmt( &$arr ) { | ||
- | $ordered=Array(); | ||
- | $reverse_id=Array(); | ||
- | $autoid=1; | ||
- | for( $i=0; $i < count($arr[1]); | ||
- | if( empty($arr[1][$i] )) | ||
- | $arr[1][$i] = $autoid++; | ||
- | $reverse_id[$arr[1][$i]]=$i; | ||
- | } | ||
- | $arr[]=$reverse_id; | ||
- | } | ||
- | |||
- | </ | ||
teams/i18n/translation-check.1437977611.txt.gz · Last modified: 2015-07-27 08:13 by schplrtz.au