Скрипты для 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

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

Скрипты для Demagog

#473

Сообщение flegont »

Вер. 383, сборка от 08.06.2020
[+] Функция встроенного интерпретатора ParagsLimitation(text, limit) - приведение абзацев в тексте к размеру, не превышающему заданный предел; cлишком большие абзацы делятся при этом на меньшие - по знакам конца предложений или знакам препинания ( в т.ч. / и \ ), или в крайнем случае - по пробелам между словами. (Идея и первоначальная разработка: tonio_k).

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

-- пример использования
z = os.clock()
s = WText(1)
s = ParagsLimitation(s,500)
-- вставляем двойные пустые строки для наглядности разбиения абзацев
s = string.gsub(s,'\r','\r\r')
print('время выполнения, сек: '..(os.clock()-z))
print()
print(s)

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

Скрипты для Demagog

#474

Сообщение flegont »

Вер. 383, сборка от 08.06.2020
Функция встроенного интерпретатора BreakKeyName() - имя горячей клавиши, назначенной в Настройках для прерывания длительных процессов; если не назначена, то вернет nil.

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

-- пример вывода сообщения пользователю в Строку состояния
local bk = BreakKeyName()
if CurrentLang() == 'Russian' then
    mess1 = 'Идет расчет '
    mess2 = ' Прервать '
else
    mess1 = 'Calculation '
    mess2 = ' Interrupt '
end
if bk then bk = mess2..bk else bk = '' end
StatusMessage(mess1..bk)

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

Скрипты для Demagog

#475

Сообщение tonio_k »

flegont писал(а):
01 июл 2020 09:57
WStat(i, dname, gauge)
функция замечательно работает! есть пара пожеланий

1)Добавить возможность по мимо окна статистики, выводить результат в любое другое окно Демагога, в т.ч. -1 для накопления или хранения промежуточных результатов при построчном применении словарей
2)для текстов и словарей с кодировкой ANSI: Измененный словарями текст выводить в переменную. Что бы при помощи WStat можно было получить аналогично Ctrl+T и измененный текст и список правил с подсчётом их срабатывания. Это нужно, что бы не применять один и тот же словарь дважды если есть необходимость получить как список правил через WStat, так и измененный этими правилами текст через WSeries.
Пример:

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

n=WStat(1, -1 slovar.rex, true) -- к окну 1 применить словарь slovar.rex результат поместить в буферное окно -1
r=WText(-1)--результат из буферного окна в переменную
print(n)--выводим измененный текст
print(r)--выводим список правил

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

Скрипты для Demagog

#476

Сообщение flegont »

1) Подумаю над этим. Действительно, WStat(i, j, dname, gauge) возможно, будет более удобна. См. пункт 2.

2) Опция Ctrl+T на самом деле - это последовательное применение к выделенному тексту опций "Сервис - Статистика - Измененный текст" и "Сервис - Статистика - Примененные правила". В интерпретаторе - это то же самое, что WFilter(i, j,...) и WStat(i, k,...). В окне j будет измененный текст, в k - примененные правила.
Ну, а сохранить в переменные: sChangeTxt = WText(j); sRuleReport = WText(k) :smile1:

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

Скрипты для Demagog

#477

Сообщение flegont »

Привел функцию WStat к виду WStat(i, j, k, dname, gauge) - подсчитывает статистику замен во вкладке i по словарю dicname, измененный текст помещает во вкладку j, список примененных правил во вкладку k; если j = k, то оба результата совмещаются в одной вкладке; gauger = true/false - показывать ли индикатор процесса (по умолчанию true).

Соответственно сделано изменение в дистрибутиве.

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

Скрипты для Demagog

#478

Сообщение tonio_k »

В попытке все же сохранить кодировку utf8 столкнулся с нехваткой ещё одного буферного окна -2 с помощью которого можно было бы последовательно склеивать накапливаемые результаты из окна -1 и -2 в окно 0-статистики
Пример:

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

s=WText(1)
WNew(-1,s)
WStat(-1, -2, "slovar1.rex", true)--получаем список сработавших правил slovar1.rex
WSeries(-1, -1, "slovar1.rex", true)--изменяем текст словарём slovar1.rex
WAdd(0,-1)--добавляем в статистику обновленный текст
WAdd(0,-2)--добавляем в статистику правила из slovar1.rex изменившие текст
WStat(-1, -2, "slovar2.rex", true)-- к измененному тексту выводим правила из словаря slovar2.rex
WSeries(-1, -1, "slovar2.rex", true)--изменяем текст следущим словарем slovar2.rex
WAdd(0,-1)
WAdd(0,-2)
UPD есть ли в настройках Демагога у меня не показывает 16 окно. Тем не менее оно существует? С ним можно работать через скрипт?

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

Скрипты для Demagog

#479

Сообщение flegont »

Окно 16 - это то же самое, что окно 0 - Статистика.

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

Скрипты для Demagog

#480

Сообщение tonio_k »

А 10 или 12 Например? Я сейчас не у компьютера поэтому вопрос задаю по памяти :smile1:

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

Скрипты для Demagog

#481

Сообщение flegont »

Всего окон, считая буферное - аж 17 штук.
Вполне достаточно для организации "суммирования текстов". Можно даже без -1 обойтись. Если нужно 2 служебных окна для накапливания двух видов результатов, то можно взять 14 и 15. А потом объединить их в 0 - Статистика.

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

Скрипты для Demagog

#482

Сообщение tonio_k »

flegont писал(а):
02 июл 2020 13:05
можно взять 14 и 15.
но при этом в настройках Демагога их может не быть? Сейчас например у меня с 1 по 9 вкладка-окно видны. Для скрипта остальные тем не менее доступны?

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

Скрипты для Demagog

#483

Сообщение flegont »

10 11 12 13 14 15 - это окна, обозначенные на вкладках буквами A B C D E F
Вполне можно сочинить скрипт, использующий эти окна как служебные. С предупреждением пользователю, что данный скрипт использует вкладки такие-то для вычислительных целей.
И необходимо, чтобы важные докумены, открытые в этих вкладках, были предварительно сохранены. Во избежание потери данных. "Продолжить? Да Нет".

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

Скрипты для Demagog

#484

Сообщение flegont »

Для интерпретатора невидимые окна (сверх разрешенного в Настройках количества) недоступны. Хотя физически они - существуют.
Почему недоступны? Когда я создавал функции интерпретатора, работающие с окнами, я поставил запрет на обращение к невидимым окнам. Просто решил, что вряд ли кому-то зачем-то такое понадобится. Ошибся, однако :pardon:
Как поставил ограничение, так могу и снять. Ближе к вечеру, сейчас я тоже не за компом.

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

Скрипты для Demagog

#485

Сообщение flegont »

Небольшое изменение в дистрибутиве вер. 384
Для функций встроенного интерпретатора W...(...) можно теперь в параметрах указывать номера вкладок, выходящие за пределы количества, объявленного в "Формат - Количество вкладок".
За исключением функций:
WActive - нельзя сделать активной невидимую вкладку
WAudio - нельзя записать аудио для вкладки, которая не может стать активной
WSel - нельзя выделить текст в невидимой вкладке
WSelText - нельзя присвоить значение тексту, который не может стать выделенным

Пример:

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

-- "Формат - Количество вкладок" указано 10
-- т.е. видны вкладки 1 2 3 4 5 6 7 8 9 0
-- Как записать информацию в невидимую вкладку A?
WNew(10)
WAdd(10,'Петр Петрович Гарин изобрел гиперболоид.\r')
WAdd(10,'Но, ничего хорошего из этого не вышло...\r')
s = WText(10)
ShowMessage(s)  -- проверяем запись информации во вкладку 
WSave(10,'Гарин.txt')  -- сохраняем из невидимой вкладки в файл
WAudio(10)  -- БУДЕТ ИГНОРИРОВАНО!

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

Скрипты для Demagog

#486

Сообщение flegont »

Пример пользовательского меню с отмечаемыми пунктами

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

-- ПРИМЕР ПОЛЬЗОВАТЕЛЬСКОГО МЕНЮ
-- (идея и первоначальная реализация: tonio_k)

-- внешний вид пометки пункта меню
mark = '(•)'
unmark = '( )'
--mark = '[x]'
--unmark = '[  ]'

menu_inifile = '123.mnu' -- куда сохранять настройки меню

-- читаем настройки из файла или задаем по умолчанию
-- false - пункт не отмечен
-- true - пункт отмечен
-- nil - не отмечаемый пункт!
if FileExists(menu_inifile) then
  m = table.load(menu_inifile)
else
  m = {}
  m.checked = {false,false,false,nil,false,nil,nil,nil} 
  m.duration = 5 
end

-- задаем меню с разделительной линией и пункт по умолчанию
caption = ' Выбрать пункт для редактирования или выполнить с текущими настройками'
items = {
'Обработать обычными словарями',
'Обработать словарями (fonems)',
'Записать в аудио MP3',
'Время аудиозаписи ~ 5 мин.',
'Выключить ПК по завершению работы',
string.rep('\150',75),
'Сохранить настройки и выйти',
'Выполнить с текущими настройками'
}
ind = 7

-- МЕНЮ С ПОМЕТКАМИ (ДОБАВИТЬ/СНЯТЬ ПОМЕТКУ: OK ИЛИ ENTER ИЛИ DBL CLICK) --

-- добавляем пометки в пункты, в соответствии с прочитанным из настроек
for i = 1,#items do
    if m.checked[i] == true then items[i] = mark..' '..items[i] end
    if m.checked[i] == false then items[i] = unmark..' '..items[i] end             
end
--
items[4] = 'Время аудиозаписи ~ '..m.duration..' мин.'

::START::

a = Menu(caption,items,ind)
if a == 0 then goto HALT end

-- меняем пометку на выбранном пункте, если он - отмечаемый
if m.checked[a] == false then
    items[a] = mark..' '..string.sub(items[a],#unmark+2,#items[a])
    m.checked[a] = true
else if m.checked[a] == true then
    items[a] = unmark..' '..string.sub(items[a],#mark+2,#items[a])
    m.checked[a] = false
end end

-- выполняем действия, назначенные на выбранный НЕ отмечаемый пункт
if a == 4 then
    -- назначаем время звучания аудио и прописываем его в пункте меню
    m.duration = m.duration+5
    k = Menu('Примерное время звучания, мин',{5,10,15,20,25,30},1)
    if k == 0 then goto START end
    m.duration = 5*k
    items[a] = 'Время аудиозаписи ~ '..m.duration..' мин.'
end
if a == 7 then
    -- сохраняем настройки меню и выходим
    table.save(m,menu_inifile) 
    goto HALT
end
if a == 8 then
    -- имя функции, выполняющей требуемое действие или команда dofile(...)
    -- ...
    goto HALT
end

goto START

::HALT::

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

Скрипты для Demagog

#487

Сообщение tonio_k »

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

a = Input('Настройка конвертации',{'Параметры'..'='.."ffmpeg.exe|-loglevel -8 -y -i %1 -af atempo=1.0 -b:a 64k %2|mp3"})
По умолчанию окно для ввода текста открывает так:
► Показать
если нажать на указную кнопку, то окно для ввода текста будет выглядеть так:
► Показать
Вопрос, а есть возможность "принудительно" заставить окно диалога сразу выводить по второму варианту? Если нет, то можно эту возможность добавить?

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

Скрипты для Demagog

#488

Сообщение flegont »

Подумаю, как добавить.

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

Скрипты для Demagog

#489

Сообщение flegont »

Вер. 384 - небольшое изменение в дистрибутиве. Функция встроенного интерпретатора - Input() теперь имеет 3 параметра:
Input(title, prompt, twocol)
twocol = true / false - отображать обе колонки "имя" и "значение" или только "значение", по умолчанию true.

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

Скрипты для Demagog

#490

Сообщение tonio_k »

Пример текста:
► Показать
Вопрос, как можно объединить все записи, избавившись от дубликатов, с суммированием чисел напротив дублирующего текста после знака "|". Что бы на выходе получить:
► Показать
Хочу применить эту схему для консолидации промежуточной статистики, получаемой при помощи функции WStat(i, j, k, dname, gauge)

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

Скрипты для Demagog

#491

Сообщение flegont »

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

-- Скрипт, консолидирующий статистику частотности строк из вкладки 1 в 0
-- Каждая запись исходного списка имеет вид: частота|строка
-- При этом строки справа от | могут дублироваться
-- После обработки дубликаты будут удалены, частоты просуммированы 

-- вспомогательные функции
function DelUtf8BOM(s)
    local bom = '\239\187\191'
    if string.sub(s,1,3) == bom then s = string.sub(s,4,#s) end
    return s
end

function AddUtf8BOM(s)
    return '\239\187\191'..s
end


-- основная процедура

os.setlocale('', 'ctype') -- для работы с национальной локалью

-- заботимся о сохранении юникодных символов
o = {}
o.File_Encoding = feUTF8
Settings(o)

WSave(1,'tmp.txt')
a = LoadFromFile('tmp.txt')
a[1] = DelUtf8BOM(a[1])

-- консолидируем статистику
c = {}
for i = 1,#a do
    b = string.split(a[i],'|')
    if #b > 1 then
        if c[b[2]] == nil then
            c[b[2]] = tonumber(b[1])
        else
            c[b[2]] = c[b[2]]+tonumber(b[1])
        end
    end
end

d = ''
for k, v in pairs(c) do
    d = d..v..'|'..k..'\r'
end

-- опять же, заботимся о юникоде
AddUtf8BOM(d)
SaveToFile({d},'tmp.txt')

-- готово!
WOpen(0,'tmp.txt')

os.setlocale('C')  -- вернуть стандартную локаль
Пример.
Текст в окне 1:

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

18|вася=Вася
1|вася=Вася
3|вася=Вася
4|вася=Вася
3|毛泽东=Мао Цзедун
10|маша=Маша
1|маша=Маша
13|маша=Маша
1|毛泽东=Мао Цзедун
13|коля=Коля
Результат в окне 0 - Статистика:

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

13|коля=Коля
24|маша=Маша
4|毛泽东=Мао Цзедун
26|вася=Вася

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

Скрипты для Demagog

#492

Сообщение flegont »

Но можно бы и еще усовершенствовать. Оформить в виде функции
FreqConsolidate(i, j, tmpfile)
Статистику частотности из окна i консолидировать в окно j, используя для работы указанный временный файл. И окно i при этом надо в итоге очищать, т.к. содержимое временного файла изменилось и показано в окне j

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

Скрипты для Demagog

#493

Сообщение tonio_k »

flegont писал(а):
15 июл 2020 10:48
Оформить в виде функции
FreqConsolidate(i, j, tmpfile)
поддерживаю! С получением доступа к окнам 13, 14, 15, когда они скрыты, теперь можно смело подгонять функции для работы с окнами. Дефицита в окнах технического назначения нет.

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

Скрипты для Demagog

#494

Сообщение flegont »

Как-то так...
FreqConsolidate(i, j, delim, tmpfile) - консолидирует статистику, находящуюся в окне i в окно j. Если i ~= j то по завершении работы окно i очистится от временного файла tmpfile, т.к. он уже изменился и открыт в j.
По умолчанию delim = '|'; tmpfile = 'tmp.txt'. Пользователь волен указывать другие символ-разделитель и имя временного файла.

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

-- Функция, консолидирующий статистику частотности строк из вкладки i в j
-- Каждая запись исходного списка в i имеет вид: ЧастотаРазделительСтрока
-- При этом строки справа от Разделитель могут дублироваться.
-- После обработки дубликаты будут удалены, частоты просуммированы
function FreqConsolidate(i, j, delim, tmpfile)
    if delim == nil then delim = '|' end
    if tmpfile == nil then tmpfile = 'tmp.txt' end

    -- вспомогательные функции
    local function DelUtf8BOM(s)
        local bom = '\239\187\191'
        if string.sub(s,1,3) == bom then s = string.sub(s,4,#s) end
        return s
    end

    local function AddUtf8BOM(s)
        return '\239\187\191'..s
    end

    -- основная процедура

    os.setlocale('', 'ctype') -- для работы с национальной локалью

    -- заботимся о сохранении юникодных символов
    local o = {}
    o.File_Encoding = feUTF8
    Settings(o)

    WSave(i,tmpfile)
    local a = LoadFromFile(tmpfile)
    a[1] = DelUtf8BOM(a[1])

    -- консолидируем статистику
    local c = {}
    local b
    for i = 1,#a do
        b = string.split(a[i],delim)
        if #b > 1 then
            if c[b[2]] == nil then
                c[b[2]] = tonumber(b[1])
            else
                c[b[2]] = c[b[2]]+tonumber(b[1])
            end
        end
    end

    local d = ''
    for k, v in pairs(c) do
        d = d..v..delim..k..'\r'
    end

    -- опять же, заботимся о юникоде
    AddUtf8BOM(d)
    SaveToFile({d},tmpfile)

    -- готово!
    WOpen(j,tmpfile)
    if i ~= j then WNew(i) end

    os.setlocale('C')  -- вернуть стандартную локаль
end
Тест. Консолидировать статистику в окне 0 и результат оставить там же.

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

FreqConsolidate(0,0) -- по умолчанию разделитель: '|'; врем. файл: tmp.txt
Было в окне 0:

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

18|вася=Вася
1|вася=Вася
3|вася=Вася
4|вася=Вася
3|毛泽东=Мао Цзедун
10|маша=Маша
1|маша=Маша
13|маша=Маша
1|毛泽东=Мао Цзедун
13|коля=Коля
Стало:

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

24|маша=Маша
4|毛泽东=Мао Цзедун
26|вася=Вася
13|коля=Коля

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

Скрипты для Demagog

#495

Сообщение tonio_k »

Единственной момент, символ "|" я использовал для наглядности примера. Фактически планировалось его применять к результатам работы WStat, а там разделитель - знак табуляции. Если заменить знак табуляции на символ "|" то при накоплении статистики с регулярными выражениями могут быть проблемы, т.к. там этот символ активно применяется. Если вашу функцию брать на вооружение как стандартную, то просьба добавить в него возможность опционально указывать по какому символу делить левую часть от правой относительно символа разделителя.

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

Скрипты для Demagog

#496

Сообщение flegont »

Откорректировал предыдущий пост.
FreqConsolidate(i, j, delim, tmpfile)
Разделитель по умолчанию: '|', временный файл: 'tmp.txt'
Для разделителя-табуляции можно написать:

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

FreqConsolidate(0, 0, '\9') -- врем. файл по умолчанию будет tmp.txt

Аватара пользователя
Lecron
Специалист

Скрипты для Demagog

#497

Сообщение Lecron »

tonio_k писал(а):
15 май 2020 18:20
Потому что в кодировке OEM 866 строка должна выглядеть так:
notepad.exe d:\агббЄЁҐЎгЄўл.txt
Если еще проблема не решена, то можно перекодировать снаружи.

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

SaveToFile({exec_string},'d:\\1.bat')
os.execute('iconv.exe -c -f UTF-8 -t CP866 d:\\1.bat > d:\\1_866.bat')
os.execute('d:\\1_866.bat')
Или, не знаю всех возможностей скриптового языка, использовать iConv в качестве SaveToFile. Отправлять {exec_string} на stdin iConv, а stdout в 1.bat. Избежим временной копии батника.

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

Скрипты для Demagog

#498

Сообщение tonio_k »

Lecron писал(а):
20 июл 2020 09:51
Если еще проблема не решена, то можно перекодировать снаружи.
решение проблемы было буквально в следующем посте-ответе. Всё решается средствами самого lua без сторонних программ.

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

Скрипты для Demagog

#499

Сообщение tonio_k »

flegont писал(а):
31 авг 2019 10:42
table.save(t, f) - сохранить таблицу t в файл f
table.load(f) - загрузить таблицу из файла f
в процессе применения почувствовал нехватку некой функции "Сравнение и односторонняя синхронизация удаленных и добавленных переменных таблицы с файлом настроек".
Пример:

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

--Настройки по умолчанию:
if not FileExists('$MySettings.txt') then
	t = {}
	t.simbol = 10000
	t.Mess = 'Внимание, проверить на ошибки!'
	t.file = [[dic\СПИСОК СЛОВАРЕЙ 03 DIC СЛОВАРИ.lua]]
	t.Ans = false
	table.save(t,'$MySettings.txt')-- сохраняем таблицу в файл
end

-- читаем таблицу (другое имя взято для чистоты эксперимента) из файла
d = table.load('$MySettings.txt')
Допустим файл с переменными $MySettings.txt уже существует и содержит переменные из ранее созданной таблицы t
Теперь в таблице t поменялись настройки по умолчанию: удаляем и добавляем по одной строке:

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

--Настройки по умолчанию:
if not FileExists('$MySettings.txt') then
	t = {}
	t.Mess = 'Внимание, проверить на ошибки!'
	t.file = [[dic\СПИСОК СЛОВАРЕЙ 03 DIC СЛОВАРИ.lua]]
	t.Ans = false
	t.Use = "новое значение"
	table.save(t,'$MySettings.txt')-- сохраняем таблицу в файл
end

-- читаем таблицу (другое имя взято для чистоты эксперимента) из файла
d = table.load('$MySettings.txt')
В таблицу d загрузятся старые данные. Вот тут и нужна функция сравнения и односторонней синхронизации таблицы t с таблицей d. Что бы недостающие переменные вместе со значением добавились из t в d, а отсутствующие в t удалились в d. Т.Е. если нет строки Use = "новое значение" в d - добавляем ее, если строка simbol = 10000 в t отсутствует, а в d присутствует, то строку simbol = 10000 удаляем из d. (Проверка должна быть только по наличию/отсутствию переменных, а не их значений.)
Эта функция нужна на случай изменения(добавления/удаления) переменных в скрипте без вынужденного возврата к настройками по умолчанию связанных с полным переписыванием содержимого файла настроек.

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

Скрипты для Demagog

#500

Сообщение flegont »

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

-- реформировать таблицу d по образцу t
function Reform(d, t)
    -- удалить из d то, чего больше нет в t
    for k,v in pairs(d) do
        if t[k] == nil then d[k] = nil end
    end
    -- добавить в d, то что появилось новое в t
    for k,v in pairs(t) do
        if d[k] == nil then d[k] = v end
    end
    return d
end

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

-- тест
d = Reform(d,t)
table.save(d,'debug.txt') -- посмотрим на результат

Ответить

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