=encoding utf-8

=head1 NAME

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

=head1 SYNOPSIS

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

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

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

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

=head1 VERSION

Version 0.9918

=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>), ChatGPT 4.1 (F<gpt4.pm>) und GPT-5 (F<gpt5.pm>) als Back-End-Engines implementiert.

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

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

In diesem Befehl bedeutet der Musterstring C<^([\w\pP].*\n)+> aufeinanderfolgende Zeilen, die mit alphanumerischen und Satzzeichen beginnen. Dieser Befehl hebt den zu übersetzenden Bereich hervor. 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 B<deepl>-Befehls ersetzt.

Standardmäßig werden Original- und Übersetzungstext im "Konfliktmarker"-Format ausgegeben, das mit L<git(1)> kompatibel ist. Mit dem C<ifdef>-Format können Sie den gewünschten Teil einfach mit dem L<unifdef(1)>-Befehl extrahieren. Das Ausgabeformat kann mit der Option B<--xlate-format> festgelegt 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 für das Muster C<(?s).+>, das auf den gesamten Text passt.

Konfliktmarkierungsformatdaten können im Nebeneinander-Stil mit dem Befehl L<sdif|App::sdif> und der Option C<-V> angezeigt werden. Da ein Vergleich auf Zeichenkettenbasis 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 den angegebenen Einheiten, aber bei einer Folge mehrerer Zeilen mit nicht-leerem Text werden diese zusammen in eine einzige Zeile umgewandelt. Dieser Vorgang wird wie folgt durchgeführt:

=over 2

=item *

Entfernen von Leerzeichen am Anfang und Ende jeder Zeile.

=item *

Wenn eine Zeile mit einem vollbreiten Satzzeichen endet, wird sie mit der nächsten Zeile verbunden.

=item *

Wenn eine Zeile mit einem vollbreiten Zeichen endet und die nächste Zeile mit einem vollbreiten Zeichen beginnt, werden die Zeilen zusammengefügt.

=item *

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

=back

Cache-Daten werden auf Basis des normalisierten Textes verwaltet, sodass auch bei Änderungen, die das Normalisierungsergebnis nicht beeinflussen, die zwischengespeicherten Übersetzungsdaten weiterhin wirksam sind.

Dieser Normalisierungsprozess wird nur für das erste (0.) und gerade nummerierte 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, erfolgt keine Normalisierung.

    greple -Mxlate -E normalized -E not-normalized

Verwenden Sie daher das erste Muster für Text, der durch Zusammenfassen mehrerer Zeilen zu einer einzigen Zeile verarbeitet werden soll, und das zweite Muster für vorformatierten Text. Wenn im ersten Muster kein Text gefunden wird, verwenden Sie ein Muster, das auf nichts passt, wie C<(?!)>.

=head1 MASKING

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

    --xlate-setopt maskfile=MASKPATTERN

Jede Zeile der Datei `MASKPATTERN` wird als regulärer Ausdruck interpretiert, passende Zeichenfolgen werden übersetzt und nach der Verarbeitung wiederhergestellt. Zeilen, die mit C<#> beginnen, werden ignoriert.

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

Wie der Text durch Maskierung umgewandelt wird, kann mit der Option B<--xlate-mask> angezeigt 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)

Der Übersetzungsprozess wird für jeden übereinstimmenden Bereich aufgerufen.

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

Das Kommandoergebnis wird an die Standardausgabe gesendet, daher ggf. in eine Datei umleiten oder das Modul L<App::Greple::update> verwenden.

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

Mit der Option B<--xlate-fold> wird der umgewandelte Text auf die angegebene Breite umgebrochen. Die Standardbreite beträgt 70 und kann mit der Option B<--xlate-fold-width> eingestellt werden. Vier Spalten sind für den Einzug reserviert, sodass jede Zeile maximal 74 Zeichen enthalten kann.

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

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

Derzeit sind folgende Engines verfügbar

=over 2

=item * B<deepl>: DeepL API

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

=item * B<gpt4>: gpt-4.1

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

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

=item * B<gpt5>: gpt-5

=back

=item B<--xlate-labor>

=item B<--xlabor>

Statt die Übersetzungs-Engine aufzurufen, wird erwartet, dass Sie selbst arbeiten. 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> bei Verwendung der Engine B<DeepL>.

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

Geben Sie das Ausgabeformat für Original- und Übersetzungstext an.

Die folgenden Formate außer C<xtxt> gehen davon aus, 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 umgewandelter Text werden im Konfliktmarker-Format 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 im benutzerdefinierten Container-Stil von Markdown ausgegeben.

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

Der obige Text wird im Folgenden in HTML ü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 Doppelpunktsequenz wie C<:::::> angeben, wird diese anstelle von 7 Doppelpunkten verwendet.

=item B<ifdef>

Original- und umgewandelter Text werden im L<cpp(1)> C<#ifdef>-Format 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.

=item B<xtxt>

Für C<space+> wird nach dem konvertierten Text ebenfalls eine neue Zeile ausgegeben.

=back

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

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

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

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

Geben Sie die maximale Zeilenanzahl an, die auf einmal an die API gesendet werden soll.

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

Geben Sie eine benutzerdefinierte Eingabeaufforderung an, die an die Übersetzungs-Engine gesendet wird. Diese Option ist nur verfügbar, wenn ChatGPT-Engines (gpt3, gpt4, gpt4o) verwendet werden. Sie können das Übersetzungsverhalten anpassen, indem Sie dem KI-Modell spezifische Anweisungen geben. Wenn die Eingabeaufforderung C<%s> enthält, wird sie 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 erzeugen.

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

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

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

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

=item B<--xlate-stripe>

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

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

=item B<--xlate-mask>

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<--match-all>

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

=item B<--lineify-cm>

=item B<--lineify-colon>

Im Fall der C<cm>- und C<colon>-Formate wird die Ausgabe zeilenweise aufgeteilt und formatiert. Daher kann das erwartete Ergebnis nicht erzielt werden, wenn nur ein Teil einer Zeile übersetzt wird. Diese Filter beheben Ausgaben, die durch die Übersetzung eines Teils einer Zeile beschädigt wurden, indem sie eine normale zeilenweise Ausgabe erzeugen.

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

=back

=head1 CACHE OPTIONS

Setzen Sie den gesamten Text der Datei als Zielbereich.

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

=over 7

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

=over 4

=item C<auto> (Default)

Verwenden Sie B<--xlate-cache=clear>, um das Cache-Management zu starten oder alle vorhandenen Cache-Daten zu bereinigen. Nach der Ausführung mit dieser Option wird eine neue Cache-Datei erstellt, falls keine existiert, und anschließend automatisch gepflegt.

=item C<create>

Pflegen Sie die Cache-Datei, wenn sie existiert.

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

Leere Cache-Datei erstellen und beenden.

=item C<clear>

Cache auf jeden Fall pflegen, solange das Ziel eine normale Datei ist.

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

Löschen Sie zuerst die Cache-Daten.

=item C<accumulate>

Verwenden Sie niemals eine Cache-Datei, auch wenn sie existiert.

=back

=item B<--xlate-update>

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

=back

=head1 COMMAND LINE INTERFACE

Diese Option erzwingt die Aktualisierung der Cache-Datei, auch wenn dies nicht notwendig ist.

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

Sie können dieses Modul einfach über die Befehlszeile mit dem in der Distribution enthaltenen C<xlate>-Befehl verwenden. Siehe die C<xlate>-Manpage für die Verwendung.

Docker-Operationen werden vom C<xrun>-Skript verarbeitet, das auch als eigenständiger Befehl verwendet werden kann. Das C<xrun>-Skript unterstützt die C<.xrunrc>-Konfigurationsdatei für persistente Container-Einstellungen.

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

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

Sie können auch die Docker- und C<make>-Optionen 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 eingebundenen Arbeits-Git-Repository.

=head1 EMACS

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

=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

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

=item OPENAI_API_KEY

OpenAI-Authentifizierungsschlüssel.

=back

=head1 INSTALL

=head2 CPANMINUS

    $ cpanm App::Greple::xlate

=head2 TOOLS

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

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::gpt4>

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

=over 2

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

Docker-Container-Image.

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

Die C<getoptlong.sh>-Bibliothek wird für die Optionsauswertung in den C<xlate>- und C<xrun>-Skripten verwendet.

=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-Befehlszeilenschnittstelle

=item * L<App::Greple>

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

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

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

=item * L<App::sdif>

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

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

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

=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>

Erstellung 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 DeepL-API (auf Japanisch)

=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
