Skip to content

Instantly share code, notes, and snippets.

@dantleech
Last active November 23, 2018 13:18
Show Gist options
  • Save dantleech/6022699 to your computer and use it in GitHub Desktop.
Save dantleech/6022699 to your computer and use it in GitHub Desktop.
Script to convert symfony YAML translation file to XLIFF
<?php
// Script to convert Symfony YAML translation files to XLIFF.
//
// Will add a .xliff version of the given file in its directory.
//
// $ php convert.php path/to/MyBundle.en.yml
$file = $argv[1];
preg_match('&^(.*?)\.(.*?)\.yml&', $file, $matches);
list($fullName, $basePath, $targetLang) = $matches;
$filename = basename($basePath);
$dir = dirname($basePath);
$dom = new \DOMDocument('1.0');
$dom->formatOutput = true;
$dom->encoding = 'utf-8';
$dom->preserveWhitespace = true;
$rootEl = $dom->createElement('xliff');
$rootEl->setAttribute('version', '1.2');
$rootEl->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
$dom->appendChild($rootEl);
$fileEl = $dom->createElement('file');
$fileEl->setAttribute('source-language', 'en');
$fileEl->setAttribute('target-language', $targetLang);
$fileEl->setAttribute('datatype', 'plaintext');
$fileEl->setAttribute('original', $filename.'.en.xliff');
$bodyEl = $dom->createElement('body');
$fileEl->appendChild($bodyEl);
$rootEl->appendChild($fileEl);
$h = fopen($fullName, 'r');
$prefix = '';
while ($line = fgets($h)) {
$line = trim($line);
if (preg_match('&^(.*?):$&', $line, $matches)) {
$prefix = $matches[1];
continue;
}
if (!$line) {
$prefix = '';
}
if (!preg_match('&^(.*?):(.*)$&', $line, $matches)) {
echo "Could not match line ". $line;
continue;
}
array_shift($matches);
list($key, $value) = $matches;
if ($prefix) {
$key = $prefix.'_'.$key;
}
$transUnitEl = $dom->createElement('trans-unit');
$transUnitEl->setAttribute('id', $key);
$sourceEl = $dom->createElement('source');
$sourceEl->nodeValue = $key;
$targetEl = $dom->createElement('target');
$targetEl->nodeValue = trim($value);
$transUnitEl->appendChild($sourceEl);
$transUnitEl->appendChild($targetEl);
$bodyEl->appendChild($transUnitEl);
}
fclose($h);
$out = $dom->saveXml();
$outfile = $dir.'/'.$filename.'.'.$targetLang.'.xliff';
file_put_contents($outfile, $out);
exit(0);
@thomas-meka
Copy link

Here my update to support quoted key or value (changes only on regexps) :

<?php
// Script to convert Symfony YAML translation files to XLIFF.
//
// Will add a .xliff version of the given file in its directory.
//
// $ php convert.php path/to/MyBundle.en.yml

$file = $argv[1];

preg_match('/^(.*?)\.(.*?)\.(?:yaml|yml)/', $file, $matches);
list($fullName, $basePath, $targetLang) = $matches;
$filename = basename($basePath);
$dir = dirname($basePath);

$dom = new \DOMDocument('1.0');
$dom->formatOutput = true;
$dom->encoding = 'utf-8';
$dom->preserveWhiteSpace = true;
$rootEl = $dom->createElement('xliff');
$rootEl->setAttribute('version', '1.2');
$rootEl->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
$dom->appendChild($rootEl);

$fileEl = $dom->createElement('file');
$fileEl->setAttribute('source-language', 'en');
$fileEl->setAttribute('target-language', $targetLang);
$fileEl->setAttribute('datatype', 'plaintext');
$fileEl->setAttribute('original', $filename.'.en.xliff');
$bodyEl = $dom->createElement('body');
$fileEl->appendChild($bodyEl);
$rootEl->appendChild($fileEl);

$h = fopen($fullName, 'r');

$prefix = '';

while ($line = fgets($h)) {
    $line = trim($line);
    if (preg_match('/^(?:(?:["\']([^\'"]+)[\'"])|(.*)) ?:$/', $line, $matches)) {
        $prefix = $matches[1];
        continue;
    }

    if (!$line) {
        $prefix = '';
    }

    if (!preg_match('/^(?:(?:["\']([^\'"]+)[\'"])|(.*)) ?: ?(?:(?:["\']([^\'"]+)[\'"])|(.*))/', $line, $matches)) {
        echo "Could not match line " . $line . "\n";
        continue;
    }
    array_shift($matches);
    list($key, $value) = $matches;

    if ($prefix) {
        $key = $prefix.'_'.$key;
    }

    $transUnitEl = $dom->createElement('trans-unit');
    $transUnitEl->setAttribute('id', $key);
    $sourceEl = $dom->createElement('source');
    $sourceEl->nodeValue = $key;
    $targetEl = $dom->createElement('target');
    $targetEl->nodeValue = trim($value);
    $transUnitEl->appendChild($sourceEl);
    $transUnitEl->appendChild($targetEl);
    $bodyEl->appendChild($transUnitEl);
}

fclose($h);

$out = $dom->saveXml();
$outfile = $dir.'/'.$filename.'.'.$targetLang.'.xliff';
file_put_contents($outfile, $out);

exit(0);

With this you can convert files like this (french keys to english) :

'Colis en attente traitement':  Parcels awaiting treatment
'Colis bloqué': parcel blocked
'Contrôle éjection : alpha' : "Ejection control : alpha"
'Chiffres divers' : Various figures
'Colis préparés' : Packages prepared
'Boites Reçus' : Cases Received
'Regroupement ...' : Cases grouping ...
'Regroupement par Client' : Cases grouping by customer
'Outils' : Tools
'Stockage' : Storage
'Info colis machine' : Machine parcel info.
'Regrouper' : Gather

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment