PageRenderTime 25ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/fam2po.php

https://github.com/CircleCode/Dynacase-tutorial-zoo
PHP | 294 lines | 261 code | 22 blank | 11 comment | 15 complexity | 905ae454d7494c2f2750f43733c38430 MD5 | raw file
  1. <?php
  2. /**
  3. * extract strings from family file (csv or ods) and generate associated po catalog
  4. *
  5. * @author Anakeen
  6. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License
  7. * @package DCP
  8. * @subpackage devtools
  9. */
  10. define ("SEPCHAR", ';');
  11. define ("ALTSEPCHAR", ' --- ');
  12. $inrow = false;
  13. $incell = false;
  14. $nrow = 0;
  15. $ncol = 0;
  16. $rows = array();
  17. $colrepeat = 0;
  18. for ($i = 1; $i < count($argv); $i++) {
  19. debugPrompt("Processing file " . $argv[$i]);
  20. $pf = pathinfo($argv[$i]);
  21. if (file_exists($argv[$i])) {
  22. if (isset($pf['extension'])) {
  23. switch ($pf['extension']) {
  24. case 'ods':
  25. debugPrompt(" --- csv extraction");
  26. $csvfile = $argv[$i] . ".csv";
  27. ods2csv($argv[$i], $csvfile);
  28. if ($csvfile) {
  29. makePo($csvfile);
  30. }
  31. unlink($csvfile);
  32. break;
  33. case 'csv':
  34. makePo($argv[$i]);
  35. break;
  36. default:
  37. debugPrompt($argv[$i] . " has an unknown extension, skipping it.");
  38. }
  39. } else {
  40. debugPrompt($argv[$i] . " has no extension, skipping it.");
  41. }
  42. } else {
  43. debugPrompt("Can't access file " . $argv[$i]);
  44. }
  45. }
  46. function startElement($parser, $name, $attrs)
  47. {
  48. global $rows, $nrow, $inrow, $incell, $ncol, $colrepeat, $celldata;
  49. if ($name == "TABLE:TABLE-ROW") {
  50. $inrow = true;
  51. if (isset($rows[$nrow])) {
  52. // fill empty cells
  53. $idx = 0;
  54. foreach ($rows[$nrow] as $k=> $v) {
  55. if (!isset($rows[$nrow][$idx])) $rows[$nrow][$idx] = '';
  56. $idx++;
  57. }
  58. ksort($rows[$nrow], SORT_NUMERIC);
  59. }
  60. $nrow++;
  61. $ncol = 0;
  62. $rows[$nrow] = array();
  63. }
  64. if ($name == "TABLE:TABLE-CELL") {
  65. $incell = true;
  66. $celldata = "";
  67. if ($attrs["TABLE:NUMBER-COLUMNS-REPEATED"]) {
  68. $colrepeat = intval($attrs["TABLE:NUMBER-COLUMNS-REPEATED"]);
  69. }
  70. }
  71. if ($name == "TEXT:P") {
  72. if (strlen($rows[$nrow][$ncol]) > 0) $rows[$nrow][$ncol] .= '\n';
  73. }
  74. }
  75. function endElement($parser, $name)
  76. {
  77. global $rows, $nrow, $inrow, $incell, $ncol, $colrepeat, $celldata;
  78. if ($name == "TABLE:TABLE-ROW") {
  79. // Remove trailing empty cells
  80. $i = $ncol - 1;
  81. while ($i >= 0) {
  82. if (strlen($rows[$nrow][$i]) > 0) {
  83. break;
  84. }
  85. $i--;
  86. }
  87. array_splice($rows[$nrow], $i + 1);
  88. $inrow = false;
  89. }
  90. if ($name == "TABLE:TABLE-CELL") {
  91. $incell = false;
  92. $rows[$nrow][$ncol] = $celldata;
  93. if ($colrepeat > 1) {
  94. $rval = $rows[$nrow][$ncol];
  95. for ($i = 1; $i < $colrepeat; $i++) {
  96. $ncol++;
  97. $rows[$nrow][$ncol] = $rval;
  98. }
  99. }
  100. //$ncol+=intval($attrs["TABLE:NUMBER-COLUMNS-REPEATED"]);
  101. $ncol++;
  102. $colrepeat = 0;
  103. }
  104. }
  105. function characterData($parser, $data)
  106. {
  107. global $rows, $nrow, $inrow, $incell, $ncol, $celldata;
  108. if ($inrow && $incell) {
  109. $celldata .= preg_replace(
  110. '/^\s*[\r\n]\s*$/ms', '', str_replace(SEPCHAR, ALTSEPCHAR, $data)
  111. );
  112. }
  113. // print $data. "- ";
  114. }
  115. function xmlcontent2csv($xmlcontent, &$fcsv)
  116. {
  117. $err = "";
  118. global $rows;
  119. $xml_parser = xml_parser_create();
  120. // Utilisons la gestion de casse, de maniere a etre surs de trouver la balise dans $map_array
  121. xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
  122. xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0);
  123. xml_set_element_handler($xml_parser, "startElement", "endElement");
  124. xml_set_character_data_handler($xml_parser, "characterData");
  125. if (!xml_parse($xml_parser, $xmlcontent)) {
  126. $err = sprintf("error XML : %s line %d",
  127. xml_error_string(xml_get_error_code($xml_parser)),
  128. xml_get_current_line_number($xml_parser)
  129. );
  130. } else {
  131. xml_parser_free($xml_parser);
  132. //print_r($rows);
  133. foreach ($rows as $k=> $row) {
  134. $fcsv .= implode(SEPCHAR, $row) . "\n";
  135. }
  136. }
  137. return $err;
  138. }
  139. function ods2content($odsfile, &$content)
  140. {
  141. $err = "";
  142. if (file_exists($odsfile)) {
  143. $cibledir = uniqid("/var/tmp/ods");
  144. $cmd = sprintf("unzip -j %s content.xml -d %s >/dev/null", $odsfile, $cibledir);
  145. system($cmd);
  146. $contentxml = $cibledir . "/content.xml";
  147. if (file_exists($contentxml)) {
  148. $content = file_get_contents($contentxml);
  149. unlink($contentxml);
  150. }
  151. rmdir($cibledir);
  152. } else {
  153. $err = "file $odsfile not found";
  154. }
  155. return $err;
  156. }
  157. function ods2csv($odsfile, $csvfile)
  158. {
  159. if ($odsfile == "") {
  160. print "odsfile needed :usage --odsfile=<ods file> [--csvfile=<csv file output>]\n";
  161. return;
  162. }
  163. $err = ods2content($odsfile, $content);
  164. if ($err == "") {
  165. $err = xmlcontent2csv($content, $csv);
  166. if ($err == "") {
  167. if ($csvfile) {
  168. $n = file_put_contents($csvfile, $csv);
  169. //if ($n > 0) print sprintf(_("csv file <%s> wroted")."\n",$csvfile);
  170. //else $err=sprintf(_("cannot write %s"),$csvfile);
  171. } else print $csv;
  172. }
  173. }
  174. if ($err != "") print "ERROR:$err\n";
  175. }
  176. function debugPrompt($msg)
  177. {
  178. error_log("fam2po: " . $msg);
  179. }
  180. function makePo($fi)
  181. {
  182. $fdoc = fopen($fi, "r");
  183. if (!$fdoc)
  184. debugPrompt("fam2po: Can't access file [$fi]");
  185. $nline = -1;
  186. $famname = "*******";
  187. $famtitle = "";
  188. while (!feof($fdoc)) {
  189. $nline++;
  190. $buffer = rtrim(fgets($fdoc, 16384));
  191. $data = explode(";", $buffer);
  192. // if (isUTF8($data)) $data=array_map("utf8_decode",$data);
  193. $num = count($data);
  194. if ($num < 1) continue;
  195. $data[0] = trim($data[0]);
  196. switch ($data[0]) {
  197. case "BEGIN":
  198. $famname = $data[5];
  199. $famtitle = $data[2];
  200. echo "#, fuzzy, ($fi::$nline)\n";
  201. echo "msgid \"" . $famname . "#title\"\n";
  202. echo "msgstr \"" . $famtitle . "\"\n\n";
  203. break;
  204. case "END":
  205. $famname = "*******";
  206. $famtitle = "";
  207. break;
  208. case "ATTR":
  209. case "MODATTR":
  210. case "PARAM":
  211. case "OPTION":
  212. echo "#. " . $data[3] . "\n";
  213. echo "#, fuzzy, ($fi::$nline)\n";
  214. echo "msgid \"" . $famname . "#" . strtolower($data[1]) . "\"\n";
  215. echo "msgstr \"" . $data[3] . "\"\n\n";
  216. // Enum ----------------------------------------------
  217. if ($data[6] == "enum" || $data[6] == "enumlist") {
  218. $d = str_replace('\,', '\#', $data[12]);
  219. $tenum = explode(",", $d);
  220. foreach ($tenum as $ke=> $ve) {
  221. $d = str_replace('\#', ',', $ve);
  222. $ee = explode("|", $d);
  223. echo "#. " . $ee[1] . "\n";
  224. echo "#, fuzzy, ($fi::$nline)\n";
  225. echo "msgid \"" . $famname . "#" . strtolower($data[1]) . "#" . (str_replace('\\', '', $ee[0])) . "\"\n";
  226. echo "msgstr \"" . (str_replace('\\', '', $ee[1])) . "\"\n\n";
  227. }
  228. }
  229. // Options ----------------------------------------------
  230. $topt = explode("|", $data[15]);
  231. foreach ($topt as $ko=> $vo) {
  232. $oo = explode("=", $vo);
  233. switch (strtolower($oo[0])) {
  234. case "elabel" :
  235. case "ititle" :
  236. case "submenu" :
  237. case "ltitle" :
  238. case "eltitle" :
  239. case "elsymbol" :
  240. case "showempty" :
  241. echo "#. " . $oo[1] . "\n";
  242. echo "#, fuzzy, ($fi::$nline)\n";
  243. echo "msgid \"" . $famname . "#" . strtolower($data[1]) . "#" . strtolower($oo[0]) . "\"\n";
  244. echo "msgstr \"" . $oo[1] . "\"\n\n";
  245. break;
  246. }
  247. }
  248. break;
  249. }
  250. }
  251. }
  252. ?>