]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-includes/pomo/po.php
Wordpress 3.0-scripts
[autoinstalls/wordpress.git] / wp-includes / pomo / po.php
index 50520670e523b18d95282e3a3915f48b861c58d3..8e3eb611512bdea6af9a28cf1fe3df36f172ac2b 100644 (file)
@@ -2,7 +2,7 @@
 /**
  * Class for working with PO files
  *
- * @version $Id: po.php 33 2009-02-16 09:33:39Z nbachiyski $
+ * @version $Id: po.php 406 2010-02-07 11:10:24Z nbachiyski $
  * @package pomo
  * @subpackage po
  */
@@ -16,7 +16,8 @@ ini_set('auto_detect_line_endings', 1);
 /**
  * Routines for working with PO files
  */
-class PO extends Translations {
+if ( !class_exists( 'PO' ) ):
+class PO extends Gettext_Translations {
 
 
        /**
@@ -75,7 +76,6 @@ class PO extends Translations {
                return fclose($fh);
        }
 
-
        /**
         * Formats a string in PO-style
         *
@@ -87,22 +87,19 @@ class PO extends Translations {
                $quote = '"';
                $slash = '\\';
                $newline = "\n";
-               $tab = "\t";
 
                $replaces = array(
                        "$slash"        => "$slash$slash",
-                       "$tab"          => '\t',
                        "$quote"        => "$slash$quote",
+                       "\t"            => '\t',
                );
+
                $string = str_replace(array_keys($replaces), array_values($replaces), $string);
 
-               $po = array();
-               foreach (explode($newline, $string) as $line) {
-                       $po[] = wordwrap($line, PO_MAX_LINE_LEN - 2, " $quote$newline$quote");
-               }
-               $po = $quote.implode("${slash}n$quote$newline$quote", $po).$quote;
+               $po = $quote.implode("${slash}n$quote$newline$quote", explode($newline, $string)).$quote;
                // add empty string on first line for readbility
-               if (false !== strpos($po, $newline)) {
+               if (false !== strpos($string, $newline) &&
+                               (substr_count($string, $newline) > 1 || !($newline === substr($string, -strlen($newline))))) {
                        $po = "$quote$quote$newline$po";
                }
                // remove empty strings
@@ -110,6 +107,37 @@ class PO extends Translations {
                return $po;
        }
 
+       /**
+        * Gives back the original string from a PO-formatted string
+        *
+        * @static
+        * @param string $string PO-formatted string
+        * @return string enascaped string
+        */
+       function unpoify($string) {
+               $escapes = array('t' => "\t", 'n' => "\n", '\\' => '\\');
+               $lines = array_map('trim', explode("\n", $string));
+               $lines = array_map(array('PO', 'trim_quotes'), $lines);
+               $unpoified = '';
+               $previous_is_backslash = false;
+               foreach($lines as $line) {
+                       preg_match_all('/./u', $line, $chars);
+                       $chars = $chars[0];
+                       foreach($chars as $char) {
+                               if (!$previous_is_backslash) {
+                                       if ('\\' == $char)
+                                               $previous_is_backslash = true;
+                                       else
+                                               $unpoified .= $char;
+                               } else {
+                                       $previous_is_backslash = false;
+                                       $unpoified .= isset($escapes[$char])? $escapes[$char] : $char;
+                               }
+                       }
+               }
+               return $unpoified;
+       }
+
        /**
         * Inserts $with in the beginning of every new line of $string and
         * returns the modified string
@@ -157,7 +185,7 @@ class PO extends Translations {
                if (!empty($entry->translator_comments)) $po[] = PO::comment_block($entry->translator_comments);
                if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.');
                if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':');
-               if (!empty($entry->flags)) $po[] = PO::comment_block(implode("\n", $entry->flags), ',');
+               if (!empty($entry->flags)) $po[] = PO::comment_block(implode("", $entry->flags), ',');
                if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context);
                $po[] = 'msgid '.PO::poify($entry->singular);
                if (!$entry->is_plural) {
@@ -173,5 +201,163 @@ class PO extends Translations {
                return implode("\n", $po);
        }
 
+       function import_from_file($filename) {
+               $f = fopen($filename, 'r');
+               if (!$f) return false;
+               $lineno = 0;
+               while (true) {
+                       $res = $this->read_entry($f, $lineno);
+                       if (!$res) break;
+                       if ($res['entry']->singular == '') {
+                               $this->set_headers($this->make_headers($res['entry']->translations[0]));
+                       } else {
+                               $this->add_entry($res['entry']);
+                       }
+               }
+               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
+               // can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural
+               $context = '';
+               $msgstr_index = 0;
+               $is_final = create_function('$context', 'return $context == "msgstr" || $context == "msgstr_plural";');
+               while (true) {
+                       $lineno++;
+                       $line = PO::read_line($f);
+                       if (!$line)  {
+                               if (feof($f)) {
+                                       if ($is_final($context))
+                                               break;
+                                       elseif (!$context) // we haven't read a line and eof came
+                                               return null;
+                                       else
+                                               return false;
+                               } else {
+                                       return false;
+                               }
+                       }
+                       if ($line == "\n") continue;
+                       $line = trim($line);
+                       if (preg_match('/^#/', $line, $m)) {
+                               // the comment is the start of a new entry
+                               if ($is_final($context)) {
+                                       PO::read_line($f, 'put-back');
+                                       $lineno--;
+                                       break;
+                               }
+                               // comments have to be at the beginning
+                               if ($context && $context != 'comment') {
+                                       return false;
+                               }
+                               // add comment
+                               $this->add_comment_to_entry($entry, $line);
+                       } elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
+                               if ($is_final($context)) {
+                                       PO::read_line($f, 'put-back');
+                                       $lineno--;
+                                       break;
+                               }
+                               if ($context && $context != 'comment') {
+                                       return false;
+                               }
+                               $context = 'msgctxt';
+                               $entry->context .= PO::unpoify($m[1]);
+                       } elseif (preg_match('/^msgid\s+(".*")/', $line, $m)) {
+                               if ($is_final($context)) {
+                                       PO::read_line($f, 'put-back');
+                                       $lineno--;
+                                       break;
+                               }
+                               if ($context && $context != 'msgctxt' && $context != 'comment') {
+                                       return false;
+                               }
+                               $context = 'msgid';
+                               $entry->singular .= PO::unpoify($m[1]);
+                       } elseif (preg_match('/^msgid_plural\s+(".*")/', $line, $m)) {
+                               if ($context != 'msgid') {
+                                       return false;
+                               }
+                               $context = 'msgid_plural';
+                               $entry->is_plural = true;
+                               $entry->plural .= PO::unpoify($m[1]);
+                       } elseif (preg_match('/^msgstr\s+(".*")/', $line, $m)) {
+                               if ($context != 'msgid') {
+                                       return false;
+                               }
+                               $context = 'msgstr';
+                               $entry->translations = array(PO::unpoify($m[1]));
+                       } elseif (preg_match('/^msgstr\[(\d+)\]\s+(".*")/', $line, $m)) {
+                               if ($context != 'msgid_plural' && $context != 'msgstr_plural') {
+                                       return false;
+                               }
+                               $context = 'msgstr_plural';
+                               $msgstr_index = $m[1];
+                               $entry->translations[$m[1]] = PO::unpoify($m[2]);
+                       } elseif (preg_match('/^".*"$/', $line)) {
+                               $unpoified = PO::unpoify($line);
+                               switch ($context) {
+                                       case 'msgid':
+                                               $entry->singular .= $unpoified; break;
+                                       case 'msgctxt':
+                                               $entry->context .= $unpoified; break;
+                                       case 'msgid_plural':
+                                               $entry->plural .= $unpoified; break;
+                                       case 'msgstr':
+                                               $entry->translations[0] .= $unpoified; break;
+                                       case 'msgstr_plural':
+                                               $entry->translations[$msgstr_index] .= $unpoified; break;
+                                       default:
+                                               return false;
+                               }
+                       } else {
+                               return false;
+                       }
+               }
+               if (array() == array_filter($entry->translations, create_function('$t', 'return $t || "0" === $t;'))) {
+                       $entry->translations = array();
+               }
+               return array('entry' => $entry, 'lineno' => $lineno);
+       }
+
+       function read_line($f, $action = 'read') {
+               static $last_line = '';
+               static $use_last_line = false;
+               if ('clear' == $action) {
+                       $last_line = '';
+                       return true;
+               }
+               if ('put-back' == $action) {
+                       $use_last_line = true;
+                       return true;
+               }
+               $line = $use_last_line? $last_line : fgets($f);
+               $last_line = $line;
+               $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));
+               if ('#:' == $first_two) {
+                       $entry->references = array_merge($entry->references, preg_split('/\s+/', $comment));
+               } elseif ('#.' == $first_two) {
+                       $entry->extracted_comments = trim($entry->extracted_comments . "\n" . $comment);
+               } elseif ('#,' == $first_two) {
+                       $entry->flags = array_merge($entry->flags, preg_split('/,\s*/', $comment));
+               } else {
+                       $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;