Скрипты для Demagog

Говорящий текстовый редактор с открытым кодом, предназначенный для чтения вслух и записи в аудиофайл текстовых файлов с использованием пакетов речевых функций SAPI4\SAPI5.

Модератор: flegont

Ответить
Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#451

Сообщение flegont »

Да, это было бы удобно. Сделаю :smile1:

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#452

Сообщение flegont »

Версия 381. Пример скрипта для записи русско-английского аудио
Текст

Код: Выделить всё

Упражнение номер один, начали

Кто там, вдалеке? Who is there, far away? Who is there, far away?
Это - ковбой Неуловимый Джо. This is the cowboy Elusive Joe. This is the cowboy Elusive Joe.
Неужели никто не может поймать его? Can no one catch him? Can no one catch him?
Да, его никто не может поймать. Yes, no one can catch him. Yes, no one can catch him.
Но, почему? But why? But why?
Потому что он - никому не нужен! Because nobody needs him! Because nobody needs him!

Конец упражнения
Скрипт

Код: Выделить всё

-- ЗАПИСЬ РУССКО-АНГЛИЙСКОГО АУДИО ДЛЯ ТЕКСТА В АКТИВНОЙ ВКЛАДКЕ
-- Дано: русские фразы чередуются с их английским переводом; английский
-- перевод повторяется дважды с 2-х секундной паузой; перед произнесением
-- перевода необходима пауза 4 секунды - чтобы ученик успел предложить
-- свой вариант перевода, а затем услышал правильный

-- запоминаем параметры первоначально активного голоса
vName, vRate, vPitch, vVolume = Voice()

k = WActive()  -- номер активного окна

-- на время работы скрипта включить многоязычный режим
o = {}
o.Reading_Multilingva = true
Settings(o)

-- настройка голосов (скорость, тембр, громкость не указаны, по умолчанию 0,0,100)
ru = 'Pavel'
en = 'Zira'

-- временные словари для пауз (их можно создать где угодно, не обязательно в папке dic)
h = HomeFolder('dic')
SaveToFile({[[([\.\?\!]+)=<silence msec="4000"/>$1]]},h..'tmp_pause4.rex')
SaveToFile({[[([\.\?\!]+)=<silence msec="2000"/>$1]]},h..'tmp_pause2.rex')

-- привязать словари к голосам (если путь не указан, то подразумевается стандартная папка ..\dic)
d = {}
d[Voice('Pavel')] = {'tmp_pause4.rex'}
d[Voice('Zira')] = {'tmp_pause2.rex'}

-- копию текста в активной вкладке разметить и поместить в Статистику 
WMarkup(k,0,ru,en)

-- словарные замены во вкладке Статистика
WFilter(0,0,d)
--WActive(0) -- для просмотра во время отладки!

-- запись двуязычного аудио по тексту в Статистике
-- т.к. измененный текст не был сохранен, то имя аудиофайла 
-- генерируется автоматически из даты и времени)
WAudio(0)

-- удалить временные словари
os.remove(h..'tmp_pause4.rex')
os.remove(h..'tmp_pause2.rex')

-- восстановить активность первоначального голоса
SetVoice(vName,vRate,vPitch,vVolume)
Русско-английское аудио

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#453

Сообщение flegont »

Версия 381, сборка от 07.02.2020

[+] LuaMatch(s, mask, pos) - функция встроенного интерпретатора, ищет совпадение в строке s по шаблону mask с позиции pos (по умолчанию 1); возвращает совпавший фрагмент и позицию его начала; если не найдено, то возвращает '', 0.
► Показать
[~] Улучшена работа опции "Формат - Литературный текст". Прежде она не всегда срабатывала на текстах, вставленных из буфера обмена.

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#454

Сообщение tonio_k »

balaamster, подскажите, где и какие изменения можно сделать в YaTTS.lua что бы ffmpeg.exe (если он вообще это может) при объединении аудиофайлов полученных с Яндекса добавлял AudioTag.info в аудиофайл из названия книги из переменной doc_name?
UPD снимаю вопрос. Ошибся все уже есть

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#455

Сообщение flegont »

Перенесено.
Добавлено tonio_k » Сегодня, 19:24

Выкладываю пример (шаблон) скрипта, который разбивает текст в окне Демагога на файлы при помощи регулярных выражений.
Как работает скрипт. С помощью регулярного выражения делаются замены в тексте за счет добавления в текст символа: "_" (нижнее подчеркивание). Этот символ будет критерием разбития текста на файлы. Поэтому в начале запуска скрипта символ "_" (нижнее подчеркивание) автоматически удаляется во всём тексте.
Пример регулярных выражений:

Код: Выделить всё

\b(Глава|Параграф)\s+([IVXХMDLC]+|\d+)=_$1 $2
-разобьёт текст по файлам - каждая глава - в отдельном файле. Данный пример в скрипте используется по умолчанию

Код: Выделить всё

^(.+)$=$1_
-разобьёт текст по файлам - каждый абзац- в отдельном файле

Код: Выделить всё

^(\x20*)(\d+)(\x20*)$=$1_Глава $2$3
-если при нумерации глав не используется слово "Глава" (только цифры) - разобьёт текст по главам с добавлением слова "Глава" в текст

В шапке скрипта можно настроить под себя переменные:
name_shablon = "Глава_" -- здесь вставляем шаблон "имя файла" который будет вставляться перед автоматической нумерацией
num_c="3" -- указываем количество цифр в автоматической нумерации
workfolder=[[D:\MP3\TXT\]]--путь по умолчанию (при открытии окна выбора папки сразу предлагает сохранение по этому пути - сразу нажимаем Ок)

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#456

Сообщение tonio_k »

Нужна помощь в решении задачи:

Имеем текст:

Код: Выделить всё

Всё верно?
Все верно,
Всё верно,
Всё верно.
Все верно?
Все верно.
Как в через команды скрипта в LUA можно этот текст "построчно" (в рамках каждого абзаца) инвертировать, что бы на выходе получить:

Код: Выделить всё

?онрев ёсВ
,онрев есВ
,онрев ёсВ
.онрев ёсВ
?онрев есВ
.онрев есВ
ну и как обратно инвертировать, что бы получить оригинальный текст?
UPD Отбой. Сам понял как. Оказывается все наработки у меня для этого уже есть. Как сделаю - выложу

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#457

Сообщение tonio_k »

tonio_k писал(а):
03 апр 2020 13:31
текст "построчно" (в рамках каждого абзаца) инвертировать

Код: Выделить всё

s = WText(1).."\r" -- в окне 1 содержится тестовый текст
local r = [[^.+$]]
local k = 1
local temp = ''
local fnd = ''

--Поиск по регулярному выражению:
while k > 0 do
CancelScript() -- проверка на прерывание скрипта пользователем
fnd, k = RexMatch(s,r,k) -- ищем текст по регулярному выражению

--ИНВЕРСИЯ найденного текста из переменной fnd
local z=#fnd
local fnd0=""
while z > 0 do
fnd0 = fnd0..string.sub(fnd,z,z)
z=z-1
end

--склеиваем результат
temp=temp..fnd0.."\r"  -- разделитель по умолчанию
if k > 0 then k = k+#fnd+1  end
end

print(temp)
Если полученный результат поместить в окно 1 - то получим "восстановление" текста

Аватара пользователя
Fabe
Постоялец

Скрипты для Demagog

#458

Сообщение Fabe »

вечер добрый
все время видает ошибку
ef open error
системе не удается найти указанный путь

при запуске скрипта в демагоге

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#459

Сообщение tonio_k »

Fabe писал(а):
11 апр 2020 01:48
все время видает ошибку
мало информации для понимания вашей ситуации. Какая версия Демагога? Какой голосовой движок? Что за скрипт вы запускаете(тот что в комплекте с Демагогом идёт или из какой либо сборки)? Запускался ли этот скрипт раньше? Запускаются ли другие скрипты? Как вы его запускаете в окне или через вызов меню? Скриншот окна ошибки было бы не плохо увидеть - в нём может быть дополнительная техническая информация

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#460

Сообщение flegont »

На пост #457

Код: Выделить всё

--ИНВЕРСИЯ найденного текста из переменной fnd
local fnd0 = string.reverse(fnd)

Аватара пользователя
Fabe
Постоялец

Скрипты для Demagog

#461

Сообщение Fabe »

tonio_k писал(а):
11 апр 2020 08:30
мало информации для понимания вашей ситуации
Болшое спасибо разобрался видимо что то с расжатием фаила не то, пекачал все работает!

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#462

Сообщение tonio_k »

Вопрос. Допустим скрипт:

Код: Выделить всё

s=WText(1)
k=1
u=1
while k < #s do -- до конца текста
fnd,k = RexMatch(s,{[[^[^_]{0,1000}[\r\n]]]},k)
if fnd>0 then
u=u+1
end
end
print(fnd,k)
Данный цикл выдаст последнее найденное совпадение (fnd,k) по регулярному выражению. Подскажите, что нужно сделать, что бы получить предпоследнее (fnd,k)[u-1] или нибудь 25-ое совпадение?

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#463

Сообщение flegont »

Данный цикл не выдаст ничего, потому что он - не работает.
1) двойные [[ ]] обозначающие строку как она есть, вступают в конфликт с [ ] в самОм регулярном выражении. Надо строку, как есть задавать примерно так:
[===[строка]===]
количество знаков = между [ [ и ] ] может быть любым, лишь бы одинаковым.
2) fnd - это найденная подстрока, поэтому нельзя написать fnd > 0
Но, идея понятна: запомнить все найденные совпадения по заданному регулярному выражению

Код: Выделить всё

-- поиск длинных абзацев в тексте
s = WText(1)
r = [[^.{1000,}$]]
u = {}  -- для запоминания найденного
k = 1
while k > 0 do
    fnd, k = RexMatch(s,r,k)
    if k > 0 then
        u[#u+1] = fnd
        k = k+#fnd+1
    end
end
-- если таблица найденного не пуста, то для примера напечатаем 1-е 
if #u > 0 then 
    print(u[1])
end

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#464

Сообщение tonio_k »

flegont писал(а):
23 авг 2019 09:23
конвертация AnsiToUtf8() и Utf8ToAnsi() для cp1251.
(будет добавлена в calculator.lua в вер. 378)
если нам нужно выполнить команду в формате cmd, то запуская os.execute() и указав в ней путь к файлу, мы не беспокоимся что в пути присутствуют русские буквы - все сработает. А вот если нам нужно выполнить две три или десяток команд или еще больше, тот проще создать bat файл и запустить его через os.execute(). Но его надо отдельно создавать, указать в нем пути и где то отдельно от скрипта lua хранить. Причем этот bat файл по своему статичен т.к. нет полной возможности его редактировать и подсовывать пути, которые генерирует скрипт через LUA.
Теперь сам вопрос: а можно сделать некий аналог AnsiToUtf8() что бы при сохранении файлов средствами LUA русские буквы перекодировались в кодировку OEM 866. Тогда будущие строки батника можно было бы прописать в теле скрипта lua в удобном и читаемом в окне CMD виде. При запуске скрипта lua генерировались бы строки для батника со всеми путями и прочей информацией на русском, которую окно cmd наглядно покажет, затем сохраняет полученные строки в файл *.bat с кодировкой OEM 866, а дальше выполняется os.execute() которая запустит созданный файл bat

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#465

Сообщение flegont »

Если правильно помню: в bat-файлах есть управление кодировками для правильного отображения текста в консоли.
chcp 1251 - кириллица Windows
chcp 866 - DOS
chcp 65001 - UTF-8
и т.п.
Например:

Код: Выделить всё

chcp 866
echo тестовый кириллический текст
pause

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#466

Сообщение tonio_k »

Я не про отображение в окне DOS, а про реальную перекодировку текста. Поясню проблему на примере:
создадим на диске файл d:\русскиебуквы.txt
Применим скрипт:

Код: Выделить всё

exec_string=[[notepad.exe d:\русскиебуквы.txt]]
os.execute(exec_string)
ShowMessage(exec_string)
всё запускается - всё ок.

Код: Выделить всё

exec_string=[[notepad.exe d:\русскиебуквы.txt]]
SaveToFile({exec_string},'d:\\1.bat')
os.execute('d:\\1.bat')
ShowMessage(exec_string)
Во втором случае батник 1.bat не срабатывает хотя имеет точно такую же строку что и в первом примере. Можем попытаться вручную запустить 1.bat - ничего не будет. Потому что в кодировке OEM 866 строка должна выглядеть так:
notepad.exe d:\агббЄЁҐЎгЄўл.txt
И если сейчас на эту "крякабразную" строку через блокнот заменить содержимое 1.bat, то он сработает. Получается нужна некая функция exec_string=WinToDos(exec_string) аналогичная Utf8ToAnsi() что бы текст можно было сохранить в OEM 866.

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#467

Сообщение flegont »

Понятно. Подумаю над этим

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#468

Сообщение flegont »

Чего тут думать, Мировой Разум нам в помощь :wink:

Код: Выделить всё

--[[
1251: А  - Я а - п  192 - 239
866:   А  - Я а - п  128 - 175
1251: р-я  240 - 255
866:   р-я  224 - 239
1251: Ё- 168 ё - 184
866:   Ё- 240 ё - 241
]]
function WinToDos(s)
    local  str = ''
    for i=1, string.len(s) do
        local byte = s:byte(i)
        local b = byte
        if (byte >= 192 and byte <= 239) then  b =  byte-64       
        elseif  (byte >= 240 and byte <= 255 ) then  b = byte-16
        elseif byte == 168 then b=240  --Ё
        elseif byte == 184 then b=241  --ё
        end
        str = str..string.char(b)
    end
    return str  
end
Пример:

Код: Выделить всё

s = [[русскиебуквы]]
s = WinToDos(s)
print(s)
Результат:
агббЄЁҐЎгЄўл

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#469

Сообщение tonio_k »

:thank: Для полного комплекта не хватает только обратного процесса s = DosToWin(s)

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#470

Сообщение flegont »

Код: Выделить всё

function DosToWin(s)
    local str = ''
    for i=1, string.len(s) do
        local byte = s:byte(i)
        local b = byte
        if (byte >= 128 and byte <= 175) then b =  byte+64       
        elseif  (byte >= 224 and byte <= 239 ) then b = byte+16
        elseif byte == 240 then b=168  --Ё
        elseif byte == 241 then b=184  --ё
        end
        str = str..string.char(b)
    end
    return str  
end
Пример:

Код: Выделить всё

s = [[агббЄЁҐЎгЄўл]]
s = DosToWin(s)
print(s) 
Результат:
русскиебуквы

Аватара пользователя
tonio_k
V.I.P.

Скрипты для Demagog

#471

Сообщение tonio_k »

Сделал скрипт "Таймер принудительного отключения ПК"

Код: Выделить всё

numberstart = 10
numberstart = Input('Установка таймера ПРИНУДИТЕЛЬНОГО отключения ПК в минутах:',{'Отключить ПК через (минут):'..'='..numberstart})
if numberstart == nil then goto HALT end
numberstart = tonumber(numberstart[1]) -- превращаем в число!
os.execute('shutdown /s /t '..(numberstart*60)..' /f /c "Demagog Script: До отключения ПК осталось: '..numberstart..' минут! Для отмены введите в командной строке: shutdown /a "')  
::HALT::
Вопрос, а есть какая нибудь хитрость, что бы мне "не высчитывать часы и минуты", а скрипт его рассчитал? Т.е. что бы я в поле ввода мог ввести 60*3+45 (получается 3 часа + 45 минут), а переменная numberstart приняла бы значение 225, а не nil как в этом скрипте? Что бы Input() можно было использовать в качестве калькулятора.

Аватара пользователя
flegont
V.I.P.

Скрипты для Demagog

#472

Сообщение flegont »

Код: Выделить всё

-- вычисляемое поле ввода
header = 'Заголовок'
itms = {'Время, мин=10'}
a = Input(header,itms)
s = 't = '..a[1]
f = load(s)  -- возвращено значение типа function
if f then 
    f()  -- выполняем ф-цию f, теперь у переменной t есть значение
    ShowMessage(t)
end
Введя в поле ввода вместо значения по умолчанию (10) что-то вроде 60*3+45 и нажав OK, получим результат: 225

Ответить

Вернуться в «Demagog»