#! /usr/bin/perl # # Copyright 2006 Luciano Montanaro # # This file is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # You should have received a copy of the GNU Library General Public License # along with this library; see the file COPYING.LIB. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. use Getopt::Std; use Text::Aspell; # Spelling check my $speller = Text::Aspell->new or die; $speller->set_option('lang','it'); #print $speller->list_dictionaries; my $verbose = 0; my $check = 0; my $line = 0; my $lasterrorline = -1; my $text; if (!getopts('wp')) { print STDERR ("Sintassi sconosciuta sulla riga di comando.\n"); printUsage(); exit; } my $source = $ARGV[0]; if (defined($source)) { open STDIN, "$source" or die "Cannot open input file"; } my %unknownWords; my %gender = ( 'artista' => 'm', 'automa' => 'm', 'autoradio' => 'f', 'cinema' => 'm', 'clima' => 'm', 'collega' => 'm', 'contro' => 'f', 'diagramma' => 'm', 'foto' => 'f', 'fotogramma' => 'm', 'istogramma' => 'm', 'mano' => 'f', 'macro' => 'f', 'meta' => 'm', 'panorama' => 'm', 'parallelogramma' => 'm', 'pianeta' => 'm', 'pirata' => 'm', 'poeta' => 'm', 'problema' => 'm', 'progettista' => 'm', 'programma' => 'm', 'promemoria' => 'm', 'sistema' => 'm', 'sottoprogramma' => 'm', 'sottosistema' => 'm', 'tema' => 'm', ); my %camelword = ( 'ASpell' => 't', 'CImg' => 't', 'CMake' => 't', 'CTags' => 't', 'CPU' => 't', 'GBit' => 't', 'GByte' => 't', 'GHz' => 't', 'GConf' => 't', 'GPhoto' => 't', 'GStreamer' => 't', 'ICal' => 't', 'ICalendar' => 't', 'ICard' => 't', 'ICCCM' => 't', 'IFrame' => 't', 'ISpell' => 't', 'MBit' => 't', 'MByte' => 't', 'MHz' => 't', 'MEncoder' => 't', 'MPlayer' => 't', 'NEdit' => 't', 'OClock' => 't', 'QApplication' => 't', 'QBrush' => 't', 'QColor' => 't', 'QMake' => 't', 'QPainter' => 't', 'QPicture' => 't', 'QRegExp' => 't', 'QString' => 't', 'QTextEdit' => 't', # 'QTopia' => 't', Qtopia should be written with only a capital Q 'QWidget' => 't', 'TByte' => 't', 'VCal' => 't', 'VCard' => 't', 'XFree' => 't', 'ZAngband' => 't', 'ZLib' => 't', 'ZModem' => 't', ); my %abbreviation = ( 'cart' => 't', 'dir' => 't', 'dim' => 't', 'dimens' => 't', 'ecc' => 't', 'es' => 't', 'espr' => 't', 'Inc' => 't', 'incr' => 't', 'Jr' => 't', 'n' => 't', 'ndt' => 't', 'orizz' => 't', 'val' => 't', 'vert' => 't', ); my %notruntogether = ( 'developer' => 't', 'Developer' => 't', 'email' => 't', 'Email' => 't', 'emoticon' => 't', 'escputil' => 't', 'gmail' => 't', 'guiicon' => 't', 'Jesper' => 't', 'klipper' => 't', 'kmail' => 't', 'KMail' => 't', 'mail' => 't', 'Mail' => 't', 'KMail' => 't', 'procmail' => 't', 'Procmail' => 't', 'sendmail' => 't', 'Sendmail' => 't', 'super' => 't', 'Super' => 't', ); my %extension = ( 'com' => 't', 'de' => 't', 'fr' => 't', 'ics' => 't', 'it' => 't', 'net' => 't', 'org' => 't', 'avi' => 't', 'doc' => 't', 'desktop' => 't', 'directory' => 't', 'dvi' => 't', 'gif' => 't', 'iso' => 't', 'mp3' => 't', 'mpg' => 't', 'mpeg' => 't', 'png' => 't', 'ogg' => 't', 'html' => 't', 'kde' => 't', 'kderc' => 't', 'jpeg' => 't', 'jpg' => 't', 'prc' => 't', 'pwm' => 't', 'pwk' => 't', 'txt' => 't', 'vcs' => 't', 'wav' => 't', ); print STDERR ("Checking $source...\n") if ($verbose); while () { $line++; if (defined($opt_p)) { $check = 1; } else { if (/^#.*$/) { # discard comments next; } elsif (/^msgid/) { # discard message ids $check = 0; print STDERR ("msgid, not checking at line $line\n") if ($verbose > 1); } elsif (/^msgctxt/) { # discard message contexts too $check = 0; print STDERR ("msgctxt, not checking at line $line\n") if ($verbose > 1); } elsif (/^msgstr/) { # check msgstr $check = 1; print STDERR ("msgstr, checking at line $line\n") if ($verbose > 1); } elsif ( /(X-Generator|Content-|POT-|Language-|Project-Id-|Report-Msgid-Bugs-To|X-KDE-DocBook-|Plural-Forms)/) { # discard special messages $check = 0; } } if ($check) { $text = $_; my $ft = filter_extra_chars($text); # Accumulate text in one string if (defined($opt_w)) { while () { $line++; last if (/^$/); last if (/^#.*$/); $text .= $_; $ft .= filter_extra_chars($_); } } $ft =~ s/\n//g; check_che($ft); check_se($ft); check_ne($ft); check_po($ft); check_si($ft); check_triple($ft); check_commas($ft); check_spaces($ft); check_accents($ft); check_apostrophe($ft); check_qual($ft); check_repeated($ft); check_e($ft); check_capitals($ft); check_english_plural($ft); check_double_uppercase($ft); check_missing_uppercase($ft); check_title_case($ft); check_bad_phrases($ft); check_gender($ft); check_qu($ft); check_common_mistyping($ft); #check_ing($ft); check_conflict_marker($ft); check_runtogether_words($ft); check_aspell($ft); check_wesnoth($ft); check_ai($ft); check_salva_come($ft); if (defined($opt_o)) { # Do checks that work only on whole messages. # For example matching parenthesis, matching quotes etc. } # check_double_vowels($ft); # TODO # } else { next; } } exit 0; sub error($) { $message = shift; print "\n$text" if ($lasterrorline != $line); $lasterrorline = $line; print ("$source:$line - $message\n"); } sub filter_extra_chars($) { # Generic rules # Remove leding and trailing '"' s/^msgstr\s*"//; s/^\s*"//; s/"\s*$//; # Change '\"' to simply '"' s/\\"/"/g; # Change "\n" to a space s/\\[nt]/ /g; # Rules useful to strip KDE markup. # Convert common html/xml entities s/<//g; s/&/&/g; s/á/á/g; s/à/à/g; s/Ä/Ä/g; s/ä/ä/g; s/ç/ç/g; s/é/é/g; s/è/è/g; s/í/í/g; s/ì/ì/g; s/ò/ò/g; s/—/---/g; s/–/--/g; s/ö/ö/g; s/Ö/Ö/g; s/ß/ß/g; s/ú/ú/g; s/ù/ù/g; s/ü/ü/g; s/Ü/Ü/g; s/_/_/g; s/"/"/g; s/ / /g; s/&konqueror;/Konqueror/g; # Silence lots of warnings in the doc. s/&kmail;/KMail/g; # Silence lots of warnings in the doc. s/&amarok;/Amarok/g; # Silence lots of warnings in the doc. s/<[ib]>//; # remove html/qtxml italics indicator s/<\/[ib]>//; # remove html/qtxml italics indicator # Remove KDE accelerator indicator s/([a-z])&([a-z])/\1\2/ig; # Remove GNOME accelerator indicator s/([a-z])_([a-z])/\1\2/ig; return $_; } sub check_se($) { my $message = shift; print STDERR ("$source:$line checking \"se\": $message\n") if ($verbose > 1); if ($message =~ /\bsè[\s\.!?]/i) { # Accented letters are not considered 'word' letters, so boundary check does not work. my $match = $&; if (!($message =~ /($match)[a-z]/i)) { error("accento su \"sé\" sbagliato"); } } if ($message =~ /\b(a|di|da|in|con|su|per|tra|fra) se\b/i and !($message =~ /\bse stess[aio]\b/i) # se stesso è accettabile... ) { error("controlla se è \"se\" o \"sé\""); } } sub check_ne($) { my $message = shift; print STDERR ("$source:$line checking \"né\": $message\n") if ($verbose > 1); if ($message =~ /[^a-z]nè\s/i) { error("accento su \"né\" sbagliato"); } } sub check_che($) { my $message = shift; print STDERR ("$source:$line checking \"-ché\": $message\n") if ($verbose > 1); if ($message =~ /([a-z]*chè)/i) { error("accento su $1 sbagliato"); } } sub check_po($) { my $message = shift; print STDERR ("$source:$line checking \"po\": $message\n") if ($verbose > 1); if (($message =~ /\bp[oò]\b/) and !(($message =~ /\b(po'|po-)/) or ($message =~ /(\bPO|\.po\b|po\b)/)) ) { error("accento su \"po'\" sbagliato"); } } sub check_si($) { my $message = shift; print STDERR ("$source:$line checking \"sì\": $message\n") if ($verbose > 1); if ($message =~ /\bsi[,;:.!\?]/i) { error("manca accento su \"sì\""); } if ($message =~ /\b(far|fai|fa|fa')\s+i\b/i) { error("manca accento su \"sì\""); } } sub check_triple($) { my $message = shift; print STDERR ("$source:$line checking triple: $message\n") if ($verbose > 1); # Sequenze di tre caratteri uguali. Ignora la linea se ci sono numeri esadecimali 0xffff ecc. if (($message =~ /([bcdfglmnprstvz])\1\1/i) and !( ($message =~ /(pppd?|kppp\w*)\b/i) or ($message =~ /0x/) or ($message =~/glossseealso/) or ($message =~/\b([BCDFGLMNPRSTVZbcdfglmnprstvz])\1\1\1?\1?\1?\1?\1?\1?\1?\1?\b/) ) ) { error("sequenza di tre o più lettere uguali"); } } sub check_double_vowels($) { my $message = shift; print STDERR ("$source:$line checking double wovels: $message\n") if ($verbose > 1); # Sequenze di tre caratteri uguali. Ignora la linea se ci sono numeri esadecimali 0xffff ecc. if (($message =~ /([aeiou])\1/i) ) { error("sequenza di due o più vocali uguali"); } } sub check_commas($) { my $message = shift; print STDERR ("$source:$line checking: $message\n") if ($verbose > 1); # Sequenze di tre caratteri uguali. Ignora la linea se ci sono numeri esadecimali 0xffff ecc. if ($message =~ /,,/) { error("virgole ripetute"); } } sub check_spaces($) { my $message = shift; print STDERR ("$source:$line checking spaces in: $message\n") if ($verbose > 1); if (($message =~ / [\.,;:!\?]/) and !( ($message =~ / !=/) or ($message =~ / \.[a-z]{1,3}/i) ) ) { error("spazio davanti a simboli di punteggiatura"); } if (($message =~ /([\.!?,;])([a-zàèéìòù]+)/i) ) { if ( !( ($message =~ /^Keywords=/) or ($message =~ /^Query=/) ) ) { if ( !( ($1 eq '.' and $extension{$2} eq 't') or ($message =~ "\.\.\.$2") ) ) { error("spazio mancante dopo simbolo di punteggiatura e prima di $2"); } } } if (($message =~ /\(\s/) ) { error("spazio dopo una parentesi aperta"); } if (($message =~ /\s\)/) ) { error("spazio prima di una parentesi chiusa"); } # For KDE docbooks: extra spaces between selected tags if (($message =~ /<(application|email|keycap|menuitem|guibutton|guiicon|guilabel|guimenu|quote)>[^<]+\s<\/\1>/i)) { error("spazio prima del tag di chiusura <$1>"); } if (($message =~ /<(keycombo)\s?.*>[^<]+\s<\/\1>/i)) { error("spazio prima del tag di chiusura <$1>"); } if (($message =~ /<(application|email|keycap|menuitem|guibutton|guiicon|guilabel|guimenu|quote)\s?.*>\s[^<]+<\/\1>/i)) { error("spazio dopo il tag di apertura <$1>"); } if (($message =~ /<(keycombo)\s?.*>\s[^<]+<\/\1>/i)) { error("spazio dopo il tag di apertura <$1>"); } } sub check_accents($) { my $message = shift; print STDERR ("$source:$line checking accents in: $message\n") if ($verbose > 1); if ( ($message =~ /(\b(lunedi|martedi|mercoledi|giovedi|venerdi)\b)/i) or ($message =~ /(\b(affinche|benche|bensi|gia|giu|puo|piu|cosi|percio|pero|perche|poiche)\b)/i) or ($message =~ /(\b(cio|cioe)[,:\s])/i) or ($message =~ /((venti|trenta|quaranta|cinquanta|sessanta|settanta|ottanta|novanta)tre\b)/i) ) { my $match = $&; if (!($message =~ /($match)[àièéìíòùú]/)) { error("accento mancante su $match"); } } if (($message =~ /\b(la)[\.,!\?;:]/i)) { error("Forse volevi dire \"là\""); } if (($message =~ /\b(li)[\.,!\?;:]/i)) { error("Forse volevi dire \"lì\""); } # KDE convention if (($message =~ /\b(menù|menú)[^w]/i)) { error("accento in eccesso"); } } sub check_apostrophe($) { my $message = shift; print STDERR ("$source:$line checking apostrophes in: $message\n") if ($verbose > 1); if (($message =~ /\b(alcun|ciascun|un|all|l)'([bcdfgklmnpqrstvz][a-z]+)\b/i)) { print STDERR ("$source:$line $1 matches apostrophe rule\n") if ($verbose > 0); if (!($gender{$2} eq 'f')) { error("apostrofo davanti a parola che inizia per consonante ($2)"); } } if (($message =~ /\b(alcun|ciascun|un)'([aeiou][a-z]*o)\b/i)) { print STDERR ("$source:$line $1 matches apostrophe rule\n") if ($verbose > 0); if (!($gender{$2} eq 'f')) { error("apostrofo sbagliato davanti a $2"); } } if (($message =~ /\b(alcun|ciascun|un)\s+([a-z]*a)\b/i)) { print STDERR ("$source:$line $1 matches apostrophe rule\n") if ($verbose > 0); print STDERR ("$source:$line gender of $1 is '$gender{$1}'\n") if ($verbose > 0); if (!($gender{$2} eq 'm')) { error("apostrofo mancante fra $1 e $2"); } } if (($message =~ /\b(alcuna|ciascuna|la|una)\s+([a-z]+o)\b/i)) { my $article = $1; print STDERR ("$source:$line $1 matches apostrophe rule\n") if ($verbose > 0); # exclude feminine words, verbal forms and "la loro" if ( ($gender{$2} ne 'f') && !($2 =~ /anno$/i) && !($2 =~ /ano$/i) && !($2 =~ /^loro$/i) ) { error("parola maschile ($2) preceduta da $1"); } } } sub check_qual($) { my $message = shift; print STDERR ("$source:$line checking for 'qual': $message\n") if ($verbose > 1); if ($message =~ /\bqual'/i) { error("qual non va seguito dall'apostrofo"); } } sub check_repeated($) { my $message = shift; print STDERR ("$source:$line checking for repeated words: $message\n") if ($verbose > 1); if ($message =~ /(\b([a-z]{2,}) \1\b)/i) { my $match = $&; if (!$message =~ /($match)[àèìòùáéíóú]/) { error("parole ripetute"); } } } sub check_e($) { my $message = shift; print STDERR ("$source:$line checking for mistyped \"è\": $message\n") if ($verbose > 1); if (($message =~ /\sé\s/i) or ($message =~ /\be['`]\s/i)) { error("\"è\" scritto male"); } } sub check_capitals($) { my $message = shift; print STDERR ("$source:$line checking capitals in: $message\n") if ($verbose > 1); if ( ($message =~ /\b(Lunedì|Martedì|Mercoledì|Giovedì|Venerdì|Sabato|Domenica)\b/) or ($message =~ /\b(Lun|Mart|Mer|Gio|Ven|Sab|Dom)\b/) or ($message =~ /\b(Gennaio|Febraio|Marzo|Aprile|Maggio|Giugno|Luglio|Agosto|Settembre|Ottobre|Novembre|Dicembre)\b/) or ($message =~ /\b(Gen|Feb|Mar|Apr|Mag|Giu|Lug|Ago|Set|Ott|Nov|Dic)\b/) ) { error("mese o giorno della settimana in maiuscolo"); } } sub check_english_plural($) { my $message = shift; print STDERR ("$source:$line checking english plurals in: $message\n") if ($verbose > 1); if ( ($message =~ /[^\/]\b((m|k|g|)bytes|(m|k|g|)bits|bugs|downloads|uploads|plugins|directories|drivers|files|forms|skins|desktops|tags|sponsors|widgets|toolkits|newsgroups)\b[^\/]/i) ) { error("plurale con la \"s\": $1"); } } sub check_double_uppercase($) { # DUe maiuscole all'inizio di una parola (di solito sono un # errore, ma ci sono eccezioni) my $message = shift; print STDERR ("$source:$line checking for double capitals: $message\n") if ($verbose > 1); # Special case for "K", since it's used in many KDE programs. if (($message =~ /\b([A-JL-WYZ]{2}[a-z]+)/)) { if (!($camelword{$1} eq 't')) { error("due lettere maiuscole all'inizio della parola $1"); } } } sub check_missing_uppercase($) { my $message = shift; print STDERR ("$source:$line checking for missing capitals: $message\n") if ($verbose > 1); # Special case for "K", since it's used in many KDE programs. if (($message =~ /([a-zàèìòùé]+)\.\s+[a-z]/)) { if (!($abbreviation{$1} eq 't')) { error("minuscola dopo un punto"); } } if (($message =~ /([a-z]+)\.\s+è/)) { if (!($abbreviation{$1} eq 't')) { error("minuscola dopo un punto"); } } } sub check_title_case($) { my $message = shift; print STDERR ("$source:$line checking for title case: $message\n") if ($verbose > 1); # if (($message =~ /^([A-Z][a-z]+\s)+[A-Z][a-z]+$/)) { # error("sembra un titolo con maiuscole all'inglese: in italiano la convenzione non si usa."); # } if (($message =~ /<(menuitem|guibutton|guiicon|guilabel|guimenu)>([A-Z][a-z]+\s)+[A-Z][a-z]+<\/\1>/)) { error("sembra un titolo com maiuscole all'inglese: in italiano la convenzione non si usa."); } } sub check_bad_phrases($) { my $message = shift; print STDERR ("$source:$line checking for click: $message\n") if ($verbose > 1); # Special case for "K", since it's used in many KDE programs. if (($message =~ /\bclick\b/i)) { error("usa \"clic\", non \"click\"."); } if (($message =~ /\b(clicca|clicchi|cliccare|cliccate|cliccando)\b/i)) { error("usa \"fare clic\", non \"cliccare\"."); } if (($message =~ /\b(indenta)/i)) { error("usa rientro, non indentazione."); } if (($message =~ /\b(botton)/i)) { error("usa tasto o pulsante, non bottone."); } if (($message =~ /\b(affianco)/i)) { error("usa a fianco non affianco."); } } sub check_qu($) { my $message = shift; # Special case for "K", since it's used in many KDE programs. if (($message =~ /q[aeio]/i)) { error("'Q' non seguita da 'u'"); } } sub check_runtogether_words($) { my $message = shift; # Special case for "K", since it's used in many KDE programs. if (($message =~ /([a-z]+(per|sul|degli|dal|con|il))[^a-zàèìòùé]/i)) { if (!($notruntogether{$1} eq 't')) { error("$2 attaccato alla parola precedente ($1)?"); } } if (($message =~ /[^a-zàèìòùé](degli|dalla)([a-zàèìòùé]+)/i)) { if (!($notruntogether{$1} eq 't')) { error("$1 attaccato alla parola successiva ($2)?"); } } } sub check_gender($) { my $message = shift; print STDERR ("$source:$line checking foreign world gender: $message\n") if ($verbose > 1); # Special case for "K", since it's used in many KDE programs. my $firstword = "alla|alle|dalla|dalle|della|delle|nella|nelle|colla|colle|sulla|sulle|ciascuna|la|le|una|altra"; if (($message =~ /\b($firstword)\s+(stack|tag|joystick|url|uri)\b/i)) { my $match = $2; error("la convenzione usata per $match è di usare il maschile ($1)"); } } sub check_ing($) { my $message = shift; print STDERR ("$source:$line checking for -ing: $message\n") if ($verbose > 1); # Special case for "K", since it's used in many KDE programs. if (($message =~ /\b([a-z]+ing)\b/i)) { my $matvh = $1; error("è preferita la forma all'infinito a quella in -ing per $match."); } } sub check_conflict_marker($) { my $message = shift; print STDERR ("$source:$line checking for conflict marker: $message\n") if ($verbose > 1); # Special case for "K", since it's used in many KDE programs. if (($message =~ />>>>>>/)) { my $matvh = $1; error("possibile rimasuglio di un conflitto CVS/SVN"); } } sub check_common_mistyping($) { my $message = shift; print STDERR ("$source:$line checking for fancy capitalization: $message\n") if ($verbose > 1); if ($message =~ /\bpostscript\b/i) { if (!($message =~ /\bPostScript\b/)) { error("normalmente, PostScript si scrive con la 'P' e la 'S' maiuscola"); } } if ($message =~ /\bamarok\b/i) { if (!($message =~ /\bAmarok\b/)) { error("attualmente, Amarok si scrive con l'iniziale (e solo quella) maiuscola"); } } if ($message =~ /\bkonqueror\b/i) { if (!($message =~ /\bKonqueror\b/)) { error("normalmente, Konqueror si scrive con la maiuscola"); } } # Errori trovati da aspell -- corretti su HEAD, devo assicurarmi di eliminarli sul branch if ($message =~ /\bcomprarir/i) { error("\"comparire\", non \"comprarire\""); } if ($message =~ /\bconneter/i) { error("\"connettere\", non \"connetere\""); } if ($message =~ /\bcondividire\b/i) { error("\"condividere\", non \"condividire\""); } if ($message =~ /\bconcella/i) { error("\"cancellare\", non \"concellare\""); } if ($message =~ /\bconfgura/i) { error("\"configurare\", non \"confgurare\""); } if ($message =~ /\bcompueter\b/i) { error("\"computer\", non \"compueter\""); } if ($message =~ /\bconemporane/i) { error("\"contemporaneo\", non \"conemoraneo\""); } if ($message =~ /\bcomportamente/i) { error("\"comportamento\", non \"comportamente\""); } if ($message =~ /\bcomuncazione/i) { error("\"comunicazione\", non \"comuncazione\""); } if ($message =~ /\bcondifica/i) { error("\"codifica\", non \"condifica\""); } if ($message =~ /\bconfendo\b/i) { error("\"confendo\"?"); } if ($message =~ /\bdaccordo\b/i) { error("\"d'accordo\", non \"daccordo\""); } if ($message =~ /\bdaltronde\b/i) { error("\"d'altronde\", non \"daltronde\""); } if ($message =~ /efficen(za|te|ti|temente)\b/i) { error("\"efficienza\", non \"efficenza\""); } if ($message =~ /\bevacq\w+\b/i) { error("\"evacuare\", non \"evacquare\""); } if ($message =~ /\binnoqu[aeio]\b/i) { error("\"innocuo\", non \"innoquo\""); } if ($message =~ /\b(obbiettiv[aeio])\b/i) { error("troppe 'b' in \"$1\""); } if ($message =~ /\bpercui\b/i) { error("\"per cui\", non \"percui\""); } if ($message =~ /\bpropi[aeo]\b/i) { error("\"proprio\", non \"propio\""); } if ($message =~ /propietà/i) { error("\"proprietà\", non \"propietà\""); } if ($message =~ /\bsopratutto\b/i) { error("\"soprattutto\", non \"sopratutto\""); } if ($message =~ /sufficent[ei]\b/i) { error("\"sufficiente\", non \"sufficente\""); } if ($message =~ /sufficenza\b/i) { error("\"sufficienza\", non \"sufficenza\""); } if ($message =~ /(\w+zzion\w+)/i) { error("'z' in eccesso in \"$1\""); } if ($message =~ /\b(and|or)\b/i) { error("congiunzione inglese -possibile refuso"); } if ( ($message =~ /(\w+mnete\w+)/i) || ($message =~ /(\w+metne\w+)/i) ) { error("'-mente scritto male in \"$1\"?"); } } sub check_aspell($) { my $message = shift; if ($message =~ /^(X-Generator|Content-|POT-|Language-|Project-Id-|Report-Msgid-Bugs-To|X-KDE-DocBook-|Plural-Forms)/) { return; } # Strip common docbook tags before spell check my $xmlKeywords = "application|address|affiliation|contrib|em|email|" . "firstname|keycombo|keycap|" . "envar|keyword|group|filename|" . "menuitem|guibutton|guiicon|guilabel|" . "guimenu|" . "command|computeroutput|option|" . "abbrev|acronym|" . "citation|firstterm|quote|emph|emphasis|"; $message =~ s/<($xmlKeywords)>//ig; $message =~ s/<\/($xmlKeywords)>//ig; $message =~ s/<($xmlKeywords) \/>//ig; my $xmlKeywords = "guimenuitem|guisubmenu|br|center"; $message =~ s/<($xmlKeywords)>/ /ig; $message =~ s/<\/($xmlKeywords)>/ /ig; $message =~ s/<($xmlKeywords) \/>/ /ig; # remove email addresses $message =~ s/[a-z0-9_]*@[a-z0-9_\.]*/ /i; $message =~ s/(ftp|http|https):\/\/[a-z0-9_@\?\.\/]*/ /i; $message =~ s/%[0-9n]/ /ig; $message =~ s/[0-9]+[a-zA-Z]*/ /ig; #my @list = split(/[ \t\n\,\.\?!#-=+\\\/><\|\{\}\[\]\"]/, $message); my @list = split(/[ \t\n,\.;\?!|:\/\\\"()\{\}\[\]=\-+\*\&<>]/, $message); #error(@list); for $i (@list) { if (!$speller->check($i)) { if (!($unknownWords{$i} eq 't')) { error("Parola sconosciuta: $i"); $unknownWords{$i} = 't'; #open(WORDS, ">>dict"); #print WORDS ("$i\n"); #close WORDS; } } } } sub check_wesnoth($) { my $message = shift; if ($message =~ /\blancier[aei]\b/i) { error("se l'unità è a piedi, usa \"fante\""); } if ($message =~ /\bnereide[ei] siren[ae]\b/i) { error("Nel nome dell'unità \"nereide\" non è necessario"); } if ($message =~ /\bsiren[ae] nereide[ei]\b/i) { error("Nel nome dell'unità \"nereide\" non è necessario"); } if ($message =~ /\btritone[ei] nereide[ei]\b/i) { error("Nel nome dell'unità \"nereide\" non è necessario"); } if ($message =~ /\bfat[ae] elfic(a|he)\b/i) { error("Nel nome dell'unità \"elfica\" non è necessario"); } if ($message =~ /\bninfa[ae] elfic(a|he)\b/i) { error("Nel nome dell'unità \"elfica\" non è necessario"); } if ($message =~ /\bdriad[ei] elfic(a|he)\b/i) { error("Nel nome dell'unità \"elfica\" non è necessario"); }if ($message =~ /\bdrag(o|hi) impositor(e|i)\b/i) { error("Il nome dell'unità è stato cambiato in \"Drago vigilante\""); } if ($message =~ /\bdrag(o|hi) sfregiator(e|i)\b/i) { error("Il nome dell'unità è stato cambiato in \"Drago sventratore\""); } if ($message =~ /\bpiaga\b/i) { error("Usa \"Contagio\""); } } sub check_ai($) { my $message = shift; if ($message =~ /\banno [a-zA-Z]\+to\b/i) { error("Controlla: anno o hanno?"); } if ($message =~ /\bo [a-zA-Z]\+to\b/i) { error("Controlla: o o ho?"); } if ($message =~ /\bai [a-zA-Z]\+to\b/i) { error("Controlla: ai o hai?"); } } sub check_salva_come($) { my $message = shift; if ($message =~ /\bsalva con nome/i) { error("Usa Salva come"); } } sub printUsage() { print STDERR ("Usage: $0 {-wp} file\n"); print STDERR ("\n"); print STDERR ("-w esegui i controlli sui messaggi completi invece che riga per riga\n"); print STDERR ("-p tratta il file come un file di puro testo (non un file .po)\n"); }