PageRenderTime 60ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/other/po-checker/modules/po.php

http://tortoisesvn.googlecode.com/
PHP | 1287 lines | 1088 code | 87 blank | 112 comment | 146 complexity | 6ba701449f1cabf72e3990a3919144b5 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, GPL-2.0, LGPL-2.0, LGPL-2.1, BSD-3-Clause, Apache-2.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. define("PO_NONE", 'PO_NONE');
  3. define("PO_MSGID", 'PO_MSGID');
  4. define("PO_MSGSTR", 'PO_MSGSTR');
  5. define("PO_DATA", 'PO_DATA');
  6. define("PO_COMMENT", 'PO_COMMENT');
  7. define("PO_EXTCMNT", 'PO_EXTCMNT');
  8. define("PO_REFERENCE", 'PO_REFERENCE');
  9. define("PO_FLAGS", 'PO_FLAGS');
  10. define("PO_EMPTY", 'PO_EMPTY');
  11. define("PO_UNKNOWN", 'PO_UNKNOWN');
  12. define("MARK_OK", 'MARK_OK');
  13. define("MARK_ERROR", 'MARK_ERROR');
  14. function IsDebugOn() {
  15. return $_SERVER['REMOTE_ADDR']=="217.75.82.130";
  16. }
  17. function ConvertCstyleNewLineToHtmlstyle($str) {
  18. $search=array("\\n");
  19. $replace=array("\\n<br />");
  20. return str_replace($search, $replace, $str);
  21. }
  22. function CompareStart($a, $b) {
  23. return $a['start']>$b['start'];
  24. }
  25. function CompareEnd($a, $b) {
  26. return $a['end']>$b['end'];
  27. }
  28. function isNonEmptyArray($var) {
  29. return (isset($var) && is_array($var) && count($var)>0);
  30. }
  31. function isEmptyArray($var) {
  32. return (isset($var) && is_array($var) && count($var)==0);
  33. }
  34. class TPo {
  35. protected $dictionary=array();
  36. protected $lines=array();
  37. protected $report=array();
  38. protected $pot=NULL;
  39. protected $spellDictFiles=array();
  40. function __construct($a, $b) {
  41. $this->Load($a, $b);
  42. }
  43. // line types NOTE MSGID MSGSTR EMPTY PARAMETER
  44. function Load($poFileName, $lang) {
  45. $this->lang=$lang;
  46. // echo "<i>Loading $poFileName</i><br />\n";
  47. $this->dictionary=array();
  48. $this->lines=array();
  49. $this->report=array();
  50. // $this->file=$poFileName;
  51. // iterate over lines
  52. unset($msgid);
  53. $lastLineType=PO_NONE;
  54. $linenum=0;
  55. $extractor="/^((#~ )?(msgid|msgstr|\")|#[\.,:| ]|#$|$)/";
  56. $extractorLite="/^(msgid|msgstr|\"|#,|$)/";
  57. $codes=array(
  58. "msgid" => PO_MSGID,
  59. "msgstr" => PO_MSGSTR,
  60. "\"" => PO_DATA,
  61. "# " => PO_COMMENT, // comment
  62. "#." => PO_EXTCMNT, // extracted
  63. "#:" => PO_REFERENCE, // reference
  64. "#," => PO_FLAGS, // flags
  65. "" => PO_EMPTY, // empty line
  66. );
  67. $block=array();
  68. // open_file & load lines
  69. $linesLoaded=file($poFileName);
  70. $linesLoaded[]=""; // add empty line to enforce block procesing
  71. foreach ($linesLoaded as $line) {
  72. //echo "$line<br/>";
  73. $line=trim($line);
  74. $linenum++;
  75. $lineType=PO_UNKNOWN;
  76. $lineRep=false;
  77. # echo "<br ><br >L:<b>".htmlspecialchars($line)."</b>";
  78. // # translator-comments
  79. // #. extracted-comments
  80. // #: reference...
  81. // #, flag...
  82. // #| msgid previous-untraslated-string
  83. // msgid untranslated-string
  84. // msgstr translated-string
  85. // empty line - next translate strings
  86. if (preg_match_all($extractorLite, $line, $result, PREG_PATTERN_ORDER)) {
  87. $command=$result[1][0];
  88. $lineType=$codes[$command];
  89. } else {
  90. $lineType=PO_UNKNOWN;
  91. // echo "unknown line in TPo file<br /><b>$line</b><br />";
  92. continue;
  93. }
  94. if (preg_match_all("/^[^\"]*\"(.*)\"[^\"]*$/", $line, $result, PREG_PATTERN_ORDER)) {
  95. $data=$result[1][0];
  96. } else {
  97. $data=substr($line, strlen($command));
  98. }
  99. # echo "<br >C:<i>".$command."</i>";
  100. # echo "<br >D:<i><b>".$data."</b></i>";
  101. # echo "<br />".$lineType;
  102. // store lines
  103. // $this->lines[]=array($lineType, $line);
  104. switch($lineType) {
  105. default:
  106. // case PO_MSGID:
  107. // case PO_MSGSTR:
  108. if (isset($block[$lineType])) {
  109. $block[$lineType].=$data;
  110. } else {
  111. $block[$lineType]=$data;
  112. }
  113. if (!isset($blockFirstLine)) {
  114. $blockFirstLine=$linenum;
  115. }
  116. break;
  117. case PO_DATA:
  118. $lineType=$lastLineType;
  119. $block[$lineType].=$data;
  120. break;
  121. case PO_EMPTY:
  122. if (isset($block) && count($block) && isset($block[PO_MSGID]) /*&& isset($block[PO_MSGSTR])*/) {
  123. $msgid=$block[PO_MSGID];
  124. $msgstr=$block[PO_MSGSTR];
  125. $flags=array();
  126. $flagsString=isset( $block[PO_FLAGS]) ? $block[PO_FLAGS] : "";
  127. $flagsStrings=explode(",", $flagsString);
  128. foreach ($flagsStrings as &$value) {
  129. $value=trim($value);
  130. }
  131. $flags=array_flip($flagsStrings);
  132. /* while ($flagString=="") {
  133. $len=strpos($flagString, ",");
  134. if (!$len) {
  135. $len=strlen($flagString);
  136. }
  137. $flag=;
  138. $flags[]=$flag
  139. $flagString=substr($flagString, $len);
  140. }//*/
  141. // echo $flagsString;
  142. $this->dictionary[$msgid]=array("text"=>$msgstr, "line"=>$blockFirstLine, "flag"=>$flags);
  143. unset($block);
  144. unset($blockFirstLine);
  145. }
  146. break;
  147. }
  148. $lastLineType=$lineType;
  149. }
  150. }
  151. function AddPot($pot) {
  152. if (is_a($pot, "TPo")) {
  153. $this->pot=$pot;
  154. } else if (is_string($pot)) {
  155. $this->pot=new TPo;
  156. $this->pot->Load($pot);
  157. } else {
  158. echo "<i>Internal warning</i>: <b>unsupported pot type</b>";
  159. }
  160. }
  161. function SetSpellingFiles($dicts) {
  162. $this->spellDictFiles=$dicts;
  163. }
  164. function buildPotReport() {
  165. $report=array();
  166. $report["type"]="pot";
  167. $report["tot"]=$this->getStringCount();
  168. // wrong new lines
  169. $data=array();
  170. $regexp="/(\\\\r\\\\n|\\\\n|\\\\r)/";
  171. // make new line style seft test
  172. foreach ($this->dictionary as $key=>$value) {
  173. $string=$key;
  174. $match=preg_match_all($regexp, $string, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  175. if ($match>1) {
  176. $match=true;
  177. foreach ($matches[0] as $key2=>$value) {
  178. $ok=$matches[0][$key2][0]==$matches[0][0][0];
  179. if (!$ok) {
  180. $match=false;
  181. }
  182. $matches[0][$key2][2]=$ok;
  183. }
  184. if (!$match) {
  185. for ($i=count($matches[0])-1; $i>=0; $i--) {
  186. $param=$matches[0][$i][0];
  187. $pos=$matches[0][$i][1];
  188. $class=$matches[0][$i][2] ? "elmark" : "elerror";
  189. $string=substr($string, 0, $pos)."<font class=\"$class\">".$param."</font>".substr($string, $pos+strlen($param));
  190. }
  191. $line=$this->dictionary[$key]["line"];
  192. $string=str_replace($search, $replace, $string);
  193. $data[]=array(count($data)+1, $line, $string);
  194. }
  195. }
  196. }
  197. $header=array("Index", "Line", "English");
  198. $table=new Table;
  199. $table->name="Wrong Newlines";
  200. $table->header=$header;
  201. $table->data=$data;
  202. $report["nls"]=$table;
  203. // esc aped characters
  204. $data=array();
  205. $regexp="/(\\\\.)/";
  206. $regexp2="/\\\\[\\\\ntr\"]/";
  207. foreach ($this->dictionary as $key=>$value) {
  208. $string=$key;
  209. $match=preg_match_all($regexp, $string, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  210. if ($match>1) {
  211. $match=true;
  212. foreach ($matches[0] as $key2=>$value) {
  213. $match2=preg_match($regexp2, $matches[0][$key2][0]);
  214. if ($match2==false) {
  215. $match=false;
  216. }
  217. $matches[0][$key2][2]=$match2!=false;
  218. }
  219. if (!$match) {
  220. for ($i=count($matches[0])-1; $i>=0; $i--) {
  221. $param=$matches[0][$i][0];
  222. $pos=$matches[0][$i][1];
  223. $class=$matches[0][$i][2] ? "elmark" : "elerror";
  224. $string=substr($string, 0, $pos)."<font class=\"$class\">".$param."</font>".substr($string, $pos+strlen($param));
  225. }
  226. $line=$this->dictionary[$key]["line"];
  227. $string=str_replace($search, $replace, $string);
  228. $data[]=array(count($data)+1, $line, $string);
  229. }
  230. }
  231. }
  232. $table=new Table;
  233. $table->name="Escapes";
  234. $table->header=array("Index", "Line", "English", "Line", "Native");
  235. $table->data=$data;
  236. $report["esc"]=$table;
  237. $this->report=$report;
  238. return true;
  239. }
  240. function BuildReport($potFile=NULL) {
  241. // clean potFile if unusable
  242. $search=array("\\n");
  243. $replace=array("\\n<br />");
  244. if ($potFile==NULL) {
  245. if (isset($this->pot)) {
  246. $potFile=$this->pot;
  247. } else {
  248. return $this->buildPotReport();
  249. }
  250. }
  251. if (is_string($potFile)) {
  252. $potFileName=$potFile;
  253. $potFile=new TPo;
  254. $potFile->Load($potFileName);
  255. }
  256. //echo "------<br/>";
  257. if (!is_a($potFile, "TPo")) {
  258. return false;
  259. }
  260. // no report was created && are there data to create report ?
  261. if (isNonEmptyArray($this->report)/* || !isNonEmptyArray($this->dictionary)*/) {
  262. return true;
  263. }
  264. $report["tot"]=$potFile->getStringCount();
  265. //acc check
  266. $data=array();
  267. $regexp="/(&.)/u";
  268. foreach ($this->dictionary as $orig=>$value) { // check all phrases
  269. $native=$value["text"];
  270. if (!isset($native) || $native=="" || $orig=="") { // no translation -> no test
  271. continue;
  272. }
  273. // native and eng did not match in containing of '&'
  274. if (substr_count($orig, "&")!==substr_count($native, "&")) {
  275. $oriMatch=preg_match_all($regexp, $orig, $matchesOnOri, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  276. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  277. $oriMarks=array();
  278. $natMarks=array();
  279. for ($i=count($matchesOnOri[0])-1; $i>=0; $i--) {
  280. $mark['start']=$matchesOnOri[0][$i][1];
  281. $mark['length']=strlen($matchesOnOri[0][$i][0]);
  282. $mark['type']=$matchesOnOri[0][$i][2] ? MARK_OK : MARK_ERROR;
  283. $oriMarks[]=$mark;
  284. }
  285. for ($i=count($matchesOnNat[0])-1; $i>=0; $i--) {
  286. $mark['start']=$matchesOnNat[0][$i][1];
  287. $mark['length']=strlen($matchesOnNat[0][$i][0]);
  288. $mark['type']=$matchesOnNat[0][$i][2] ? MARK_OK : MARK_WARNING;
  289. $natMarks[]=$mark;
  290. }
  291. $orig=TPo::CreateHtmlFromMarks($oriMarks, $orig);
  292. $native=TPo::CreateHtmlFromMarks($natMarks, $native);
  293. $natLine=$value["line"];
  294. if (isset($value["flag"]["fuzzy"])) {
  295. $natLine.="(Fuzzy)";
  296. }
  297. $oriLine=isset($potFile) ? $potFile->dictionary[$orig]["line"] : ":";
  298. $index=count($data)+1;
  299. $data[]=array($index, $oriLine, array('html'=>$orig), $natLine, array('html'=>$native));
  300. }
  301. }
  302. $table=new Table;
  303. $table->name="Misssing/Unexpected Accs";
  304. $table->header=array("Index", "Line", "English", "Line", "Native");
  305. $table->data=$data;
  306. $report["acc"]=$table;
  307. // wrong new line style
  308. $data=array();
  309. $regexp="/(\\\\r\\\\n|\\\\n|\\\\r)/";
  310. if (isset($potFile)) {
  311. foreach ($potFile->dictionary as $key=>$value) {
  312. $orig=$key;
  313. if (!isset($orig) || $orig=="") {
  314. continue;
  315. }
  316. $native=$this->dictionary[$key]["text"];
  317. if (!isset($native) || $native=="") {
  318. continue;
  319. }
  320. $oriMatch=preg_match_all($regexp, $orig, $matchesOnOri, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  321. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  322. if ($oriMatch || $natMatch) {
  323. $oriMarks=array();
  324. $natMarks=array();
  325. $match=true;
  326. if ($oriMatch) {
  327. $nls=$matchesOnOri[0][0][0];
  328. } else {
  329. $match=false;
  330. $nls=$matchesOnNat[0][0][0];
  331. }
  332. foreach ($matchesOnOri[0] as $value2) {
  333. $ok=($value2[0]==$nls);
  334. $mark['start']=$value2[1];
  335. $mark['length']=strlen($value2[0]);
  336. $mark['type']=$ok ? MARK_OK : MARK_ERROR;
  337. $oriMarks[]=$mark;
  338. if (!$ok) {
  339. $match=false;
  340. }
  341. }
  342. foreach ($matchesOnNat[0] as $value2) {
  343. $ok=($value2[0]==$nls);
  344. $mark['start']=$value2[1];
  345. $mark['length']=strlen($value2[0]);
  346. $mark['type']=$ok ? MARK_OK : MARK_ERROR;
  347. $natMarks[]=$mark;
  348. if (!$ok) {
  349. $match=false;
  350. }
  351. }
  352. if (!$match) {
  353. $orig=TPo::CreateHtmlFromMarks($oriMarks, $orig);
  354. $native=TPo::CreateHtmlFromMarks($natMarks, $native);
  355. $natLine=$value["line"];
  356. if (isset($value["flag"]["fuzzy"])) {
  357. $natLine .= "(Fuzzy)";
  358. }
  359. $oriLine=isset($potFile) ? $potFile->dictionary[$orig]["line"] : ":";
  360. $index=count($data)+1;
  361. $data[]=array($index, $oriLine, array('html'=>$orig), $natLine, array('html'=>$native));
  362. }
  363. }
  364. }
  365. }
  366. $table=new Table;
  367. $table->name="Wrong Newline style";
  368. $table->header=array("Index", "Line", "English", "Line", "Native");
  369. $table->data=$data;
  370. $report["nls"]=$table;
  371. // escaped characters
  372. $data=array();
  373. $regexp="/(\\\\.)/";
  374. $listDefault=array( "\\\"" => 1, "\\r" => 1, "\\n" => 1);
  375. $listCorrect=array( "\\\"" => 1, "\\r" => 1, "\\n" => 1, "\\\\" => 1, "\\");
  376. if (isset($potFile)) {
  377. foreach ($potFile->dictionary as $key=>$value) {
  378. $orig=$key;
  379. if (!isset($orig) || $orig=="") {
  380. continue;
  381. }
  382. $native=$this->dictionary[$key]["text"];
  383. if (!isset($native) || $native=="") {
  384. continue;
  385. }
  386. $oriMatch=preg_match_all($regexp, $orig, $matchesOnOri, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  387. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  388. if ($oriMatch || $natMatch) {
  389. $oriMarks=array();
  390. $natMarks=array();
  391. $match=true;
  392. // build list of escapes in eng
  393. $list=$listDefault;
  394. foreach ($matchesOnOri[0] as $value2) {
  395. $element=$value2[0];
  396. $list[$element]++;
  397. $mark['start']=$value2[1];
  398. $mark['length']=strlen($element);
  399. $mark['type']=MARK_OK;
  400. $oriMarks[]=$mark;
  401. }
  402. // mark unknown chars
  403. foreach ($matchesOnNat[0] as $value2) {
  404. $element=$value2[0];
  405. $ok=isset($list[$element]);
  406. if (!$ok) {
  407. $match=false;
  408. }
  409. $mark['start']=$value2[1];
  410. $mark['length']=strlen($element);
  411. $mark['type']=$ok ? MARK_OK : MARK_ERROR;
  412. $natMarks[]=$mark;
  413. }
  414. // if error found add line to data
  415. if (!$match) {
  416. $orig=TPo::CreateHtmlFromMarks($oriMarks, $orig);
  417. $native=TPo::CreateHtmlFromMarks($natMarks, $native);
  418. $natLine=$value["line"];
  419. if (isset($value["flag"]["fuzzy"])) {
  420. $natLine .= "(Fuzzy)";
  421. }
  422. $oriLine=isset($potFile) ? $potFile->dictionary[$orig]["line"] : ":";
  423. $index=count($data)+1;
  424. $data[]=array($index, $oriLine, array('html'=>$orig), $natLine, array('html'=>$native));
  425. }
  426. }
  427. }
  428. }
  429. $table=new Table;
  430. $table->name="Wrong Newlines";
  431. $table->header=array("Index", "Line", "English", "Line", "Native");
  432. $table->data=$data;
  433. $report["esc"]=$table;
  434. // wrong parameters
  435. $data=array();
  436. if (isset($potFile)) {
  437. //todo: check only "c-format" strings -> speed up
  438. $regexp="/%([1-9]![l]?[diouxXsS]!|[1-9]|[0-9*]*[diouxXsS]|[+\\-]*[0-9*]*?l?d|I64d|[+\\-]?[0-9]*\\.?[0-9]*f)/";
  439. foreach ($potFile->dictionary as $key=>$value) {
  440. $orig=$key;
  441. if (!isset($orig) || $orig=="") {
  442. continue;
  443. }
  444. $native=$this->dictionary[$key]["text"];
  445. if (!isset($native) || $native=="") {
  446. continue;
  447. }
  448. $engMatch=preg_match_all($regexp, $orig, $matchesOnEng, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  449. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  450. if ($engMatch || $natMatch) {
  451. $usesNumbered=false;
  452. $usesOrdered=false;
  453. $note="";
  454. $match=(count($matchesOnEng[0])==count($matchesOnNat[0]) ? true : false);
  455. foreach ($matchesOnEng[0] as $key2=>$value2) {
  456. $origParstr=$matchesOnEng[0][$key2][0];
  457. if (strpos($origParstr, "!")===false) {
  458. $usesOrdered=true;
  459. $ok=($origParstr==$matchesOnNat[0][$key2][0]);
  460. } else {
  461. $usesNumbered=true;
  462. $count=0;
  463. foreach ($matchesOnNat[0] as $rec) {
  464. if ($origParstr==$rec[0]) {
  465. $count++;
  466. }
  467. }
  468. $count2=0;
  469. foreach ($matchesOnEng[0] as $rec) {
  470. if ($origParstr==$rec[0]) {
  471. $count2++;
  472. }
  473. }
  474. $ok=($count==1) && ($count2==1);
  475. }
  476. if (!$ok) {
  477. $match=false;
  478. }
  479. $matchesOnEng[0][$key2][2]=$ok;
  480. }
  481. foreach ($matchesOnNat[0] as $key2=>$value2) {
  482. $nativeParstr=$matchesOnNat[0][$key2][0];
  483. if (strpos($nativeParstr, "!")===false) {
  484. $ok=($nativeParstr==$matchesOnEng[0][$key2][0]);
  485. } else {
  486. $count=0;
  487. foreach ($matchesOnEng[0] as $rec) {
  488. if ($nativeParstr==$rec[0]) {
  489. $count++;
  490. }
  491. }
  492. $count2=0;
  493. foreach ($matchesOnNat[0] as $rec) {
  494. if ($nativeParstr==$rec[0]) {
  495. $count2++;
  496. }
  497. }
  498. $ok=($count==1) && ($count2==1);
  499. }
  500. if (!$ok) {
  501. $match=false;
  502. }
  503. $matchesOnNat[0][$key2][2]=$ok;
  504. }
  505. if (isset($usesNumber) && $usesNumber && $UsedOrdered) {
  506. $match=false;
  507. $note="Ordered and Numbered params found!";
  508. }
  509. if (!$match) {
  510. for ($i=count($matchesOnEng[0])-1; $i>=0; $i--) {
  511. $param=$matchesOnEng[0][$i][0];
  512. $pos=$matchesOnEng[0][$i][1];
  513. $class=$matchesOnEng[0][$i][2] ? "elmark" : "elerror";
  514. $orig=substr($orig, 0, $pos)."<font class=\"$class\">".$param."</font>".substr($orig, $pos+strlen($param));
  515. }
  516. for ($i=count($matchesOnNat[0])-1; $i>=0; $i--) {
  517. $param=$matchesOnNat[0][$i][0];
  518. $pos=$matchesOnNat[0][$i][1];
  519. $class=$matchesOnNat[0][$i][2] ? "elmark" : "elerror";
  520. $native=substr($native, 0, $pos)."<font class=\"$class\">".$param."</font>".substr($native, $pos+strlen($param));
  521. }
  522. $orig=str_replace($search, $replace, $orig);
  523. $native=str_replace($search, $replace, $native);
  524. $lineN=$this->dictionary[$key]["line"];
  525. $lineE=$potFile->dictionary[$key]["line"];
  526. if (isset($this->dictionary[$key]["flag"]["fuzzy"])) {
  527. $lineN.="(Fuzzy)";
  528. }
  529. $data[]=array(count($data)+1, $lineE, $orig, $lineN, $native);
  530. }//*/
  531. }
  532. }
  533. }
  534. $table=new Table;
  535. $table->name="Wrong Params";
  536. $table->header=array("Index", "Line", "English", "Line", "Native");
  537. $table->data=$data;
  538. $report["par"]=$table;
  539. // wrong parameters
  540. /* $data=array();
  541. if (isset($potFile)) {
  542. // todo: check only "c-format" strings -> speed up
  543. $regexp="/(%(%|[1-9]|[0-9*]*[diouxXsS]|[+\\-]*[0-9*]*?l?d|I64d|[+\\-]?[0-9]*\\.?[0-9]*f|[A-Z]*%))/";
  544. $regexp="/(%(%|[1-9]|[0-9*]*[diouxXsS]|[+\\-]*[0-9*]*?l?d|I64d|[+\\-]?[0-9]*\\.?[0-9]*f|[A-Z]*%))|(\\\\[\\\\nr\"])/";
  545. foreach ($potFile->dictionary as $key=>$value) {
  546. $orig=$key;
  547. if (!isset($orig) || $orig=="") {
  548. continue;
  549. }
  550. $native=$this->dictionary[$key]["text"];
  551. if (!isset($native) || $native=="") {
  552. continue;
  553. }
  554. $engMatch=preg_match_all($regexp, $orig, $matchesOnEng, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  555. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  556. if ($engMatch || $natMatch) {
  557. $haveNewLine=false;
  558. $haveParam=false;
  559. $match=true;
  560. foreach ($matchesOnEng[3] as $key2=>$value2) {
  561. if ($value2[0]!="") {
  562. // echo "<pre>".var_dump($value2)."</pre>";
  563. $haveNewLine=true;
  564. }
  565. }
  566. foreach ($matchesOnEng[1] as $key2=>$value2) {
  567. if ($value2[0]!="") {
  568. $haveParam=true;
  569. }
  570. }
  571. if ($haveParam==false || $haveNewLine==false) { // skip translations whot dont have both param and new line
  572. continue;
  573. }
  574. foreach ($matchesOnEng[0] as $key2=>$value2) {
  575. $ok=($matchesOnEng[0][$key2][0]==$matchesOnNat[0][$key2][0]);
  576. if (!$ok) {
  577. $match=false;
  578. }
  579. $matchesOnEng[0][$key2][2]=$ok;
  580. }
  581. foreach ($matchesOnNat[0] as $key2=>$value2) {
  582. $ok=($matchesOnEng[0][$key2][0]==$matchesOnNat[0][$key2][0]);
  583. if (!$ok) {
  584. $match=false;
  585. }
  586. $matchesOnNat[0][$key2][2]=$ok;
  587. }
  588. if (!$match) {
  589. for ($i=count($matchesOnEng[0])-1; $i>=0; $i--) {
  590. $param=$matchesOnEng[0][$i][0];
  591. $pos=$matchesOnEng[0][$i][1];
  592. $class=$matchesOnEng[0][$i][2] ? "elmark" : "elerror";
  593. $orig=substr($orig, 0, $pos)."<font class=\"$class\">".$param."</font>".substr($orig, $pos+strlen($param));
  594. }
  595. for ($i=count($matchesOnNat[0])-1; $i>=0; $i--) {
  596. $param=$matchesOnNat[0][$i][0];
  597. $pos=$matchesOnNat[0][$i][1];
  598. $class=$matchesOnNat[0][$i][2] ? "elmark" : "elerror";
  599. $native=substr($native, 0, $pos)."<font class=\"$class\">".$param."</font>".substr($native, $pos+strlen($param));
  600. }
  601. $orig=str_replace($search, $replace, $orig);
  602. $native=str_replace($search, $replace, $native);
  603. $lineN=$this->dictionary[$key]["line"];
  604. $lineE=$potFile->dictionary[$key]["line"];
  605. if (isset($this->dictionary[$key]["flag"]["fuzzy"])) {
  606. $lineN.="(Fuzzy)";
  607. }
  608. $data[]=array(count($data)+1, $lineE, $orig, $lineN, $native);
  609. }
  610. }
  611. }
  612. }
  613. $table=new Table;
  614. $table->name="Wrong Params Line";
  615. $table->header=array("Index", "Line", "English", "Line", "Native");
  616. $table->data=$data;
  617. // $report["p2l"]=$table;//*/
  618. // non traslated
  619. $data=array();
  620. if (isset($potFile)) {
  621. foreach ($potFile->dictionary as $key=>$value) {
  622. $orig=$key;
  623. if (isset($this->dictionary[$key]["text"])) {
  624. $native=$this->dictionary[$key]["text"];
  625. } else {
  626. $native="";
  627. }
  628. if ($native=="") {
  629. $lineN=$this->dictionary[$key]["line"];
  630. $lineE=$potFile->dictionary[$key]["line"];
  631. $orig=str_replace($search, $replace, $orig);
  632. $data[]=array(count($data)+1, $lineE, $orig, $lineN);
  633. }
  634. }
  635. } else {
  636. echo "no pot file<br/>";
  637. }
  638. $table=new Table;
  639. $table->name="Nottranslated";
  640. $table->header=array("Index", "Line", "English", "Line");
  641. $table->data=$data;
  642. $report["unt"]=$table;
  643. // fuzzy
  644. $data=array();
  645. foreach ($this->dictionary as $key=>$value) {
  646. $orig=$key;
  647. $flags=$value["flag"];
  648. if (!isset($flags) || count($flags)<1) {
  649. continue;
  650. }
  651. if (isset($flags) && isset($flags["fuzzy"])) {
  652. $lineN=$this->dictionary[$key]["line"];
  653. $native=$value["text"];
  654. $orig=str_replace($search, $replace, $orig);
  655. $native=str_replace($search, $replace, $native);
  656. $data[]=array(count($data)+1, "-", $orig, $lineN, $native);
  657. }
  658. }
  659. $table=new Table;
  660. $table->name="Fuzzy";
  661. $table->header=array("Index", "Line", "English", "Line", "Native");
  662. $table->data=$data;
  663. $report["fuz"]=$table;
  664. $this->report=$report;
  665. return true;
  666. }
  667. function BuildReportFor($report) {
  668. switch ($report) {
  669. case "acc":
  670. $this->checkAcc();
  671. break;
  672. case "nls":
  673. $this->checkNls();
  674. break;
  675. case "spl":
  676. $this->checkSpl();
  677. break;
  678. default:
  679. $this->BuildReport();
  680. }
  681. return $this->report[$report];
  682. }
  683. // check for accelerators mishmash
  684. function checkAcc() {
  685. if (isset($this->pot)) {
  686. $potFile=$this->pot;
  687. } else {
  688. echo "no pot set<br/>\n";
  689. return;
  690. }
  691. //$lang=$this->lang;
  692. $data=array();
  693. $regexp="/(&.)/u";
  694. foreach ($this->dictionary as $orig=>$value) { // check all phrases
  695. $native=$value["text"];
  696. if (!isset($native) || $native=="" || $orig=="") { // no translation -> no test
  697. continue;
  698. }
  699. // native and eng did not match in containing of '&'
  700. if (substr_count($orig, "&")!==substr_count($native, "&")) {
  701. $oriMatch=preg_match_all($regexp, $orig, $matchesOnOri, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  702. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  703. $oriMarks=array();
  704. $natMarks=array();
  705. for ($i=count($matchesOnOri[0])-1; $i>=0; $i--) {
  706. $mark['start']=$matchesOnOri[0][$i][1];
  707. $mark['length']=strlen($matchesOnOri[0][$i][0]);
  708. $mark['type']=$matchesOnOri[0][$i][2] ? MARK_OK : MARK_ERROR;
  709. $oriMarks[]=$mark;
  710. }
  711. for ($i=count($matchesOnNat[0])-1; $i>=0; $i--) {
  712. $mark['start']=$matchesOnNat[0][$i][1];
  713. $mark['length']=strlen($matchesOnNat[0][$i][0]);
  714. $mark['type']=$matchesOnNat[0][$i][2] ? MARK_OK : MARK_WARNING;
  715. $natMarks[]=$mark;
  716. }
  717. $orig=TPo::CreateHtmlFromMarks($oriMarks, $orig);
  718. $native=TPo::CreateHtmlFromMarks($natMarks, $native);
  719. $natLine=$value["line"];
  720. if (isset($value["flag"]["fuzzy"])) {
  721. $natLine.="(Fuzzy)";
  722. }
  723. $oriLine=isset($potFile) ? $potFile->dictionary[$orig]["line"] : ":";
  724. $index=count($data)+1;
  725. $data[]=array($index, $oriLine, array('html'=>$orig), $natLine, array('html'=>$native));
  726. }
  727. }
  728. $table=new Table;
  729. $table->name="Misssing/Unexpected Accs";
  730. // $table->description="<p>Testing spelling of translation. We use ASPELL dictionaris for PSPELL. <b><i>in development</i></b> </p>";
  731. $table->header=array("Index", "Line", "English", "Line", "Native");
  732. $table->data=$data;
  733. $this->report["acc"]=$table;
  734. // $this->report["spl"]["error"]="Dictionary not found.";
  735. // $this->report["spl"]["error"]="Internal error";
  736. }
  737. /// Check new line style - original and translated NLS should match
  738. function checkNls() {
  739. }
  740. // check for wrong spelling
  741. function checkSpl() {
  742. if (isset($this->pot)) {
  743. $potFile=$this->pot;
  744. } else {
  745. return;
  746. }
  747. $lang=$this->lang;
  748. $data=array();
  749. if (false && $this->lang) {
  750. $suggestEnabled=$this->lang != "hu";
  751. $suggestEnabled=$suggestEnabled && $this->lang != "de";
  752. echo "<!--";
  753. $pspell_link = pspell_new($this->lang, "", "", "utf-8", PSPELL_FAST);
  754. $pspell_links=array();
  755. echo "LLLLL";
  756. foreach ($this->spellDictFiles as $spellDictFile) {
  757. echo "<br />\n".$spellDictFile."<br />\n";
  758. $pspell_link_local = pspell_new_personal($spellDictFiles."1", $this->lang, "", "", "utf-8");
  759. if ($pspell_link_local) {
  760. $word="Aktionsskript";
  761. // $word="Aktionsskript";
  762. echo "\n$pspell_link_local: $spellDictFile : $word =";
  763. echo pspell_check($pspell_link_local, $word);
  764. $word="COM";
  765. echo "\n$pspell_link_local: $spellDictFile : $word =";
  766. echo pspell_check($pspell_link_local, $word);
  767. $word="BASE";
  768. echo "\n$pspell_link_local: $spellDictFile : $word =";
  769. echo pspell_check($pspell_link_local, $word);
  770. $word="Diff";
  771. echo "\n$pspell_link_local: $spellDictFile : $word =";
  772. echo pspell_check($pspell_link_local, $word);
  773. $word="BABE";
  774. echo "\n$pspell_link_local: $spellDictFile : $word =";
  775. echo pspell_check($pspell_link_local, $word);
  776. $pspell_links[] = $pspell_link_local;
  777. }
  778. }
  779. echo "-->";
  780. $regexp="/[A-Za-z0-9\\x{80}-\\x{ffff}]+/u";
  781. $regexp2="/^[A-Za-z]*$/";
  782. $regexp3="/\\b$word\\b/i";
  783. $preprocessSearch=array("&", "<", ">", "\\n", "\\r", "\\t", "%s", "%d", "%ld", "/");
  784. $preprocessReplace=array("", " < ", " > ", " \\n ", " \\r ", " \\t ", " %s ", " %d ", " %ld ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ");
  785. $postprocessSearch=array("\\n");
  786. $postprocessReplace=array("\\n<br />");
  787. if ($pspell_link) {
  788. foreach ($potFile->dictionary as $key=>$value) {
  789. $orig=$key;
  790. if (!isset($orig) || $orig=="") {
  791. continue;
  792. }
  793. $native=$this->dictionary[$key]["text"];
  794. if (!isset($native) || $native=="") {
  795. continue;
  796. }
  797. $native=str_replace($preprocessSearch, $preprocessReplace, $native);
  798. $orig=str_replace($preprocessSearch, $preprocessReplace, $orig);
  799. $natMatch=preg_match_all($regexp, $native, $matchesOnNat, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE);
  800. // $string=$native;
  801. if ($natMatch) {
  802. $match=true;
  803. for ($i = 0; $i < count($matchesOnNat[0]); $i++) {
  804. $word=$matchesOnNat[0][$i][0];
  805. // if (!preg_match($regexp2, $word)) {
  806. // continue;
  807. // }
  808. $wordOk=pspell_check($pspell_link, $word);
  809. if (!$wordOk) {
  810. // echo "<b>$word</b><br />";
  811. foreach ($pspell_links as $pspell_link_local) {
  812. $wordOk=pspell_check($pspell_link_local, $word);
  813. // echo "<!--$pspell_link_local, $word = $wordOk --!>\n";
  814. // echo "<!-- DUMP:";
  815. // var_dump($pspell_link_local);
  816. // echo " --!>\n";
  817. // echo "<!-- SET:".isset($pspell_link_local)." --!>\n";
  818. if ($wordOk) {
  819. echo "<!--OK --!>\n";
  820. break;
  821. }
  822. }
  823. }
  824. if (!$wordOk) {
  825. if ($suggestEnabled) {
  826. $suggestArr=pspell_suggest($pspell_link, $word);
  827. $suggestStr=implode(", ", $suggestArr);
  828. $matchesOnNat[0][$i]['sugestion']='suggest:'.$suggestStr;
  829. }
  830. // if (strpos($orig, $word)!==false) {
  831. // $regexp3="/\\b".$word."[$.^A-Za-z0-9]/i";
  832. $regexp3="/\\b".$word."\\b/i";
  833. if (preg_match($regexp3, $orig)) {
  834. $mark=MARK_WARNING;
  835. } else {
  836. $mark=MARK_ERROR;
  837. $match=false;
  838. }
  839. } else {
  840. $mark=MARK_OK;
  841. }
  842. $matchesOnNat[0][$i][2]=$mark;
  843. }
  844. if (!$match) {
  845. for ($i=count($matchesOnNat[0])-1; $i>=0; $i--) {
  846. if (!isset($matchesOnNat[0][$i][2])) {
  847. continue;
  848. }
  849. $param=$matchesOnNat[0][$i][0];
  850. $pos=$matchesOnNat[0][$i][1];
  851. if ($param=="n" && $pos && $native[$pos-1]=="\\") {
  852. continue;
  853. }
  854. switch ($matchesOnNat[0][$i][2]) {
  855. case MARK_OK:
  856. $class= "elmark";
  857. break;
  858. case MARK_ERROR:
  859. $class="elerror";
  860. break;
  861. case MARK_WARNING:
  862. $class="elwarning";
  863. break;
  864. }
  865. $replaceStr="<font class=\"$class\">".$param."</font>";
  866. if (isset($matchesOnNat[0][$i]['sugestion'])) {
  867. $replaceStr="<acronym title=\"".$matchesOnNat[0][$i]['sugestion']."\">$replaceStr</acronym>";
  868. }
  869. $native=substr($native, 0, $pos).$replaceStr.substr($native, $pos+strlen($param));
  870. }
  871. $orig=str_replace($postprocessSearch, $postprocessReplace, $orig);
  872. $native=str_replace($postprocessSearch, $postprocessReplace, $native);
  873. $lineN=$this->dictionary[$key]["line"];
  874. $lineE=$potFile->dictionary[$key]["line"];
  875. if (isset($this->dictionary[$key]["flag"]["fuzzy"])) {
  876. $lineN.="(Fuzzy)";
  877. }
  878. $data[]=array(count($data)+1, $lineE, $orig, $lineN, $native);
  879. }
  880. flush();
  881. }
  882. }
  883. pspell_clear_session($pspell_link);
  884. $table=new Table;
  885. $table->name="Spell check";
  886. $table->description="<p>Testing spelling of translation. We use ASPELL dictionaris for PSPELL. <b><i>in development</i></b> </p>";
  887. $table->header=array("Index", "Line", "English", "Line", "Native");
  888. $table->data=$data;
  889. $this->report["spl"]=$table;
  890. } else {
  891. $this->report["spl"]["error"]="Dictionary not found.";
  892. }
  893. } else {
  894. $this->report["spl"]["error"]="Internal error";
  895. }
  896. }
  897. function CreateHtmlFromMarks($marks, $string, $debug=0) {
  898. // mark params:
  899. // start, end:
  900. // class: error, warning, mark, none
  901. // suggestion:
  902. // set class from mark for all makrs
  903. foreach ($marks as &$mark) {
  904. if (!isset($mark['class'])) {
  905. switch ($mark['type']) {
  906. default:
  907. case MARK_OK:
  908. $class="elmark";
  909. break;
  910. case MARK_ERROR:
  911. $class="elerror";
  912. break;
  913. case MARK_WARNING:
  914. $class="elwarning";
  915. break;
  916. }
  917. $mark['class']=$class;
  918. }
  919. if (!isset($mark['end'])) {
  920. $mark['end']=$mark['start']+$mark['length'];
  921. }
  922. }
  923. sort($marks);
  924. // sort marks by start
  925. $marksStartSorted=$marks;
  926. usort($marksStartSorted, CompareStart);
  927. // $marksEndSorted=$marks;
  928. // usort($marksEndSorted, CompareEnd);
  929. // check if properly nested
  930. // TODO: check nesting
  931. // create part breaks string
  932. $breaks=array();
  933. unset($mark);
  934. foreach ($marksStartSorted as $mark) {
  935. $start=$mark['start'];
  936. $end=$mark['end'];
  937. $breaks[$start] = $breaks[$start]."<font class=\"".$mark['class']."\">";
  938. $breaks[$end] = "</font>".$breaks[$end];
  939. }
  940. // go over parts and create final string
  941. $position=0;
  942. $result="";
  943. foreach ($breaks as $pos=>$break) {
  944. $substring=substr($string, $position, $pos-$position);
  945. if (isset($postprocessSearch) && isset($postprocessReplace)) {
  946. $substring=str_replace($postprocessSearch, $postprocessReplace, $substring);
  947. }
  948. $substring=htmlspecialchars($substring);
  949. $result .= $substring . $break;
  950. $position=$pos;
  951. }
  952. $substring=substr($string, $position);
  953. // $substring=str_replace($postprocessSearch, $postprocessReplace, $substring);
  954. $substring=htmlspecialchars($substring);
  955. $result .= $substring;
  956. // recode to html
  957. if ($debug) {
  958. echo ($result);
  959. }
  960. return ConvertCstyleNewLineToHtmlstyle($result);
  961. }
  962. function GetErrorTypes() {
  963. return array_keys($this->report);
  964. }
  965. function GetErrorCount($name) {
  966. if (isset($this->report[$name])) {
  967. $count=$this->report[$name];
  968. } else {
  969. $count=$this->BuildReportFor($name);
  970. }
  971. if (!isset($count)) {
  972. return false;
  973. }
  974. if (is_a($count, "Table")) {
  975. $count=count($count->data);
  976. }
  977. if (is_array($count)) {
  978. $count=count($count);
  979. }
  980. return $count;
  981. }
  982. function save($poFileName="") {
  983. if ($poFileName=="") { // export to browser
  984. } else { // export to file
  985. }
  986. }
  987. function translate($str) {
  988. return $this->dictionary[$str]["text"];
  989. }
  990. // update from .pot file
  991. function update($poFileName){
  992. }
  993. function addTranslate($origText, $nativeText){
  994. }
  995. function getTranslate($origText){
  996. }
  997. function getAllOrigs(){
  998. return $this->dictionary;
  999. }
  1000. function getProgress(){
  1001. BuildReport();
  1002. return $this->report();
  1003. return array(
  1004. "translate" => $this->report["unt"]);
  1005. }
  1006. function getStringCount(){
  1007. return count($this->dictionary);
  1008. }
  1009. function printReport($potFile=NULL) {
  1010. $this->BuildReport($potFile);
  1011. if (isset($this->report["param"])) {
  1012. $this->report["param"]->output();
  1013. } else {
  1014. }
  1015. if (!isset($lang)) {
  1016. $lang="";
  1017. }
  1018. if ($this->report["type"]=="pot") {
  1019. echo "<a name=\"nls\"></a><a name=\"nls$lang\"></a><h3>Differences in new line style within one string</h3>\n";
  1020. // echo "<p>
  1021. // </p>\n";
  1022. $table=$this->report["nls"];
  1023. if (isset($table)) {
  1024. if (count($table->data)) { // table exists and has data
  1025. $table->output();
  1026. echo "<sup>Note: Line numbers are as in commited file, it may differ when you update to use newer .pot, also edited multiline messages may shift line position.</sup>\n";
  1027. echo "<p>Total:".count($table->data)."</p>\n";
  1028. } else {
  1029. echo "<p><b>PASS</b></p>\n";
  1030. }
  1031. } else {
  1032. echo "<p><i>Internal error</i></p>";
  1033. }
  1034. echo "<a name=\"esc\"></a><a name=\"esc$lang\"></a><h3>Escaped chars</h3>\n";
  1035. // echo "<p>
  1036. // </p>\n";
  1037. $table=$this->report["esc"];
  1038. if (isset($table)) {
  1039. if (count($table->data)) { // table exists and has data
  1040. $table->output();
  1041. echo "<sup>Note: Line numbers are as in commited file, it may differ when you update to use newer .pot, also edited multiline messages may shift line position.</sup>\n";
  1042. echo "<p>Total:".count($table->data)."</p>\n";
  1043. } else {
  1044. echo "<p><b>PASS</b></p>\n";
  1045. }
  1046. } else {
  1047. echo "<p><i>Internal error</i></p>";
  1048. }
  1049. return;
  1050. }
  1051. // clean potFile if unusable
  1052. // todo: check class
  1053. if ($potFile==NULL) {
  1054. unset($potFile);
  1055. }
  1056. $lang=$this->lang;
  1057. echo "<a name=\"par\"></a><a name=\"par$lang\"></a><h3>Parameter strings test</h3>\n";
  1058. echo "<p>This test is necessary to pass or you can expect crashing of TSVN - specially true when you use
  1059. longer type as is in English like %s instead of %d, %ld instead of %d, etc. Also having more parameters lead to crash TSVN.
  1060. When TSVN not crash, the information is still wrong. For example number instead of text.</p>\n";
  1061. $table=$this->report["par"];
  1062. if (isset($table)) {
  1063. if (count($table->data)) { // table exists and has data
  1064. $table->output();
  1065. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1066. echo "<p>Total:".count($table->data)."</p>\n";
  1067. } else {
  1068. echo "<p><b>PASS</b></p>\n";
  1069. }
  1070. } else {
  1071. echo "<p><i>Internal error</i></p>";
  1072. }
  1073. /* echo "<a name=\"par$lang\"></a><h3>Parameters to lines test</h3>\n";
  1074. echo "<p>If you pass previous test this one is only for ... </p>\n";
  1075. $table=$this->report["p2l"];
  1076. if (isset($table)) {
  1077. if (count($table->data)) { // table exists and has data
  1078. $table->output();
  1079. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1080. echo "<p>Total:".count($table->data)."</p>\n";
  1081. } else {
  1082. echo "<p><b>PASS</b></p>\n";
  1083. }
  1084. } else {
  1085. echo "<p><i>Internal error</i></p>";
  1086. }//*/
  1087. echo "<a name=\"acc\"></a><a name=\"acc$lang\"></a><h3>Missing/Unexpected Key Accelerator test</h3>\n";
  1088. echo "<p>This is accessibility test. Passing this test is recommended.
  1089. If you are interesting in more details about accelerator key overlapping I may enable such test for your language, but in fact there not too much to do against it.
  1090. According <a href=\"http://tortoisesvn.net/user/2\">Luebbe</a> and <a href=\"http://tortoisesvn.net/user/3\">Stefan</a>
  1091. there is no problem about it you just have to use accelerator more time to select element and then use enter or space for activate button.
  1092. </p>\n";
  1093. $table=$this->report["acc"];
  1094. if (isset($table)) {
  1095. if (count($table->data)) { // table exists and has data
  1096. $table->output();
  1097. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1098. echo "<p>Total:".count($table->data)."</p>\n";
  1099. } else {
  1100. echo "<p><b>PASS</b></p>\n";
  1101. }
  1102. } else {
  1103. echo "<p><i>Internal error</i></p>";
  1104. }
  1105. /* echo "<a name=\"nls\"></a><a name=\"nls$lang\"></a><h3>Differences in new line style</h3>\n";
  1106. echo "<p>This tests if new line style from pot match localized new line style. <b>This test may have false positives when English text has new line style inconsistence.</b>
  1107. Using more lines for Native when English use just one is also alowed for most of translation even here reported.
  1108. </p>\n";
  1109. $table=$this->report["nls"];
  1110. if (isset($table)) {
  1111. if (count($table->data)) { // table exists and has data
  1112. $table->output();
  1113. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1114. echo "<p>Total:".count($table->data)."</p>\n";
  1115. } else {
  1116. echo "<p><b>PASS</b></p>\n";
  1117. }
  1118. } else {
  1119. echo "<p><i>Internal error</i></p>";
  1120. }//*/
  1121. echo "<a name=\"unt\"></a><a name=\"unt$lang\"></a><h3>Not translated strings test</h3>\n";
  1122. echo "<p>This tests if all strings has been translated. Translated mean that there in native string set. If English and native are same it is not marked as not translated, this just can happen.</p>\n";
  1123. $table=$this->report["unt"];
  1124. if (isset($table)) {
  1125. if (count($table->data)) { // table exists and has data
  1126. $table->output();
  1127. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1128. echo "<p>Total:".count($table->data)."</p>\n";
  1129. } else {
  1130. echo "<p><b>PASS</b></p>\n";
  1131. }
  1132. } else {
  1133. echo "<p><i>Internal error</i></p>";
  1134. }
  1135. echo "<a name=\"fuz\" /><a name=\"fuz$lang\" /><h3>Fuzzy mark test</h3>\n";
  1136. echo "<p>String marked as fuzzy is not in final shape.</p>\n";
  1137. $table=$this->report["fuz"];
  1138. if (isset($table)) {
  1139. if (count($table->data)) { // table exists and has data
  1140. $table->output();
  1141. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1142. echo "<p>Total:".count($table->data)."</p>\n";
  1143. } else {
  1144. echo "<p><b>PASS</b></p>\n";
  1145. }
  1146. } else {
  1147. echo "<p><i>Internal error or not implemented</i></p>";
  1148. }
  1149. echo "<a name=\"esc\" /><a name=\"esc$lang\" /><h3>Escaped chars test</h3>\n";
  1150. echo "<p>This test check if all escaped chars are known and its using match with English. Even you get red here it may be legal for your language.<br/>This test is in developing now. Ignored are: \\r \\n (wee new line style test) and \\\".</p>\n";
  1151. $table=$this->report["esc"];
  1152. if (isset($table)) {
  1153. if (count($table->data)) { // table exists and has data
  1154. $table->output();
  1155. echo "<sup>Note: Line numbers are as in committed file, it may differ when you update to use newer .pot, also edited multi line messages may shift line position.</sup>\n";
  1156. echo "<p>Total:".count($table->data)."</p>\n";
  1157. } else {
  1158. echo "<p><b>PASS</b></p>\n";
  1159. }
  1160. } else {
  1161. echo "<p><i>Internal error or not implemented</i></p>";
  1162. }
  1163. $testName="spl";
  1164. $table=$this->report[$

Large files files are truncated, but you can click here to view the full file