generate_gettext_files.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Generate Gettext-format language files from the existing language files.
  5. *
  6. * @author Yannick Warnier <yannick.warnier@beeznest.com>
  7. */
  8. die(); //remove before execution
  9. require_once __DIR__.'/../../../main/inc/global.inc.php';
  10. ini_set('memory_limit', '600M');
  11. $partial = false; //if set to true, do not add empty strings to .po files
  12. $destinationDir = '/tmp/gettext'; //where to put the generated files
  13. /**
  14. * Get list of languages.
  15. */
  16. $langPath = api_get_path(SYS_LANG_PATH);
  17. $languagesListFull = scandir($langPath);
  18. $languagesList = [];
  19. foreach ($languagesListFull as $language) {
  20. if (substr($language, 0, 1) === '.') {
  21. continue;
  22. } elseif ($language === 'index.html') {
  23. continue;
  24. } else {
  25. $languagesList[] = $language;
  26. }
  27. }
  28. /**
  29. * Get English language terms (the main source of terms)
  30. */
  31. $path = $langPath.'english';
  32. $terms = $originalTerms = [];
  33. $file = $path.'/trad4all.inc.php';
  34. if (is_file($file)) {
  35. $originalTerms = SubLanguageManager::get_all_language_variable_in_file($file, true);
  36. }
  37. foreach ($originalTerms as $index => $translation) {
  38. if (!isset($terms[$index])) {
  39. $terms[$index] = trim(rtrim($translation, ';'), '"');
  40. }
  41. }
  42. // get only the array keys (the language variables defined in language files)
  43. //$definedTerms = array_flip(array_keys($terms));
  44. echo count($terms)." terms were found in language files".PHP_EOL;
  45. // make sure we have an ISO 639-1 (or-2 if no -1) to give the gettext file
  46. $langToIso639v1 = [
  47. 'arabic' => 'ar',
  48. 'asturian' => 'ast_ES',
  49. 'basque' => 'eu_ES',
  50. 'bengali' => 'bn_BD',
  51. 'bosnian' => 'bs_BA',
  52. 'brazilian' => 'pt_BR',
  53. 'bulgarian' => 'bg_BG',
  54. 'catalan' => 'ca',
  55. 'croatian' => 'hr_HR',
  56. 'czech' => 'cs_CZ',
  57. 'danish' => 'da',
  58. 'dari' => 'fa_AF',
  59. 'dutch' => 'nl',
  60. 'english' => 'en_US',
  61. 'estonian' => 'et',
  62. 'esperanto' => 'eo',
  63. 'faroese' => 'fo_FO',
  64. 'finnish' => 'fi_FI',
  65. 'french' => 'fr_FR',
  66. 'friulian' => 'fur',
  67. 'galician' => 'gl',
  68. 'georgian' => 'ka_GE',
  69. 'german' => 'de',
  70. 'greek' => 'el',
  71. 'hebrew' => 'he_IL',
  72. 'hindi' => 'hi',
  73. 'hungarian' => 'hu_HU',
  74. 'indonesian' => 'id_ID',
  75. 'italian' => 'it',
  76. 'japanese' => 'ja',
  77. 'korean' => 'ko_KR',
  78. 'latvian' => 'lv_LV',
  79. 'lithuanian' => 'lt_LT',
  80. 'macedonian' => 'mk_MK',
  81. 'malay' => 'ms_MY',
  82. 'norwegian' => 'nn_NO',
  83. 'occitan' => 'oc',
  84. 'pashto' => 'ps',
  85. 'persian' => 'fa_IR',
  86. 'polish' => 'pl_PL',
  87. 'portuguese' => 'pt_PT',
  88. 'quechua_cusco' => 'quz_PE',
  89. 'romanian' => 'ro_RO',
  90. 'russian' => 'ru_RU',
  91. 'serbian' => 'sr_RS',
  92. 'simpl_chinese' => 'zh_CN',
  93. 'slovak' => 'sk_SK',
  94. 'slovenian' => 'sl_SI',
  95. 'somali' => 'so_SO',
  96. 'spanish' => 'es',
  97. 'spanish_latin' => 'es_MX',
  98. 'swahili' => 'sw_KE',
  99. 'swedish' => 'sv_SE',
  100. 'tagalog' => 'tl_PH',
  101. 'thai' => 'th',
  102. 'tibetan' => 'bo_CN',
  103. 'trad_chinese' => 'zh_TW',
  104. 'turkish' => 'tr',
  105. 'ukrainian' => 'uk_UA',
  106. 'vietnamese' => 'vi_VN',
  107. 'xhosa' => 'xh_ZA',
  108. 'yoruba' => 'yo_NG',
  109. ];
  110. $langToPOFilename = [
  111. 'arabic' => 'ar',
  112. 'asturian' => 'ast_ES',
  113. 'basque' => 'eu_ES',
  114. 'bengali' => 'bn',
  115. 'bosnian' => 'bs',
  116. 'brazilian' => 'pt_BR',
  117. 'bulgarian' => 'bg',
  118. 'catalan' => 'ca_ES',
  119. 'croatian' => 'hr',
  120. 'czech' => 'cs',
  121. 'danish' => 'da',
  122. 'dari' => 'fa_AF',
  123. 'dutch' => 'nl',
  124. 'english' => 'en',
  125. 'estonian' => 'et',
  126. 'esperanto' => 'eo',
  127. 'faroese' => 'fo',
  128. 'finnish' => 'fi',
  129. 'french' => 'fr',
  130. 'friulian' => 'fur_IT',
  131. 'galician' => 'gl_ES',
  132. 'georgian' => 'ka',
  133. 'german' => 'de',
  134. 'greek' => 'el',
  135. 'hebrew' => 'he',
  136. 'hindi' => 'hi',
  137. 'hungarian' => 'hu',
  138. 'indonesian' => 'id',
  139. 'italian' => 'it',
  140. 'japanese' => 'ja',
  141. 'korean' => 'ko',
  142. 'latvian' => 'lv',
  143. 'lithuanian' => 'lt',
  144. 'macedonian' => 'mk',
  145. 'malay' => 'ms',
  146. 'norwegian' => 'nn',
  147. 'occitan' => 'oc_FR',
  148. 'pashto' => 'ps',
  149. 'persian' => 'fa',
  150. 'polish' => 'pl',
  151. 'portuguese' => 'pt',
  152. 'quechua_cusco' => 'qu',
  153. 'romanian' => 'ro',
  154. 'russian' => 'ru',
  155. 'serbian' => 'sr',
  156. 'simpl_chinese' => 'zh_CN',
  157. 'slovak' => 'sk',
  158. 'slovenian' => 'sl',
  159. 'somali' => 'so',
  160. 'spanish' => 'es',
  161. 'spanish_latin' => 'es_MX',
  162. 'swahili' => 'sw',
  163. 'swedish' => 'sv',
  164. 'tagalog' => 'tl',
  165. 'thai' => 'th',
  166. 'tibetan' => 'bo',
  167. 'trad_chinese' => 'zh_TW',
  168. 'turkish' => 'tr',
  169. 'ukrainian' => 'uk',
  170. 'vietnamese' => 'vi',
  171. 'xhosa' => 'xh',
  172. 'yoruba' => 'yo',
  173. ];
  174. /**
  175. * Generate .pot and .po files
  176. * See https://webtranslateit.com/en/docs/file_formats/gettext_po/
  177. */
  178. $baseFilename = 'main';
  179. if (!is_dir($destinationDir)) {
  180. mkdir($destinationDir);
  181. }
  182. if (!is_dir($destinationDir.'/'.$baseFilename)) {
  183. mkdir($destinationDir.'/'.$baseFilename);
  184. }
  185. $destinationDir .= '/';
  186. $destinationFilePot = $destinationDir.'/'.$baseFilename.'/'.$baseFilename.'.pot';
  187. foreach ($languagesList as $language) {
  188. $termsInLanguage = $originalTermsInLanguage = [];
  189. $file = $langPath.$language.'/trad4all.inc.php';
  190. $languageCode = $langToIso639v1[$language];
  191. $languageFilename = $langToPOFilename[$language];
  192. $destinationFile = $destinationDir.'/'.$baseFilename.'/'.$languageFilename.'.po';
  193. $header = 'msgid ""'."\n".'msgstr ""'."\n".
  194. '"Project-Id-Version: chamilo-lms\n"'."\n".
  195. '"Language: '.$languageCode.'\n"'."\n".
  196. '"Content-Type: text/plain; charset=UTF-8\n"'."\n".
  197. '"Content-Transfer-Encoding: 8bit\n"'."\n\n";
  198. file_put_contents($destinationFile, $header);
  199. $originalTermsInLanguage = SubLanguageManager::get_all_language_variable_in_file(
  200. $file,
  201. true
  202. );
  203. foreach ($originalTermsInLanguage as $id => $content) {
  204. if (!isset($termsInLanguage[$id])) {
  205. $termsInLanguage[$id] = trim(rtrim($content, ';'), '"');
  206. }
  207. }
  208. $bigString = '';
  209. $bigStringPot = '';
  210. $doneTranslations = [];
  211. foreach ($terms as $term => $englishTranslation) {
  212. if (isset($doneTranslations[$englishTranslation])) {
  213. continue;
  214. }
  215. $doneTranslations[$englishTranslation] = true;
  216. $translatedTerm = '';
  217. if (!empty($termsInLanguage[$term])) {
  218. $translatedTerm = $termsInLanguage[$term];
  219. } else {
  220. if ($partial) {
  221. //do not include terms with empty translation
  222. continue;
  223. }
  224. }
  225. // Here we apply a little correction to avoid unterminated strings
  226. // when a string ends with a \"
  227. if (preg_match('/\\\$/', $englishTranslation)) {
  228. $englishTranslation .= '"';
  229. }
  230. $englishTranslation2 = '';
  231. $search = ['\\{', '\\}', '\\(', '\\)', '\\;'];
  232. $replace = ['\\\\{', '\\\\}', '\\\\(', '\\\\)', '\\\\;'];
  233. $englishTranslation = str_replace($search, $replace, $englishTranslation);
  234. if (preg_match('/\\\$/', $translatedTerm)) {
  235. $translatedTerm .= '"';
  236. }
  237. $translatedTerm = str_replace($search, $replace, $translatedTerm);
  238. // Now build the line
  239. $bigString .= 'msgid "'.$englishTranslation.'"'."\n".'msgstr "'.$translatedTerm.'"'."\n\n";
  240. if ($language === 'english') {
  241. //$bigStringPot .= 'msgid "'.$term.'"'."\n".'msgstr ""'."\n\n";
  242. }
  243. }
  244. file_put_contents($destinationFile, $bigString, FILE_APPEND);
  245. if ($language === 'english') {
  246. file_put_contents($destinationFilePot, $header.$bigString, FILE_APPEND);
  247. }
  248. }
  249. echo "Done generating gettext files in $destinationDir!\n";