=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<xlate> B<Greple> находит желаемые текстовые блоки и заменяет их переведенным текстом. В настоящее время в качестве движка используются модули DeepL (F<deepl.pm>) и ChatGPT (F<gpt3.pm>). Также включена экспериментальная поддержка для gpt-4 и gpt-4o.

Если вы хотите перевести обычные текстовые блоки в документе, написанном в стиле Perl's pod, используйте команду B<greple> с модулем C<xlate::deepl> и C<perl> следующим образом:

    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

Обработка выполняется в указанных единицах, но в случае последовательности нескольких строк непустого текста они объединяются вместе в одну строку. Эта операция выполняется следующим образом:

=over 2

=item *

Удалить пробелы в начале и в конце каждой строки.

=item *

Если строка заканчивается символом пунктуации полной ширины, объедините ее с следующей строкой.

=item *

Если строка заканчивается полноширинным символом, а следующая строка начинается с полноширинного символа, объединить строки.

=item *

Если конец или начало строки не является полноширинным символом, объединить их, вставив пробел.

=back

Данные кэша управляются на основе нормализованного текста, поэтому даже если вносятся изменения, не влияющие на результаты нормализации, кэшированные данные перевода останутся действительными.

Этот процесс нормализации выполняется только для первого (0-го) и четных шаблонов. Таким образом, если два шаблона указаны следующим образом, текст, соответствующий первому шаблону, будет обработан после нормализации, и никакой процесс нормализации не будет выполнен для текста, соответствующего второму шаблону.

    greple -Mxlate -E normalized -E not-normalized

Следовательно, используйте первый шаблон для текста, который должен быть обработан путем объединения нескольких строк в одну строку, и используйте второй шаблон для предварительно отформатированного текста. Если в первом шаблоне нет текста для сопоставления, используйте шаблон, который ничего не сопоставляет, например, C<(?!)>.

=head1 MASKING

Иногда бывают части текста, которые вы не хотите переводить. Например, теги в файлах разметки. 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>. Четыре столбца зарезервированы для операции run-in, поэтому каждая строка может содержать не более 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>

Вместо вызова движка перевода, от вас ожидается выполнение работы. После подготовки текста для перевода, он копируется в буфер обмена. Ожидается, что вы вставите его в форму, скопируете результат в буфер обмена и нажмете Enter.

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

Укажите целевой язык. Вы можете получить доступные языки с помощью команды C<deepl languages>, когда используется движок B<DeepL>.

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

Укажите формат вывода для оригинального и переведенного текста.

Следующие форматы, отличные от C<xtxt>, предполагают, что часть, которую нужно перевести, представляет собой набор строк. Фактически, можно перевести только часть строки, и указание формата, отличного от 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 style="background-color: #f4f4f4; color: #333; border: 1px solid #ccc; border-radius: 5px; padding: 10px;">

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

По умолчанию количество двоеточий равно 7. Если вы укажете последовательность двоеточий, например C<:::::>, она будет использоваться вместо 7 двоеточий.

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

Original text:

=item B<xtxt>

Если формат - C<xtxt> (переведенный текст) или неизвестный, будет выведен только переведенный текст.

=back

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

Переведите следующий текст на русский язык, построчно.

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

Укажите максимальное количество строк текста, отправляемых в API за один раз.

Установите это значение равным 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>.

Также, поскольку предоставляются make-файлы для различных стилей документов, перевод на другие языки возможен без особых указаний. Используйте опцию C<-M>.

Вы также можете объединить опции Docker и C<make>, чтобы запустить C<make> в среде Docker.

Запуск, подобный C<xlate -C>, запустит оболочку с текущим рабочим git-репозиторием подключенным.

Прочтите японскую статью в разделе "СМОТРИТЕ ТАКЖЕ" для получения подробной информации.

=head1 EMACS

Загрузите файл F<xlate.el>, включенный в репозиторий, чтобы использовать команду C<xlate> из редактора Emacs. Функция 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 и командная строка.

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

Вы можете использовать модуль C<-Mupdate>, чтобы изменять файлы на основе результата команды B<greple>.

=item * L<App::sdif>

Используйте B<sdif>, чтобы показать формат маркера конфликта рядом с опцией B<-V>.

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

Модуль Greple для перевода и замены только необходимых частей с использованием API DeepL (на японском)

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

Генерация документов на 15 языках с помощью модуля DeepL API (на японском)

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

Автоматическая среда Docker для перевода с использованием API DeepL (на японском)

=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
