Commit cfd88469 authored by Richard Mansfield's avatar Richard Mansfield

Add scripts to convert langpacks to/from po format

parent 50712e4e
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2010 Catalyst IT Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Reads a Mahara language pack, and outputs a single file in .po format
* Expects:
* - Name of a directory containing default English language pack
* - Name of a directory containing a translation
* - Filename to write PO entries
* The Mahara filename & language key are written to the reference and
* msgctxt lines of each PO entry. Strings found in the translation but
* not in the English langpack are ignored.
*/
define('L_START', 0);
define('L_STRING', 1);
define('L_LBRACKET', 2);
define('L_STRINGKEY', 3);
define('L_RBRACKET', 4);
define('L_EQUALS', 5);
define('L_STRINGVALUE', 6);
define('L_HEREDOCSTRING', 7);
define('L_HEREDOCEND', 8);
define('L_SEMI', 9);
// Reading default en.utf8 langpack files fails unless INTERNAL is defined
define('INTERNAL', 1);
function phptopo($en_strings, $fileid, $in, $pot) {
$rawtokens = token_get_all(file_get_contents($in));
$po = "\n";
$state = L_START;
foreach ($rawtokens as $t) {
if ($t[0] == T_WHITESPACE) {
continue;
}
if ($state == L_START && $t[0] == T_STRING && $t[1] == 'defined') {
$state = L_STRING;
}
elseif (($state == L_STRING || $state == L_START) && $t[0] == T_VARIABLE && $t[1] == '$string') {
$keys = array();
$values = array();
$state = L_LBRACKET;
}
elseif ($state == L_LBRACKET && $t == '[') {
$state = L_STRINGKEY;
}
elseif ($state == L_STRINGKEY && $t[0] == T_CONSTANT_ENCAPSED_STRING) {
$keys[] = $t[1];
$state = L_RBRACKET;
}
elseif ($state == L_RBRACKET && $t == ']') {
$state = L_EQUALS;
}
elseif ($state == L_EQUALS && $t == '=') {
$state = L_STRINGVALUE;
}
elseif ($state == L_STRINGVALUE && $t[0] == T_VARIABLE && $t[1] == '$string') {
$state = L_LBRACKET;
}
elseif ($state == L_STRINGVALUE && $t[0] == T_CONSTANT_ENCAPSED_STRING) {
$values[] = $t[1];
$state = L_SEMI;
}
elseif ($state == L_STRINGVALUE && $t[0] == T_START_HEREDOC) {
unset($heredoc);
$state = L_HEREDOCSTRING;
}
elseif ($state == L_HEREDOCSTRING && $t[0] == T_ENCAPSED_AND_WHITESPACE) {
$heredoc = $t[1];
$state = L_HEREDOCEND;
}
elseif ($state == L_HEREDOCEND && $t[0] == T_END_HEREDOC) {
$state = L_SEMI;
}
elseif ($state == L_SEMI && $t[0] == '.') {
$state = L_STRINGVALUE;
}
elseif ($state == L_SEMI && $t == ';') {
foreach ($keys as $key) {
eval('$k = ' . $key . ';');
if (isset($en_strings[$k])) {
$po .= "\n\n#: $fileid $k";
$po .= "\nmsgctxt \"$fileid $k\"";
$po .= "\nmsgid \"" . addcslashes($en_strings[$k], "\\\"\r\n") . '"';
$po .= "\nmsgstr \"";
if (!$pot) {
if (isset($heredoc)) {
$po .= addcslashes($heredoc, "\\\"\r\n");
}
else {
foreach ($values as $qstring) {
eval('$s = ' . $qstring . ';');
$po .= addcslashes($s, "\\\"\r\n");
}
}
}
$po .= '"';
}
if (isset($heredoc)) {
unset($heredoc);
}
}
$state = L_STRING;
}
elseif ($state == L_STRING && $t[0] == T_CLOSE_TAG) {
break;
}
elseif ($state != L_START && $state != L_STRING) {
$state = L_STRING;
}
}
return $po;
}
function get_langfile_list(&$list, $dir) {
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file != '.' && $file != '..') {
$path = $dir . '/' . $file;
if (is_dir($path)) {
get_langfile_list($list, $path);
}
else if (is_file($path) && is_readable($path)) {
$list[] = $path;
}
}
}
closedir($dh);
}
}
}
$en_dir = $argv[1];
$source = $argv[2];
$destfile = $argv[3];
$destdir = dirname($destfile);
if (!is_dir($destdir)) {
mkdir($destdir, 0755, true);
}
if (file_exists($destfile)) {
unlink($destfile);
}
$sourcefiles = array();
get_langfile_list($sourcefiles, $source);
$pot = preg_match('/.pot$/', $destfile); // Create .pot template
if (!empty($sourcefiles)) {
foreach ($sourcefiles as $sourcefile) {
$langfile = substr($sourcefile, strlen($source) + 1);
$en_file = preg_replace('/lang\/[a-zA-Z_]+\.utf8\//', 'lang/en.utf8/', $langfile);
$en_file = $en_dir . '/' . $en_file;
if (!file_exists($en_file)) {
continue;
}
$po = null;
if (preg_match('/lang\/.*\.utf8\/.*\.html$/', $langfile)) {
$po .= "\n\n#: $langfile";
$po .= "\nmsgctxt \"$langfile\"";
$po .= "\nmsgid \"" . addcslashes(file_get_contents($en_file), "\\\"\r\n") . '"';
$po .= "\nmsgstr \"" . ($pot ? '' : addcslashes(file_get_contents($sourcefile), "\\\"\r\n")) . '"';
}
if (preg_match('/lang\/.*\.utf8\/.*\.php$/', $langfile)) {
$string = array();
include ($en_file); // Fills $string
$po = phptopo($string, $langfile, $sourcefile, $pot);
}
if ($po) {
file_put_contents($destfile, $po, FILE_APPEND);
}
}
}
#!/usr/bin/perl -w
# Takes a Mahara .po file generated by php-po.php, and converts it
# into a Mahara language pack containing help files (html) and string
# files (php).
# Assumes the .po reference comments contain either an html filename
# or a php filename followed by a space and a mahara language string
# key.
# po-php.pl /path/to/po/files/fr-1.3_STABLE.po /path/to/langpacks/fr.utf8 fr.utf8
use File::Path qw(make_path);
use File::Basename qw(fileparse);
use Locale::PO;
my ($inputfile, $outputdir, $lang) = @ARGV;
my $strings = Locale::PO->load_file_asarray($inputfile);
my %htmlfiles = ();
my %phpfiles = ();
foreach my $po (@$strings) {
my $content = $po->msgstr();
$content =~ s{\\n}{\n}g;
my $reference = $po->reference();
if ($reference =~ m{^(\S*lang/)\S+\.utf8(/\S+)\.html$}) {
my $filename = $1 . $lang . $2 . '.html';
$htmlfiles{$filename} = $po->dequote($content);
}
elsif ($reference =~ m{^(\S*lang/)\S+\.utf8(/\S+)\.php (\S+)$}) {
my $key = $3;
my $filename = $1 . $lang . $2 . '.php';
$phpfiles{$filename}->{$key} = $content;
}
}
foreach my $htmlfile (keys %htmlfiles) {
my ($filename, $subdir, $suffix) = fileparse($htmlfile);
my $dir = $outputdir . '/' . $subdir;
make_path($dir);
open(my $fh, '>', "$dir/$filename");
print $fh $htmlfiles{$htmlfile};
close $fh;
}
foreach my $phpfile (keys %phpfiles) {
my ($filename, $subdir, $suffix) = fileparse($phpfile);
my $dir = $outputdir . '/' . $subdir;
make_path($dir);
open(my $fh, '>', "$dir/$filename");
print $fh "<?php\n\ndefined('INTERNAL') || die();\n\n";
foreach my $key (sort keys %{$phpfiles{$phpfile}}) {
print $fh "\$string['$key'] = " . $phpfiles{$phpfile}->{$key} . ";\n";
}
close $fh;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment