WordPress.org

Make WordPress Core


Ignore:
Timestamp:
06/23/2009 04:32:52 PM (12 years ago)
Author:
ryan
Message:

Merge latest pomo. Works around mbstring.func_overload. Props nbachiyski. fixes #10236 for trunk

File:
1 edited

Legend:

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

    r10810 r11626  
    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.