=encoding utf-8

=head1 NAME

App::Greple::xlate - Übersetzungsunterstützungsmodul für greple

=head1 SYNOPSIS

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

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

    greple -Mxlate --xlate-engine gpt5 --xlate pattern target-file

=head1 VERSION

Version 1.0201

=head1 DESCRIPTION

B<Greple> B<xlate>-Modul findet gewünschte Textblöcke und ersetzt sie durch den übersetzten Text. Derzeit sind DeepL (F<deepl.pm>) und das GPT-5.5-(F<gpt5.pm>)-Modul als Backend-Engine implementiert.

Wenn Sie normale Textblöcke in einem Dokument im POD-Stil von Perl übersetzen möchten, verwenden Sie den Befehl B<greple> mit den Modulen C<xlate::deepl> und C<perl> wie folgt:

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

In diesem Befehl bedeutet die Zeichenkette C<^([\w\pP].*\n)+> aufeinanderfolgende Zeilen, die mit alphanumerischen und Interpunktionszeichen beginnen. Dieser Befehl zeigt den zu übersetzenden Bereich hervorgehoben an. Die Option B<--all> wird verwendet, um den gesamten Text auszugeben.

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

Fügen Sie dann die Option C<--xlate> hinzu, um den ausgewählten Bereich zu übersetzen. Dann werden die gewünschten Abschnitte gefunden und durch die Ausgabe des Befehls B<deepl> ersetzt.

Standardmäßig werden Original- und übersetzter Text im „Konfliktmarker“-Format ausgegeben, das mit L<git(1)> kompatibel ist. Mit dem Format C<ifdef> können Sie den gewünschten Teil einfach mit dem Befehl L<unifdef(1)> erhalten. Das Ausgabeformat kann mit der Option B<--xlate-format> angegeben werden.

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

Wenn Sie den gesamten Text übersetzen möchten, verwenden Sie die Option B<--match-all>. Dies ist eine Abkürzung, um das Muster C<(?s).+> anzugeben, das den gesamten Text erfasst.

Daten im Konfliktmarker-Format können im Side-by-Side-Stil mit dem Befehl L<sdif|App::sdif> und der Option C<-V> angezeigt werden. Da ein Vergleich pro Zeichenkette keinen Sinn ergibt, wird die Option C<--no-cdif> empfohlen. Wenn Sie den Text nicht einfärben müssen, geben Sie C<--no-textcolor> (oder C<--no-tc>) an.

    sdif -V --no-filename --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

Die Verarbeitung erfolgt in angegebenen Einheiten, aber bei einer Folge mehrerer Zeilen nichtleeren Textes werden diese zusammen in eine einzelne Zeile konvertiert. Dieser Vorgang wird wie folgt durchgeführt:

=over 2

=item *

Entfernen Sie Leerzeichen am Anfang und Ende jeder Zeile.

=item *

Wenn eine Zeile mit einem vollbreiten Satzzeichen endet, mit der nächsten Zeile verketten.

=item *

Wenn eine Zeile mit einem vollbreiten Zeichen endet und die nächste Zeile mit einem vollbreiten Zeichen beginnt, die Zeilen verketten.

=item *

Wenn entweder das Ende oder der Anfang einer Zeile kein vollbreites Zeichen ist, sie durch Einfügen eines Leerzeichens verketten.

=back

Cache-Daten werden auf Basis des normalisierten Textes verwaltet, sodass zwischengespeicherte Übersetzungsdaten weiterhin wirksam sind, selbst wenn Änderungen vorgenommen werden, die das Normalisierungsergebnis nicht beeinflussen.

Dieser Normalisierungsprozess wird nur für das erste (0.) und die geradzahligen Muster durchgeführt. Wenn also zwei Muster wie folgt angegeben werden, wird der Text, der dem ersten Muster entspricht, nach der Normalisierung verarbeitet, und für den Text, der dem zweiten Muster entspricht, wird kein Normalisierungsprozess durchgeführt.

    greple -Mxlate -E normalized -E not-normalized

Verwenden Sie daher das erste Muster für Text, der durch das Kombinieren mehrerer Zeilen zu einer einzelnen Zeile verarbeitet werden soll, und das zweite Muster für vorformatierten Text. Wenn es keinen Text gibt, der auf das erste Muster passt, verwenden Sie ein Muster, das nichts trifft, wie C<(?!)>.

=head1 MASKING

Gelegentlich gibt es Textteile, die nicht übersetzt werden sollen. Zum Beispiel Tags in Markdown-Dateien. DeepL schlägt in solchen Fällen vor, den auszuschließenden Teil des Textes in XML-Tags umzuwandeln, zu übersetzen und nach Abschluss der Übersetzung wiederherzustellen. Um dies zu unterstützen, ist es möglich, die Teile zu spezifizieren, die von der Übersetzung maskiert werden sollen.

    --xlate-setopt maskfile=MASKPATTERN

Dies interpretiert jede Zeile der Datei C<MASKPATTERN> als regulären Ausdruck, übersetzt Zeichenfolgen, die damit übereinstimmen, und stellt nach der Verarbeitung den ursprünglichen Zustand wieder her. Zeilen, die mit C<#> beginnen, werden ignoriert.

Komplexe Muster können mit einem durch Backslash maskierten Zeilenumbruch über mehrere Zeilen geschrieben werden.

Wie der Text durch Maskierung transformiert wird, kann mit der Option B<--xlate-mask> gesehen werden.

Diese Schnittstelle ist experimentell und kann sich in Zukunft ändern.

=head1 OPTIONS

=over 7

=item B<--xlate>

=item B<--xlate-color>

=item B<--xlate-fold>

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

Rufen Sie den Übersetzungsprozess für jeden übereinstimmenden Bereich auf.

Ohne diese Option verhält sich B<greple> wie ein normaler Suchbefehl. So können Sie prüfen, welcher Teil der Datei Gegenstand der Übersetzung wird, bevor die eigentliche Arbeit gestartet wird.

Das Kommandoergebnis geht an die Standardausgabe; leiten Sie es bei Bedarf in eine Datei um oder erwägen Sie die Verwendung des Moduls L<App::Greple::update>.

Option B<--xlate> ruft die Option B<--xlate-color> mit der Option B<--color=never> auf.

Mit der Option B<--xlate-fold> wird der konvertierte Text auf die angegebene Breite umgebrochen. Die Standardbreite beträgt 70 und kann mit der Option B<--xlate-fold-width> gesetzt werden. Vier Spalten sind für die Einlaufoperation reserviert, sodass jede Zeile höchstens 74 Zeichen aufnehmen kann.

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

Gibt die zu verwendende Übersetzungs-Engine an. Wenn Sie das Engine-Modul direkt angeben, wie C<-Mxlate::deepl>, müssen Sie diese Option nicht verwenden.

Derzeit sind die folgenden Engines verfügbar

=over 2

=item * B<deepl>: DeepL API

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

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

Die Schnittstelle von B<gpt-4o> ist instabil und kann derzeit nicht garantiert korrekt funktionieren.

=item * B<gpt5>: gpt-5.5

=back

=item B<--xlate-labor>

=item B<--xlabor>

Anstatt die Übersetzungs-Engine aufzurufen, wird erwartet, dass Sie die Arbeit übernehmen. Nachdem der zu übersetzende Text vorbereitet wurde, wird er in die Zwischenablage kopiert. Sie sollen ihn in das Formular einfügen, das Ergebnis in die Zwischenablage kopieren und die Eingabetaste drücken.

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

Geben Sie die Zielsprache an. Verfügbare Sprachen erhalten Sie mit dem Befehl C<deepl languages>, wenn Sie die Engine B<DeepL> verwenden.

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

Geben Sie das Ausgabeformat für Original- und übersetzten Text an.

Die folgenden Formate außer C<xtxt> setzen voraus, dass der zu übersetzende Teil eine Sammlung von Zeilen ist. Tatsächlich ist es möglich, nur einen Teil einer Zeile zu übersetzen, aber die Angabe eines anderen Formats als C<xtxt> führt nicht zu sinnvollen Ergebnissen.

=over 4

=item B<conflict>, B<cm>

Original- und konvertierter Text werden im Konfliktmarker-Format von L<git(1)> ausgegeben.

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

Sie können die Originaldatei mit dem nächsten Befehl L<sed(1)> wiederherstellen.

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

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

Der Original- und der übersetzte Text werden in einem benutzerdefinierten Containerstil von Markdown ausgegeben.

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

Der obige Text wird im HTML in Folgendes übersetzt.

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

Die Anzahl der Doppelpunkte beträgt standardmäßig 7. Wenn Sie eine Doppelpunktsfolge wie C<:::::> angeben, wird diese anstelle von 7 Doppelpunkten verwendet.

=item B<ifdef>

Original- und konvertierter Text werden im Format L<cpp(1)> C<#ifdef> ausgegeben.

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

Sie können nur den japanischen Text mit dem Befehl B<unifdef> abrufen:

    unifdef -UORIGINAL -DJA foo.ja.pm

=item B<space>

=item B<space+>

Original- und konvertierter Text werden durch eine einzelne Leerzeile getrennt ausgegeben. Für C<space+> wird nach dem konvertierten Text zusätzlich ein Zeilenumbruch ausgegeben.

=item B<xtxt>

Wenn das Format C<xtxt> (übersetzter Text) oder unbekannt ist, wird nur der übersetzte Text ausgegeben.

=back

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

Geben Sie die maximale Textlänge an, die auf einmal an die API gesendet wird. Der Standardwert ist für den kostenlosen DeepL-Konto-Dienst festgelegt: 128K für die API (B<--xlate>) und 5000 für die Zwischenablage-Schnittstelle (B<--xlate-labor>). Wenn Sie den Pro-Dienst verwenden, können Sie diese Werte möglicherweise ändern.

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

Geben Sie die maximale Anzahl von Textzeilen an, die auf einmal an die API gesendet werden.

Setzen Sie diesen Wert auf 1, wenn Sie eine Zeile nach der anderen übersetzen möchten. Diese Option hat Vorrang vor der Option C<--xlate-maxlen>.

=item B<--xlate-prompt>=I<text>

Geben Sie einen benutzerdefinierten Prompt an, der an die Übersetzungs-Engine gesendet werden soll. Diese Option ist nur verfügbar, wenn ChatGPT-Engines (gpt3, gpt4o, gpt5) verwendet werden. Sie können das Übersetzungsverhalten anpassen, indem Sie dem KI-Modell spezifische Anweisungen geben. Wenn der Prompt C<%s> enthält, wird er durch den Namen der Zielsprache ersetzt.

=item B<--xlate-context>=I<text>

Geben Sie zusätzliche Kontextinformationen an, die an die Übersetzungs-Engine gesendet werden. Diese Option kann mehrfach verwendet werden, um mehrere Kontextzeichenfolgen bereitzustellen. Die Kontextinformationen helfen der Übersetzungs-Engine, den Hintergrund zu verstehen und genauere Übersetzungen zu liefern.

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

Geben Sie eine Glossar-ID an, die für die Übersetzung verwendet werden soll. Diese Option ist nur bei Verwendung der DeepL-Engine verfügbar. Die Glossar-ID sollte aus Ihrem DeepL-Konto stammen und sorgt für eine konsistente Übersetzung spezifischer Begriffe.

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

Sehen Sie das Übersetzungsergebnis in Echtzeit in der STDERR-Ausgabe.

=item B<--xlate-stripe>

Verwenden Sie das Modul L<App::Greple::stripe>, um den übereinstimmenden Teil im Zebra-Streifen-Stil anzuzeigen. Dies ist nützlich, wenn die übereinstimmenden Teile nahtlos aneinandergrenzen.

Die Farbpalette wird entsprechend der Hintergrundfarbe des Terminals umgeschaltet. Wenn Sie dies explizit angeben möchten, können Sie B<--xlate-stripe-light> oder B<--xlate-stripe-dark> verwenden.

=item B<--xlate-mask>

Führen Sie die Maskierungsfunktion aus und zeigen Sie den konvertierten Text unverändert ohne Wiederherstellung an.

=item B<--match-all>

Setzen Sie den gesamten Text der Datei als Zielbereich.

=item B<--lineify-cm>

=item B<--lineify-colon>

Bei den Formaten C<cm> und C<colon> wird die Ausgabe zeilenweise aufgeteilt und formatiert. Wenn daher nur ein Teil einer Zeile übersetzt werden soll, kann das erwartete Ergebnis nicht erzielt werden. Diese Filter korrigieren Ausgaben, die durch das Übersetzen eines Zeilenteils beschädigt wurden, zu einer normalen zeilenweisen Ausgabe.

In der aktuellen Implementierung werden mehrere übersetzte Teile einer Zeile als unabhängige Zeilen ausgegeben.

=back

=head1 CACHE OPTIONS

Das Modul B<xlate> kann für jede Datei zwischengespeicherten Übersetzungstext speichern und ihn vor der Ausführung einlesen, um den Overhead von Serveranfragen zu vermeiden. Mit der Standard-Cache-Strategie C<auto> werden Cache-Daten nur beibehalten, wenn die Cache-Datei für die Zieldatei existiert.

Verwenden Sie B<--xlate-cache=clear>, um die Cache-Verwaltung zu starten oder alle vorhandenen Cache-Daten zu bereinigen. Wenn diese Option einmal ausgeführt wurde, wird eine neue Cache-Datei erstellt, falls keine vorhanden ist, und anschließend automatisch gepflegt.

=over 7

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

=over 4

=item C<auto> (Default)

Pflegen Sie die Cache-Datei, falls sie existiert.

=item C<create>

Leere Cache-Datei erstellen und beenden.

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

Den Cache dennoch beibehalten, solange das Ziel eine normale Datei ist.

=item C<clear>

Zuerst die Cache-Daten löschen.

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

Cache-Datei niemals verwenden, selbst wenn sie existiert.

=item C<accumulate>

Standardmäßig werden ungenutzte Daten aus der Cache-Datei entfernt. Wenn Sie sie nicht entfernen und in der Datei behalten möchten, verwenden Sie C<accumulate>.

=back

=item B<--xlate-update>

Diese Option erzwingt das Aktualisieren der Cache-Datei, auch wenn es nicht notwendig ist.

=back

=head1 COMMAND LINE INTERFACE

Sie können dieses Modul einfach über die Kommandozeile verwenden, indem Sie den in der Distribution enthaltenen Befehl C<xlate> verwenden. Siehe die C<xlate>-Manpage zur Verwendung.

Der C<xlate>-Befehl unterstützt GNU-ähnliche Long-Optionen wie C<--to-lang>, C<--from-lang>, C<--engine> und C<--file>. Verwenden Sie C<xlate -h>, um alle verfügbaren Optionen anzuzeigen.

Der Befehl C<xlate> arbeitet mit der Docker-Umgebung zusammen. Selbst wenn Sie lokal nichts installiert haben, können Sie ihn verwenden, solange Docker verfügbar ist. Verwenden Sie die Option C<-D> oder C<-C>.

Docker-Operationen werden von L<App::dozo> gehandhabt, das auch als eigenständiger Befehl verwendet werden kann. Der Befehl C<dozo> unterstützt die Konfigurationsdatei C<.dozorc> für persistente Container-Einstellungen.

Da Makefiles für verschiedene Dokumentstile bereitgestellt werden, ist die Übersetzung in andere Sprachen ohne besondere Spezifikation möglich. Verwenden Sie die Option C<-M>.

Sie können die Optionen Docker und C<make> auch kombinieren, sodass Sie C<make> in einer Docker-Umgebung ausführen können.

Das Ausführen wie C<xlate -C> startet eine Shell mit dem aktuell eingehängten Git-Repository als Arbeitsverzeichnis.

Lesen Sie den japanischen Artikel im Abschnitt L</SEE ALSO> für Details.

=head1 EMACS

Laden Sie die im Repository enthaltene Datei F<xlate.el>, um den Befehl C<xlate> aus dem Emacs-Editor zu verwenden. Die Funktion C<xlate-region> übersetzt den angegebenen Bereich. Die Standardsprache ist C<EN-US>, und Sie können die Sprache angeben, indem Sie sie mit Präfix-Argument aufrufen.

=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

Legen Sie Ihren Authentifizierungsschlüssel für den DeepL-Dienst fest.

=item OPENAI_API_KEY

OpenAI-Authentifizierungsschlüssel.

=back

=head1 INSTALL

=head2 CPANMINUS

    $ cpanm App::Greple::xlate

=head2 TOOLS

Sie müssen die Kommandozeilentools für DeepL und ChatGPT installieren.

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

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

=head1 SEE ALSO

=head2 MODULES

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

L<App::dozo> - Generischer Docker-Runner, der von xlate für Container-Operationen verwendet wird

=head2 RELATED MODULES

=over 2

=item * L<App::Greple>

Siehe das Handbuch B<greple> für Details zum Zieltextmuster. Verwenden Sie die Optionen B<--inside>, B<--outside>, B<--include>, B<--exclude>, um den Abgleichsbereich einzuschränken.

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

Sie können das Modul C<-Mupdate> verwenden, um Dateien anhand des Ergebnisses des Befehls B<greple> zu ändern.

=item * L<App::sdif>

Verwenden Sie B<sdif>, um das Konfliktmarker-Format nebeneinander mit der Option B<-V> anzuzeigen.

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

Greple-Modul B<stripe> wird mit der Option B<--xlate-stripe> verwendet.

=back

=head2 RESOURCES

=over 2

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

Docker-Container-Image.

=item * L<https://github.com/tecolicom/getoptlong>

Die Bibliothek C<getoptlong.sh>, die für die Optionsanalyse im Skript C<xlate> und L<App::dozo> verwendet wird.

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

DeepL-Python-Bibliothek und CLI-Befehl.

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

OpenAI-Python-Bibliothek

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

OpenAI-Kommandozeilenschnittstelle

=back

=head2 ARTICLES

=over 2

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

Greple-Modul zum Übersetzen und Ersetzen nur der notwendigen Teile mit der DeepL-API (auf Japanisch)

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

Erzeugen von Dokumenten in 15 Sprachen mit dem DeepL-API-Modul (auf Japanisch)

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

Automatische Übersetzungs-Docker-Umgebung mit der DeepL-API (auf Japanisch)

=back

=head1 AUTHOR

Kazumasa Utashiro

=head1 LICENSE

Copyright © 2023-2026 Kazumasa Utashiro.

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

=cut
