TimeTrex/tools/i18n/po2json.php

180 lines
4.2 KiB
PHP
Raw Permalink Normal View History

2022-12-13 07:10:06 +01:00
<?php
if ( PHP_SAPI != 'cli' ) {
echo "This script can only be called from the Command Line.\n";
exit;
}
/**
* String object
*/
class PoeditString {
public $key;
public $value;
public $fuzzy;
public $comments;
function __construct( $key, $value = '', $fuzzy = false, $comments = [] ) {
$this->key = $key;
$this->value = $value;
$this->fuzzy = $fuzzy;
$this->comments = (array)$comments;
}
public function __toString() {
$str = '';
foreach ( $this->comments as $c ) {
$str .= "#: $c\n";
}
if ( $this->fuzzy ) {
$str .= "#, fuzzy\n";
}
$str .= 'msgid "' . str_replace( '"', '\\"', $this->key ) . '"' . "\n";
$str .= 'msgstr "' . str_replace( '"', '\\"', $this->value ) . '"' . "\n";
$str .= "\n";
return $str;
}
}
/**
* Parser object
*/
class PoeditParser {
protected $file;
protected $header = '';
protected $strings = [];
protected function _fixQuotes( $str ) {
return stripslashes( $str );
}
public function __construct( $file ) {
$this->file = $file;
}
public function parse() {
$contents = file_get_contents( $this->file );
$parts = preg_split( '#(\r\n|\n){2}#', $contents, -1, PREG_SPLIT_NO_EMPTY );
$this->header = array_shift( $parts );
foreach ( $parts as $part ) {
// parse comments
$comments = [];
preg_match_all( '#^\\#: (.*?)$#m', $part, $matches, PREG_SET_ORDER );
foreach ( $matches as $m ) {
$comments[] = $m[1];
}
$isFuzzy = preg_match( '#^\\#, fuzzy$#im', $part ) ? true : false;
preg_match_all( '# ^ (msgid|msgstr)\ " ( (?: (?>[^"\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\" )* ) (?<!\\\\)" $ #ixm', $part, $matches2, PREG_SET_ORDER );
$k = null;
if ( isset( $matches2[0][2] ) ) {
$k = $this->_fixQuotes( $matches2[0][2] );
}
$v = !empty( $matches2[1][2] ) ? $this->_fixQuotes( $matches2[1][2] ) : '';
$this->strings[$k] = new PoeditString( $k, $v, $isFuzzy, $comments );
}
}
public function merge( $strings ) {
foreach ( (array)$strings as $str ) {
if ( !in_array( $str, array_keys( $this->strings ) ) ) {
$this->strings[$str] = new PoeditString( $str );
}
}
}
public function getHeader() {
return $this->header;
}
public function getStrings() {
return $this->strings;
}
public function getJSON() {
$str = [];
foreach ( $this->strings as $s ) {
echo "String: Key: " . $s->key . " Value: " . $s->value . "\n";
if ( $s->value /*&& strlen($s->value) > 0*/ ) {
$str[$s->key] = $s->value;
} else {
//$str[$s->key] = $s->key; //Don't export strings that haven't been translated to save space.
}
}
return json_encode( $str );
}
public function toJSON( $outputFilename, $varName = 'l10n' ) {
$str = "$varName = " . $this->getJSON();
return file_put_contents( $outputFilename, $str ) !== false;
}
public function save( $filename = null ) {
$data = $this->header . "\n\n";
foreach ( $this->strings as $str ) {
$data .= $str;
}
return file_put_contents( $filename ? $filename : $this->file, $data ) !== false;
}
}
/**
*
* @param unknown_type $args
*/
function buildOptions( $args ) {
$options = [
'-o' => null,
'-i' => null,
'-n' => 'l10n',
];
$len = count( $args );
$i = 0;
while ( $i < $len ) {
if ( preg_match( '#^-[a-z]$#i', $args[$i] ) ) {
$options[$args[$i]] = isset( $args[$i + 1] ) ? trim( $args[$i + 1] ) : true;
$i += 2;
} else {
$options[] = $args[$i];
$i++;
}
}
return $options;
}
/**
* Script entry point
*
* Usage :
* =======
* php po2json -i <path/to/file.po> -o <path/to/file.json> {optional} -n <variable name (default is l10n)>
*
* This script is based on the project jsgettext : http://code.google.com/p/jsgettext/
* I've updated it slightly to meet my need
*/
$options = buildOptions( $argv );
if ( !file_exists( $options['-i'] ) || !is_readable( $options['-i'] ) ) {
die( "Invalid input file. Make sure it exists and is readable." . "\n" );
}
$poeditParser = new PoeditParser( $options['-i'] );
$poeditParser->parse();
if ( $poeditParser->toJSON( $options['-o'], $options['-n'] ) ) {
$strings = count( $poeditParser->getStrings() );
echo "Successfully exported " . $strings . " strings.\n";
} else {
echo "Cannor write to file '{$options['-o']}'.\n";
}