Mantisの日本語マニュアルから対訳データ取得

翻訳のための前準備として、1.0.0の日本語マニュアルと英語版のマニュアルの翻訳データを作成してみました。

htmlのパース試行

最初はSimpleXMLでDOMと取ってきてと考えていたのですが、どうもきれいにとれない。

<td class="description">
	<span class="description">Description</span>
	<br /><br />
	正しく動作するには以下のバージョンが必要です。<br />
</td>
<||

こんな構造だと「Description」は取れるけれど「正しく動作するには以下のバージョンが必要です。」は取れませんでした。

>|php|
<?php
$file_name = '1.2.3.html';
$file_data = file_get_contents( $file_name );

$doc = new DOMDocument();
$doc->loadHTML($file_data);

$xml = simplexml_load_string( $doc->saveXML() );

ちなみにこんな処理でxhtmlに変換してからじゃないとパースしてくれません。マニュアルはxhtmlで書かれているのですが、imgとかが閉じていないんですよね。

力技でのhtmlパース

文体で分けるので、こんな感じで分けました。

<?php
$file_data = file_get_contents( $filename );

$file_data = preg_replace('/<li>/', "\n</li>", $file_data );
$file_data = preg_replace('/<span/', "\n<span", $file_data );

$lines = mb_split( "\n", $file_data );

$list = array();
foreach( $lines as $item ){
	$line = trim( strip_tags( $item, '' ) );
	if( $line ){
		$list[] = $line;
	}
}

$string_list[$list[0]] = $list;

文が始まりそうなところに改行を入れて、strip_tagsで文章だけ抜き出し。最初の項目がページのタイトルなので、その名前で保存しておきます。

日本語ページと英語ページの対応チェック

日本語版は翻訳時に番号を並び替えちゃったみたいです。もしくは元にしたものがこの形式だったのかな?
ページのタイトルの翻訳表をがんばって作成して、同じページの組み合わせで項目の並び替えを行いました。

ページごとの利用文字列リスト出力

<?php
foreach( $string_list as $key => $item ){
	if( isset( $title_list[$key] ) ){
		$ja_key = $title_list[$key];
		$ct = count( $item );
		if( $ct < count( $string_list_ja[$ja_key] ) ){
			$ct = count( $string_list_ja[$ja_key] );
		}

		for( $i = 0 ; $i < $ct ; $i++ ){
			echo '"'.$item[$i] . '","' . $string_list_ja[$ja_key][$i] . '"'."\n";
		}
		echo ",\n";
		echo ",\n";
		echo ",\n";
		echo ",\n";
		echo ",\n";
	}
}

同じページは同じような文字が順番ででてくると期待してCSVに落とします。続けて処理をしますので最後に予備用の5行も一緒に出力します。

対訳を修正

ここが一番大変ですが、目視で英文と日本語で対応しているところをあわせていきます。今回はOOoのカルクを利用して、ちくちく処理を行いました。

TMXへの出力

CSVからTMXに出力します。

<?php

$filename = 'lang.csv';

$file = file_get_contents($filename);

$lines = mb_split( "\n", $file );

$glossary = array();
foreach( $lines as $lines => $line ){
	$item = mb_split( "\t", $line );
	if( trim( $item[0] ) && trim( $item[1] ) ){
		$glossary[trim( $item[0] )] = trim( $item[1] );
	}
}

$str = '';
$str .= '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$str .= '<!DOCTYPE tmx SYSTEM "tmx11.dtd">' . "\n";
$str .= '<tmx version="1.1">' . "\n";
$str .= '  <header' . "\n";
$str .= '    creationtool="OmegaT"' . "\n";
$str .= '    creationtoolversion="1.7.3_2"' . "\n";
$str .= '    segtype="sentence"' . "\n";
$str .= '    o-tmf="OmegaT TMX"' . "\n";
$str .= '    adminlang="EN-US"' . "\n";
$str .= '    srclang="EN-US"' . "\n";
$str .= '    datatype="plaintext"' . "\n";
$str .= '  >' . "\n";
$str .= '  </header>' . "\n";
$str .= '  <body>' . "\n";

foreach( $glossary as $key => $item ){
	$str .= '    <tu>' . "\n";
	$str .= '      <tuv lang="EN-US">' . "\n";
	$str .= '        <seg>' . htmlspecialchars($key) . '</seg>' . "\n";
	$str .= '      </tuv>' . "\n";
	$str .= '      <tuv lang="JA">' . "\n";
	$str .= '        <seg>' . htmlspecialchars($item) . '</seg>' . "\n";
	$str .= '      </tuv>' . "\n";
	$str .= '    </tu>' . "\n";
}

$str .= '  </body>' . "\n";
$str .= '</tmx>' . "\n";

echo $str;

とりあえず空白何もしないでそのまま出力です。

OmagaTに読み込ませる

いまいち出来上がったtmxが読み込めるか自信がなかったので読み込ませます。その後に保存して正しいフォーマットになった物で完了とします。

感想

下準備なので、このtmxだとかなりの不備があります。これを元に翻訳作業を行っていき、途中で本当に利用している単語だけにするクリーニング作業が必要になりそうですね。

とりあえず出来上がったファイルをアップしておきます。

http://akira.info/labs/mantis/project_save.tmx

あと一度編集中にページが戻ってしまい、消えてしまいました(涙) だけどバックアップ機能が最近搭載されたので、一命を取り留めました! やっぱりブログ系はある程度バックアップとか必要なんですね。自分で実装するのは面倒そうですが(笑)