=encoding utf-8

=head1 NAME

App::Greple::xlate - módulo de soporte de traducción para 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> el módulo encuentra los bloques de texto deseados y los reemplaza por el texto traducido. Actualmente, los módulos DeepL (F<deepl.pm>), ChatGPT 4.1 (F<gpt4.pm>) y GPT-5 (F<gpt5.pm>) están implementados como motores de back-end.

Si desea traducir bloques de texto normales en un documento escrito en el estilo pod de Perl, utilice el comando B<greple> con los módulos C<xlate::deepl> y C<perl> de la siguiente manera:

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

En este comando, la cadena de patrón C<^([\w\pP].*\n)+> significa líneas consecutivas que comienzan con letras alfanuméricas y de puntuación. Este comando muestra el área a traducir resaltada. La opción B<--all> se utiliza para producir el texto completo.

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

Luego agregue la opción C<--xlate> para traducir el área seleccionada. Así, encontrará las secciones deseadas y las reemplazará por la salida del comando B<deepl>.

Por defecto, el texto original y el traducido se imprimen en el formato de "marcador de conflicto" compatible con L<git(1)>. Usando el formato C<ifdef>, puede obtener la parte deseada fácilmente con el comando L<unifdef(1)>. El formato de salida se puede especificar con la opción 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>

Si desea traducir todo el texto, utilice la opción B<--match-all>. Esto es un atajo para especificar el patrón C<(?s).+> que coincide con todo el texto.

Los datos en formato de marcador de conflicto pueden visualizarse en estilo lado a lado mediante el comando L<sdif|App::sdif> con la opción C<-V>. Dado que no tiene sentido comparar por cada cadena, se recomienda la opción C<--no-cdif>. Si no necesitas colorear el texto, especifica C<--no-textcolor> (o 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

El procesamiento se realiza en las unidades especificadas, pero en el caso de una secuencia de varias líneas de texto no vacío, se convierten juntas en una sola línea. Esta operación se realiza de la siguiente manera:

=over 2

=item *

Eliminar los espacios en blanco al principio y al final de cada línea.

=item *

Si una línea termina con un carácter de puntuación de ancho completo, concatenar con la siguiente línea.

=item *

Si una línea termina con un carácter de ancho completo y la siguiente línea comienza con un carácter de ancho completo, concatenar las líneas.

=item *

Si el final o el principio de una línea no es un carácter de ancho completo, concatenarlas insertando un carácter de espacio.

=back

Los datos de caché se gestionan en función del texto normalizado, por lo que incluso si se realizan modificaciones que no afectan los resultados de la normalización, los datos de traducción en caché seguirán siendo efectivos.

Este proceso de normalización se realiza solo para el primer (0º) y los patrones de número par. Así, si se especifican dos patrones como sigue, el texto que coincida con el primer patrón se procesará después de la normalización, y no se realizará ningún proceso de normalización en el texto que coincida con el segundo patrón.

    greple -Mxlate -E normalized -E not-normalized

Por lo tanto, utilice el primer patrón para el texto que deba procesarse combinando varias líneas en una sola línea, y utilice el segundo patrón para el texto preformateado. Si no hay texto que coincida con el primer patrón, utilice un patrón que no coincida con nada, como C<(?!)>.

=head1 MASKING

Ocasionalmente, hay partes del texto que no deseas traducir. Por ejemplo, las etiquetas en archivos markdown. DeepL sugiere que en tales casos, la parte del texto que se debe excluir se convierta en etiquetas XML, se traduzca y luego se restaure después de completar la traducción. Para admitir esto, es posible especificar las partes que se deben enmascarar de la traducción.

    --xlate-setopt maskfile=MASKPATTERN

Esto interpretará cada línea del archivo `MASKPATTERN` como una expresión regular, traducirá las cadenas que coincidan y las revertirá después del procesamiento. Las líneas que comienzan con C<#> se ignoran.

Un patrón complejo puede escribirse en varias líneas con una nueva línea escapada con barra invertida.

Cómo se transforma el texto mediante el enmascaramiento puede verse con la opción B<--xlate-mask>.

Esta interfaz es experimental y está sujeta a cambios en el futuro.

=head1 OPTIONS

=over 7

=item B<--xlate>

=item B<--xlate-color>

=item B<--xlate-fold>

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

Invoca el proceso de traducción para cada área coincidente.

Sin esta opción, B<greple> se comporta como un comando de búsqueda normal. Así puedes comprobar qué parte del archivo será objeto de la traducción antes de invocar el trabajo real.

El resultado del comando va a la salida estándar, así que redirígelo a un archivo si es necesario, o considera usar el módulo L<App::Greple::update>.

La opción B<--xlate> llama a la opción B<--xlate-color> con la opción B<--color=never>.

Con la opción B<--xlate-fold>, el texto convertido se pliega por el ancho especificado. El ancho predeterminado es 70 y se puede establecer con la opción B<--xlate-fold-width>. Se reservan cuatro columnas para la operación run-in, por lo que cada línea puede contener como máximo 74 caracteres.

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

Especifica el motor de traducción que se va a utilizar. Si especificas el módulo del motor directamente, como C<-Mxlate::deepl>, no necesitas usar esta opción.

En este momento, los siguientes motores están disponibles

=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

La interfaz de B<gpt-4o> es inestable y no se puede garantizar que funcione correctamente en este momento.

=item * B<gpt5>: gpt-5

=back

=item B<--xlate-labor>

=item B<--xlabor>

En lugar de llamar al motor de traducción, se espera que trabajes manualmente. Después de preparar el texto a traducir, se copia al portapapeles. Se espera que lo pegues en el formulario, copies el resultado al portapapeles y presiones return.

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

Especifica el idioma de destino. Puedes obtener los idiomas disponibles con el comando C<deepl languages> al usar el motor B<DeepL>.

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

Especifica el formato de salida para el texto original y traducido.

Los siguientes formatos, aparte de C<xtxt>, asumen que la parte a traducir es una colección de líneas. De hecho, es posible traducir solo una parte de una línea, pero especificar un formato distinto de C<xtxt> no producirá resultados significativos.

=over 4

=item B<conflict>, B<cm>

El texto original y el convertido se imprimen en formato de marcador de conflicto L<git(1)>.

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

Puedes recuperar el archivo original con el siguiente comando L<sed(1)>.

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

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

El texto original y el traducido se muestran en el estilo de contenedor personalizado de markdown.

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

El texto anterior se traducirá a lo siguiente en HTML.

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

El número de dos puntos es 7 por defecto. Si especificas una secuencia de dos puntos como C<:::::>, se utiliza en lugar de 7 dos puntos.

=item B<ifdef>

El texto original y el convertido se imprimen en formato L<cpp(1)> C<#ifdef>.

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

Puedes recuperar solo el texto en japonés con el comando B<unifdef>:

    unifdef -UORIGINAL -DJA foo.ja.pm

=item B<space>

=item B<space+>

El texto original y el texto convertido se imprimen separados por una sola línea en blanco.

=item B<xtxt>

Para C<space+>, también se imprime una nueva línea después del texto convertido.

=back

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

Si el formato es C<xtxt> (texto traducido) o desconocido, solo se imprime el texto traducido.

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

Especifique la longitud máxima del texto que se enviará a la API de una vez. El valor predeterminado se establece como para el servicio de cuenta gratuita de DeepL: 128K para la API (B<--xlate>) y 5000 para la interfaz del portapapeles (B<--xlate-labor>). Puede cambiar estos valores si utiliza el servicio Pro.

Especifique el número máximo de líneas de texto que se enviarán a la API de una vez.

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

Especifique un mensaje personalizado para enviar al motor de traducción. Esta opción solo está disponible cuando se utilizan motores ChatGPT (gpt3, gpt4, gpt4o). Puede personalizar el comportamiento de la traducción proporcionando instrucciones específicas al modelo de IA. Si el mensaje contiene C<%s>, será reemplazado por el nombre del idioma de destino.

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

Especifique información de contexto adicional para enviar al motor de traducción. Esta opción se puede usar varias veces para proporcionar múltiples cadenas de contexto. La información de contexto ayuda al motor de traducción a comprender el trasfondo y producir traducciones más precisas.

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

Especifique un ID de glosario para usar en la traducción. Esta opción solo está disponible cuando se utiliza el motor DeepL. El ID de glosario debe obtenerse de su cuenta de DeepL y garantiza la traducción coherente de términos específicos.

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

Establezca este valor en 1 si desea traducir una línea a la vez. Esta opción tiene prioridad sobre la opción C<--xlate-maxlen>.

=item B<--xlate-stripe>

Vea el resultado de la traducción en tiempo real en la salida STDERR.

Utilice el módulo L<App::Greple::stripe> para mostrar la parte coincidente con un patrón de rayas tipo cebra. Esto es útil cuando las partes coincidentes están conectadas una tras otra.

=item B<--xlate-mask>

La paleta de colores se cambia según el color de fondo del terminal. Si desea especificarlo explícitamente, puede usar B<--xlate-stripe-light> o B<--xlate-stripe-dark>.

=item B<--match-all>

Realice la función de enmascaramiento y muestre el texto convertido tal cual sin restauración.

=item B<--lineify-cm>

=item B<--lineify-colon>

En el caso de los formatos C<cm> y C<colon>, la salida se divide y se formatea línea por línea. Por lo tanto, si solo se traduce una parte de una línea, no se puede obtener el resultado esperado. Estos filtros corrigen la salida que se corrompe al traducir parte de una línea en una salida normal línea por línea.

En la implementación actual, si se traducen varias partes de una línea, se muestran como líneas independientes.

=back

=head1 CACHE OPTIONS

Establezca todo el texto del archivo como área objetivo.

El módulo B<xlate> puede almacenar texto traducido en caché para cada archivo y leerlo antes de la ejecución para eliminar la sobrecarga de solicitar al servidor. Con la estrategia de caché predeterminada C<auto>, mantiene los datos en caché solo cuando existe el archivo de caché para el archivo objetivo.

=over 7

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

=over 4

=item C<auto> (Default)

Utilice B<--xlate-cache=clear> para iniciar la gestión de caché o limpiar todos los datos de caché existentes. Una vez ejecutado con esta opción, se creará un nuevo archivo de caché si no existe y luego se mantendrá automáticamente.

=item C<create>

Mantenga el archivo de caché si existe.

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

Cree un archivo de caché vacío y salga.

=item C<clear>

Mantenga la caché de todos modos siempre que el objetivo sea un archivo normal.

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

Borre primero los datos de la caché.

=item C<accumulate>

Nunca use el archivo de caché aunque exista.

=back

=item B<--xlate-update>

Por comportamiento predeterminado, los datos no utilizados se eliminan del archivo de caché. Si no desea eliminarlos y mantenerlos en el archivo, use C<accumulate>.

=back

=head1 COMMAND LINE INTERFACE

Esta opción fuerza la actualización del archivo de caché aunque no sea necesario.

El comando C<xlate> admite opciones largas al estilo GNU como C<--to-lang>, C<--from-lang>, C<--engine> y C<--file>. Utilice C<xlate -h> para ver todas las opciones disponibles.

Puede utilizar fácilmente este módulo desde la línea de comandos usando el comando C<xlate> incluido en la distribución. Consulte la página del manual C<xlate> para su uso.

Las operaciones de Docker son gestionadas por el script C<xrun>, que también puede usarse como un comando independiente. El script C<xrun> admite el archivo de configuración C<.xrunrc> para ajustes persistentes del contenedor.

El comando C<xlate> funciona en conjunto con el entorno Docker, por lo que incluso si no tiene nada instalado, puede usarlo siempre que Docker esté disponible. Use la opción C<-D> o C<-C>.

Además, dado que se proporcionan makefiles para varios estilos de documentos, la traducción a otros idiomas es posible sin especificaciones especiales. Use la opción C<-M>.

También puede combinar las opciones Docker y C<make> para que pueda ejecutar C<make> en un entorno Docker.

Ejecutar como C<xlate -C> iniciará una shell con el repositorio git de trabajo actual montado.

=head1 EMACS

Carga el archivo F<xlate.el> incluido en el repositorio para usar el comando C<xlate> desde el 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

La función C<xlate-region> traduce la región dada. El idioma predeterminado es C<EN-US> y puedes especificar el idioma invocándolo con un argumento prefijo.

=item OPENAI_API_KEY

Configura tu clave de autenticación para el servicio DeepL.

=back

=head1 INSTALL

=head2 CPANMINUS

    $ cpanm App::Greple::xlate

=head2 TOOLS

Clave de autenticación de OpenAI.

Debes instalar las herramientas de línea de comandos para DeepL y ChatGPT.

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

=head1 SEE ALSO

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

L<App::Greple::xlate>

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

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

La biblioteca C<getoptlong.sh> se utiliza para el análisis de opciones en los scripts C<xlate> y C<xrun>.

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

Imagen de contenedor Docker.

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

Biblioteca Python de DeepL y comando CLI.

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

Biblioteca Python de OpenAI

=item * L<App::Greple>

Interfaz de línea de comandos de OpenAI

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

Consulta el manual B<greple> para más detalles sobre el patrón de texto objetivo. Usa las opciones B<--inside>, B<--outside>, B<--include>, B<--exclude> para limitar el área de coincidencia.

=item * L<App::sdif>

Puedes usar el módulo C<-Mupdate> para modificar archivos según el resultado del comando B<greple>.

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

Usa B<sdif> para mostrar el formato del marcador de conflicto lado a lado con la opción B<-V>.

=back

=head2 ARTICLES

=over 2

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

El módulo Greple B<stripe> se usa con la opción B<--xlate-stripe>.

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

Módulo Greple para traducir y reemplazar solo las partes necesarias con la API de DeepL (en japonés)

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

Generación de documentos en 15 idiomas con el módulo de la API de DeepL (en japonés)

=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
