Скрипты для Demagog

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

Модератор: flegont

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

Скрипты для Demagog

#401

Сообщение tonio_k »

flegont писал(а):
14 июл 2019 19:18
В нем отображаются подсказки о назначении элементов интерфейса, при наведении на них мышью.
тогда рассмотрите такое пожелание:
дать возможность через скрипт в это поле выводить текстовую информацию на время работы скрипта. Сейчас, Пока работает скрипт, все равно "при наведении на них мышью." - не работает, а так, можно будет как прогресс-статус работы скрипта свой в это поле выводить - без всяких текстовых сообщений поверх экрана. " Скромный минимализм" :smile1:

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

Скрипты для Demagog

#402

Сообщение flegont »

Я подобные опыты уже делал. Именно для какого-нибудь отображения прогресса. Например, последовательное печатание процента выполнения. Не работает, и я пока не понял, почему.

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

Скрипты для Demagog

#403

Сообщение tonio_k »

Подскажите, как можно решить такую задачу.
Нужно вставить абзац \r между двумя строками если выполнены любое из 2 условий:
1) длина сравниваемых строк отличается
2) последние 5 символов сравниваемых строк отличаются
Пример текста:
► Показать

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

Скрипты для Demagog

#404

Сообщение flegont »

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

s = WText(1) -- в окне 1 содержится тестовый текст
a = string.split(s,'\r')
for i = 1,#a-1 do
    if (#a[i] ~= #a[i+1]) or (string.sub(a[i],-5) ~= string.sub(a[i+1],-5)) then
        a[i] = a[i]..'\r'
    end
end
s = table.concat(a,'\r')
print(s)
► Показать

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

Скрипты для Demagog

#405

Сообщение tonio_k »

flegont, :thank_you:

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#406

Сообщение balaamster »

skreb писал(а):
15 июл 2019 17:56
Как сделать, чтобы после обработки выводились изначальные имена обрабатываемых текстовых файлов, а не номер 0001.mp3
Изменён скрипт YaTTS.lua - при "склейке" аудиофрагментов именование файлов теперь имеет вид "имя файла книги_nnnn.mp3", где nnnn - порядковый номер. Если была запущена озвучка несохранённой вкладки, то именование имеет вид "tmp_doc_nnnn.mp3"

Внесены небольшие "косметические" правки в окно "YaTTS Configurator"
Demagog+YandexTTS.zip
(28.41 КБ) 987 скачиваний

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

Скрипты для Demagog

#407

Сообщение tonio_k »

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

local function TextSortAndDelDubl(dubltext)
local r = string.split(dubltext,'\r') -- преобразовываем текст в ТАБЛИЦУ
	  r = table.sortuniq(r) -- сортируем и удаляем дубликаты в ТАБЛИЦЕ
	  r = table.concat(r,'\r')  -- преобразовываем ТАБЛИЦУ в текст
return r
end
s=WText(1) -- применить к окну 1
s=TextSortAndDelDubl(s) -- удаляем дубликаты
print(s)
текст:
- А ты включай нас в свои гениальные планы, - посоветовал Денис, - и все будет путём. Ты посмотри, какая команда у тебя подобралась! Один Алекс чего стоит. Шесть медведей навскидку, и ни одна свинья даже хрюкнуть не успела. Всех наповал! Алекс, скажи честно, как тебе это удаётся?
- А ты включай нас в свои гениальные планы, - посоветовал Денис, - и всё будет путём. Ты посмотри, какая команда у тебя подобралась! Один Алекс чего стоит. Шесть медведей навскидку, и ни одна свинья даже хрюкнуть не успела. Всех наповал! Алекс, скажи честно, как тебе это удаётся?

Вопрос, почему сортировка меняет местами эти 2 строки? между строками разница только в символе Ё - а он идет после Е

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

Скрипты для Demagog

#408

Сообщение flegont »

Это в русском алфавите Ё идет после Е. А в юникоде это не так. Можно написать в окне Демагога русский алфавит, и ставя текстовый курсор перед очередной буквой, смотреть их коды в строке состояния. На Ё будет выпадение из возрастающей последовательности. Код Ё меньше кода Е, вот строки и меняются местами при сортировке.

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

Скрипты для Demagog

#409

Сообщение tonio_k »

сначала было рванулся прямо в функции замену "е" рус. на "е" лат. сделать, с возвратом обратно после отработки функции, но сообразил, что это чревато ситуацией когда начало строки с буквы "е" начинается. Такая замена эту строку выше строк начинающихся с русской буквы "а" может переместить :surprise2: . Мда... это исключение с Ё надо как то запомнить :waiting2:

Аватара пользователя
lplee

Скрипты для Demagog

#410

Сообщение lplee »

Работает ли Демагог с новой версией Яндекс ТТС, где нужно вводить не ключ разработчика, а токен?

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#411

Сообщение balaamster »

lplee писал(а):
16 июл 2019 00:28
Работает ли Демагог с новой версией Яндекс ТТС
На текущий момент связка "Demagog + Яндекс TTS-скрипты" работает только со "старой" версией сервиса, где используется ключ разработчика.

Адаптации под "новую" версию сервиса, с токеном, обещать не могу, но, если появится большое количество свободного времени, то посмотрю, как можно адаптировать скрипты под него.

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

Скрипты для Demagog

#412

Сообщение tonio_k »

подскажите, можно ли через скрипт сделать:
Содержимое буфера обмена в переменную s
s="изменен_"..s
измененную Переменную s поместить в буфер обмена

В итоге что бы можно было скопировать текст в любом источнике (Ctrl+C),
открыть окно Демагога и запустить выше указанный скрипт,
Вернуться в источник и вставить из буфера обмена измененный скриптом текст (Ctrl+V).

Аватара пользователя
balaamster
Обыватель

Скрипты для Demagog

#413

Сообщение balaamster »

tonio_k писал(а):
17 июл 2019 18:08
подскажите, можно ли через скрипт сделать:
Можно:

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

--буфер в переменную
s = Clipboard()

--изменяем s
s = "изменён_"..s

--переменную в буфер
Clipboard(s)

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

Скрипты для Demagog

#414

Сообщение tonio_k »

balaamster писал(а):
15 июл 2019 21:58
Demagog+YandexTTS.zip
пожелание к доработке: склеивание аудио файлов что бы происходило в одном окне (без мелькания открывания и закрывания окон к каждому файлу) Может это можно сделать через применение консольной команды к предварительно созданному созданному плейлисту?

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

Скрипты для Demagog

#415

Сообщение tonio_k »

Version 7.30.377
Я два дня ломал голову, почему у меня сломались раньше нормально работающие скрипты - словари с фонемами стали некорректно работать (вставлять со знаки вопроса в кодировке). Вроде нигде по ходу скрипта текст в переменную не переносил и словари применяются к окну а не к переменной... Оказалось, что я в настройках самого Демагога (Файл кодировка) как то раз изменил кодировку сохранения на ANSI а вернуть на UTF8 - благополучно забыл. А WSave() сохраняет именно так, как в настройках указано.
Что бы избежать подобных ситуаций и расширить возможности сохранения в файл через WSave() пожелание к функции Settings(o) - добавить возможность менять кодировку сохранения файла.

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

Скрипты для Demagog

#416

Сообщение flegont »

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

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

Скрипты для Demagog

#417

Сообщение tonio_k »

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

tom = 1 -- начальная нумерация тома
tom = Input('АВТОМАТИЧЕСКАЯ НУМЕРАЦИЯ',{'Начать нумерацию с цифры:'..'='..tom})
tom = tom[1]
print(tom+1)
результат 2.0

Математически верно, но вот в плане озвучки звучит как "два точка ноль"

Если переменную tom округлить:

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

tom = math.floor(tom[1]) -- округление до целого числа

результат 2 - то есть как надо без ноля.

Вопрос, это особенность lua или функции Input() ?

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

Скрипты для Demagog

#418

Сообщение flegont »

Это особенность и Lua и функции Input() - возвращающей все введенные данные, как строки, Здесь строка (string), изображающая число, автоматически преобразуется в число (number) при сложении с 1.

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

tom = 1 -- начальная нумерация тома
tom = Input('АВТОМАТИЧЕСКАЯ НУМЕРАЦИЯ',{'Начать нумерацию с цифры:'..'='..tom})
tom = tom[1]
print(type(tom)) -- увидим, что тип введенного значения - строка!
print(tom) -- печать строки tom
print(tom+1) -- автоматическое преобразование результата в число и печать

Результат:
string
1
2.0

ВОТ, КАК ПРАВИЛЬНО:

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

tom = 1 -- начальная нумерация тома
tom = Input('АВТОМАТИЧЕСКАЯ НУМЕРАЦИЯ',{'Начать нумерацию с цифры:'..'='..tom})
tom = tonumber(tom[1]) -- номер тома - число!
print(type(tom))
print(tom)
print(tom+1)
Результат:
number
1
2

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

Скрипты для Demagog

#419

Сообщение tonio_k »

flegont писал(а):
31 май 2019 11:16
Cancel() - функция встроенного интерпретатора. Возвращает true если была нажата глобальная клавиша прерывания длительных процессов (Break по умолчанию). Используется для досрочного прекращения работы скрипта.
так как любая ошибка в lua (в скрипте или в функции) останавливает выполнение скрипта - решил взять эту особенность на вооружение:

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

--ФУНКЦИИ:
function CancelScript()
    local txt_cancel = 'ПОЛЬЗОВАТЕЛЬ ВРУЧНУЮ ПРЕРВАЛ РАБОТУ СКРИПТА!'
    if Cancel() then
        Gauge(0) -- убираем зеленую полосу прогресса 
        StatusMessage(txt_cancel)
        error('\r\r\r'..AnsiToUtf8(txt_cancel,true)..'\r\r',0) 
    end
end

function AnsiToUtf8(s,hasbom)
    local q = {}
    local bom = '\239\187\191'
    local u, a, b, k
    -- russian unicode table
    q['А'] = 1040
    q['Б'] = 1041
    q['В'] = 1042
    q['Г'] = 1043
    q['Д'] = 1044
    q['Е'] = 1045
    q['Ж'] = 1046
    q['З'] = 1047
    q['И'] = 1048
    q['Й'] = 1049
    q['К'] = 1050
    q['Л'] = 1051
    q['М'] = 1052
    q['Н'] = 1053
    q['О'] = 1054
    q['П'] = 1055
    q['Р'] = 1056
    q['С'] = 1057
    q['Т'] = 1058
    q['У'] = 1059
    q['Ф'] = 1060
    q['Х'] = 1061
    q['Ц'] = 1062
    q['Ч'] = 1063
    q['Ш'] = 1064
    q['Щ'] = 1065
    q['Ъ'] = 1066
    q['Ы'] = 1067
    q['Ь'] = 1068
    q['Э'] = 1069
    q['Ю'] = 1070
    q['Я'] = 1071 
    q['Ё'] = 1025  
    --
    q['а'] = 1072
    q['б'] = 1073
    q['в'] = 1074
    q['г'] = 1075
    q['д'] = 1076
    q['е'] = 1077
    q['ж'] = 1078
    q['з'] = 1079
    q['и'] = 1080
    q['й'] = 1081
    q['к'] = 1082
    q['л'] = 1083
    q['м'] = 1084
    q['н'] = 1085
    q['о'] = 1086
    q['п'] = 1087
    q['р'] = 1088
    q['с'] = 1089
    q['т'] = 1090
    q['у'] = 1091
    q['ф'] = 1092
    q['х'] = 1093
    q['ц'] = 1094
    q['ч'] = 1095
    q['ш'] = 1096
    q['щ'] = 1097
    q['ъ'] = 1098
    q['ы'] = 1099
    q['ь'] = 1100
    q['э'] = 1101
    q['ю'] = 1102
    q['я'] = 1103   
    q['ё'] = 1105
    --
    u = ''
    for i = 1,#s do
        b = string.sub(s,i,i)
        if string.byte(b) < 128 then
            u = u..b
        else
            k = q[b]
            if k == nil then a = '?' else a = utf8.char(k) end
            u = u..a
        end
    end
    if hasbom then u = bom..u end
    return u
end

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

-- ПРИМЕР 
for i = 1,1000000000 do
    a = i
    CancelScript()
end
::HALT::
ShowMessage(a)
Сообщение когда CancelScript() отлавливает нажатие глобальной клавиши и прерывает скрит:
► Показать
Удобство CancelScript() - можно вставлять в любую функцию без применения ссылки на ::HALT::

*функция function AnsiToUtf8 - применяется для корректного отображения русских букв в информационном сообщении об ошибке lua

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

Скрипты для Demagog

#420

Сообщение flegont »

Русско-английский вариант:

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

-- Cancel script when user pressed global hotkey Break
function CancelScript()
    local msg, umsg
    if CurrentLang() == 'Russian' then
        msg = 'СКРИПТ ПРЕРВАН ПОЛЬЗОВАТЕЛЕМ!'
        umsg = AnsiToUtf8(msg,true)
    else
        msg = 'SCRIPT TERMINATED BY USER!'
        umsg = msg
    end
    if Cancel() then
        Gauge(0) -- remove progress bar (if was activated) 
        StatusMessage(msg)
        error(umsg..'\r\r',0) 
    end
end

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

Скрипты для Demagog

#421

Сообщение flegont »

У приведенной выше функции AnsiToUtf8() есть серьезный недостаток. Если в тексте встретятся символы с кодами > 127 и < 256, но не являющиеся русскими буквами, то при конвертации они превратятся в знак вопроса "?"
Вот полная конвертация AnsiToUtf8() и Utf8ToAnsi() для cp1251.
(будет добавлена в calculator.lua в вер. 378)

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

-- Full convert ANSI <---> UTF-8 for cp1251 code page --
local ansi_decode={
  [128]='\208\130',[129]='\208\131',[130]='\226\128\154',[131]='\209\147',[132]='\226\128\158',[133]='\226\128\166',
  [134]='\226\128\160',[135]='\226\128\161',[136]='\226\130\172',[137]='\226\128\176',[138]='\208\137',[139]='\226\128\185',
  [140]='\208\138',[141]='\208\140',[142]='\208\139',[143]='\208\143',[144]='\209\146',[145]='\226\128\152',
  [146]='\226\128\153',[147]='\226\128\156',[148]='\226\128\157',[149]='\226\128\162',[150]='\226\128\147',[151]='\226\128\148',
  [152]='\194\152',[153]='\226\132\162',[154]='\209\153',[155]='\226\128\186',[156]='\209\154',[157]='\209\156',
  [158]='\209\155',[159]='\209\159',[160]='\194\160',[161]='\209\142',[162]='\209\158',[163]='\208\136',
  [164]='\194\164',[165]='\210\144',[166]='\194\166',[167]='\194\167',[168]='\208\129',[169]='\194\169',
  [170]='\208\132',[171]='\194\171',[172]='\194\172',[173]='\194\173',[174]='\194\174',[175]='\208\135',
  [176]='\194\176',[177]='\194\177',[178]='\208\134',[179]='\209\150',[180]='\210\145',[181]='\194\181',
  [182]='\194\182',[183]='\194\183',[184]='\209\145',[185]='\226\132\150',[186]='\209\148',[187]='\194\187',
  [188]='\209\152',[189]='\208\133',[190]='\209\149',[191]='\209\151'
}
local utf8_decode={
  [128]={[147]='\150',[148]='\151',[152]='\145',[153]='\146',[154]='\130',[156]='\147',[157]='\148',[158]='\132',[160]='\134',[161]='\135',[162]='\149',[166]='\133',[176]='\137',[185]='\139',[186]='\155'},
  [130]={[172]='\136'},
  [132]={[150]='\185',[162]='\153'},
  [194]={[152]='\152',[160]='\160',[164]='\164',[166]='\166',[167]='\167',[169]='\169',[171]='\171',[172]='\172',[173]='\173',[174]='\174',[176]='\176',[177]='\177',[181]='\181',[182]='\182',[183]='\183',[187]='\187'},
  [208]={[129]='\168',[130]='\128',[131]='\129',[132]='\170',[133]='\189',[134]='\178',[135]='\175',[136]='\163',[137]='\138',[138]='\140',[139]='\142',[140]='\141',[143]='\143',[144]='\192',[145]='\193',[146]='\194',[147]='\195',[148]='\196',
    [149]='\197',[150]='\198',[151]='\199',[152]='\200',[153]='\201',[154]='\202',[155]='\203',[156]='\204',[157]='\205',[158]='\206',[159]='\207',[160]='\208',[161]='\209',[162]='\210',[163]='\211',[164]='\212',[165]='\213',[166]='\214',
    [167]='\215',[168]='\216',[169]='\217',[170]='\218',[171]='\219',[172]='\220',[173]='\221',[174]='\222',[175]='\223',[176]='\224',[177]='\225',[178]='\226',[179]='\227',[180]='\228',[181]='\229',[182]='\230',[183]='\231',[184]='\232',
    [185]='\233',[186]='\234',[187]='\235',[188]='\236',[189]='\237',[190]='\238',[191]='\239'},
  [209]={[128]='\240',[129]='\241',[130]='\242',[131]='\243',[132]='\244',[133]='\245',[134]='\246',[135]='\247',[136]='\248',[137]='\249',[138]='\250',[139]='\251',[140]='\252',[141]='\253',[142]='\254',[143]='\255',[144]='\161',[145]='\184',
    [146]='\144',[147]='\131',[148]='\186',[149]='\190',[150]='\179',[151]='\191',[152]='\188',[153]='\154',[154]='\156',[155]='\158',[156]='\157',[158]='\162',[159]='\159'},[210]={[144]='\165',[145]='\180'}
}

local nmdc = {
  [36] = '$',
  [124] = '|'
}

function AnsiToUtf8(s, hasbom)
  local bom = '\239\187\191'
  local r, b = ''
  for i = 1, s and s:len() or 0 do
    b = s:byte(i)
    if b < 128 then
      r = r..string.char(b)
    else
      if b > 239 then
        r = r..'\209'..string.char(b - 112)
      elseif b > 191 then
        r = r..'\208'..string.char(b - 48)
      elseif ansi_decode[b] then
        r = r..ansi_decode[b]
      else
        r = r..'_'
      end
    end
  end
  if hasbom then r = bom..r end
  return r
end

function Utf8ToAnsi(s)
  local bom = '\239\187\191'
  local a, j, r, b = 0, 0, ''
  if string.sub(s,1,3) == bom then s = string.sub(s,4,#s) end
  for i = 1, s and s:len() or 0 do
    b = s:byte(i)
    if b < 128 then
      if nmdc[b] then
        r = r..nmdc[b]
      else
        r = r..string.char(b)
      end
    elseif a == 2 then
      a, j = a - 1, b
    elseif a == 1 then
      a, r = a - 1, r..utf8_decode[j][b]
    elseif b == 226 then
      a = 2
    elseif b == 194 or b == 208 or b == 209 or b == 210 then
      j, a = b, 1
    else
      r = r..'_'
    end
  end
  return r
end
-- End of full convert ANSI <---> UTF-8 --

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

Скрипты для Demagog

#422

Сообщение flegont »

Скрипт, работающий с файлом в кодировке utf-8, содержащем транскрипцию IPA (МФА).
Используется недокументированная особенность функции LoadFromFile(fname, allformats)
Без 2-го параметра = true она читает файл побайтно, без автоматического преобразования в ansi.
Казалось очевидным, что таким способом можно корректно прочесть только файл в кодировке ansi. На самом деле, правильно читаются и файлы в кодировке utf-8 :wink:

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

-- ПРОВЕРКА PLS-СЛОВАРЯ НА ДУБЛИКАТЫ
-- Важно! Файл словаря должен быть в кодировке UTF-8

fname = 'ЙЦУКЕН.pls' -- файл словаря, укажите свой

a = LoadFromFile(fname) -- побайтная загрузка файла в кодировке ansi или utf-8
s = table.concat(a,'\r') -- словарь загружен в строку s

-- При попытке отобразить такую utf8-строку командами print() или ShowMessage()
-- на месте кириллицы и МФА-транскрипции будут кракозябры. Но, можно сохранить в файл :)
--SaveToFile({s},'sss.txt') -- отладочная проверка! 

-- Список секций словаря
a = {}
pos = 1
for i = 1,#s do
    k, z = string.find(s,'<lexeme>',pos,true)
    if k then
        pos = z+1
        ke, ze = string.find(s,'</lexeme>',pos,true)
        if ke then
            b = string.sub(s,k,ze)
            a[#a+1] = b
            pos = ze+1
        end
    end
end
table.sort(a)

-- В сортированном списке секций дубликаты идут подряд
d = {}
for i = 1,#a-1 do
    if a[i] ~= '' then
        for j = i+1,#a do
            if a[j] == a[i] then  -- найдена секция-дубликат
                d[#d+1] = a[j]
                a[j] = ''
            else
                break
            end
        end
    end
    StatusMessage('Проверено '..math.ceil(100*i/#a)..'%')
end
-- Сохраняем результат
SaveToFile(d,'_out_.txt')
ShowMessage(fname..'\r'..'Найдено дубликатов '..#d..'\r'..'Результат в файле _out_.txt')
StatusMessage('')

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

Скрипты для Demagog

#423

Сообщение tonio_k »

a = LoadFromFile(fname) -- побайтная загрузка файла в кодировке ansi или utf-8
Интересно, а побайтное открытие быстрее будет, чем:
WOpen(0,fname); a=WText(0) ?
это я размышляю в сторону склеивания файлов (в частности несколько словарей в один)

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

Скрипты для Demagog

#424

Сообщение flegont »

Через WText() мы всегда будем получать только ansi-строку, но никогда не получим utf-8
Следовательно, вся МФА-транскрипция превратится в знаки ???....

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

Скрипты для Demagog

#425

Сообщение tonio_k »

tonio_k писал(а):
25 авг 2019 14:56
WOpen(0,fname); a=WText(0) ?
это я неудачный пример привел.
имелось в виду склеивание файлов по схеме:

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

dic = HomeFolder('dic')

WOpen(0,dic..'70.ФОНЕМЫ Dopolneniya строчные.dic')
WAdd(-1,0)
WOpen(0,dic..'75.ФОНЕМЫ-ОМО.dic')
WAdd(-1,0)
WOpen(0,dic..'78.ФОНЕМЫ.dic')
WAdd(-1,0)
WNew(0)
WAdd(0,-1)
WSave(0,"#ФОНЕМЫ.dic")
Сравнить по скорости склеивания с таким вариантом на основе примера, который вы сейчас выложили:

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

dic = HomeFolder('dic')

a1 = LoadFromFile(dic..'70.ФОНЕМЫ Dopolneniya строчные.dic')
s1 = table.concat(a1,'\r') -- словарь загружен в строку s

a2 = LoadFromFile(dic..'75.ФОНЕМЫ-ОМО.dic')
s2 = table.concat(a2,'\r') -- словарь загружен в строку s

a3 = LoadFromFile(dic..'78.ФОНЕМЫ.dic')
s3 = table.concat(a3,'\r') -- словарь загружен в строку s

s=s1..s2..s3

SaveToFile({s},'#ФОНЕМЫ.dic')
Вот я сейчас попробовал и результат по скорости мне очень понравился (3 больших файла склеились в один за секунду). Однако надо тестировать. Я раньше склеивал файлы через CMD по схеме (copy 1.txt+2.txt+3.txt sum.txt) вроде работало, но отказался от этого метода. Так как то это один раз привело к ошибке "неизвестная кодирока" при открытии файла. Этот способ явно похож на CMD...

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

Скрипты для Demagog

#426

Сообщение flegont »

В Lua загрузка больших файлов действительно происходит очень быстро. Так что, если есть уверенность, что файл в ansi или utf8 кодировке, то вполне можно этим воспользоваться.

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

Скрипты для Demagog

#427

Сообщение tonio_k »

Оказывается при склеивании файлов в моем примере в тело текста попадает символы Utf-8 BOM - думаю они и создают проблему с возможной ошибкой определения кодировки при открытии файла. Вопрос, как его почистить?

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

Скрипты для Demagog

#428

Сообщение flegont »

В сообщении #421 дан исходный текст функции Utf8ToAnsi(s)
В ней как раз есть фрагмент - чистка строки s от BOM:

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

local bom = '\239\187\191'
if string.sub(s,1,3) == bom then s = string.sub(s,4,#s) end

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

Скрипты для Demagog

#429

Сообщение tonio_k »

Сделал две функции по работе с переменными хранящимися в файле. Первая - для считывания значения, вторая - для перезаписи значения в файл.
Содержимое файла с переменными должен быть в виде:
Шапка (-любой текст)
переменная=значение
переменная=значение
переменная=значение


Пример содержимого файла с переменными:

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

::Мои настройки::
simbol=10800
Mess=Внимание проверить на ошибки!
f_fail=dic\\СПИСОК СЛОВАРЕЙ 03 DIC СЛОВАРИ.lua
Функции:

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

--Найти переменную в файле и получить её значение
function ReadValueFromFile(value,f_path) 
    local s = LoadFromFile(f_path,true)
    s = table.concat(s, '\r')  -- преобразовываем список в ТЕКСТ
    f_peremen = value
    start_pos, end_pos = string.find(s, "\013"..f_peremen.."=[^\r]+",1)
    fnd = string.sub(s,start_pos,end_pos)
    fnd = string.sub(s,start_pos+1+#f_peremen+1,end_pos)
    return fnd
end

--Найти переменную в файле и ПЕРЕЗАПИСАТЬ её значение
function RewriteValueToFile(value,variable_value, f_path) 
    local s = LoadFromFile(f_path,true)
    s = table.concat(s, '\r')  -- преобразовываем список в ТЕКСТ
    f_peremen = value
    znach = variable_value
    start_pos, end_pos = string.find(s, "\013"..f_peremen.."=[^\r\n]+",1)
    s = string.sub(s,1,start_pos)..f_peremen.."="..znach..string.sub(s,end_pos,#s)
    s = string.gsub(s, '\r', '\r\n')--что бы в блокноте нормально открывал
    SaveToFile({s}, f_path)
    return s
end
Пример применения:
Пример 1

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

is="$мои переменные.txt"

simbol=ReadValueFromFile("simbol",is)--найти переменную в файле и присвоить значение
--simbol = tonumber(simbol)--переменную переводим в числовой формат
simbol=simbol-1
print(simbol)
RewriteValueToFile("simbol",simbol, is) -- перепишем полученное новое значение  simbol
Пример 2

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

is="$мои переменные.txt"
f_fail=ReadValueFromFile("f_fail",is)--открыть файл по пути, взятого из файла с переменными
WOpen(0,f_fail)

Вопрос :tongue2: , - не понятно, почему если в первом примере убрать ремарку у

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

--simbol = tonumber(simbol)-переменную переводим в числовой формат
то при повторном запуске число в файле вдруг начинает увеличивается ....

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

Скрипты для Demagog

#430

Сообщение flegont »

Ничего такого не увидел :thinking: Всё прекрасно работает: число в файле при каждом запуске уменьшается на 1, и совпадает с тем, которое отображается в окне "0 - Статистика". Независимо от того, заремлена или нет строка: simbol = tonumber(simbol)

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

Скрипты для Demagog

#431

Сообщение tonio_k »

flegont писал(а):
30 авг 2019 17:32
при каждом запуске уменьшается на 1,
► Показать

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

Скрипты для Demagog

#432

Сообщение flegont »

Да, какая-то нерегулярная ошибка. На некоторых начальных значениях работает, на других как бы наложение со сдвигом одной строки-числа на другую. А преобразование в число и обратно добавляет остроты в блюдо - за счет периодического отрезания символов .0
В общем, где-то путаница с позициями, когда из текста вырезается значение, потом куда-то измененное вставляется.

Но всё решаемо. Нет надобности превращать считанную из файла таблицу строк в единый текст.
Работаем непосредственно с нею. Учтем, что каждая строка таблицы (за исключением комментариев #блаблабла) имеет вид "name=value".

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

#Мои настройки
simbol=10800
Mess=Внимание проверить на ошибки!
f_fail=dic\\СПИСОК СЛОВАРЕЙ 03 DIC СЛОВАРИ.lua

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

--Найти переменную в файле по имени и получить её значение
-- Замечание. Имя переменной НЕ может начинаться с символа #
function ValueFromFile(name, f_path) 
    local t = LoadFromFile(f_path,true)
    for i = 1,#t do
        local a = string.split(t[i],'=')
        if a[1] and string.sub(a[1],1,1) ~= '#' and  a[1] == name then 
            return a[2]
        end
    end    
end

--Найти переменную в файле и ПЕРЕЗАПИСАТЬ её значение
function ValueToFile(name, value, f_path) 
    local t = LoadFromFile(f_path,true)
    for i = 1,#t do
        local a = string.split(t[i],'=')
        if a[1] == name then
            t[i] = name..'='..value
        end
    end
    SaveToFile(t,f_path)
end

--Пример 1

is = "$мои переменные.txt"
simbol = ValueFromFile("simbol",is)--найти переменную в файле и присвоить значение
simbol = tonumber(simbol) --переменную переводим в числовой формат
simbol = simbol-1
print(simbol)
ValueToFile("simbol",simbol, is) -- перепишем полученное новое значение  simbol

--Пример 2
is = "$мои переменные.txt"
f_fail = ValueFromFile("f_fail",is)--открыть файл по пути, взятого из файла с переменными
WOpen(0,f_fail)

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

Скрипты для Demagog

#433

Сообщение flegont »

Версия 7.30.378 (сборка от 31.08.2019)

Добавлены функции встроенного интерпретатора:
table.save(t, f) - сохранить таблицу t в файл f
table.load(f) - загрузить таблицу из файла f

Пример использования:

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

-- создаем таблицу значений, которые требуется 
-- сохранить для дальнейшего использования
t = {}
t.simbol = 10000
t.Mess = 'Внимание, проверить на ошибки!'
t.file = [[dic\СПИСОК СЛОВАРЕЙ 03 DIC СЛОВАРИ.lua]]
t.Ans = false

-- сохраняем таблицу в файл
table.save(t,'$MySettings.txt')

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

-- любое сохраненное значение доступно по имени, например:
ShowMessage(d.Mess)

-- значения сохраняются с учетом их типов, проверим:
for k, v in pairs(d) do
    ShowMessage(k..' = '..tostring(v))
end

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

Скрипты для Demagog

#434

Сообщение flegont »

Версия 378 сборка от 24.09.2019

Добавлена опция командной строки: /a "имя скрипта.lua"

Пример использования со скриптом, написанным balaamster:

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

chcp 1251
start /min Demagog.exe "d:\Books\Пророк.txt" /a "d:\Demagog\_Tests_\YaTTS.lua" /m /q
Результат:
Demagog будет запущен свернутым в значок, и откроет в первом свободном окне или окне Статистики файл "Пророк.txt". Это окно станет активным. А скрипт YaTTS.lua отправит текст из активного окна сервису Яндекс, и получит обратно готовую аудиокнигу. По окончании работы Demagog автоматически закроется.

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

Скрипты для Demagog

#435

Сообщение flegont »

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

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

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

Кто там, вдалеке? 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 секунды - чтобы ученик успел предложить
-- свой вариант перевода, а затем услышать правильный

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)

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

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

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

Скрипты для Demagog

#436

Сообщение tonio_k »

Тестировал Мультилингва. Понравилось. Как бы не менял настройки голоса в панели меню, как в скрипте указано, - тем голосом(в т.ч. скорость, тембр) и будет осуществлена запись.
Однако заметил, что обратно настройки в панели настроек не восстанавливаются - что не очень хорошо. В окне Демагога при работе с текстом и словарями у меня в настройках стоит скорость 1, а записываю в аудио со скоростью 0 . Конвертер ffmpeg меняет базовую скорость при конвертировании в аудио с нужным мне ускорением)
В связи с этим подскажите, как можно "запоминать" показатели настройки голоса что бы их, например, сохранять в переменную для последующего восстановления после отработки скрипта.
Получается скрипт как бы "сбивает" пользовательские настройки

Еще момент. Произошло тут у меня приключение :smile3: - записываю в мультилингва - голос в аудио файлах хрипит. Попробовал без Мультилингва - хрипит. Думал это результат обновления Демагога что-то сбилось. Уже хотел гневный отзыв писать - Оказывается (вот не знаю как) но сбилась настройка SAFT22kH16BitMono
Отсюда вопрос, Может эту настройку как то можно скрипту доверить? Или Окошко это прятать от пользовательского случайного нажатия. Или всплывающее окно предупреждения "Вы уверены что хотите поменять" - короче надо это поле как то зафиксировать от изменений в привязке к голосу.

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

Скрипты для Demagog

#437

Сообщение flegont »

Есть такой эффект - при многоязычном чтении / записи аудио происходит последовательное переключение голосов и соответствующее изменение их настроек, что отражается в Панели управления. На каком голосе чтение остановилось, тот и останется в выпадающем списке с предписанными многоязычной разметкой настройками.

А хотелось бы, чтобы настройки голосов сами возвращались к "первоначальным"
- какие были до того, как режим Мультилингвы был включен. Хоть при обычной работе, хоть при работе с мультилингвой через скрипт.

Подумаю над этим :thinking:

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

Скрипты для Demagog

#438

Сообщение flegont »

Вот тоже интересный вопрос:
Нужна ли Мультилингва, как отдельный режим, который пользователь включает / выключает?

Программа ведь и сама может определить: есть ли в тексте разметка мультилингвы - и соответственно читать текст переключая или не переключая голоса.

Аватара пользователя
good_cat
Администратор

Скрипты для Demagog

#439

Сообщение good_cat »

Здесь возникает еще один интересный момент - чаще встречается билингва, три и более языков в одном тексте встречаются значительно реже. Может быть имеет смысл подумать над заданием в настройках двух голосов именно для этого случая. Это имеет смысл когда один из языков - латиница, а второй нет и возможно автоматическое распознавание.

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

Скрипты для Demagog

#440

Сообщение flegont »

"Чтение - Мультилингва - Настроить..."
http://aloys.narod.ru/sof/1/demagog.htm#8
Кар раз настройка для пары "Кириллический язык - Английский язык"
Вместо русского можно задавать голос (если таковой есть) для украинского, белорусского, сербского, македонского, болгарского.

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

Скрипты для Demagog

#441

Сообщение tonio_k »

good_cat писал(а):
24 дек 2019 15:41
чаще встречается билингва
а мне функция мультилингва нужна для того, что бы запущенная запись в аудио не зависела от того, какой голос и какая для него выбрана скорость в текущих настройках Демагога. Теперь с новой версии Демагога Я этот параметр жёстко прописываю в самом скрипте за счёт принудительной вставки в начале текста тэг с параметрами голоса для мультилингва

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

Скрипты для Demagog

#442

Сообщение flegont »

Ну, значит, пущай оно так и будет :smile1:
Осталось только в следующей версии сделать запоминание параметров активного голоса до начала чтения мультилингвы, чтобы по окончании чтения (записи аудио) в Панели инструментов вновь был тот же голос.

Аватара пользователя
good_cat
Администратор

Скрипты для Demagog

#443

Сообщение good_cat »

flegont писал(а):
24 дек 2019 15:52
настройка для пары "Кириллический язык - Английский язык"
Вместо русского можно задавать голос (если таковой есть) для украинского, белорусского, сербского, македонского, болгарского.
А вместо английского - шведский, итальянский, французский, немецкий? :smile1:
Или есть ограничение - только английский?

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

Скрипты для Demagog

#444

Сообщение tonio_k »

При первом запуске настроек Речь-Мультилингва-Настроить...
Окно Русского языка пустое.
Нажимаем на кнопку [...] - выходит выплывающий список голосов. Выбираю голос Maxim и нажимаю кнопку "Вставить разметку"
в текст вставляется {{,0,0,100,0,0,100}}
окно с настройкой Мультилингва - закрывается.
При повторном запуске Речь-Мультилингва-Настроить... Окно Русского языка опять пустое.
Т.Е. пока не выберишь голос, нажмешь ок. Заново не запустишь меню Речь-Мультилингва-Настроить... изменения не сохраняются и вставка разметки работает некорректно

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

Скрипты для Demagog

#445

Сообщение flegont »

1) good_cat, двуязычная настройка работает для пары языков, один из которых содержит все буквенные символы кодовой страницы cp1251 (кириллица Windows), а второй - 26 букв стандартного латинского алфавита. Поскольку оба алфавита НЕ пересекаются, то программа может однозначно определить где какой язык.
Если мне скажут, какие еще символы добавить в латинский алфавит для адекватного отображения прочих европейских языков, то в следующей версии можно будет вместо английского ставить в паре с русским, например, испанский или немецкий или еще какой... :smile1:

2) tonio_k, да не совсем удачно вышло - нигде не упомянуто, что кнопка OK - главная, и пока она не нажата - выбор голоса не подтвержден. Отсюда и ошибка.
Второй затык - программа сама вставляет в Настройку русские и английские голоса, если только в их полных именах есть фрагменты "Russia" и "English"

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

Скрипты для Demagog

#446

Сообщение tonio_k »

из argo-interpreter:
WFilter
Если имя словаря указано без пути, то предполагается, что словарь находится в рабочей папке Demagog в стандартной папке ..\dic.
Я так понял, это изменение возникло начиная с вер. 379?
Смотрю, у меня в текст перестали подставляться фонемы. Как оказалось, у меня скрипт склеивает несколько файлов словарей dic в один временный файл #ФОНЕМЫ.dic, который сохраняется в корневой папке \Demagog\#ФОНЕМЫ.dic
► Показать
А применялся этот временный словарь командой:

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

WFilter(0,0,"#ФОНЕМЫ.dic",false)
Предполагая, что если путь не указан, значит файл находится в корневом \Demagog\

Теперь, что бы этот словарь цеплялся, нужно указать так:

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

WFilter(0,0,HomeFolder().."#ФОНЕМЫ.dic",false)
Вопрос, может в WFilter добавить контроль с прерыванием скрипта и выводом сообщения об ошибке в случае отсутствия файла по указанному пути?

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

Скрипты для Demagog

#447

Сообщение flegont »

Да, с 379-й стандартное расположение словаря без указанного пути - папка dic.

Сообщения, стопорящие выполнение скрипта раздражают пользователей. Логичное поведение WFilter - ничего не делать, если словарь не существует, т.с. на нет и суда нет :wink:
Но, если уж так необходимо контролировать существование файла, то в интерпретаторе есть функция Exists(f)

Добавлять еще один параметр в WFilter для указания: выводить ли сообщение об отсутствии словаря... ну, пока не очень хочется плодить параметры. Вместе с ними растет и сложность исходного кода :thinking:

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

Скрипты для Demagog

#448

Сообщение tonio_k »

flegont писал(а):
25 дек 2019 23:03
Логичное поведение WFilter - ничего не делать, если словарь не существует, т.с. на нет и суда нет
а мне кажется логичнее наоборот, без дополнительных параметров сделать "обязательной" проверку на наличие файла в сам WFilter. Если в скрипте все правильно, то... , это значит, что Всё правильно, всё работает. Если неправильно, то выходит ошибка о которой я буду знать, а не начинать редактировать скрипт, удивляться, почему у меня в штатном режиме все работает, а в скрипте нет. Причём я могу записать пару книг и только начав слушать понять, что что то где то не работает. Перечитывать код, вставлять прерывания что бы выявить где теряется словарь и почему?
"Образно" игнорирование отсутствия словаря выглядит так, будто я в штатном режиме в Демагоге ставлю галочку на словаре в панели словарей, которого в реальности нет. Но при перезагрузке Демагога этот словарь остаётся в панели словарей.

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

Скрипты для Demagog

#449

Сообщение flegont »

Ну, попробую эдакую проверку "реальности словаря" в WFilter поэлегантней, с минимальными правками кода сделать :wink:

Заодно будет подправлена опция "Речь - Мультилингва - Настроить..." Все настройки русского и английского голосов вступают в действие сразу, как введены. Можно сразу давить кнопку "Вставить разметку", при этом окно настройки не будет закрываться. Но при этом позволит продолжать работу с Демагогом.
Например, перейти в другую вкладку, чтобы вставить разметку и туда. И даже, по ходу дела поменяв настройки рус/англ голосов, чтобы в разных вкладках была разная разметка. По окончании "разметочных работ", окно настройки закрываем кнопкой "Закрыть".

Так же чуть-чуть изменю функцию Voice(shortname). Кроме полного имени голоса будет дополнительно возвращать скорость и тембр, установленные в Панели инструментов. Использовать ли эту дополнительную информацию - на усмотрение пользователя.

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

-- Пример 1. Получить имя активного голоса
vName = Voice()

-- Пример 2
-- получить параметры активного голоса
vName, vRate, vPitch = Voice()
-- активировать другой голос и записать с ним аудиофайл
SetVoice('Pavel',1,0)
WAudio(1)
-- восстановить активность предыдущего голоса
SetVoice(vName,vRate,vPitch)

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

Скрипты для Demagog

#450

Сообщение tonio_k »

Пожелание к функции WSeries в калькуляторе что бы она выводила количество созданных файлов - что бы эта функция была близка к штатной функции Демагог.

Ответить

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