1#!/usr/bin/gawk -f 2 3# This program is free software; you can redistribute it and/or 4# modify it under the terms of the GNU General Public License as 5# published by the Free Software Foundation; either version 2 of the 6# License, or (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, but 9# WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11# General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 17# This script will (hopefully!) check the completeness of a .po 18# translation file. It will report untranslated strings, as well 19# as fuzzy ones. It will print a summary at the end of the check 20# that says how many strings there are, how many are translated 21# (and the percentage it represents), how many are fuzzy (and the 22# percentage it represents amongst translated strings), and how 23# many are untranslated (and the percentage it represents). 24# It will _not_ tell you whether your file is syntactically correct 25# (eg. check for terminating double quotes!). And of course it 26# will _not_ tell you whether the translations are correct! ;-] 27# 28# It was originally been written for SANE backends translations, but 29# shall be able to check any .po file. 30# 31# Originally written by Yann E. MORIN 32# <yann dot morin dot 1998 at anciens dot enib dot fr> 33# 34# Output will look like : 35# [./src/foobar.c:2345](321)- "This is the string" 36# \____________/ \__/ \_/ | \________________/ 37# | | | | | 38# | | | | \-> Original untranslated string 39# | | | | 40# | | | \-> flag telling whether it is 41# | | | fuzzy (F) or not (-) 42# | | | 43# | | \-> line number in the .po file 44# | | 45# | \-> line number in the source file 46# | 47# \-> filename where the original string lies 48# 49# 50# Last four lines will look like : 51# Translated : 23 (23.0%) 52# of which : 2 fuzzy ( 8.6%) 53# Not translated : 77 (77.0%) 54# Total : 100 55# 56# 57# TODO: 58# - Print the fuzzy translated string at the same level as the 59# untranslated one; 60# - basic checks about syntax (missing terminating double quotes); 61# - option for brief mode (only last four lines); 62# - other? 63 64 65BEGIN \ 66{ 67 count = 0; 68 fuzzy = 0; 69 is_fuzzy = 0; 70 missing = 0; 71 first = 1; 72} 73 74# Is this translation fuzzy? If so count it 75$1 == "#," && $2 ~ /^fuzzy(|,)$/ \ 76{ 77 fuzzy++; 78 # Next translation will be fuzzy! 79 is_fuzzy = 1; 80} 81 82$1 == "#:" \ 83{ 84 file = $2; 85} 86 87# Skip the first msgid as it is no true translation 88$1 ~ /msgid/ && first == 1 \ 89{ 90 first = 0; 91 next; 92} 93 94$1 ~ /msgid/ && first == 0 \ 95{ 96 # One more translation 97 count++; 98 line = NR; 99 100 # Gets the untranslated string (with double quotes :-( ) 101 $1 = ""; 102 original = $0; 103 getline; 104 while( $1 != "msgstr" ) 105 { 106 original = original $0 107 getline; 108 } 109 110 # Now extract the translated string (with double quotes as well :-( ) 111 $1 = ""; 112 translation = $0; 113 # In case we have no blank line after the last translation (EOF), 114 # we need to stop this silly loop. Allowing a 10-line message. 115 len = 10; 116 getline; 117 while( $0 != "" && $0 !~ /^#/ && len != 0 ) 118 { 119 translation = translation $0 120 getline; 121 len--; 122 } 123 124 # Remove double quotes from multi-line messages and translations 125 msg = "" 126 n = split( original, a, "\"" ); 127 # start at 2 to get rid of the preceding space 128 for( i=2; i<=n; i++ ) 129 { 130 msg = msg a[i]; 131 } 132 trans = ""; 133 n = split( translation, a, "\"" ); 134 # start at 2 to get rid of the preceding space 135 for( i=2; i<=n; i++ ) 136 { 137 trans = trans a[i] 138 } 139 140 # Checks whether we have a translation or not, whether it is fuzzy or not 141 if( ( trans == "" ) || ( is_fuzzy == 1 ) ) 142 { 143 # Enclose original messages between double quotes 144 printf( "[%s](%d)", file, line ); 145 if( is_fuzzy == 1 ) 146 { 147 printf( "F" ); 148 } 149 else 150 { 151 printf( "-" ); 152 } 153 printf( " \"%s\"\n", msg ); 154 if( trans == "" ) 155 { 156 missing++; 157 } 158 } 159 160 is_fuzzy = 0; 161} 162 163END \ 164{ 165 # Lines are longer than 80 chars, but I won't cut them 166 printf( "\n" ); 167 printf( "Translated : %4d (%4.1f%%)\n", count-missing, 100.0*(count-missing)/count ); 168 printf( " of which : %4d fuzzy (%4.1f%%)\n", fuzzy, 100*fuzzy/(count-missing) ); 169 printf( "Not translated : %4d (%4.1f%%)\n", missing, 100.0*missing/count ); 170 printf( "Total : %4d\n", count ); 171} 172