=encoding utf-8

=head1 NAME

App::Greple::xlate - grepleの翻訳サポートモジュール

=head1 SYNOPSIS

    greple -Mxlate -e ENGINE --xlate pattern target-file

    greple -Mxlate::deepl --xlate pattern target-file

=head1 VERSION

Version 0.9908

=head1 DESCRIPTION

B<Greple> B<xlate>モジュールは、望ましいテキストブロックを見つけて翻訳されたテキストに置き換える機能を提供します。現在、DeepL（F<deepl.pm>）とChatGPT（F<gpt3.pm>）モジュールがバックエンドエンジンとして実装されています。gpt-4とgpt-4oの実験的なサポートも含まれています。

Perlのpodスタイルで書かれたドキュメント内の通常のテキストブロックを翻訳したい場合は、次のようにC<xlate::deepl>とC<perl>モジュールを使用したB<greple>コマンドを使用してください。

    greple -Mxlate::deepl -Mperl --pod --re '^([\w\pP].*\n)+' --all foo.pm

このコマンドでは、パターン文字列C<^([\w\pP].*\n)+>は、アルファベット、数字、句読点で始まる連続した行を意味します。このコマンドは、翻訳する領域をハイライト表示します。オプションB<--all>は、全文を表示するために使用されます。

=for html <p>
<img width="750" src="https://raw.githubusercontent.com/kaz-utashiro/App-Greple-xlate/main/images/select-area.png">
</p>

次に、選択したエリアを翻訳するためにC<--xlate>オプションを追加します。そうすると、必要なセクションを見つけて、それらをB<deepl>コマンドの出力で置き換えます。

デフォルトでは、元のテキストと翻訳されたテキストはL<git(1)>と互換性のある「競合マーカー」形式で出力されます。C<ifdef>形式を使用すると、L<unifdef(1)>コマンドで必要な部分を簡単に取得できます。出力形式はB<--xlate-format>オプションで指定できます。

=for html <p>
<img width="750" src="https://raw.githubusercontent.com/kaz-utashiro/App-Greple-xlate/main/images/format-conflict.png">
</p>

テキスト全体を翻訳したい場合は、B<--match-all>オプションを使用してください。これは、テキスト全体にマッチするパターンC<(?s).+>を指定するためのショートカットです。

コンフリクトマーカーフォーマットデータは、C<sdif>コマンドをC<-V>オプションとともに使用することで、サイドバイサイドスタイルで表示できます。文字列単位で比較する意味がないため、C<--no-cdif>オプションが推奨されています。テキストに色を付ける必要がない場合は、C<--no-textcolor>（またはC<--no-tc>）を指定してください。

    sdif -V --no-tc --no-cdif data_shishin.deepl-EN-US.cm

=for html <p>
<img width="750" src="https://raw.githubusercontent.com/kaz-utashiro/App-Greple-xlate/main/images/sdif-cm-view.png">
</p>

=head1 NORMALIZATION

処理は指定された単位で行われますが、複数行の非空のテキストのシーケンスの場合、それらは一緒に1行に変換されます。この操作は次のように行われます：

=over 2

=item *

各行の先頭と末尾の空白を削除します。

=item *

もし行が全角の句読点で終わる場合は、次の行と結合してください。

=item *

行が全角文字で終わり、次の行が全角文字で始まる場合、行を連結します。

=item *

行の終わりまたは始まりが全角文字でない場合、スペース文字を挿入してそれらを連結します。

=back

キャッシュデータは正規化されたテキストに基づいて管理されるため、正規化結果に影響を与えない変更が行われても、キャッシュされた翻訳データは引き続き有効です。

この正規化プロセスは、最初の（0番目）および偶数番目のパターンに対してのみ実行されます。したがって、2つのパターンが次のように指定された場合、最初のパターンに一致するテキストは正規化後に処理され、2番目のパターンに一致するテキストには正規化プロセスが実行されません。

    greple -Mxlate -E normalized -E not-normalized

したがって、複数の行を1行に結合して処理するテキストには最初のパターンを使用し、整形済みのテキストには2番目のパターンを使用します。最初のパターンに一致するテキストがない場合は、C<(?!)>のように何も一致しないパターンを使用してください。

=head1 MASKING

時々、翻訳したくないテキストの部分があります。たとえば、markdownファイル内のタグなどです。DeepLは、そのような場合、翻訳を除外するテキスト部分をXMLタグに変換し、翻訳が完了した後に元に戻すことを提案しています。これをサポートするために、翻訳からマスクする部分を指定することができます。

    --xlate-setopt maskfile=MASKPATTERN

これにより、ファイル`MASKPATTERN`の各行を正規表現として解釈し、それに一致する文字列を翻訳し、処理後に元に戻します。行頭がC<#>で始まる行は無視されます。

複雑なパターンは、バックスラッシュで改行をエスケープして複数行に書くことができます。

テキストがマスキングによって変換される方法は、B<--xlate-mask>オプションで確認できます。

このインターフェースは実験的であり、将来変更される可能性があります。

=head1 OPTIONS

=over 7

=item B<--xlate>

=item B<--xlate-color>

=item B<--xlate-fold>

=item B<--xlate-fold-width>=I<n> (Default: 70)

一致したエリアごとに翻訳プロセスを呼び出します。

このオプションを指定しない場合、B<greple>は通常の検索コマンドとして動作します。したがって、実際の作業を呼び出す前に、ファイルのどの部分が翻訳の対象になるかを確認できます。

コマンドの結果は標準出力に表示されるため、必要に応じてファイルにリダイレクトするか、L<App::Greple::update>モジュールを使用することを検討してください。

オプションB<--xlate>は、B<--xlate-color>オプションをB<--color=never>オプションとともに呼び出します。

B<--xlate-fold>オプションを使用すると、変換されたテキストが指定された幅で折り返されます。デフォルトの幅は70で、B<--xlate-fold-width>オプションで設定できます。4つの列はランイン操作に予約されているため、各行には最大で74文字が含まれることができます。

=item B<--xlate-engine>=I<engine>

使用する翻訳エンジンを指定します。C<-Mxlate::deepl>のようにエンジンモジュールを直接指定する場合は、このオプションを使用する必要はありません。

現時点では、以下のエンジンが利用可能です。

=over 2

=item * B<deepl>: DeepL API

=item * B<gpt3>: gpt-3.5-turbo

=item * B<gpt4>: gpt-4-turbo

=item * B<gpt4o>: gpt-4o-mini

B<gpt-4o>のインターフェースは不安定であり、現時点では正常に動作することが保証されていません。

=back

=item B<--xlate-labor>

=item B<--xlabor>

翻訳エンジンを呼び出す代わりに、あなたが作業することが期待されています。翻訳するためのテキストを準備した後、それらはクリップボードにコピーされます。フォームに貼り付けて結果をクリップボードにコピーし、リターンキーを押すことが期待されています。

=item B<--xlate-to> (Default: C<EN-US>)

対象言語を指定します。B<DeepL>エンジンを使用する場合は、C<deepl languages>コマンドで使用可能な言語を取得できます。

=item B<--xlate-format>=I<format> (Default: C<conflict>)

元のテキストと翻訳されたテキストの出力形式を指定します。

C<xtxt>以外の以下のフォーマットは、翻訳する部分が複数行のコレクションであると想定しています。実際には、1行の一部のみを翻訳することも可能であり、C<xtxt>以外のフォーマットを指定しても意味のある結果は得られません。

=over 4

=item B<conflict>, B<cm>

オリジナルと変換されたテキストは、L<git(1)>の競合マーカーフォーマットで印刷されます。

    <<<<<<< ORIGINAL
    original text
    =======
    translated Japanese text
    >>>>>>> JA

次のL<sed(1)>コマンドで元のファイルを復元できます。

    sed -e '/^<<<<<<< /d' -e '/^=======$/,/^>>>>>>> /d'

=item B<colon>, I<:::::::>

```html

    ::::::: ORIGINAL
    original text
    :::::::
    ::::::: JA
    translated Japanese text
    :::::::

<div class="translation">

    <div class="ORIGINAL">
    original text
    </div>
    <div class="JA">
    translated Japanese text
    </div>

Number of colon is 7 by default. If you specify colon sequence like `:::::::`, it is used instead of 7 colons.

=item B<ifdef>

オリジナルと変換されたテキストは、L<cpp(1)>のC<#ifdef>フォーマットで印刷されます。

    #ifdef ORIGINAL
    original text
    #endif
    #ifdef JA
    translated Japanese text
    #endif

B<unifdef>コマンドで日本語のテキストのみを取得できます：

    unifdef -UORIGINAL -DJA foo.ja.pm

=item B<space>

=item B<space+>

Hello, how can I help you today?

=item B<xtxt>

形式がC<xtxt>（翻訳されたテキスト）または不明な場合、翻訳されたテキストのみが表示されます。

=back

=item B<--xlate-maxlen>=I<chars> (Default: 0)

以下のテキストを日本語に翻訳してください。一度にAPIに送信するテキストの最大長を指定してください。デフォルト値は、無料のDeepLアカウントサービスに設定されています：API（B<--xlate>）には128K、クリップボードインターフェース（B<--xlate-labor>）には5000です。Proサービスを使用している場合は、これらの値を変更できるかもしれません。

=item B<--xlate-maxline>=I<n> (Default: 0)

一度にAPIに送信するテキストの最大行数を指定します。

1行ずつ翻訳したい場合は、この値を1に設定してください。このオプションはC<--xlate-maxlen>オプションよりも優先されます。

=item B<-->[B<no->]B<xlate-progress> (Default: True)

STDERR出力でリアルタイムに翻訳結果を確認します。

=item B<--xlate-stripe>

マッチした部分をゼブラストライプのように表示するために、L<App::Greple::stripe>モジュールを使用します。マッチした部分が連続している場合に便利です。

カラーパレットは、端末の背景色に応じて切り替わります。明示的に指定したい場合は、B<--xlate-stripe-light>またはB<--xlate-stripe-dark>を使用できます。

=item B<--xlate-mask>

マスキング機能を実行し、変換されたテキストを復元せずに表示します。

=item B<--match-all>

ファイルの全体のテキストを対象エリアとして設定します。

=back

=head1 CACHE OPTIONS

B<xlate>モジュールは、各ファイルの翻訳のキャッシュテキストを保存し、実行前にそれを読み込んでサーバーへの問い合わせのオーバーヘッドを排除することができます。デフォルトのキャッシュ戦略C<auto>では、対象ファイルのキャッシュファイルが存在する場合にのみキャッシュデータを保持します。

B<--xlate-cache=clear>を使用してキャッシュ管理を開始するか、既存のすべてのキャッシュデータをクリアします。このオプションを使用して実行すると、新しいキャッシュファイルが存在しない場合は作成され、その後自動的に維持されます。

=over 7

=item --xlate-cache=I<strategy>

=over 4

=item C<auto> (Default)

キャッシュファイルが存在する場合はメンテナンスします。

=item C<create>

空のキャッシュファイルを作成して終了します。

=item C<always>, C<yes>, C<1>

対象が通常のファイルである限り、常にキャッシュをメンテナンスします。

=item C<clear>

まずキャッシュデータをクリアします。

=item C<never>, C<no>, C<0>

キャッシュファイルを使用しないでください。

=item C<accumulate>

デフォルトの動作では、キャッシュファイルから未使用のデータが削除されます。それらを削除せずにファイルに保持したい場合は、C<accumulate>を使用してください。

=back

=item B<--xlate-update>

このオプションは、必要ない場合でもキャッシュファイルを更新するように強制します。

=back

=head1 COMMAND LINE INTERFACE

このモジュールは、配布物に含まれる C<xlate> コマンドを使用することで、簡単にコマンドラインから利用できます。使用方法については、C<xlate> マニュアルページを参照してください。

C<xlate>コマンドはDocker環境と連携して動作するため、手元に何もインストールされていなくても、Dockerが利用可能であれば使用することができます。C<-D>またはC<-C>オプションを使用してください。

また、さまざまなドキュメントスタイルのためのメイクファイルが提供されているため、特別な指定なしに他の言語への翻訳も可能です。C<-M>オプションを使用してください。

DockerとC<make>オプションを組み合わせることもできます。これにより、Docker環境でC<make>を実行できます。

C<xlate -C>のように実行すると、現在の作業gitリポジトリがマウントされたシェルが起動します。

詳細については、L</関連記事>セクションの日本語の記事を読んでください。

=head1 EMACS

EmacsエディタからC<xlate>コマンドを使用するには、リポジトリに含まれるF<xlate.el>ファイルをロードしてください。C<xlate-region>関数は指定された領域を翻訳します。デフォルトの言語はC<EN-US>であり、プレフィックス引数を使用して言語を指定することができます。

=for html <p>
<img width="750" src="https://raw.githubusercontent.com/kaz-utashiro/App-Greple-xlate/main/images/emacs.png">
</p>

=head1 ENVIRONMENT

=over 7

=item DEEPL_AUTH_KEY

DeepLサービスの認証キーを設定してください。

=item OPENAI_API_KEY

OpenAIの認証キーです。

=back

=head1 INSTALL

=head2 CPANMINUS

    $ cpanm App::Greple::xlate

=head2 TOOLS

DeepLとChatGPTのコマンドラインツールをインストールする必要があります。

L<https://github.com/DeepLcom/deepl-python>

L<https://github.com/tecolicom/App-gpty>

=head1 SEE ALSO

L<App::Greple::xlate>

L<App::Greple::xlate::deepl>

L<App::Greple::xlate::gpt3>

=over 2

=item * L<https://hub.docker.com/r/tecolicom/xlate>

Dockerコンテナイメージ。

=item * L<https://github.com/DeepLcom/deepl-python>

DeepL PythonライブラリとCLIコマンドです。

=item * L<https://github.com/openai/openai-python>

OpenAI Pythonライブラリ

=item * L<https://github.com/tecolicom/App-gpty>

OpenAIコマンドラインインターフェース

=item * L<App::Greple>

対象のテキストパターンに関する詳細については、B<greple>マニュアルを参照してください。一致する範囲を制限するために、B<--inside>、B<--outside>、B<--include>、B<--exclude>オプションを使用できます。

=item * L<App::Greple::update>

B<greple>コマンドの結果を使用してファイルを変更するために、C<-Mupdate>モジュールを使用することができます。

=item * L<App::sdif>

B<-V>オプションとともに、衝突マーカーフォーマットを並べて表示するためにB<sdif>を使用してください。

=item * L<App::Greple::stripe>

Greple B<stripe>モジュールは、B<--xlate-stripe>オプションを使用しています。

=back

=head2 ARTICLES

=over 2

=item * L<https://qiita.com/kaz-utashiro/items/1c1a51a4591922e18250>

DeepL APIを使用して必要な部分のみを翻訳および置換するためのGrepleモジュール（日本語）

=item * L<https://qiita.com/kaz-utashiro/items/a5e19736416ca183ecf6>

DeepL APIモジュールを使用して15言語でドキュメントを生成する（日本語）

=item * L<https://qiita.com/kaz-utashiro/items/1b9e155d6ae0620ab4dd>

DeepL APIを使用した自動翻訳Docker環境（日本語）

=back

=head1 AUTHOR

Kazumasa Utashiro

=head1 LICENSE

Copyright © 2023-2025 Kazumasa Utashiro.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut
