Страница 5 из 13

Скрипты для Demagog

Добавлено: 02 дек 2018 20:40
flegont
Конвертер № 3 у меня не пашет. Хоть conv.bat полный путь, хоть без пути. Мгновенно мелькает черное окошко и все. mp3 не создан, исходный wav удален.

А первые 2 конвертера - работают прекрасно. Особенно 2-й. Смотрю, как всё это крутится, потом слушаю, и медленно обалдеваю, придерживая рукой отвисающую от изумления челюсть... :smile1:
Пример чтения :up:

Скрипты для Demagog

Добавлено: 02 дек 2018 21:09
tonio_k
balaamster писал(а):
25 ноя 2018 21:37
Для реверберации нужно прописать такие настройки:
-loglevel -8 -y -i %1 -af "aecho=0.8:0.6:20|40:0.2|0.2, atempo=1.1" -b:a 64k %2
conv.zip
реверберацию, думаю, тоже надо в отдельный пункт меню выделить "добавить реверберацию?"

Скрипты для Demagog

Добавлено: 02 дек 2018 21:12
flegont
Конвертер №2. Желательно также дать пользователю возможность выбирать в меню соотношение громкости фона и речи. А то бывает, музыка местами глушить диктора.

Скрипты для Demagog

Добавлено: 02 дек 2018 21:47
tonio_k
flegont писал(а):
02 дек 2018 20:40
Конвертер № 3 у меня не пашет
у меня работает хорошо.
► Показать
и да, - нужно указывать полный путь. Жаль, что нужно полный путь указывать. Не портабл :boy_crying:

Скрипты для Demagog

Добавлено: 02 дек 2018 22:04
balaamster
tonio_k писал(а):
02 дек 2018 21:09
реверберацию, думаю, тоже надо в отдельный пункт меню выделить "добавить реверберацию?"
flegont писал(а):
02 дек 2018 21:12
Желательно также дать пользователю возможность выбирать в меню соотношение громкости фона и речи.
Добавил выбор реверберации и уровня громкости фона. В архиве только обновлённый скрипт.
converter_lua.zip
(5.12 КБ) 646 скачиваний
flegont писал(а):
02 дек 2018 20:40
Конвертер № 3 у меня не пашет
Проверил скрипт ещё раз, поправил переменные, где могут потребоваться кавычки для путей с пробелами.

На досуге попробую для bat-конвертера добавить параметры для реверберации и громкости фона.
tonio_k писал(а):
02 дек 2018 21:47
и да, - нужно указывать полный путь. Жаль, что нужно полный путь указывать. Не портабл
Попробовал добавить "& pause", чтобы успеть прочитать, что пишется в окне, при вводе только conv.bat в CustomEncoder:
"conv.bat" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.
не знаю, получится это побороть или нет.

Скрипты для Demagog

Добавлено: 02 дек 2018 22:18
tonio_k
flegont, такая мысль, может сделать консольную реализацию демагога в отношении своих скриптов?
Например demagog.exe confert.lua - ну а в confert.lua - все что душа программиста требует :loveboy: ?
Как вариант demagog.exe в качестве Custom encoder где все настройки в соответствующем скрипте

Скрипты для Demagog

Добавлено: 02 дек 2018 22:24
balaamster
upd.
Добавил в bat-конвертер
Теперь параметры
%1 %2 64 1.0 true 0.1
порядок параметров получается такой: путь_входного_файла путь_выходного_файла битрейт темп реверберация громкость_фона
реверберация - true или false
громкость_фона - 0.1 - 1.0
converter_bat(new).zip
(1.83 КБ) 669 скачиваний

Скрипты для Demagog

Добавлено: 02 дек 2018 22:31
tonio_k
balaamster,
converter_lua.zip "Выберите громкость фонового звука" - только ведь созрел, что бы поднять этот вопрос. А вы уже его решили :jokingly:

Скрипты для Demagog

Добавлено: 02 дек 2018 23:02
flegont
Конвертер №4 :ok: :victory: всё работает!

Скрипты для Demagog

Добавлено: 02 дек 2018 23:10
flegont
консольную реализацию демагога
Нет. Демагог всегда будет существовать в том виде, как он есть. Это - не какая-то там утилита, а довольно мощный текстовый редактор, который я использую, когда Блокнота мне уже мало, а Word'а - еще много. А то, что Демагог умеет читать вслух и записывать аудио - это приятный бонус :big_smile:
P.S. А то, что он еще и скрипты выполняет - так это был мой каприз, захотелось, чтобы программа, умеющая говорить, могла бы еще и считать. (Может, сказалось то, что я по образованию - математик). Первоначально опция так и называлась; "Калькулятор" :smile3:

Скрипты для Demagog

Добавлено: 03 дек 2018 07:44
flegont
При желании, можно, конечно запустить Демагог из командной строки, свернутым в значок.

Вызов программы из командной строки:
Demagog.exe имя_файла список_параметров. Список параметров - необязателен. Параметры в списке разделяются пробелами и могут следовать в любом порядке. Их значения следующие:

/m - запустить программу свернутой в значок
/r - открыть файл и начать чтение вслух
/s - открыть файл и сохранить текст в виде аудиофайла
/c - прочесть вслух текст из буфера обмена
/q - закрыть программу после окончания чтения
Например: Demagog "C:\Tests\Некий текст.txt" /m /r /q

Скрипты для Demagog

Добавлено: 03 дек 2018 12:34
tonio_k
flegont писал(а):
30 ноя 2018 13:56
Я точно не помню, надо глянуть в программе: как работает WText(). Возможно, там остался "артефакт"
из argo-interpreter:
WText(i) возвращает ansi-строку, содержащую текст (или его выделенный фрагмент) из вкладки i
Думаю, это не "артефакт", а нужная фишка. Присвоение переменной выделенный текст - тоже может пригодиться.

Для "чистого" присвоения переменной s содержимое вкладки хотел попробовать сделать через последовательность:

BufNew(s) -- очищаем буфер
r = BufAdd(1, s) -- присваиваем переменной r содержимое вкладки 1
ShowMessage(r)

но так почему то не работает...

Скрипты для Demagog

Добавлено: 03 дек 2018 14:06
flegont
или его выделенный фрагмент
Сам факт, что я когда-то такую нужную фишку сделал и напрочь о ней забыл, означает, что сделал не так, как надо. Поэтому будет переделано. WText(i) будет возвращать текст из вкладки i.
А уже существующая функция WSelText(i, z), заменяющая выделенный во вкладке i текст, строкой z, будет иметь дополнительный вариант. WSelText(i) с одним аргументом - номером вкладки, вернет выделенный текст в этой вкладке или '' если выделения нет.
По крайней мере, по названию функции будет ясно, с чем именно она работает - с выделенным текстом.
Для "чистого" присвоения
Функции Buf...() не возвращают значений. Они только оперируют с внутренним буфером. Единственный способ получить содержимое буфера: BufOpen(i) - открыть буфер в какой-нибудь вкладке.
И я не совсем понял, что имеется в виду под "чистым" присвоением? Сохранить содержащийся в буфере юникод? Ничего не выйдет, Lua все юникодные символы заменит знаком ?

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

s = "日本"  -- написать юникод в Lua-скрипте можем
ShowMessage(s)  -- работать с ним - нет
Поэтому я и придумал ВБ, чтобы выполнять конкатенацию текстов, НЕ обращаясь к работе со строками в Lua. Это - сохраняет юникод, т.к. с ВБ работает Демагог. По соответствующим командам, подаваемым из Lua-скрипта :wink:

Скрипты для Demagog

Добавлено: 03 дек 2018 15:21
tonio_k
flegont писал(а):
03 дек 2018 14:06
что имеется в виду под "чистым" присвоением?
я имел в виду содержимое окна без "выделения строк" - т.е. содержимое окна как оно есть. Не удачно выразился :dont_know:

Скрипты для Demagog

Добавлено: 04 дек 2018 17:53
flegont
RexRepl(s, r) - замены в строке s по массиву rex-правил r.
DicRepl(s, r, fastalg) - замены в строке s по массиву dic-правил r; fastalg = true/false - использовать быстрый алгоритм или прямой перебор, по умолчанию true.

Основное применение: оперативное тестирование правил rex и dic, не содержащих юникода.
Тестирование одиночного правила:

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

r = [[\bвсе\b\s+(\w+)\s+(\w+)ло\b=всё $1 $2ло]]
s = [[Мне все давно надоело...]]
s = RexRepl(s,{r})
ShowMessage(s)

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

r = [[все * *ло=всё ло]]
s = [[Мне все давно надоело...]]
s = DicRepl(s,{r})
ShowMessage(s)
Тестирование словаря:

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

d = LoadFromFile(HomeFolder('dic')..'Michel.dic',true)
s = WText(1)
z = os.clock()
s = DicRepl(s,d)
ShowMessage('Time = '..os.clock()-z)
WNew(0,s)

Скрипты для Demagog

Добавлено: 06 дек 2018 01:32
tonio_k
Скрипт для тестирования и сравнения между собой двух правил REX, в особенности - насколько "быстрее" или "медленнее" будет работать тот или иной вариант написания одного и того же правила. Создан на основе примера от flegont.

В теле скрипта находим:

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

-- СРАВНИТЬ СКОРОСТЬ РАБОТЫ ПРАВИЛ (ДА=1)
yes_no = 0
Для активации тестирования скорости, нужно указать yes_no = 1
Тогда создается "нагрузка" - будет умножен текст из переменной s в n=10000 раз.

Скрипт:

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

r0 = [[
(\bатласными\b)((\s(\w+)?){1,}(подушками)(\w+)?)=атлАсными $2
]]
r1 = [[
\b(атласными)\s+([^\.,!?-]*)\b(подушками)=атлАсными $2$3
]]
s = [[
атласными и всякими разными подушками
]]

-- СРАВНИТЬ СКОРОСТЬ РАБОТЫ ПРАВИЛ (ДА=1)
yes_no = 0

log_s = s
log_s0 = RexRepl(s,{r0})
log_s1 = RexRepl(s,{r1})

if yes_no == 1 then
n=10000 
k=''
for i = 1,n do
k=s..'\r'..k
end
s = k
end 

z = os.clock()
s0 = RexRepl(s,{r0})
log_r0 = 'Time = '..os.clock()-z

z = os.clock()
s1 = RexRepl(s,{r1})
log_r1 = 'Time = '..os.clock()-z

z = os.clock()
s0 = RexRepl(s,{r0})
log_r0 = log_r0..'\r'..'Time = '..os.clock()-z

z = os.clock()
s1 = RexRepl(s,{r1})
log_r1 = log_r1..'\r'..'Time = '..os.clock()-z

z = os.clock()
s0 = RexRepl(s,{r0})
log_r0 = log_r0..'\r'..'Time = '..os.clock()-z

z = os.clock()
s1 = RexRepl(s,{r1})
log_r1 = log_r1..'\r'..'Time = '..os.clock()-z

ShowMessage(log_s..'\r'..log_s0..'\r'..log_s1..'\r\r'..'Павило r0\r'..log_r0..'\r\r'..'Павило r1\r'..log_r1)



Отправлено спустя 18 минут 59 секунд:
При подсчете времени работы правила, делается прогон по 3 раза чередуясь между собой - что бы исключить влияние сторонних процессов на ПК и выявления среднего результата по каждому правилу.

Скрипты для Demagog

Добавлено: 08 дек 2018 23:48
balaamster
tonio_k писал(а):
06 дек 2018 01:51
Скрипт для тестирования и сравнения между собой двух правил REX
Чуть модифицировал скрипт.
  • добавлены запросы регулярных выражений через поля ввода
  • добавлен запрос строки, на которой проверяются выражения
  • добавлен запрос на тестирование скорости.
  • повторяющиеся действия (получение строк в переменные log_r0, log_r1) вынес в функцию и цикл

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

local yn_cap = 'СРАВНИТЬ СКОРОСТЬ РАБОТЫ ПРАВИЛ?'
local r0_cap = 'Регулярное выражение №1'
local r1_cap = 'Регулярное выражение №2'
local s_cap = 'Введите тестовую строку'

local r0_def = [[
(\bатласными\b)((\s(\w+)?){1,}(подушками)(\w+)?)=атлАсными$2
]]
local r1_def = [[
\b(атласными)\s+([^\.,!?-]*)\b(подушками)=атлАсными $2$3
]]
local s_def = [[
атласными и всякими разными подушками
]]

local r0 = Input(r0_cap,{string.format('rex #1=%s',r0_def)})
if not r0 or r0[1] == '' then
    ShowMessage('Необходимо зполнить "Регулярное выражение №1"')
    goto HALT
else
    r0 = r0[1]
end
local r1 = Input(r1_cap,{string.format('rex #2=%s',r1_def)})
if not r1 or r1[1] == '' then
    ShowMessage('Необходимо зполнить "Регулярное выражение №2"')
    goto HALT
else
    r1 = r1[1]
end
local s = Input(s_cap,{string.format('Строка=%s',s_def)})
if not s or s[1] == '' then
    ShowMessage('Необходимо зполнить тестовую строку')
    goto HALT
else
    s = s[1]
end


-- СРАВНИТЬ СКОРОСТЬ РАБОТЫ ПРАВИЛ (ДА=1)
local yes_no = Menu(yn_cap, {'Да','Нет'})
if yes_no == 0 then goto HALT end


function rex_time(str, rex)
    local z = os.clock()
    local s0 = RexRepl(str,{rex})
    return string.format('Time = %s\n', os.clock()-z)
end


local log_s = s
local log_s0 = RexRepl(s,{r0})
local log_s1 = RexRepl(s,{r1})

if yes_no == 1 then
    local n = 10000
    s = string.rep(s, n, '\n')
end


local log_r0 = ''
local log_r1 = ''


for i=1,3 do
    log_r0 = string.format('%s%s',log_r0,rex_time(s, r0))
    log_r1 = string.format('%s%s',log_r1,rex_time(s, r1))
end

out = string.format('%s\n%s\n%s\n\nПравило r0\n%s\n\nПравило r1\n%s',log_s, log_s0, log_s1, log_r0, log_r1)
ShowMessage(out)

::HALT::
Чуть сам не забыл, что повторить строку несколько раз можно через встроенную функцию

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

string.rep(s, n [, sep])
s - строка, которую нужно повторить
n - число повторений
sep - разделитель.

Скрипты для Demagog

Добавлено: 09 дек 2018 01:55
tonio_k
Обязательно возьму на вооружение технологию диалогов.
Однако лично мне удобнее работать не запуская сам скрипт, а работать со скриптом как с тестовым документом. Я даже сразу его сохранил как txt файл. Вношу изменения в строки с правилами держа их все перед глазами одновременно и имея возможность перескакивать с одного правила на другое копируя или делая замены. Нажимая на F2 для текущего окна что бы прямо на месте увидеть результат срабатывания. И при необходимости включать или отключать секундомер.

Скрипты для Demagog

Добавлено: 09 дек 2018 09:51
flegont
Нажимая на F2 для текущего окна
Я часто поступаю так же. Работаю со скриптом, как с текстом, в "отладочном режиме" по F2. Такой экспериментальный скрипт может состоять из разных частей, каждую из которых запускаю отдельно, меняя метку в первой строке.

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

-- блоки для разных экспериментов
goto B2  -- выполнить нужный блок

::B1::
-- блок 1
    ...
goto HALT

::B2::
-- блок 2
    ...
goto HALT

::B3::
-- блок 3
    ...
goto HALT
...
...
::HALT::

Скрипты для Demagog

Добавлено: 28 фев 2019 20:25
tonio_k
balaamster писал(а):
28 фев 2019 13:43
Про автоматическую замену
есть мысль попробовать реализовать эту идею через скрипт взяв за идею мой эксперимент.
1) нужно адаптировать словарь rex например под вид:

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

#адреса
\b(букв|другого|насчёт|несуществующего|обратного|первого|поиск|постоянного|сетевого)([^\.,:!?-]*)\s+(адреса)\b=$1$2 Адреса
\b(без марок|имени)\s+(и|или|с)\s+(\bадреса\b)=$1 $2 Адреса
\b(без|без [егоёих]{1,3}|однако [егоёих]{1,3}|ближе|вместо|вдоль|вглубь|вне|внутр[ьи]|возле|возле [егоёих]{1,3}|вокруг|всего|второй|выше|выше [егоёих]{1,3}|глубине|дальше|дв[ае]|для|для [егоёих]{1,3}|до|до [егоёих]{1,3}|другой|из|из [запод]{1,3}|кроме|кроме [егоёих]{1,3}|мимо|моего|моей|напротив|нашего|нашей|нет|при себе её|ни|ни [егоёих]{1,3}|ниже|об[ае]|оба [егоёихэт]{1,3}|одной|от|от [егоёих]{1,3}|около|первой|посреди|против|против [егоёих]{1,3}|с|с [егоёих]{1,3}|своего|своей|сего|следующей|снаружи|твоего|твоей|той|того|три|у|у [егоёих]{1,3}|четыре|этого)\s+(\bадреса\b)=$1 Адреса
\b(пароля)(\S| -) адреса=$1$2 Адреса
(\bадреса)\s([^\.,:!?-]*)\b(не )(будет|зна[етлю]+|остави[влт]|куда выслать|моей|помню|скажу|спросил)(\w+)?=Адреса $2$3$4$5
#

#аду
\b(настоящему|полыхающему)([^\.,:!?-]*)\s(\bаду\b)=$1$2 Аду
#

#ангара
(\bангара\b)\s([^\.,:!?-]*)\b(на связи)\b=ангарА $2$3
#
Далее применяем скрипт, в котором прописываем следующую схему:

2) в открытом тексте книги вывести все найденные слова в окно статистики критерий поиска:
.*\b(адреса|ангара|аду ... и так далее весь перечень индекс слов )\b.*

в этом критерии поиска мы указываем все индекс слова, которые у нас есть в словарях
в результатае в окно статистики получаем список слов, к которым у нас есть правила в словаре rex за минусом слов-омографов, которые у нас в тексте не встречаются.
полученный список приводим в вид:
адреса|ангара|аду

3) открываем словарь rex в демагоге и выводим все подходящие в окно статистики критерий поиска:
^\#(адреса|ангара|аду)[^#]+
4) сохраняем полученный файл как temp.rex
5) применяем полученный файл в дальнейшей обработке текста


Отправлено спустя 8 минут 53 секунды:
если словарь сделать вида:
#ангара
(\bангара\b)\s([^\.,:!?-]*)\b(на связи)\b=ангарА $2$3
#

то получить быстро список индекс-слов можно
задав поиск вывести все подходящие по критерию:
\#(\w+)
в полученном результате сделать замену:
\#(\w+)\r=$1|


Отправлено спустя 8 минут 57 секунд:
tonio_k писал(а):
28 фев 2019 20:34
если словарь сделать вида:
#ангара
(\bангара\b)\s([^\.,:!?-]*)\b(на связи)\b=ангарА $2$3
#
что немаловажно, такое изменение словаря rex никак не повлияет на обычный метод его применения в Демагоге

Скрипты для Demagog

Добавлено: 28 фев 2019 21:04
flegont
А если так...
Это лишь черновой набросок :pardon:
1) Получить список всех правил из словаря, который хотим "профильтровать

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

h = LoadFromFile(HomeFolder('dic')..'MySlovar.rex',true)
2)

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

-- Надо найти в тесте книги все слова, которые есть в в левых частях правил из списка h
WOpen(1,f)  -- открыть файл книги f в окне 1
s = WText(1)  -- извлечь текст из окна 1 в строку s
-- просмотр всех слов в строке s
z = 1
while true do
    if j ~= nil then
        i, j = string.find(s, '%a+',z) -- найдены позиции начала и конца очередного слова
        w = string,sub(s,i,j) -- очередное слово
        -- проверяем: есть ли w в h
        omo = {}  -- список правил из словаря, для которых есть омографы в тексте
        for i = 1,#h do
           -- тут каким-то способом выделяем из h[i] левую часть
           ...
           left = ...
           if left == w then 
               omo[#omo+1] = h[i] -- занесли подходящее правило в список
           end 
        end 
    end
end
-- в осадке остался список "подходящих" к данной книге правил
-- применяем их к строке s
RexRepl(s, omo) 
SaveToFile({s},'Измененный текст.txt')
UPDATE. В общем случае всё вышеизложенное не сработает. Т.к. левая часть правила не обязана совпадать с каким-либо омографом. И простым перебором слов текста, подходящие правила в словаре не выявить.

Скрипты для Demagog

Добавлено: 28 фев 2019 21:13
tonio_k
пока менял словарь, наткнулся на правило:
(\w+(дному|мому)\b\s?(\w+)?)\s{1,4}(\bаэро)?(порту\b)=$1 $4пОрту
при поиске индекса \bпорту\b слово аэропорту будет проигнорированно.
такие правила надо либо дублировать и добавлять индекс #аэропорту либо присваивать индекс #прочее и все подобные правила присваивать индекс #прочее

Скрипты для Demagog

Добавлено: 28 фев 2019 21:27
flegont
Да, действительно, нельзя левую часть правила просто считать индексом. Я был слишком оптимистичен в своих размышлениях :suspect:

Скрипты для Demagog

Добавлено: 28 фев 2019 21:30
tonio_k
flegont писал(а):
28 фев 2019 21:04
-- Надо найти в тесте книги все слова, которые есть в в левых частях правил из списка
а это не будет шыло на мыло? REX и так ищет в тесте книги все слова, которые есть в в левой части правила и, если находит, то производит замену.
Идея индекса - это поиск слов омографов из постоянного списка взятого из rex словаря.
Когда список слов омографов встречающихся в книге получен, то за минусом длины этой списка уменьшается словарь REX - из него достаются только те правила, которые хоть раз да будут применены. Остальные правила, которые работали в холостую, будут отброшены. Именно это уменьшение rex словаря - дает теоретический прирос скорости обработки. Зато прибавляется время на поиск индекс слов и подготовка словаря под них.


Отправлено спустя 21 минуту 57 секунд:
tonio_k писал(а):
28 фев 2019 21:30
Зато прибавляется время на поиск индекс слов и подготовка словаря под них.
тут я надеюсь, что поиск индекс слов с помощью быстрого алгоритма DIC сделает эту операцию чуть быстрее.

Скрипты для Demagog

Добавлено: 28 фев 2019 22:45
flegont
Это даже не шило на мыло, а прямая ошибка. На ночь глядя, я стал рассеянным, даже не подумал, что левая часть - не обязана совпадать с каким-либо омографом. А значит, простым перебором по словам в тексте подходящее правило никак не выявить :clown:
Только ручная работа... :cry_baby:

Скрипты для Demagog

Добавлено: 01 мар 2019 19:28
tonio_k
Решил начать "ваять" скрипт ускорения работы словарей rex и сразу затык... :cry_baby:

Правка - Найти, (по шаблону rex) Все подходящие
\#(адреса|аду|ангара|атлас|атласа)[^#]+
работает хорошо

а вот скрипт с этим запросом пишет ошибку "Некорректное регулярное выражение"

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

ind = WActive()
s = WText(ind)
header = 'Поиск фрагментов с заданными словами'
askname = 'Регулярное выражение (REX):'
defname = [[^(.)*(.)*=(.)*(.)*$]]

::START::

if FileExists('#rexFind.@') then 
    fnd = LoadFromFile('#rexFind.@')[1]
else
    fnd = defname
end

fnd = Input(header,{askname..'='..fnd})
if not fnd then goto HALT end
fnd = fnd[1]
if fnd == [[]] then 
	fnd = defname
	SaveToFile({fnd},'#rexFind.@')
	goto HALT
 end

SaveToFile({fnd},'#rexFind.@')

WNew(0)
r = fnd
k = 1
while k > 0 do
    fnd, k = RexMatch(s,r,k)
    WLog(fnd)
    if k > 0 then k = k+#fnd+1  end
end
WActive(0)

-- установить курсор на первой позиции найденного
s = WText(ind)
fnd, k = RexMatch(s,r,1)
if k > 0 then WSel(ind,k-1,#fnd) end

::HALT::
Текст для тестирования:
► Показать

Отправлено спустя 2 минуты 12 секунд:
и сразу вопрос, как через скрипт сделать текст без дубликатов


Отправлено спустя 11 минут :
выявил, что затык возникает на этапе диалога.
так как в таком виде ошибки не выводит и все находит:

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

ind = WActive()
s = WText(ind)
header = 'Поиск фрагментов с заданными словами'
askname = 'Регулярное выражение (REX):'
defname = [[\#(адреса|аду|ангара|атлас|атласа)[^#]+]]

::START::
fnd=defname
WNew(0)
r = fnd
k = 1
while k > 0 do
    fnd, k = RexMatch(s,r,k)
    WLog(fnd)
    if k > 0 then k = k+#fnd+1  end
end
WActive(0)

-- установить курсор на первой позиции найденного
s = WText(ind)
fnd, k = RexMatch(s,r,1)
if k > 0 then WSel(ind,k-1,#fnd) end

::HALT::

Скрипты для Demagog

Добавлено: 01 мар 2019 21:53
flegont
пишет ошибку "Некорректное регулярное выражение"
Это - ошибка функции Input() :cry_baby: Как оказалось, она некорректно воспринимает символ | во вводимом в нее тексте. И обрывает текст именно на нем.
Думаю, как исправить.

Скрипты для Demagog

Добавлено: 01 мар 2019 23:08
balaamster
Сегодня появилась идея для обработки rex-словаря омографов.

Ниже приведён черновик скрипта. Вроде работает, но надо протестировать на более полном словаре и разных текстах.

Так как омографов меньше, чем слов в тексте. то будем искать омограф в тексте, а не слово из текстового блока книги в списке омографов.
1. Форматируем словарь по схеме, аналогичной предложенной tonio_k, с модификациями:
► Показать
2. Открываем rex-словарь в первом окне
3. Открываем текст книги во втором окне.
тестовый фрагмент:
► Показать
4. Из любого другого окна (кроме "Статистика") запускаем скрипт:

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

-- полный rex-словарь омографов
local rex = WText(1)

-- окно с текстом книги
local text = WText(2)

-- сокращённый rex
local short_rex = {}


-- разбираем словарь на хэш-таблицу "слово_омограф"="строки с правилами"
local rules = {}
for i,j in string.gmatch(rex, '###([^\r\n ]+)(.-)###end') do
    rules[i]=j
end

-- составляем массив сокращённого rex-словаря
for i, j in pairs(rules) do
    -- если слово-омограф (ключ) есть в тексте, то добавляем его правила в сокращённый словарь
    if string.find(text,i) then
        -- разбиваем набор правил на отдельные строки для добавления в массив
        for rule in string.gmatch(j, "([^\r\n]+)") do
                table.insert(short_rex,rule)
        end
    end
end

-- применяем сокращённый словарь
local a = RexRepl(text, short_rex)
print(a)


-- печатаем содержимое сокращённого словаря
for i, j in pairs(short_rex) do
    print(i, j)
end

Скрипты для Demagog

Добавлено: 02 мар 2019 00:00
tonio_k
balaamster писал(а):
01 мар 2019 23:08
Ниже приведён черновик скрипта
balaamster, вот чуть-чуть меня опередил! :smile3:
Мой вариант:
1) требование к словарю - любое количество # перед индекс словом. Решетка # перед индекс словом одновременно является и концовкой для предыдущего списка. Поэтому в самом конце словаря # - поставить обязательно. Так что перелопатить уже существующий словарь - чуть проще :wink:
► Показать
2) Скрипт применяется к активному окну с книгой.

3) сначала получаем полный список индекс слов из словаря

4)запускается анализ текста книги на присутствие в ней омографов из п.3

5) на основании полученного в п.4 списка ищутся все правила в словаре rex

6) найденные правила записываются в словарь SPEEDOMOREX.rex

7) полученный словарь уже можно подцеплять к основному скрипту обработки словарей

8) словарь SPEEDOMOREX.rex после отработки остальными словарями нужно удалить, что бы не болтался с активными.

flegont, обратите внимание на вкладку --!!!ЗДЕСЬ НУЖНА ЧИСТКА ОТ ДУБЛИКАТОВ!!! (пока не знаю как) - знаний не хватает либо доп функцию в скрипте требуется

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

--черновик скрипта ускорения REX словарей с омографами (в словаре должны быть индекс-слова) SPEEDOMOREX

ind = WActive() -- получаем номер активного окна (окно с открытой книгой)

-- ПОЛУЧЕНИЕ СПИСКА ИНДЕКС-СЛОВ ИЗ СЛОВАРЯ REX
WActive(0)
homedir = HomeFolder('dic')

WOpen(0,homedir..'20_REX_Замены от waska.rex') -- открываем словарь, который надо ускорить

rex_dic = WText(0) -- в переменную текст из словаря REX (что бы повторно его не открывать)

s = rex_dic -- в переменную текст из словаря для получения индекс-слов  

WNew(0)
fnd = [[\#(\w+)]]
WNew(0)

r = fnd
k = 1

WLog([[\b(]])
while k > 0 do
    fnd, k = RexMatch(s,r,k)
    WLog(fnd)
	if k > 0 then k = k+#fnd+1  end
end
WLog([[)\b]])

s = WText(0) -- переносим список индекс слов в переменную

--!!!ЗДЕСЬ НУЖНА ЧИСТКА ОТ ДУБЛИКАТОВ!!! (пока не знаю как)

WNew(0)

--ЧИСТКА
r0 = [[
\#(\w+)[\r\n]+=$1|
[\r\n](\w+|)=$1
\|\)=)
]]

log_s = RexRepl(s,{r0}) -- проводим замены (чистка) и получаем критерий поиска по индекс словам



--АНАЛИЗ ТЕКСТА (поиск по полученному выше списку индекс-слов)
WActive(ind) -- активируем окно с книгой

fnd=log_s -- вместо автоматического ПОЛУЧЕНИЕ СПИСКА ИНДЕКС-СЛОВ ИЗ СЛОВАРЯ REX (выше) здесь можно сразу вручную указать свой поисковый запрос по шаблону REX по всем индекс-словам

r = fnd
k = 1
WLog([[\#(]])
while k > 0 do
    fnd, k = RexMatch(s,r,k)
    WLog(fnd)
	if k > 0 then k = k+#fnd+1  end
end
WLog([[)[^#]+]])
s = WText(0) -- записываем результат в переменную результат

--!!!ЗДЕСЬ НУЖНА ЧИСТКА ОТ ДУБЛИКАТОВ!!! (пока не знаю как)

--ЧИСТКА
r0 = [[
(\w+)[\r\n]+=$1|
[\r\n](\w+|)=$1
\|\)=)
]]

log_s = RexRepl(s,{r0}) -- получаем список слов, которые точно встречаются в тексте 
WNew(0)

s = rex_dic -- текст из словаря REX (который открывали в самом начале)

fnd=log_s
r = fnd
k = 1

while k > 0 do
    fnd, k = RexMatch(s,r,k)
    WLog(fnd)
    if k > 0 then k = k+#fnd+1  end
end
WActive(0)

WSave(0,homedir..'SPEEDOMOREX.rex') -- сохраняем новый ускоренный REX словарь в папку dic
WNew(0)

-- после применения к тексту словаря SPEEDOMOREX.rex его обязательно нужно удалить:
-- os.remove(homedir..'SPEEDOMOREX.rex')
-- что бы он не болтался среди акивных словарей

::HALT::



Отправлено спустя 29 минут 57 секунд:
balaamster писал(а):
01 мар 2019 23:08
for i,j in string.gmatch(rex, '###([^\r\n ]+)(.-)###
тут можно поставить:
'\#(\w+)[^\#]+'
тогда будет под мой вариант оформления словаря.

Скрипты для Demagog

Добавлено: 02 мар 2019 09:36
flegont
Информация к размышлению...

dic-словари в "быстром алгоритме" работают быстро потому, что каждый раз перед их применением выполняется "индексация" (точнее хеширование) словаря по первому слову в левой части правила.

Для rex-словарей ничего подобного придумать не смог - слишком сложная у регулярных выражений структура.

Составление "индексированного" rex-словаря вручную - работа очень трудоемкая, и в общем случае такой подход принят быть не может.
Но... чорт возьми, можно ли как-то индексацию rex-словаря автоматизировать?!

Иногда я думаю о некоем "процессе обучения". Пусть бы Демагог выполнял поиск по rex-правилам в некоем реальном большом тексте (текстах), и отмечал: какое слово/словосочетание было найдено очередным правилом.
Это слово и принять в качестве индекса для данного правила. Процесс длительный, возможно, с перерывами и сохранением промежуточного результата в файл.
Чем больший объем текстов будет использован для "обучения", тем точнее будет результат. При этом некоторые правила не будут проиндексированы, т.к. ни разу не сработают на реальных текстах. Тоже, кстати, полезная была бы информация.
:suspect: :suspect: :suspect:

Скрипты для Demagog

Добавлено: 02 мар 2019 09:52
flegont
НУЖНА ЧИСТКА ОТ ДУБЛИКАТОВ
В общем случае, например, так:

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

-- очистить список строк lines от дубликатов
t = {}  -- список без дубликатов
table.sort(lines)
t[1] = lines[1]
for i = 2, #lines do
    if lines[i] ~= t[#t] then t[#t+1] = lines[i] end
end
for i = 1, #t do
    print(t[i])
end  

Скрипты для Demagog

Добавлено: 02 мар 2019 12:15
tonio_k
balaamster, омографы в словаре - это условно ограниченный список.
Следовательно автоматическое получение индекса из файла rex не совсем обязательная процедура. Я даже свой​ скрипт разделил на две условные части: "Поиск индекса" и "анализ текста".
Так как Новые омографы в словаре rex добавляются очень редко (условно он уже полностью заполнен), то
Индексацию словаря для формирования поискового запроса поиска омографов в книге можно сделать вручную - один раз, поместить его в виде поискового запроса по шаблону rex в шапку словаря. И уже этот запрос брать из шапки при каждом обращении к словарю. Таким образом, чуть чуть сокращается время за счёт исключения затраты времени на его формирование.

Мои теоретические расчеты: индексный метод ощутимый прирост в скорости даст только при сериальной обработке книги.

Принцип тут такой:
Чем меньше отрезок текста, тем быстрее в нем что либо искать и количество встречающихся омографов на единицу сериала статистически меньше чем во всём тексте. Следовательно, при анализе текста сериала, будет получен сравнительно меньший по размеру словарь, чем словарь, который бы мы получили ко всей книге. При этом, размер основного словаря для каждой серии остаётся неизменным.

Возьмём основной словарь за базу сравнения:

В долях (!взяты с потолка!):
Соотношение 2/3 - это проиндексированный словарь ко всему тексту книги в сравнении с основным словарем. Если тут его применить к сериалу, то прироста скорости мы не должны особо почувствовать. Здесь​ проиндексированный словарь Не особо отличается от основного

Соотношение 1/3 - это проиндексированный словарь к единице сериала в сравнении с основным словарем. Вот тут и будет прирост в скорости.

Но если на каждом сериале будет происходить автоматическая индексация словаря, которая тоже занимает время, то для его экономии идея с переносом поискового запроса в шапку словаря - будет иметь смысл. Этот запрос можно будет всегда откорректировать, если появится новое слово-омограф.


Отправлено спустя 4 минуты :
Этот поисковый запрос получения индекса вообще можно сразу в теле скрипта прописать


Отправлено спустя 4 минуты 44 секунды:
Подумал немного... Нет, все же нужен. Это для себя я могу такое сделать, а вот для сборки... Где пользователь захочет что то добавить, он это добавит в словаре. И это автоматом будет подхвачено. Особенно если этот скрипт будет перенесён в функцию

Скрипты для Demagog

Добавлено: 02 мар 2019 15:29
balaamster
Утро вечера мудренее.
Сегодня понял, что предложенный вчера скрипт условно рабочий.
В строке

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

if string.find(text,i) then
я проверяю, есть ли слово из заголовков rex-словаря в тексте книги, но я не учёл, что string.find ищет шаблон, а не слово целиком. Для заголовка "ноги" эта функция найдёт в тексте книги и "ноги" и "миноги".
После такой ошибки появилась идея к заголовкам добавлять какой-либо символ, как обозначение границы слова, так как в наборах паттернов в lua нет обозначения границы через "\b", но есть %f[набор] - обозначает границу, где, слева от данной конструкции,нет символов из набора, а справа они есть.
То есть слово на кириллице можно задать так: "%f[А-яёЁ][А-яёЁ]+%f[^А-яёЁ]"

Можно в rex-словаре писать заголовки так:
► Показать
_ - будет обозначать границу слова слева
| - границу слова слева
Тогда заголовок "порту|" будет соответствовать и "порту" и "аэропорту". как задумывалось в вышеуказанном выражении
После делаем ряд замен:

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

local b_start = "%%f[А-яёЁ]"
local b_end = "%%f[^А-яёЁ]"
key = string.gsub(i, "_", b_start)
key = string.gsub(key, "|", b_end)
--проверяем, есть ли в тексте наш заголовок-шаблон?
if string.find(text,key) then
Но и такой преобразованный скрипт заставил задуматься - получается, что я вызываю поиск в большом текстовом файле для каждого заголовка-шаблона.
Тут вспомнил черновик flegont - там производился перебор слов текста книги и проверялся на их совпадение с левой частью регекса. Я решил попробовать перебор слов из текста и проверять на соответствие с заголовком. Если совпадение есть, то во временный словарь добавляется набор правил, соответствующих заголовку и в массив stop добавляется это слово, чтобы избежать повторного добавления строк. тут уже придётся делать отдельные заголовки для "порту"

И третий вариант - модификация второго, о чём я изначально думал, задавая вопрос о совмещении хэш-таблиц и rex-словаря. Проходимся по массиву строк, проверяем на наличие в ней омографов и применяем соответствующий им список правил. Если омографов в строке нет, то rex-словарь не применяется.

Тесты (пока "синтетические", размеченный словарь пробный)
В качестве текста - фрагмент книги, 4876 строк, 1 272 744 символа.
Каждый вариант запускался по три раза.
► Показать
Результаты, в секундах
► Показать
test.zip
(2.57 КБ) 546 скачиваний
Остаётся создать размеченный rex-словарь для омографов и протестировать в реальных условиях.

Скрипты для Demagog

Добавлено: 02 мар 2019 16:00
tonio_k
flegont писал(а):
02 мар 2019 09:52
НУЖНА ЧИСТКА ОТ ДУБЛИКАТОВ
В общем случае, например, так:
а можно пример немного адаптировать применении к окну Демагога
s = WText(1)
и вот в этой s - убрать все дубликаты

Скрипты для Demagog

Добавлено: 02 мар 2019 16:31
balaamster
tonio_k писал(а):
02 мар 2019 16:00
а можно пример немного адаптировать применении к окну Демагога
Думаю, что можно так:

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

-- преобразовать строку в таблицу
function string.totable(str)
	local tbl = {}	
	for i in string.gmatch(str,'[^\r\n]+') do
		table.insert(tbl, i)
	end
	return tbl
end

-- очистить список строк lines от дубликатов
function table.getuniq(lines)
	local t = {}  -- список без дубликатов
	table.sort(lines)
	t[1] = lines[1]
	for i = 2, #lines do
	    if lines[i] ~= t[#t] then t[#t+1] = lines[i] end
	end
	return t
end

local s = WText(1)

local tb = table.getuniq(string.totable(s))

for i = 1, #tb do
    print(tb[i])
end

Скрипты для Demagog

Добавлено: 02 мар 2019 17:02
flegont
Преобразовать длинную строку (то есть - текст) s в список строк lines:

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

lines = string.split(s,'\r\n')
Замечание. И этот пример, и предыдущий, от balaamster - игнорируют пустые строки в тексте. Потому что идущие подряд разделители \r\n...\r\n считаются за один.

Скрипты для Demagog

Добавлено: 02 мар 2019 17:10
balaamster
flegont писал(а):
02 мар 2019 17:02
string.split(s,'\r')
:thank:
Плохая память и частые перерывы в использовании языка - причина моего "изобретения велосипеда".
Хорошая вещь склероз - узнаёшь столько нового :smile1:

Скрипты для Demagog

Добавлено: 02 мар 2019 17:19
flegont
"Дорог тысячи, цель - одна" (с) :smile1:

Скрипты для Demagog

Добавлено: 02 мар 2019 17:31
tonio_k
flegont писал(а):
02 мар 2019 17:02
lines = string.split(s,'\r\n')
а в итоге то как будет закончено выглядеть? Извините что настаиваю, но таблицы для меня это трехмерный мир для плоского разума))

Скрипты для Demagog

Добавлено: 02 мар 2019 17:45
balaamster
В конечном виде вот так:

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

-- очистить список строк lines от дубликатов
function table.getuniq(lines)
	local t = {}  -- список без дубликатов
	table.sort(lines)
	t[1] = lines[1]
	for i = 2, #lines do
	    if lines[i] ~= t[#t] then t[#t+1] = lines[i] end
	end
	return t
end

local s = WText(1)

-- таблица с неповторяющимися строками
local tb = table.getuniq(string.split(s,'\r'))

-- строка, полученная из таблицы, расположенной выше
new_s = table.concat(tb, '\r')

Скрипты для Demagog

Добавлено: 02 мар 2019 17:49
tonio_k
flegont,
balaamster писал(а):
02 мар 2019 17:45
function table.getuniq(lines)
может в calculator добавить?

Скрипты для Demagog

Добавлено: 02 мар 2019 18:41
flegont
Можно и добавить. Только название лучше слегка изменить. Это НЕ удаление дубликатов из исходной таблицы. Это - СОРТИРОВКА исходной таблицы с удалением дубликатов.
table.sortunic(lines)

Скрипты для Demagog

Добавлено: 02 мар 2019 19:12
wasyaka
tonio_k писал(а):
02 мар 2019 12:24
В долях (!взяты с потолка!):
Соотношение 2/3 - это проиндексированный словарь ко всему тексту книги в сравнении с основным словарем. Если тут его применить к сериалу, то прироста скорости мы не должны особо почувствовать. Здесь​ проиндексированный словарь Не особо отличается от основного
А в еденицах времени можно?
(всё касается только растановке омографов)
К примеру текст в тхт размером в полметра - до; после
У меня такой текст примерно 7,5 минуты - грубо 0,1 метра текста -полторы минуты,
Единственная сложность нажать АЖ ТРИ кнопки :big_smile:
На выходе от 300 до 500 необработанных из них (при соответствующем омо авто) от 70 до 120 надо вручную или в уме перевести -типо примечание:... :big_smile:

Скрипты для Demagog

Добавлено: 02 мар 2019 20:17
tonio_k
wasyaka писал(а):
02 мар 2019 19:12
А в еденицах времени можно?
можно, но позже. сначала надо словарь подготовить под индексы.
Да и сам скрипт по созданию урезанного словаря нуждается в доработке.

balaamster, появилась мысль, как решить проблему с вариантом когда одно правило применяется для двойных омографов: поезда бронепоезда стекла бронестекла
При поиске индексации всех омографов в словаре применить запрос:
\#[^.\s]$

А в словаре rex такие варианты индексов записывать по схеме:
► Показать

А уже в полученном списке произвести замену:
,=\r


Отправлено спустя 2 часа 25 минут 41 секунду:
balaamster,
► Показать
это правило навело меня на мысль,так как текст после решетки все равно становится частью запроса по шаблону rex, то можно индекс и так завести:
###забега([июалет]+


Отправлено спустя 11 минут 2 секунды:
tonio_k писал(а):
02 мар 2019 22:42
При поиске индексации всех омографов в словаре применить запрос:
\#[^.\s]$
ошибка. правильно:
\#[^.]+$
убрал запрет на пробел. Вдруг будет необходимость ввести в качестве индекса не только слово, но и словосочетание, например: "из зАмка"


Отправлено спустя 1 день 12 часов 48 минут 17 секунд:
Закончил я "ваять" :hammerdrill: :morncoffee: скрипт под "индексный метод" применения словаря.
Хотя львиную долю времени занимает адаптация вручную словаря rex под этот метод.

Скрипт разбил на 2 файла:
SPEEDOMOREX_index.lua ищет все индекс слова в файле rex. Из найденного списка слов создает поисковый запрос по шаблону rex и помещает его в файл index.@
► Показать
SPEEDOMOREX_new_dictionary.lua берёт поисковый запрос из файла index.@ применяет его к тексту в окне статистики. Полученный список из найденных слов преобразует в поисковый запрос по шаблону rex и запускает поиск по словарю rex. Все найденные правила сохраняет во временный файл SPEEDOMOREX.rex
► Показать
Причина разбития на 2 скрипта: 1 скрипт запускается в самом начале до начала обработки сериалов. К каждому сериалу применяется уже 2 скрипт, который берет данные из index.@

Сборку Демагог с готовыми и настроенными скриптами для экспериментов c разными методами применения словарей выложу на основной ветке


Отправлено спустя 1 день 1 час 3 минуты 9 секунд:
flegont, я правильно понимаю, если уж применил команду:

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

s = WText(0)
то с этого момента текст в эту переменную попадает в ANSI кодировке?

Скрипты для Demagog

Добавлено: 05 мар 2019 14:38
flegont
1) Да, Именно так. Какая бы ни была кодировка исходного файла, после попадания в интерпретатор, извлеченный текст будет преобразован в ansi-строку. Преобразование будет полностью корректным для английского алфавита (по умолчанию) и для алфавита местной локали. В данном случае, для русского языка. Если же в файле присутствовали символы НЕ английские и НЕ русские, тогда вместо них знак ?

2) Библиотека VerySimpleLua, которая используется в Демагоге для встроенного интерпретатора, работает только с ansi-строками. Поэтому, как бы я ни старался, например выполнять файл скрипта в кодировке utf-8, когда дело доходит до работы со строками, то... ввжжжух! и всё utf-8 содержимое скрипта превращается в ansi. См. п. 1

Скрипты для Demagog

Добавлено: 05 мар 2019 16:23
tonio_k

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

s = WText(0)
RexRepl(s,{r0}) 
тогда получается к RexRepl текст в Юникоде никак не передать?
тот же вопрос к RexMatch(s,r,k)

Скрипты для Demagog

Добавлено: 05 мар 2019 17:28
flegont
Пока не вижу, как. То есть, можно написать нечто вроде

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

-- сохранить этот скрипт в кодировке utf-8
-- и выполнить
s1 = 'Hello, World!'
s2 = 'Привет, Мир!'
s3 = 'こんにちは世界!'

ShowMessage(s1)
ShowMessage(s2)
ShowMessage(s3)

print(s1)
print(s2)
print(s3)
Видим, что английский+местная локаль (т.е. русский) - отображаются правильно.
А прочие символы (здесь - японский) гибнут на этапе присвоения строковой константы переменной s.

Скрипты для Demagog

Добавлено: 05 мар 2019 17:46
flegont
Начиная с Lua 5.3 разработчики добавили ограниченную поддержку utf-8. Как и раньше, нельзя указывать юникодные символы явно. Но можно через их десятичные коды.

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

-- создание файла в кодировке utf-8
bom = '\239\187\191'  -- маркер кодировки utf-8
s = bom..utf8.char(9658)..'   '..utf8.char(12371)..utf8.char(12435) ..utf8.char(12395)..utf8.char(12385)..utf8.char(12399)..utf8.char(19990)..utf8.char(30028)..'!'
SaveToFile({s},'testUTF8.txt')
ShowMessage('Файл testUTF8.txt создан!')
Гляньте полученный файл в Блокноте или загрузите в Демагог.
Должен быть черный треугольник, 3 пробела, и фраза по японски: Привет, Мир!


Отправлено спустя 22 минуты :
Хм... Если строку или список строк - rex-правил, содержащих текст в utf-8 невозможно задать явно, то может прочесть из файла? (который, конечно, должен быть в кодировке utf-8)

Надо учебник Роберта Иерусалимского почитать... :thinking:

Скрипты для Demagog

Добавлено: 05 мар 2019 18:19
tonio_k
есть результат!

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

►   こんにちは世界!


причем WLog(s) дает:

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

п»їв–є   гЃ“г‚“гЃ«гЃЎгЃЇдё–з•Њ!

WOpen (0,testUTF8.txt) дает:

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

►   こんにちは世界!
и даже если мы получим
s=► こんにちは世界! будет ли с ним еще работать LUA в плане поиска и замен

Скрипты для Demagog

Добавлено: 05 мар 2019 20:46
flegont
Черт его знает... Надо поэкспериментировать.