「git rebase in depth」の和訳について

[git rebase in depth][rebase]という記事があり、git-rebase(1) を使う際に有用と感じたため和訳しました。翻訳は[git rebaseを掘り下げる][rebase-ja]から閲覧できます。またリポジトリ[sourcehut / ~gemmaro/git-rebase.io][repo]も公開されているため、誤植の報告や訳文の改善を受け付けられますし、私家訳用にフォークしても良いでしょう。

Gitそのものについてではありませんが、本記事ではこの作業について簡単に紹介し、[Git Advent Calendar 2023][cal]の一枠とします。

なお、本記事は[GNU自由文書ライセンス][fdl]1.3版以降のもとに使用が許諾されます。
引用されるソースコードについては引用元の使用許諾にしたがいます。

[cal]: https://qiita.com/advent-calendar/2023/git
[fdl]: https://www.gnu.org/licenses/fdl-1.3.html

## 翻訳管理

今回の原文のリポジトリはとても単純なファイル構成となっています。翻訳対象のファイルは`/index.html`だけです。

```text
+ index.css
+ index.html
+ LICENSE
+ README.md
+ static
  + isometric-grid.png
```

それではと`/index.html`を日本語用に複製して、そのままそのファイルを編集することも一案です。

```text
+ index.css  # 複製元
+ index.html # 複製元
+ LICENSE
+ README.md
+ static
  + isometric-grid.png
+ ja
  + index.html # 複製先
  + index.css  # 複製先
```

しかしもし今後、原文書`/index.html`が変更されたとすると、和訳した`/ja/index.html`もそれに追従しなければなりません。今回の場合、原文書は既に版管理されていますから、git-diff(1) を活用して差分を目視して翻訳を更新することは可能でしょうが、割と幸運な例に属します。HTMLファイルの内容についても手ずからしたためられたシンプルで可読性の高いHTMLファイルですが、もしこれが静的サイト生成器から出力された物を使うよりないとなると、差分の確認も難しくなります。

そこで登場するのが翻訳管理ツールです。原文書の生じた変更を追跡できるようにするために、以下の工程を踏むようにするのがよくある機構です。ここで、実際の翻訳作業である3以外を自動化するのがツールの役割です。機械学習による自動翻訳の精度が上がってきた現代に於いては下訳も自動化できそうです。

1. 原文書から翻訳単位（文や段落）を抽出する。
2. 抽出された翻訳単位から対訳表を作成する。
3. 対訳表を編集して翻訳作業を行う。
4. 原文書と対訳表から翻訳文書を生成する。
5. ある時、原文書に変更が生じる。
6. 対訳表を更新する。
7. 手順3に戻って以下繰り返し。

このようなツールとしては[po4a][po4a]や[Translate Toolkit][tt]、[OmegaT][omegat]などがあり、またツールが対訳表として用いる形式にも[GNU gettext][gettext]、[TMX][tmx]、[XLIFF][xliff]、[Fluent][fluent]など様々です。

ここでは可搬性の比較的高いpo4aを使うことにします。po4aはGettext PO形式で対訳表を扱いますから、この形式を楽に編集できるエディタがあると捗ります。例としてEmacsのPOモードがあります。

po4a用の準備をすると以下のようになります。ファイルパスは柔軟に変更できますが、大体こんな感じになるでしょう。

```text
+ index.css  # 複製元
+ index.html # 原文書
+ LICENSE
+ README.md
+ static
  + isometric-grid.png
+ translation
  + ja
    + index.html # 生成された翻訳文書
    + index.css  # 複製先
  + po
    + all.pot    # 原文書から抽出されたテンプレート用の対訳表
    + ja.po      # 日本語用の対訳表
  + po4a.cfg     # po4aの構成
```

あとは対訳表`/translation/po/ja.po`を編集しつつ、po4aを走らせて翻訳文書`/translation/ja/index.html`を確認するだけです。

ただし実際のファイル構成は上とは少し違っています。

まず、po4aではHTMLをそのままでは扱えないため、XHTMLに変換する工程が必要です。ここではXMLとHTMLの構文解析ライブラリであるNokogiriを使ってRubyのスクリプトを用意しています。なお、po4aが対応している形式は色々あり、[po4a / Table of Contents][mods]の各モジュールとして構文解析器が定義されています。

```ruby
#!/usr/bin/env ruby

require 'nokogiri'

puts Nokogiri::HTML($stdin).to_xhtml
```

また、翻訳文書には補遺として原文書のクレジットを記載することが必須のことがほとんどですが、この機構もpo4aに一応備わっています。この仕組みは結構ややこしく、補遺の内容`/translation/add/ja/ref`と構成`/translation/po4a.cfg`での指定から雰囲気が掴めるかもしれません。

最後に、細かいところですがpo4aがHTMLから翻訳単位を抽出すると、ある場合に余計な空行が挿入されるようです。これについては既存の報告がないか探したのち、報告と修正の提案を考えていきたいところです。差し当たっては最終的なwebページを生成するスクリプト`finalize`を用意し、po4aにより生成されたHTML文書からそのような空白が除かれるようにしています。

```ruby
#!/usr/bin/env ruby

require "nokogiri"
# ...

doc = Nokogiri::HTML($stdin)

doc.xpath('//pre').each do |pre_tag|
  start_index = 0
  pre_tag.children.each_with_index do |child, index|
    next if child.is_a?(::Nokogiri::XML::Comment) || child.is_a?(::Nokogiri::XML::Text) && child.content.match?(/\A\s*\Z/)
    start_index = index
    break
  end
  pre_tag.children = pre_tag.children[start_index..]
end

# ...
```

以上で概説した工程についてはGNU Makeファイル`/translation/Makefile`にタスクとして定義されており、`make --directory translation タスク名`とするだけで必要なだけ処理が走るようになっています。

[po4a]: https://po4a.org/
[tt]: http://docs.translatehouse.org/projects/translate-toolkit/en/latest/
[omegat]: https://omegat.org/
[gettext]: https://www.gnu.org/software/gettext/
[tmx]: http://xml.coverpages.org/tmxSpec971212.html
[xliff]: http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm
[fluent]: https://projectfluent.org/
[mods]: https://po4a.org/man/

## ローカルで確認

Gettext POファイルでの訳文の確認もある程度はできますが、できればwebブラウザで仕上がりを見たいところです。ローカルでwebサーバーを立ち上げる方法は色々ありますが、私の環境ではApache HTTPdを稼動させているためこれを使います。`/etc/hosts`に`git-rebase.local`が`localhost`相当のIPアドレスを指すように追記し、HTTPdの構成で仮想ホストを追加するだけです。

HTTPdが無い場合でも、RubyやPythonで立ち上げることは簡単です。例えば[Guix][guix]でRubyのローカルサーバーを立ち上げるには以下とします。Rubyのバージョンは現在ネイティブコンパイルが機能するRubyのバージョンを指定していますが、今後もバージョンが更新されていくことでしょう。

```sh
cd translation
guix shell ruby@3.1 ruby-webrick
ruby -run -ehttpd ja
```

[guix]: https://guix.gnu.org/

## sourcehut pagesで公開

GitHubやGitBucketにはリポジトリに含まれるファイルをwebサイトとして閲覧できるようにする機能があります。また[Surge][surge]のように、静的なコンテンツをアップロードするwebサービスもあります。sourcehutについてもそのようなサービスが提供されており、それがsourcehut pagesです。使い方については[sourcehut pages / Quick start with sourcehut pages][quick-start]にあります。

利用できるドメインは`ユーザー名.srht.site`ですから、本訳用にはスラグ`git-rebase`をパスに付け、`gemmaro.srht.site/git-rebase`を割り当てることにしました。

とりたてて詰まるところはありませんが、`tar`のオプションは書かれている通りに揃えると良いでしょう。違う圧縮方式では`hut pages publish`コマンド時にエラーになります。

また、webページ`index.html`から`index.css`へのスタイルシートの読み込みがありますが、どうしたことか相対パスが効かないようです。そのため先の`finalize`スクリプトではスタイルシートへのパスを受け取れるようにし、デプロイ用の呼び出し箇所では絶対パスの`/git-rebase/index.css`を指定しています。

```ruby
require "nokogiri"
require "optparse"

stylesheet = nil
OptionParser.new do |parser|
  parser.on("--stylesheet=PATH") { |path| stylesheet = path }
  parser.on("--help") do
    warn parser.help
    exit
  end
end.parse!

doc = Nokogiri::HTML($stdin)

# ...

doc.xpath('//link').first["href"] = stylesheet if stylesheet

# ...
```

```make
# ...

${deploy-webpage}: ${temporary-output-webpage} ${finalize-script}
	${make-directory}
	./${finalize-script} --stylesheet=/${git-rebase-slug}/${stylesheet-filename} < $< > $@
```

## まとめ

本記事ではGitに関係する記事の和訳作業の周辺について書きました。Gitに限らず、日本語以外で書かれた有用な技術情報は多く公開されています。そうしたもののうち、特に頻繁に参照していることに気付いたら、和訳してみるのも手かと思います。

翻訳管理ツール活用の程良くややこしい一事例の紹介でした。

[rebase]: https://git-rebase.io/
[rebase-ja]: https://gemmaro.srht.site/git-rebase
[repo]: https://git.sr.ht/~gemmaro/git-rebase.io
[quick-start]: https://srht.site/quickstart
[surge]: https://surge.sh/