Make WordPress Core


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.8/wp-includes/pomo/po.php

    r10810 r11627  
    33 * Class for working with PO files
    44 *
    5  * @version $Id: po.php 33 2009-02-16 09:33:39Z nbachiyski $
     5 * @version $Id: po.php 123 2009-05-13 19:35:43Z nbachiyski $
    66 * @package pomo
    77 * @subpackage po
     
    1717 * Routines for working with PO files
    1818 */
    19 class PO extends Translations {
    20 
     19class PO extends Gettext_Translations {
     20       
    2121
    2222        /**
     
    7676        }
    7777
    78 
    7978        /**
    8079         * Formats a string in PO-style
     
    8887                $slash = '\\';
    8988                $newline = "\n";
    90                 $tab = "\t";
    9189
    9290                $replaces = array(
    9391                        "$slash"        => "$slash$slash",
    94                         "$tab"          => '\t',
    9592                        "$quote"        => "$slash$quote",
     93                        "\t"            => '\t',
    9694                );
     95
    9796                $string = str_replace(array_keys($replaces), array_values($replaces), $string);
    9897
    99                 $po = array();
    100                 foreach (explode($newline, $string) as $line) {
    101                         $po[] = wordwrap($line, PO_MAX_LINE_LEN - 2, " $quote$newline$quote");
    102                 }
    103                 $po = $quote.implode("${slash}n$quote$newline$quote", $po).$quote;
     98                $po = $quote.implode("${slash}n$quote$newline$quote", explode($newline, $string)).$quote;
    10499                // add empty string on first line for readbility
    105                 if (false !== strpos($po, $newline)) {
     100                if (false !== strpos($string, $newline) &&
     101                                (substr_count($string, $newline) > 1 || !($newline === substr($string, -strlen($newline))))) {
    106102                        $po = "$quote$quote$newline$po";
    107103                }
     
    110106                return $po;
    111107        }
    112 
    113         /**
    114          * Inserts $with in the beginning of every new line of $string and
     108       
     109        /**
     110         * Gives back the original string from a PO-formatted string
     111         *
     112         * @static
     113         * @param string $string PO-formatted string
     114         * @return string enascaped string
     115         */
     116        function unpoify($string) {
     117                $escapes = array('t' => "\t", 'n' => "\n", '\\' => '\\');
     118                $lines = array_map('trim', explode("\n", $string));
     119                $lines = array_map(array('PO', 'trim_quotes'), $lines);
     120                $unpoified = '';
     121                $previous_is_backslash = false;
     122                foreach($lines as $line) {
     123                        preg_match_all('/./u', $line, $chars);
     124                        $chars = $chars[0];
     125                        foreach($chars as $char) {
     126                                if (!$previous_is_backslash) {
     127                                        if ('\\' == $char)
     128                                                $previous_is_backslash = true;
     129                                        else
     130                                                $unpoified .= $char;
     131                                } else {
     132                                        $previous_is_backslash = false;
     133                                        $unpoified .= isset($escapes[$char])? $escapes[$char] : $char;
     134                                }
     135                        }
     136                }
     137                return $unpoified;
     138        }
     139
     140        /**
     141         * Inserts $with in the beginning of every new line of $string and
    115142         * returns the modified string
    116143         *
     
    158185                if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.');
    159186                if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':');
    160                 if (!empty($entry->flags)) $po[] = PO::comment_block(implode("\n", $entry->flags), ',');
     187                if (!empty($entry->flags)) $po[] = PO::comment_block(implode(", ", $entry->flags), ',');
    161188                if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context);
    162189                $po[] = 'msgid '.PO::poify($entry->singular);
     
    174201        }
    175202
     203        function import_from_file($filename) {
     204                $f = fopen($filename, 'r');
     205                if (!$f) return false;
     206                $lineno = 0;
     207                while (true) {
     208                        $res = $this->read_entry($f, $lineno);
     209                        if (!$res) break;
     210                        if ($res['entry']->singular == '') {
     211                                $this->set_headers($this->make_headers($res['entry']->translations[0]));
     212                        } else {
     213                                $this->add_entry($res['entry']);
     214                        }
     215                }
     216                PO::read_line($f, 'clear');
     217                return $res !== false;
     218        }
     219       
     220        function read_entry($f, $lineno = 0) {
     221                $entry = new Translation_Entry();
     222                // where were we in the last step
     223                // can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural
     224                $context = '';
     225                $msgstr_index = 0;
     226                $is_final = create_function('$context', 'return $context == "msgstr" || $context == "msgstr_plural";');
     227                while (true) {
     228                        $lineno++;
     229                        $line = PO::read_line($f);
     230                        if (!$line)  {
     231                                if (feof($f)) {
     232                                        if ($is_final($context))
     233                                                break;
     234                                        elseif (!$context) // we haven't read a line and eof came
     235                                                return null;
     236                                        else
     237                                                return false;
     238                                } else {
     239                                        return false;
     240                                }
     241                        }
     242                        if ($line == "\n") continue;
     243                        $line = trim($line);
     244                        if (preg_match('/^#/', $line, $m)) {
     245                                // the comment is the start of a new entry
     246                                if ($is_final($context)) {
     247                                        PO::read_line($f, 'put-back');
     248                                        $lineno--;
     249                                        break;
     250                                }
     251                                // comments have to be at the beginning
     252                                if ($context && $context != 'comment') {
     253                                        return false;
     254                                }
     255                                // add comment
     256                                $this->add_comment_to_entry($entry, $line);;
     257                        } elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
     258                                if ($is_final($context)) {
     259                                        PO::read_line($f, 'put-back');
     260                                        $lineno--;
     261                                        break;
     262                                }
     263                                if ($context && $context != 'comment') {
     264                                        return false;
     265                                }
     266                                $context = 'msgctxt';
     267                                $entry->context .= PO::unpoify($m[1]);
     268                        } elseif (preg_match('/^msgid\s+(".*")/', $line, $m)) {
     269                                if ($is_final($context)) {
     270                                        PO::read_line($f, 'put-back');
     271                                        $lineno--;
     272                                        break;
     273                                }
     274                                if ($context && $context != 'msgctxt' && $context != 'comment') {
     275                                        return false;
     276                                }
     277                                $context = 'msgid';
     278                                $entry->singular .= PO::unpoify($m[1]);
     279                        } elseif (preg_match('/^msgid_plural\s+(".*")/', $line, $m)) {
     280                                if ($context != 'msgid') {
     281                                        return false;
     282                                }
     283                                $context = 'msgid_plural';
     284                                $entry->is_plural = true;
     285                                $entry->plural .= PO::unpoify($m[1]);
     286                        } elseif (preg_match('/^msgstr\s+(".*")/', $line, $m)) {
     287                                if ($context != 'msgid') {
     288                                        return false;
     289                                }
     290                                $context = 'msgstr';
     291                                $entry->translations = array(PO::unpoify($m[1]));
     292                        } elseif (preg_match('/^msgstr\[(\d+)\]\s+(".*")/', $line, $m)) {
     293                                if ($context != 'msgid_plural' && $context != 'msgstr_plural') {
     294                                        return false;
     295                                }
     296                                $context = 'msgstr_plural';
     297                                $msgstr_index = $m[1];
     298                                $entry->translations[$m[1]] = PO::unpoify($m[2]);
     299                        } elseif (preg_match('/^".*"$/', $line)) {
     300                                $unpoified = PO::unpoify($line);
     301                                switch ($context) {
     302                                        case 'msgid':
     303                                                $entry->singular .= $unpoified; break;
     304                                        case 'msgctxt':
     305                                                $entry->context .= $unpoified; break;
     306                                        case 'msgid_plural':
     307                                                $entry->plural .= $unpoified; break;
     308                                        case 'msgstr':
     309                                                $entry->translations[0] .= $unpoified; break;
     310                                        case 'msgstr_plural':
     311                                                $entry->translations[$msgstr_index] .= $unpoified; break;
     312                                        default:
     313                                                return false;
     314                                }
     315                        } else {
     316                                return false;
     317                        }
     318                }
     319                if (array() == array_filter($entry->translations)) $entry->translations = array();
     320                return array('entry' => $entry, 'lineno' => $lineno);
     321        }
     322       
     323        function read_line($f, $action = 'read') {
     324                static $last_line = '';
     325                static $use_last_line = false;
     326                if ('clear' == $action) {
     327                        $last_line = '';
     328                        return true;
     329                }
     330                if ('put-back' == $action) {
     331                        $use_last_line = true;
     332                        return true;
     333                }
     334                $line = $use_last_line? $last_line : fgets($f);
     335                $last_line = $line;
     336                $use_last_line = false;
     337                return $line;
     338        }
     339       
     340        function add_comment_to_entry(&$entry, $po_comment_line) {
     341                $first_two = substr($po_comment_line, 0, 2);
     342                $comment = trim(substr($po_comment_line, 2));
     343                if ('#:' == $first_two) {
     344                        $entry->references = array_merge($entry->references, preg_split('/\s+/', $comment));
     345                } elseif ('#.' == $first_two) {
     346                        $entry->extracted_comments = trim($entry->extracted_comments . "\n" . $comment);
     347                } elseif ('#,' == $first_two) {
     348                        $entry->flags = array_merge($entry->flags, preg_split('/,\s*/', $comment));
     349                } else {
     350                        $entry->translator_comments = trim($entry->translator_comments . "\n" . $comment);
     351                }
     352        }
     353       
     354        function trim_quotes($s) {
     355                if ( substr($s, 0, 1) == '"') $s = substr($s, 1);
     356                if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1);
     357                return $s;
     358        }
    176359}
    177360?>
Note: See TracChangeset for help on using the changeset viewer.