Sync pomo library with the current GlotPress version

git-svn-id: http://svn.automattic.com/wordpress/trunk@18528 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
nbachiyski 2011-08-11 04:29:35 +00:00
parent cdb9e49b8c
commit 688eebdc26
5 changed files with 110 additions and 51 deletions

View File

@ -2,7 +2,7 @@
/**
* Contains Translation_Entry class
*
* @version $Id: entry.php 406 2010-02-07 11:10:24Z nbachiyski $
* @version $Id: entry.php 621 2011-06-13 12:21:50Z nbachiyski $
* @package pomo
* @subpackage entry
*/
@ -65,5 +65,14 @@ class Translation_Entry {
// prepend context and EOT, like in MO files
return is_null($this->context)? $this->singular : $this->context.chr(4).$this->singular;
}
function merge_with(&$other) {
$this->flags = array_unique( array_merge( $this->flags, $other->flags ) );
$this->references = array_unique( array_merge( $this->references, $other->references ) );
if ( $this->extracted_comments != $other->extracted_comments ) {
$this->extracted_comments .= $other->extracted_comments;
}
}
}
endif;

View File

@ -2,7 +2,7 @@
/**
* Class for working with MO files
*
* @version $Id: mo.php 406 2010-02-07 11:10:24Z nbachiyski $
* @version $Id: mo.php 602 2011-01-30 12:43:29Z nbachiyski $
* @package pomo
* @subpackage mo
*/
@ -30,6 +30,20 @@ class MO extends Gettext_Translations {
function export_to_file($filename) {
$fh = fopen($filename, 'wb');
if ( !$fh ) return false;
$res = $this->export_to_file_handle( $fh );
fclose($fh);
return $res;
}
function export() {
$tmp_fh = fopen("php://temp", 'r+');
if ( !$tmp_fh ) return false;
$this->export_to_file_handle( $tmp_fh );
rewind( $tmp_fh );
return stream_get_contents( $tmp_fh );
}
function export_to_file_handle($fh) {
$entries = array_filter($this->entries, create_function('$e', 'return !empty($e->translations);'));
ksort($entries);
$magic = 0x950412de;
@ -43,7 +57,7 @@ class MO extends Gettext_Translations {
fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr,
$translations_lenghts_addr, $size_of_hash, $hash_addr));
fseek($fh, $originals_lenghts_addr);
// headers' msgid is an empty string
fwrite($fh, pack('VV', 0, $current_addr));
$current_addr++;
@ -55,24 +69,24 @@ class MO extends Gettext_Translations {
fwrite($fh, pack('VV', $length, $current_addr));
$current_addr += $length + 1; // account for the NULL byte after
}
$exported_headers = $this->export_headers();
fwrite($fh, pack('VV', strlen($exported_headers), $current_addr));
$current_addr += strlen($exported_headers) + 1;
$translations_table = $exported_headers . chr(0);
foreach($entries as $entry) {
$translations_table .= $this->export_translations($entry) . chr(0);
$length = strlen($this->export_translations($entry));
fwrite($fh, pack('VV', $length, $current_addr));
$current_addr += $length + 1;
}
fwrite($fh, $originals_table);
fwrite($fh, $translations_table);
fclose($fh);
return true;
}
function export_original($entry) {
//TODO: warnings for control characters
$exported = $entry->singular;
@ -80,12 +94,12 @@ class MO extends Gettext_Translations {
if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported;
return $exported;
}
function export_translations($entry) {
//TODO: warnings for control characters
return implode(chr(0), $entry->translations);
}
function export_headers() {
$exported = '';
foreach($this->headers as $header => $value) {
@ -193,7 +207,7 @@ class MO extends Gettext_Translations {
/**
* Build a Translation_Entry from original string and translation strings,
* found in a MO file
*
*
* @static
* @param string $original original string to translate from MO file. Might contain
* 0x04 as context separator or 0x00 as singular/plural separator

View File

@ -2,7 +2,7 @@
/**
* Class for working with PO files
*
* @version $Id: po.php 406 2010-02-07 11:10:24Z nbachiyski $
* @version $Id: po.php 589 2010-12-18 01:40:57Z nbachiyski $
* @package pomo
* @subpackage po
*/
@ -18,7 +18,8 @@ ini_set('auto_detect_line_endings', 1);
*/
if ( !class_exists( 'PO' ) ):
class PO extends Gettext_Translations {
var $comments_before_headers = '';
/**
* Exports headers to a PO entry
@ -31,7 +32,11 @@ class PO extends Gettext_Translations {
$header_string.= "$header: $value\n";
}
$poified = PO::poify($header_string);
return rtrim("msgid \"\"\nmsgstr $poified");
if ($this->comments_before_headers)
$before_headers = $this->prepend_each_line(rtrim($this->comments_before_headers)."\n", '# ');
else
$before_headers = '';
return rtrim("{$before_headers}msgid \"\"\nmsgstr $poified");
}
/**
@ -75,6 +80,15 @@ class PO extends Gettext_Translations {
if (false === $res) return false;
return fclose($fh);
}
/**
* Text to include as a comment before the start of the PO contents
*
* Doesn't need to include # in the beginning of lines, these are added automatically
*/
function set_comment_before_headers( $text ) {
$this->comments_before_headers = $text;
}
/**
* Formats a string in PO-style
@ -106,10 +120,10 @@ class PO extends Gettext_Translations {
$po = str_replace("$newline$quote$quote", '', $po);
return $po;
}
/**
* Gives back the original string from a PO-formatted string
*
*
* @static
* @param string $string PO-formatted string
* @return string enascaped string
@ -139,7 +153,7 @@ class PO extends Gettext_Translations {
}
/**
* Inserts $with in the beginning of every new line of $string and
* Inserts $with in the beginning of every new line of $string and
* returns the modified string
*
* @static
@ -217,7 +231,7 @@ class PO extends Gettext_Translations {
PO::read_line($f, 'clear');
return $res !== false;
}
function read_entry($f, $lineno = 0) {
$entry = new Translation_Entry();
// where were we in the last step
@ -254,7 +268,7 @@ class PO extends Gettext_Translations {
return false;
}
// add comment
$this->add_comment_to_entry($entry, $line);
$this->add_comment_to_entry($entry, $line);;
} elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
if ($is_final($context)) {
PO::read_line($f, 'put-back');
@ -322,7 +336,7 @@ class PO extends Gettext_Translations {
}
return array('entry' => $entry, 'lineno' => $lineno);
}
function read_line($f, $action = 'read') {
static $last_line = '';
static $use_last_line = false;
@ -339,7 +353,7 @@ class PO extends Gettext_Translations {
$use_last_line = false;
return $line;
}
function add_comment_to_entry(&$entry, $po_comment_line) {
$first_two = substr($po_comment_line, 0, 2);
$comment = trim(substr($po_comment_line, 2));
@ -353,11 +367,11 @@ class PO extends Gettext_Translations {
$entry->translator_comments = trim($entry->translator_comments . "\n" . $comment);
}
}
function trim_quotes($s) {
if ( substr($s, 0, 1) == '"') $s = substr($s, 1);
if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1);
return $s;
}
}
endif;
endif;

View File

@ -3,26 +3,26 @@
* Classes, which help reading streams of data from files.
* Based on the classes from Danilo Segan <danilo@kvota.net>
*
* @version $Id: streams.php 406 2010-02-07 11:10:24Z nbachiyski $
* @version $Id: streams.php 597 2011-01-16 20:14:36Z nbachiyski $
* @package pomo
* @subpackage streams
*/
if ( !class_exists( 'POMO_Reader' ) ):
class POMO_Reader {
var $endian = 'little';
var $_post = '';
function POMO_Reader() {
$this->is_overloaded = ((ini_get("mbstring.func_overload") & 2) != 0) && function_exists('mb_substr');
$this->_pos = 0;
}
/**
* Sets the endianness of the file.
*
* @param string $endian 'big' or 'little'
* @param $endian string 'big' or 'little'
*/
function setEndian($endian) {
$this->endian = $endian;
@ -57,8 +57,8 @@ class POMO_Reader {
$endian_letter = ('big' == $this->endian)? 'N' : 'V';
return unpack($endian_letter.$count, $bytes);
}
function substr($string, $start, $length) {
if ($this->is_overloaded) {
return mb_substr($string, $start, $length, 'ascii');
@ -66,7 +66,7 @@ class POMO_Reader {
return substr($string, $start, $length);
}
}
function strlen($string) {
if ($this->is_overloaded) {
return mb_strlen($string, 'ascii');
@ -74,7 +74,7 @@ class POMO_Reader {
return strlen($string);
}
}
function str_split($string, $chunk_size) {
if (!function_exists('str_split')) {
$length = $this->strlen($string);
@ -86,8 +86,8 @@ class POMO_Reader {
return str_split( $string, $chunk_size );
}
}
function pos() {
return $this->_pos;
}
@ -95,7 +95,7 @@ class POMO_Reader {
function is_resource() {
return true;
}
function close() {
return true;
}
@ -106,13 +106,13 @@ if ( !class_exists( 'POMO_FileReader' ) ):
class POMO_FileReader extends POMO_Reader {
function POMO_FileReader($filename) {
parent::POMO_Reader();
$this->_f = fopen($filename, 'r');
$this->_f = fopen($filename, 'rb');
}
function read($bytes) {
return fread($this->_f, $bytes);
}
function seekto($pos) {
if ( -1 == fseek($this->_f, $pos, SEEK_SET)) {
return false;
@ -120,19 +120,19 @@ class POMO_FileReader extends POMO_Reader {
$this->_pos = $pos;
return true;
}
function is_resource() {
return is_resource($this->_f);
}
function feof() {
return feof($this->_f);
}
function close() {
return fclose($this->_f);
}
function read_all() {
$all = '';
while ( !$this->feof() )
@ -148,9 +148,9 @@ if ( !class_exists( 'POMO_StringReader' ) ):
* of a physical file.
*/
class POMO_StringReader extends POMO_Reader {
var $_str = '';
function POMO_StringReader($str = '') {
parent::POMO_Reader();
$this->_str = $str;
@ -178,7 +178,7 @@ class POMO_StringReader extends POMO_Reader {
function read_all() {
return $this->substr($this->_str, $this->_pos, $this->strlen($this->_str));
}
}
endif;

View File

@ -2,7 +2,7 @@
/**
* Class for a set of entries for translation and their associated headers
*
* @version $Id: translations.php 406 2010-02-07 11:10:24Z nbachiyski $
* @version $Id: translations.php 590 2010-12-20 19:58:37Z nbachiyski $
* @package pomo
* @subpackage translations
*/
@ -29,6 +29,19 @@ class Translations {
$this->entries[$key] = &$entry;
return true;
}
function add_entry_or_merge($entry) {
if (is_array($entry)) {
$entry = new Translation_Entry($entry);
}
$key = $entry->key();
if (false === $key) return false;
if (isset($this->entries[$key]))
$this->entries[$key]->merge_with($entry);
else
$this->entries[$key] = &$entry;
return true;
}
/**
* Sets $header PO header to $value
@ -108,6 +121,15 @@ class Translations {
$this->entries[$entry->key()] = $entry;
}
}
function merge_originals_with(&$other) {
foreach( $other->entries as $entry ) {
if ( !isset( $this->entries[$entry->key()] ) )
$this->entries[$entry->key()] = $entry;
else
$this->entries[$entry->key()]->merge_with($entry);
}
}
}
class Gettext_Translations extends Translations {
@ -126,7 +148,7 @@ class Gettext_Translations extends Translations {
}
return call_user_func($this->_gettext_select_plural_form, $count);
}
function nplurals_and_expression_from_header($header) {
if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) {
$nplurals = (int)$matches[1];
@ -152,7 +174,7 @@ class Gettext_Translations extends Translations {
/**
* Adds parantheses to the inner parts of ternary operators in
* plural expressions, because PHP evaluates ternary oerators from left to right
*
*
* @param string $expression the expression without parentheses
* @return string the expression with parentheses added
*/
@ -180,7 +202,7 @@ class Gettext_Translations extends Translations {
}
return rtrim($res, ';');
}
function make_headers($translation) {
$headers = array();
// sometimes \ns are used instead of real new lines
@ -193,7 +215,7 @@ class Gettext_Translations extends Translations {
}
return $headers;
}
function set_header($header, $value) {
parent::set_header($header, $value);
if ('Plural-Forms' == $header) {
@ -212,7 +234,7 @@ if ( !class_exists( 'NOOP_Translations' ) ):
class NOOP_Translations {
var $entries = array();
var $headers = array();
function add_entry($entry) {
return true;
}