| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- <?php
- /**
- * Generate .mo files from .po files.
- * Run: php generate-mo.php
- * Or use Poedit / WP-CLI: wp i18n make-mo .
- */
- if (php_sapi_name() !== 'cli') {
- die('CLI only');
- }
- $dir = __DIR__;
- $po_files = glob($dir . '/*.po');
- foreach ($po_files as $po_file) {
- $mo_file = preg_replace('/\.po$/', '.mo', $po_file);
- echo "Converting: " . basename($po_file) . " -> " . basename($mo_file) . "\n";
- $entries = parse_po($po_file);
- write_mo($mo_file, $entries);
- echo "Done. " . count($entries) . " entries.\n";
- }
- function parse_po($file) {
- $content = file_get_contents($file);
- $entries = array();
- $current_msgid = null;
- $current_msgstr = array();
- $current_msgid_plural = null;
- $state = '';
- $lines = explode("\n", $content);
- foreach ($lines as $line) {
- $line = trim($line);
- // Skip comments
- if (empty($line) || $line[0] === '#') {
- if ($current_msgid !== null && $state !== '') {
- save_entry($entries, $current_msgid, $current_msgid_plural, $current_msgstr);
- $current_msgid = null;
- $current_msgid_plural = null;
- $current_msgstr = array();
- $state = '';
- }
- continue;
- }
- if (preg_match('/^msgid\s+"(.*)"$/', $line, $m)) {
- if ($current_msgid !== null) {
- save_entry($entries, $current_msgid, $current_msgid_plural, $current_msgstr);
- }
- $current_msgid = stripcslashes($m[1]);
- $current_msgid_plural = null;
- $current_msgstr = array();
- $state = 'msgid';
- } elseif (preg_match('/^msgid_plural\s+"(.*)"$/', $line, $m)) {
- $current_msgid_plural = stripcslashes($m[1]);
- $state = 'msgid_plural';
- } elseif (preg_match('/^msgstr\s+"(.*)"$/', $line, $m)) {
- $current_msgstr[0] = stripcslashes($m[1]);
- $state = 'msgstr';
- } elseif (preg_match('/^msgstr\[(\d+)\]\s+"(.*)"$/', $line, $m)) {
- $current_msgstr[(int)$m[1]] = stripcslashes($m[2]);
- $state = 'msgstr[' . $m[1] . ']';
- } elseif (preg_match('/^"(.*)"$/', $line, $m)) {
- $val = stripcslashes($m[1]);
- if ($state === 'msgid') {
- $current_msgid .= $val;
- } elseif ($state === 'msgid_plural') {
- $current_msgid_plural .= $val;
- } elseif (preg_match('/^msgstr/', $state)) {
- $idx = 0;
- if (preg_match('/\[(\d+)\]/', $state, $im)) {
- $idx = (int)$im[1];
- }
- $current_msgstr[$idx] = ($current_msgstr[$idx] ?? '') . $val;
- }
- }
- }
- if ($current_msgid !== null) {
- save_entry($entries, $current_msgid, $current_msgid_plural, $current_msgstr);
- }
- return $entries;
- }
- function save_entry(&$entries, $msgid, $msgid_plural, $msgstr) {
- if ($msgid === null) return;
- if ($msgid_plural !== null) {
- $key = $msgid . "\x00" . $msgid_plural;
- ksort($msgstr);
- $val = implode("\x00", $msgstr);
- } else {
- $key = $msgid;
- $val = $msgstr[0] ?? '';
- }
- $entries[$key] = $val;
- }
- function write_mo($file, $entries) {
- ksort($entries);
- $offsets = array();
- $ids = '';
- $strs = '';
- foreach ($entries as $id => $str) {
- $offsets[] = array(strlen($id), strlen($ids), strlen($str), strlen($strs));
- $ids .= $id . "\x00";
- $strs .= $str . "\x00";
- }
- $count = count($offsets);
- $header_size = 28;
- $key_offset_start = $header_size;
- $val_offset_start = $key_offset_start + $count * 8;
- $keys_start = $val_offset_start + $count * 8;
- $vals_start = $keys_start + strlen($ids);
- $output = pack('V', 0x950412de); // magic
- $output .= pack('V', 0); // revision
- $output .= pack('V', $count); // number of strings
- $output .= pack('V', $key_offset_start); // offset of original strings table
- $output .= pack('V', $val_offset_start); // offset of translated strings table
- $output .= pack('V', 0); // hash table size
- $output .= pack('V', 0); // hash table offset
- // Original strings offsets
- foreach ($offsets as $o) {
- $output .= pack('V', $o[0]); // length
- $output .= pack('V', $keys_start + $o[1]); // offset
- }
- // Translated strings offsets
- foreach ($offsets as $o) {
- $output .= pack('V', $o[2]); // length
- $output .= pack('V', $vals_start + $o[3]); // offset
- }
- $output .= $ids;
- $output .= $strs;
- file_put_contents($file, $output);
- }
|