=encoding utf-8

=head1 NAME

App::Greple::xlate - modul dukungan terjemahan untuk 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 menemukan blok teks yang diinginkan dan menggantinya dengan teks terjemahan. Saat ini modul DeepL (F<deepl.pm>), ChatGPT 4.1 (F<gpt4.pm>), dan GPT-5 (F<gpt5.pm>) telah diimplementasikan sebagai mesin back-end.

Jika Anda ingin menerjemahkan blok teks biasa dalam dokumen yang ditulis dengan gaya pod Perl, gunakan perintah B<greple> dengan modul C<xlate::deepl> dan C<perl> seperti ini:

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

Dalam perintah ini, string pola C<^([\w\pP].*\n)+> berarti baris-baris berurutan yang dimulai dengan huruf alfanumerik dan tanda baca. Perintah ini menampilkan area yang akan diterjemahkan dengan sorotan. Opsi B<--all> digunakan untuk menghasilkan seluruh teks.

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

Kemudian tambahkan opsi C<--xlate> untuk menerjemahkan area yang dipilih. Maka, modul ini akan menemukan bagian yang diinginkan dan menggantinya dengan keluaran perintah B<deepl>.

Secara default, teks asli dan terjemahan dicetak dalam format "conflict marker" yang kompatibel dengan L<git(1)>. Dengan menggunakan format C<ifdef>, Anda dapat mengambil bagian yang diinginkan dengan perintah L<unifdef(1)> dengan mudah. Format keluaran dapat ditentukan dengan opsi 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>

Jika Anda ingin menerjemahkan seluruh teks, gunakan opsi B<--match-all>. Ini adalah jalan pintas untuk menentukan pola C<(?s).+> yang cocok dengan seluruh teks.

Format data penanda konflik dapat dilihat dalam gaya berdampingan dengan perintah L<sdif|App::sdif> menggunakan opsi C<-V>. Karena tidak masuk akal untuk membandingkan berdasarkan per-string, opsi C<--no-cdif> direkomendasikan. Jika Anda tidak perlu mewarnai teks, tentukan C<--no-textcolor> (atau C<--no-tc>).

    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

Pemrosesan dilakukan dalam satuan yang ditentukan, tetapi dalam kasus urutan beberapa baris teks yang tidak kosong, semuanya akan diubah bersama menjadi satu baris. Operasi ini dilakukan sebagai berikut:

=over 2

=item *

Hapus spasi di awal dan akhir setiap baris.

=item *

Jika sebuah baris diakhiri dengan karakter tanda baca lebar penuh, gabungkan dengan baris berikutnya.

=item *

Jika sebuah baris diakhiri dengan karakter lebar penuh dan baris berikutnya dimulai dengan karakter lebar penuh, gabungkan baris-baris tersebut.

=item *

Jika baik akhir maupun awal baris bukan karakter lebar penuh, gabungkan dengan menyisipkan karakter spasi.

=back

Data cache dikelola berdasarkan teks yang dinormalisasi, sehingga meskipun ada modifikasi yang tidak memengaruhi hasil normalisasi, data terjemahan yang di-cache tetap berlaku.

Proses normalisasi ini hanya dilakukan untuk pola pertama (ke-0) dan bernomor genap. Jadi, jika dua pola ditentukan seperti berikut, teks yang cocok dengan pola pertama akan diproses setelah normalisasi, dan tidak ada proses normalisasi pada teks yang cocok dengan pola kedua.

    greple -Mxlate -E normalized -E not-normalized

Oleh karena itu, gunakan pola pertama untuk teks yang akan diproses dengan menggabungkan beberapa baris menjadi satu baris, dan gunakan pola kedua untuk teks yang sudah diformat sebelumnya. Jika tidak ada teks yang cocok pada pola pertama, gunakan pola yang tidak cocok dengan apa pun, seperti C<(?!)>.

=head1 MASKING

Kadang-kadang, ada bagian dari teks yang tidak ingin Anda terjemahkan. Misalnya, tag dalam file markdown. DeepL menyarankan bahwa dalam kasus seperti itu, bagian teks yang ingin dikecualikan diubah menjadi tag XML, diterjemahkan, lalu dikembalikan setelah terjemahan selesai. Untuk mendukung ini, dimungkinkan untuk menentukan bagian-bagian yang akan dimask dari terjemahan.

    --xlate-setopt maskfile=MASKPATTERN

Ini akan menafsirkan setiap baris file `MASKPATTERN` sebagai ekspresi reguler, menerjemahkan string yang cocok dengannya, dan mengembalikannya setelah diproses. Baris yang diawali dengan C<#> diabaikan.

Pola kompleks dapat ditulis dalam beberapa baris dengan newline yang di-escape dengan backslash.

Bagaimana teks diubah dengan masking dapat dilihat dengan opsi B<--xlate-mask>.

Antarmuka ini bersifat eksperimental dan dapat berubah di masa depan.

=head1 OPTIONS

=over 7

=item B<--xlate>

=item B<--xlate-color>

=item B<--xlate-fold>

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

Proses terjemahan dijalankan untuk setiap area yang cocok.

Tanpa opsi ini, B<greple> berperilaku sebagai perintah pencarian biasa. Jadi Anda dapat memeriksa bagian mana dari file yang akan menjadi subjek terjemahan sebelum menjalankan pekerjaan sebenarnya.

Hasil perintah akan keluar ke standar, jadi arahkan ke file jika perlu, atau pertimbangkan untuk menggunakan modul L<App::Greple::update>.

Opsi B<--xlate> memanggil opsi B<--xlate-color> dengan opsi B<--color=never>.

Dengan opsi B<--xlate-fold>, teks yang telah dikonversi akan dilipat sesuai lebar yang ditentukan. Lebar default adalah 70 dan dapat diatur dengan opsi B<--xlate-fold-width>. Empat kolom dicadangkan untuk operasi run-in, jadi setiap baris dapat menampung maksimal 74 karakter.

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

Menentukan mesin terjemahan yang akan digunakan. Jika Anda menentukan modul mesin secara langsung, seperti C<-Mxlate::deepl>, Anda tidak perlu menggunakan opsi ini.

Saat ini, mesin-mesin berikut tersedia

=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

Antarmuka B<gpt-4o> tidak stabil dan tidak dapat dijamin berfungsi dengan benar saat ini.

=item * B<gpt5>: gpt-5

=back

=item B<--xlate-labor>

=item B<--xlabor>

Alih-alih memanggil mesin terjemahan, Anda diharapkan untuk bekerja secara manual. Setelah menyiapkan teks yang akan diterjemahkan, teks tersebut disalin ke clipboard. Anda diharapkan menempelkannya ke formulir, menyalin hasilnya ke clipboard, dan menekan return.

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

Tentukan bahasa target. Anda dapat melihat bahasa yang tersedia dengan perintah C<deepl languages> saat menggunakan mesin B<DeepL>.

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

Tentukan format keluaran untuk teks asli dan terjemahan.

Format berikut selain C<xtxt> mengasumsikan bahwa bagian yang akan diterjemahkan adalah kumpulan baris. Sebenarnya, dimungkinkan untuk menerjemahkan hanya sebagian dari satu baris, tetapi menentukan format selain C<xtxt> tidak akan menghasilkan hasil yang bermakna.

=over 4

=item B<conflict>, B<cm>

Teks asli dan yang telah dikonversi dicetak dalam format penanda konflik L<git(1)>.

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

Anda dapat memulihkan file asli dengan perintah L<sed(1)> berikutnya.

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

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

Teks asli dan terjemahan dikeluarkan dalam gaya custom container markdown.

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

Teks di atas akan diterjemahkan menjadi berikut ini dalam HTML.

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

Jumlah titik dua adalah 7 secara default. Jika Anda menentukan urutan titik dua seperti C<:::::>, itu akan digunakan sebagai pengganti 7 titik dua.

=item B<ifdef>

Teks asli dan yang telah dikonversi dicetak dalam format L<cpp(1)> C<#ifdef>.

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

Anda dapat mengambil hanya teks Jepang dengan perintah B<unifdef>:

    unifdef -UORIGINAL -DJA foo.ja.pm

=item B<space>

=item B<space+>

Teks asli dan teks yang telah dikonversi dicetak dipisahkan oleh satu baris kosong.

=item B<xtxt>

Untuk C<space+>, juga akan menghasilkan baris baru setelah teks yang telah dikonversi.

=back

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

Jika formatnya adalah C<xtxt> (teks yang diterjemahkan) atau tidak dikenal, hanya teks yang diterjemahkan yang dicetak.

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

Tentukan panjang maksimum teks yang akan dikirim ke API sekaligus. Nilai default diatur seperti untuk layanan akun gratis DeepL: 128K untuk API (B<--xlate>) dan 5000 untuk antarmuka clipboard (B<--xlate-labor>). Anda mungkin dapat mengubah nilai ini jika menggunakan layanan Pro.

Tentukan jumlah baris maksimum teks yang akan dikirim ke API sekaligus.

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

Tentukan prompt khusus yang akan dikirimkan ke mesin terjemahan. Opsi ini hanya tersedia saat menggunakan mesin ChatGPT (gpt3, gpt4, gpt4o). Anda dapat menyesuaikan perilaku terjemahan dengan memberikan instruksi spesifik kepada model AI. Jika prompt berisi C<%s>, maka akan digantikan dengan nama bahasa target.

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

Tentukan informasi konteks tambahan yang akan dikirimkan ke mesin terjemahan. Opsi ini dapat digunakan beberapa kali untuk memberikan beberapa string konteks. Informasi konteks membantu mesin terjemahan memahami latar belakang dan menghasilkan terjemahan yang lebih akurat.

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

Tentukan ID glosarium yang akan digunakan untuk terjemahan. Opsi ini hanya tersedia saat menggunakan mesin DeepL. ID glosarium harus diperoleh dari akun DeepL Anda dan memastikan konsistensi terjemahan istilah tertentu.

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

Atur nilai ini ke 1 jika Anda ingin menerjemahkan satu baris pada satu waktu. Opsi ini memiliki prioritas lebih tinggi daripada opsi C<--xlate-maxlen>.

=item B<--xlate-stripe>

Lihat hasil terjemahan secara real time di output STDERR.

Gunakan modul L<App::Greple::stripe> untuk menampilkan bagian yang cocok dengan pola zebra striping. Ini berguna ketika bagian yang cocok terhubung secara berurutan.

=item B<--xlate-mask>

Palet warna akan berganti sesuai dengan warna latar belakang terminal. Jika Anda ingin menentukan secara eksplisit, Anda dapat menggunakan B<--xlate-stripe-light> atau B<--xlate-stripe-dark>.

=item B<--match-all>

Lakukan fungsi masking dan tampilkan teks yang telah dikonversi apa adanya tanpa pemulihan.

=item B<--lineify-cm>

=item B<--lineify-colon>

Dalam kasus format C<cm> dan C<colon>, output dibagi dan diformat baris demi baris. Oleh karena itu, jika hanya sebagian dari sebuah baris yang diterjemahkan, hasil yang diharapkan tidak dapat diperoleh. Filter-filter ini memperbaiki output yang rusak akibat menerjemahkan sebagian baris menjadi output normal baris demi baris.

Dalam implementasi saat ini, jika beberapa bagian dari sebuah baris diterjemahkan, bagian-bagian tersebut akan dikeluarkan sebagai baris yang berdiri sendiri.

=back

=head1 CACHE OPTIONS

Atur seluruh teks file sebagai area target.

Modul B<xlate> dapat menyimpan teks terjemahan yang di-cache untuk setiap file dan membacanya sebelum eksekusi untuk menghilangkan overhead permintaan ke server. Dengan strategi cache default C<auto>, data cache hanya dipertahankan jika file cache ada untuk file target.

=over 7

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

=over 4

=item C<auto> (Default)

Gunakan B<--xlate-cache=clear> untuk memulai manajemen cache atau membersihkan semua data cache yang ada. Setelah dijalankan dengan opsi ini, file cache baru akan dibuat jika belum ada dan kemudian akan dipelihara secara otomatis setelahnya.

=item C<create>

Pertahankan file cache jika ada.

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

Buat file cache kosong dan keluar.

=item C<clear>

Tetap pertahankan cache selama target adalah file normal.

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

Bersihkan data cache terlebih dahulu.

=item C<accumulate>

Jangan pernah menggunakan file cache meskipun sudah ada.

=back

=item B<--xlate-update>

Secara default, data yang tidak digunakan akan dihapus dari file cache. Jika Anda tidak ingin menghapusnya dan tetap menyimpannya di file, gunakan C<accumulate>.

=back

=head1 COMMAND LINE INTERFACE

Opsi ini memaksa pembaruan file cache meskipun tidak diperlukan.

Perintah C<xlate> mendukung opsi panjang gaya GNU seperti C<--to-lang>, C<--from-lang>, C<--engine>, dan C<--file>. Gunakan C<xlate -h> untuk melihat semua opsi yang tersedia.

Anda dapat dengan mudah menggunakan modul ini dari baris perintah dengan menggunakan perintah C<xlate> yang disertakan dalam distribusi. Lihat halaman manual C<xlate> untuk penggunaannya.

Operasi Docker ditangani oleh skrip C<xrun>, yang juga dapat digunakan sebagai perintah mandiri. Skrip C<xrun> mendukung file konfigurasi C<.xrunrc> untuk pengaturan kontainer yang persisten.

Perintah C<xlate> bekerja bersama dengan lingkungan Docker, jadi meskipun Anda tidak memiliki apa pun yang terinstal, Anda dapat menggunakannya selama Docker tersedia. Gunakan opsi C<-D> atau C<-C>.

Selain itu, karena makefile untuk berbagai gaya dokumen disediakan, terjemahan ke bahasa lain dimungkinkan tanpa spesifikasi khusus. Gunakan opsi C<-M>.

Anda juga dapat menggabungkan opsi Docker dan C<make> sehingga Anda dapat menjalankan C<make> di lingkungan Docker.

Menjalankan seperti C<xlate -C> akan meluncurkan shell dengan repositori git kerja saat ini yang terpasang.

=head1 EMACS

Muat file F<xlate.el> yang disertakan dalam repositori untuk menggunakan perintah C<xlate> dari editor Emacs.

=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

Fungsi C<xlate-region> menerjemahkan region yang diberikan.

=item OPENAI_API_KEY

Bahasa default adalah C<EN-US> dan Anda dapat menentukan bahasa dengan memanggilnya menggunakan argumen prefiks.

=back

=head1 INSTALL

=head2 CPANMINUS

    $ cpanm App::Greple::xlate

=head2 TOOLS

Atur kunci autentikasi Anda untuk layanan DeepL.

Kunci autentikasi OpenAI.

Anda harus menginstal alat baris perintah untuk DeepL dan ChatGPT.

=head1 SEE ALSO

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

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

L<App::Greple::xlate::gpt4>

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

=over 2

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

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

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

Pustaka C<getoptlong.sh> digunakan untuk parsing opsi di skrip C<xlate> dan C<xrun>.

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

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

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

Gambar kontainer Docker.

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

Pustaka Python DeepL dan perintah CLI.

=item * L<App::Greple>

Pustaka Python OpenAI

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

Antarmuka baris perintah OpenAI

=item * L<App::sdif>

Lihat manual B<greple> untuk detail tentang pola teks target. Gunakan opsi B<--inside>, B<--outside>, B<--include>, B<--exclude> untuk membatasi area pencocokan.

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

Anda dapat menggunakan modul C<-Mupdate> untuk memodifikasi file berdasarkan hasil perintah B<greple>.

=back

=head2 ARTICLES

=over 2

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

Gunakan B<sdif> untuk menampilkan format penanda konflik berdampingan dengan opsi B<-V>.

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

Modul Greple B<stripe> digunakan dengan opsi B<--xlate-stripe>.

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

Modul Greple untuk menerjemahkan dan mengganti hanya bagian yang diperlukan dengan API DeepL (dalam bahasa Jepang)

=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
