Скрипты для Demagog

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

Модератор: flegont

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

Скрипты для Demagog

#1

Сообщение flegont »

Demagog умеет выполнять вычисления по заранее заданным в текстовом файле командам. Такой текст, содержащий только команды и комментарии к ним, называется скрипт. Для выполнения скриптов в Demagog'e используется встроенный интерпретатор языка программирования Lua (версии 5.3).

Файлы скриптов должны иметь расширение .lua
Чтобы выполнить скрипт, загруженный в активное окно Демагога, нужно нажать F2. Такой режим полезен для отладки скрипта.
Но наиболее практично выполнять скрипты, не загружая их в Демагог, а непосредственно из файла. Для этого файл скрипта должен находиться в рабочей папке ..\_Tests_. Тогда его можно увидеть в меню "Выполнить скрипт - Из файла".
Несколько примеров скриптов поставляются с дистрибутивом программы.

Могут спросить: а зачем оно надо?
Ответ такой. Встроенный интерпретатор позволяет выполнять не только команды языка Lua, но и инициировать выполнение некоторых важных опций Демагога. Для этого интерпретатор пополнен несколькими "импортированными" функциями, отсутствующими в самом языке. Например:

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

ind = WActive() -- получить номер активного окна
-- обработать текст в активном окне указанным словарем
WFilter(ind, ind, HomeFolder('dic')..'Michel.dic')
WAudio(ind) -- записать аудио
ShowMessage('Работа закончена!')
Это лишь условный пример, но он демонстрирует возможность автоматизации рутинных действий пользователя.

Руководство пользователя. Сверх-краткое (пока) описание функций интерпретатора, включающее также полный перечень импортированных функций, содержится в дистрибутиве Демагога: ..\_Tests_\argo-interpreter.htm
Общие руководства (разной степени простоты или сложности) по языку Lua можно найти в Интернете.

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

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

Скрипты для Demagog

#2

Сообщение flegont »

Pronunciation adjustment.lua
Скрипт входит в состав дистрибутива Демагога. Позволяет произвести словарные замены по заданному набору словарей. Наборы словарей можно указывать в текстовых файлах с расширением .lst, размещенных в папке ..\dic - т.н. "плей-листах".
Порядок словарей - произвольный, какой захочет пользователь.
Можно работать, как с текстом в текущем окне, так и загрузить новый файл.

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

Скрипты для Demagog

#3

Сообщение flegont »

Collection of texts.lua
Скрипт входит в состав дистрибутива Демагога. Позволяет объединить воедино документы разных форматов, распознавание которых поддерживает Демагог: DOC, DOCX, RTF, HTML, FB2, EPUB, TXT...

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

Скрипты для Demagog

#4

Сообщение flegont »

Audio recording and computer shutdown.lua
Скрипт входит в состав дистрибутива Демагога. Позволяет выполнить запись аудио с последующим выключением компьютера.

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

Скрипты для Demagog

#5

Сообщение tonio_k »

В плане развития направления скриптов, вот какие бы направления хотелось бы реализовать:
1) Функционал "Сериалы". Скрипт, который бы разбивал файл книги на части по шаблону 0001, 0002 и т.д. Затем по циклу каждый файл по порядку прогнать через словари, ну и запись в аудио параллельно.
2) Замены по правилам rex.
В теле скрипта указать список правил rex (грубо говоря скопировать из словарейu REX) и построчно применить их к тексту. Что бы при этом показывал время работы в долях секунды и количество произведенных замен. Это реализация поднятой тут темы, ну и вообще пригодится для разовых замен и тестирования правил


Отправлено спустя 3 минуты 35 секунд:
К п.1 Уточнение: цикл: файл открыть, применить словари, переписать файл, записать в mp3


Отправлено спустя 35 минут 39 секунд:
к п.2 пример для расчета времени работы части кода
► Показать



Отправлено спустя 1 час 14 минут 23 секунды:
К п.2 Такая мысль. Вместо того что бы доробатывать модуль поиска:
каждое правило из тела скрипта сохранять в файл temp.rex куда перезаписывается правило REX из тела скрипта, затем полученый словарь применить к тексту (с замерами по времени). Затем берём следующее правило и т.д.


Отправлено спустя 5 минут 18 секунд:
... Только это не покажет количество срабатываний

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

Скрипты для Demagog

#6

Сообщение flegont »

В теле скрипта указать список правил rex
Тут надо поэкспериментировать. У Lua собственная система кодов для поиска в тексте, и некоторые символы, в т.ч. обратный слэш, воспринимаются как служебные.

Поэтому строковые значения надо заключать в двойные квадратные скобки, тогда все символы воспримутся, как они есть:
s = [[\bвсе пропало\b]]; print(s)
s = [[\w+]]; print(s)

Останется проблема с использованием в теле скрипта юникодных символов, например:
s = [[fsʲˈɵ prɐpˈalə]]; print(s) Результат: fs??? pr?p?al? :scratch:

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

Скрипты для Demagog

#7

Сообщение tonio_k »

Настаивать не буду, но те словари rex, которые пробегали мимо меня не содержали замен с юникодом. Так что можно попробовать работать с тем, что есть. Даже интересно узнать, работая с кодировкой ANSI может будет прирост в скорости? :suspect:

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

Скрипты для Demagog

#8

Сообщение flegont »

Какого-то особого выигрыша в скорости не ожидаю, но точный ответ даст только эксперимент.


Отправлено спустя 17 часов 3 минуты 35 секунд:
Но сперва протестирую одну небольшую модификацию встроенного интерпретатора, которая должна позволить ему понимать юникод.

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

Скрипты для Demagog

#9

Сообщение balaamster »

flegont,
В стандартной библиотеке Lua мне не попался функционал работы с файловой системой.

Было бы здорово, если бы появилась функция AllFolders(folder[,mask]), которая бы возвращала таблицу с каталогами, находящимися по пути folder, а опциональный параметр mask позволял бы отфильтровать имена по маске (хотя это можно будет и через if else сделать).
С такой функцией можно и не реализовывать рекурсивный обход каталогов, а пользователь сам напишет функцию с требуемой глубиной рекурсии.

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

Скрипты для Demagog

#10

Сообщение flegont »

Функционал для работы с файлами в Lua есть, но довольно скудный. В книжке Роберто Иерусалимского это глава 22. Библиотека ввода-вывода.

Поискал в Инете: как в Lua можно получить список папок по заданному пути? Для Windows нашел вот такое (чорт побери, кто бы мог подумать... :scratch:). В любом окне Демагога пишем строчку (путь в ней можно поменять на любой):

for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end

Жмем F2 и в окне Статистики видим список папок в C:\Program Files

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

Скрипты для Demagog

#11

Сообщение flegont »

Функции, написанные пользователем
Как быть, если пользователь написал на Lua собственные функции, которые хочет в дальнейшем использовать в своих скриптах? Где их хранить, чтобы интерпретатор их видел?
► Показать
Таким образом можно создать сколь угодно большую пользовательскую библиотеку функций для встроенного интерпретатора.

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

Скрипты для Demagog

#12

Сообщение tonio_k »

flegont, помню вы скидывали пример скрипта типа простого шаблона "схемы" sample.lua . В дистрибутиве его нет. Может здесь в шапке его добавить? Для начинающих он нужен точно.

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

Скрипты для Demagog

#13

Сообщение flegont »

В самом первом сообщении этой темы синим цветом 5 строчек. Это, по сути и есть тот пример sample.lua. Я эти строки сейчас выделил жирным шрифтом, чтоб заметнее было :smile1:

А вообще-то, надо постепенно разворачивать, углублять, детализировать нынешнее краткое описание ..\_Tests_\argo-interpreter.htm, снабдить его поясняющими примерами. Вот только времени пока нет :sad:

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

Скрипты для Demagog

#14

Сообщение tonio_k »

► Показать
как прописать путь из переменной homedir в строку WAudio так, что бы при начале записи аудио не выходило окно с предложением выбрать папку для сохранения?


Отправлено спустя 6 минут 54 секунды:
и дополню вопрос. Приведите пример Как вызвать в начале работы скрипта окно с выбором папки и результат выбора присвоить переменной homedir , что бы её "жестко" не прописывать в теле скрипта

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

Скрипты для Demagog

#15

Сообщение balaamster »

tonio_k писал(а):
19 окт 2018 13:31
Приведите пример Как вызвать в начале работы скрипта окно с выбором папки и результат выбора присвоить переменной homedir , что бы её "жестко" не прописывать в теле скрипта
Можно так:

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

homedir = Folders("Выберите папку", "С:\\стартовая_папка\\по_умолчанию", true)
Где "С:\\стартовая_папка\\по_умолчанию" - путь, с которого желаете начать обзор.
true - позволит создавать новые каталоги в диалоге выбора.

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

Скрипты для Demagog

#16

Сообщение flegont »

как прописать путь из переменной homedir в строку WAudio так, что бы при начале записи аудио не выходило окно с предложением выбрать папку для сохранения?
Снять галочку: Сервис - Общие настройки - Аудио - Спрашивать куда сохранять аудио (иначе там же, где исходный текст)

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

Скрипты для Demagog

#17

Сообщение tonio_k »

flegont писал(а):
19 окт 2018 16:42
Снять галочку
это надо в будущем обязательно добавить в ..\_Tests_\argo-interpreter.htm к
описанию WAudio

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

Скрипты для Demagog

#18

Сообщение flegont »

Да, добавлю.

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

Скрипты для Demagog

#19

Сообщение tonio_k »

tonio_k писал(а):
19 окт 2018 17:00
Снять галочку: Сервис - Общие настройки - Аудио
А может для "Спрашивать куда сохранять аудио" добавить в WAudio как дополнительный параметр (true/false)? Иначе для "полностью автоматической" отработки скрипта, необходимо каждый раз "не забыть" убрать галочку.

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

Скрипты для Demagog

#20

Сообщение flegont »

Хорошая мысль. В следующей версии сделаю. Тогда и в argo-interpreter.htm добавлять ничего не придется :smile1:

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

Скрипты для Demagog

#21

Сообщение tonio_k »

Хочу через скрипт осуществить запись в аудио предварительно разбитый файл на сериалы. Разбил на файлы 0001.txt 0002.txt
► Показать
С чем столкнулся:
1) Демагог пытается "продолжить" сериал - приходится отключать разбивать на сериал в настройках Демагога.
Может тут тоже на уровне скрипта регулировать разбивать на сериалы или нет (true/false)?

2) Когда доходит до 0002.txt - опять начинается запись 0001.mp3 Ошибка в скрипте?

Впорос. Я правильно понял, Повторяющийся отрезок скрипта
► Показать
я могу внести в отдельный файл.lia

и тогда скрипт уже будет выглядеть так:
► Показать

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

Скрипты для Demagog

#22

Сообщение flegont »

function TextToAudio(homedir,filename)
  local hometxt = homedir..filename..'.txt'
  local homemp3 = homedir..filename..'.mp3'
  WOpen(1,hometxt)
  WAudio(1,homemp3)
  WNew(1)
end


Поместить эту функцию в файл mylib.lua в папке work
В скрипте она будет вызываться так:

require "work/mylib" -- подключение библиотеки, ОДИН раз в начале!
...
homedir = ... -- папка где лежат текстовые файлы
filename = ... -- имя конкретного текстового файла в этой папке
...
TextToAudio(homedir,filename)
-- получили аудиофайл с тем же именем и расширением .mp3
...

Как-то так в общем...

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

Скрипты для Demagog

#23

Сообщение balaamster »

flegont писал(а):
18 окт 2018 23:55
for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end
Замечательное решение, кроссплатформенное, использует функционал ОС.
Даже рекурсивный обход папок получилось сделать:
► Показать
Результатом работы сценария будет рекурсивный список путей от исходного каталога.

Ох уж эта кириллица...

Кириллица, в именах папок, ломает работу сценария:
► Показать
Уже испробовал разные варианты, не помогает:
Запуск командной строки с выводом в ansi и сменой кодировки на cp1251
for dir in io.popen(string.format([[cmd /a chcp 1251 && dir %s /b /ad]],path)):lines() do print(dir) end

Запуск командной строки с выводом в unicode и сменой кодировки на utf-8
for dir in io.popen(string.format([[cmd /u chcp 65001 && dir %s /b /ad]],path)):lines() do print(dir) end

P.S. попробовал в интерпретаторе lua53.exe - кириллица выводится корректно.
Можно ли как-то поправить кириллицу во встроенном интерпретаторе?

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

Скрипты для Demagog

#24

Сообщение flegont »

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

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

Скрипты для Demagog

#25

Сообщение tonio_k »

flegont писал(а):
19 окт 2018 16:42
Снять галочку: Сервис - Общие настройки - Аудио - Спрашивать куда сохранять аудио (иначе там же, где исходный текст)
Вопрос, в скрипте для WAudio предусмотрено принудительное указание другой папки сохранения MP3? Например:
► Показать
Из этих строк скрипта сейчас всего два варианта событий:
1) либо (снята галочка) mp3 файлы падают в тот же каталог, где книга источник
2) либо (возвращаем галочку) после долгой работы словарей скрипт встаёт на паузу и ждет действий пользователя - указать в какую папку сохранять mp3


Отправлено спустя 1 час 7 минут 2 секунды:
Пытаясь прописать команду WSave - сохранить резервную копию обработанного словарями текст (перед самым началом записи в mp3 - WAudio), случайно обнаружил, что аудиофайлы начинают помещаться именно в ту папку, куда и был сохранен этот самый текст.
► Показать
Это есть ответ на мой же вопрос выше :up:

Если этот резервный файл кому-то будет мешать, то его можно удалить добавив строку
os.remove(homedir..'last_text.txt')

Тогда новый вопрос, как вместо last_text.txt прописать так, что бы указывалось имя открытого файла в окне ind?

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

Скрипты для Demagog

#26

Сообщение flegont »

в скрипте для WAudio предусмотрено принудительное указание другой папки сохранения MP3?
Пока нет, но будет соответствующий 2-й параметр: папка назначения. Ее указание приведет к игнорированию запроса папки назначения, если он был задан в Настройках. Если 2-й параметр задан, как пустая строка, то запрос папки назначения также будет игнорирован, и папкой назначения будет считаться та, где лежит озвучиваемый текст.
аудиофайлы начинают помещаться именно в ту папку, куда и был сохранен этот самый текст.
Когда в Настройках снята галка о запросе папки назначения для аудио, то аудио-файлы размещаются там же, где находится озвучиваемый текст
что бы указывалось имя открытого файла в окне ind?
В следующей версии добавлю функцию WName(i) - имя файла, открытого в окне i.

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

Скрипты для Demagog

#27

Сообщение balaamster »

Проблему с выводом кириллицы нашёл на просторах интернета.
Как оказалось, при запуске cmd-команд из lua, необходимо смену кодировки передавать по конвейеру:

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

"chcp 1251 | echo Привет"
А не в виде последовательного выполнения команд.

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

"chcp 1251 && echo Привет"
В попытках решить проблему, сегодня пришёл к более простому решению, нежели написал вчера:
► Показать
Функция принимает на входе путь к стартовому каталогу, возвращает таблицу со стартовым каталогом и его подкаталогами.

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

Скрипты для Demagog

#28

Сообщение flegont »

!! Очень полезная информация :thank_you:

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

Скрипты для Demagog

#29

Сообщение tonio_k »

WName(i)
► Показать
Так как WName выдает имя файла с расширением и полный путь к этому файлу, то как можно открываемый из одной папки файл Моя книга.fb2 обработать по словарю и сохранить в другую папку но уже Моя книга.txt?
По хорошему, я ожидал, что WName будет выдавать только текст наименования файла без расширения и полного пути: Моя книга

Тогда скрипт будет так выглядеть:
► Показать
А этот сохраненный файл можно так же через скрипт открть и поставить на запись в mp3:
► Показать



Отправлено спустя 10 минут 37 секунд:
может WName(i) добавить параметр false - только имя без расширения и пути?

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

Скрипты для Demagog

#30

Сообщение flegont »

Думал об этом. Но, я предпочитаю извлекать полные имена файлов, чтобы можно было их использовать для обращения к файлам. Для получения кратких имен (т.е. без путей), и отдельно путей (без имен), хочу создать 2 функции для интерпретатора:
ExtractFileName(full_file_name)
ExtractFilePath(full_file_name)

Их можно написать, собственно, на Lua.
Ну, можно и 3-ю:
ChangeFileExt(file_name, new_ext) для изменения типа файла.
Например: txtfile = ChangeFileExt(mp3file, '.txt')
Еще пример:
simple_name = ChangeFileExt(ExtractFileName(full_file_name), '') -- извлекает имя без пути и без расширения

P.S. А может, всё это уже изобретено :big_smile: ведь язык Lua не вчера родился. Надо в Инете поискать.

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

Скрипты для Demagog

#31

Сообщение balaamster »

tonio_k, Как временное решение можно:

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

-- разбиваем путь на компоненты
path_parts = string.split(WName(ind),"\\") 

-- берём последний элемент пути (имя файла) и удаляем расширение
namebook = string.gsub(path_parts[#path_parts],"%.%w+$","") 
flegont,
как я понял, string.split - это уже функция добавленная в Demagog? В справочнике по lua её не нашёл, хотя функция очень нужная и полезная.
Также как и отсутствие обращения к элементу строки по индексу, как в python, очень огорчило. Пришлось набросать преобразование строки в таблицу.


Отправлено спустя 58 минут 50 секунд:
flegont писал(а):
24 окт 2018 15:25
P.S. А может, всё это уже изобретено
Скорее всего, уже есть библиотеки для работы с путями.
Мне, например, интересно "изобретать велосипед", в качестве средства познакомиться с lua поближе.

Набросал черновой вариант подобных функций. Конечно, нужно их оттестировать на разных тестовых строках и, возможно, добавить ещё какие-нибудь проверки.
► Показать

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

Скрипты для Demagog

#32

Сообщение flegont »

string.split - это уже функция добавленная в Demagog?
..\profiles\calculator.lua
Я уже упоминал о "личных" библиотеках пользователя. так вот calculator.lua - это личная библиотека Демагога, она подключается автоматически при запуске любого скрипта.
В ней содержатся функции, написанные чисто на Lua, при этом они могут использовать и функции, импортированные из Демагога.
Функция string.split как раз там и прописана.
От версии к версии ..\profiles\calculator.lua может изменяться. Все изменения в нем я стараюсь делать, сохраняя совместимость с предыдущими версиями, чтобы ранее созданные скрипты оставались работоспособными.
интересно "изобретать велосипед", в качестве средства познакомиться с lua поближе
Мне тоже. Вот, только что изобрел - одна функция вместо трех. Принимает полное имя файла и возвращает массив из 3-х строк: путь, краткое имя без расширения, расширение.
► Показать
Пример:
► Показать
Также как и отсутствие обращения к элементу строки по индексу, как в python
Да, строки в Lua - статические. Как я понимаю, это сделано ради быстродействия.
Приходится, для получения k-го элемента строки, изворачиваться как-то так: b = string.sub(s,k,k)

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

Скрипты для Demagog

#33

Сообщение flegont »

Включил SplitFileName() в ..\profiles\calculator.lua, дописал о ней в мануале ..\_Tests_\argo_interpreter.htm и обновил дистрибутив на сайте. Теперь интерпретатор эту функцию видит.

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

Скрипты для Demagog

#34

Сообщение tonio_k »

подскажите как lua, например, z=123 превратить в формат 00ч 02м 03с ?

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

Скрипты для Demagog

#35

Сообщение balaamster »

tonio_k писал(а):
26 окт 2018 12:57
превратить в формат 00ч 02м 03с
По идее как-то так:
► Показать



Отправлено спустя 51 минуту 8 секунд:
Прошу прощения, ошибся в формулах, плохой из меня математик:

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

z=123 

h = math.floor(z / 60^2)
m = math.floor((z % 60^2) / 60)
s = math.floor(z % 60)
result = string.format("%02dч. %02dм. %02dс.", h, m, s)

print(result)

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

Скрипты для Demagog

#36

Сообщение flegont »

А вот так можно просто перевести системное время в дату и время
(дата - в англо-американском формате):

print(os.date("%c"))
Пример результата:
10/26/18 18:46:55

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

Скрипты для Demagog

#37

Сообщение tonio_k »

Варианты "вывода" системной даты в Европейском формате:

print(os.date("%d.%m.%Y")..' '..os.date("%X"))
Пример результата: 26.10.2018 19:21:24

print(os.date("%d.%m.%Y"))
Пример результата: 26.10.2018

print(os.date("%X"))
Пример результата: 19:21:24

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

Скрипты для Demagog

#38

Сообщение flegont »

UPDATE 27.10.2018 14:37
Функция Fragments(s, fragsize, parag), разбивающая текст на фрагменты с заданным количеством символов
Возвращает список строк-фрагментов.
Параметр s - это ооочччень длинная строка, представляющая собой текст некоей книги. Может быть получена, например, извлечением текста из документа, загруженного в окне Демагога: s = WText(i).
Необязательный параметр parag - если true, то фрагменты собираются из абзацев, иначе (по умолчанию) - из предложений.
Сборка фрагментов из абзацев может потребоваться:
а) для обеспечения большей логической полноты фрагмента;
б) для правильного деления на фрагменты текста, являющегося словарем.
► Показать
Пример скрипта, использующего эту функцию. Создание серии файлов из текста в активном окне.
► Показать

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

Скрипты для Demagog

#39

Сообщение balaamster »

Попробовал написать функцию для перебора подкаталогов, с учётом появившейся AllFolders.
Возможно, кому-нибудь пригодится.
recursion_dirs(path[, dmask])
path - строка, путь к стартовому каталогу
dmask - строка, маска для отбора каталогов, необязательный параметр.
Функция возвращает таблицу со списком подкаталогов (с полными путями), включая стартовый каталог.

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

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

Скрипты для Demagog

#40

Сообщение tonio_k »

flegont писал(а):
27 окт 2018 11:04
Пример скрипта, использующего эту функцию.
1) А можно эту функцию и сам скрипт объединить в один скрипт? т.е. Саму функцию в шапку поместить. В таком виде будет работать?
► Показать
2) Было бы не плохо добавить в эту function Fragments вставку в начале и конце название файла и номер части (как в настройках сериалов Демагог: "%1". Serie %2)


Отправлено спустя 12 минут 22 секунды:
3) А можно еще пример функции, которая будет открывать эти разбитые N0001.txt, N0002.txt ... и т.д. файлы, применять словарь dic и перезаписывать измененный файл?

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

Скрипты для Demagog

#41

Сообщение flegont »

1) Нет. Работа закончится, как только выполнение дойдет до строчки return b - завершить работу функции, вернув список фрагментов b

2) Функцию Fragments я включу в состав функций интерпретатора, как она есть. Для этого не нужно ничего менять в программе, вставлю в "личную библиотеку Демагога" и всё. (Со своим экземпляром Демагога я это уже проделал :wink: )
На ее основе можно уже создать функцию пользователя, делающую сериал из файла fname. Назовем ее к примеру MakeSeries(fname, fragsize, parag, header, ender) - параметры - header и ender - это шаблоны начальной и конечной фраз в каждой серии.

3) Сразу несколько идей, надо проверить...

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

Скрипты для Demagog

#42

Сообщение flegont »

Функция WSeries(i, folder, fragsize, parag, header, ender, startnum)

Создает сериал из документа, открытого в окне i
folder - папка назначения;
fragsize - размер серии в символах;
Необязательные параметры:
parag = true - набор фрагментов по абзацам, false - по предложениям; по умолчанию false;
header - заголовочная фраза серии, к которой автоматически добавится ее номер;
ender - последняя фраза серии, к которой автоматически добавится ее номер.
startnum - начальный номер серии, по умолчанию 1

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

function WSeries(i, folder, fragsize, parag, header, ender, startnum)
    local fname
    local s = WText(i)
    local b = Fragments(s,fragsize,parag)
    local k = #folder
    if not startnum then
        startnum = 1
    end
    if string.sub(folder,k,k) ~= '/' and string.sub(folder,k,k) ~= '\\' then
        folder = folder..'\\'
    end
    for i = 1,#b do
        fname = folder..string.format("%04d",(i+startnum-1))..'.txt'
        if header then
            b[i] = header..' '..(i+startnum-1)..'\r'..b[i]
        end
        if ender then
            b[i] = b[i]..'\r'..ender..' '..(i+startnum-1)
        end
        SaveToFile({b[i]},fname)
    end
end
Пример использования:
WSeries(11, [[d:/MP3]], 6000, true, 'Серия', 'Конец серии')

Имена файлов серий имеют вид: 0001.txt, 0002.txt ... и т.д.

Замечание. Конечный слэш в имени папки назначения можно не указывать, тогда он добавится автоматически.

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

Скрипты для Demagog

#43

Сообщение tonio_k »

flegont писал(а):
28 окт 2018 22:25
true, 'Серия', 'Конец серии'
хотел уточнить, а автоматическая нумерация сериала и его начальный номер (%2) Блок 1, Бок 2 и т.д?


Отправлено спустя 2 минуты 12 секунд:
Уточню, где можно поменять начальный номер?

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

Скрипты для Demagog

#44

Сообщение flegont »

Пока что я сделал автоматическое прибавление номера серии к заголовочной и оконечной фразе, а начальное значение всегда = 1. Но это не проблема. Добавлю еще один необязательный параметр startnum, по умолчанию 1

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

Скрипты для Demagog

#45

Сообщение flegont »

Добавил параметр startnum, отредактировалсообщение #42


Отправлено спустя 9 часов 2 минуты 45 секунд:
Итак, у нас теперь есть функция WSeries, которая мигом нашинкует :jokingly: сериал из документа в указанном ей окне. Но, нужна еще одна функция! Чтобы смогла к каждому файлу сериала применить заданный список словарей и сохранить измененный текст сериии, в том же месте, под тем же именем.
Кажется, всё просто. Однако, вспомним, что для словарей формата dic есть 2 режима работы.
Мы легко можем написать список словарей в виде {словарь1, словарь2, словарь3,...}, где словарьN - это имя словаря, заданное, как выражение или, как строковая переменная.

Ну, и как мы укажем нашей функции, что "Какой-то_там_словарь.dic" надо применить к тексту по "быстрому алгоритму", а "Другой_словарь.dic" - "прямым перебором"?! :suspect:

(продолжение следует)

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

Скрипты для Demagog

#46

Сообщение tonio_k »

Вот тут хочу высказать пожелание, которую я не озвучивал, так как думал, что это можно реализовать за счёт скрипта.
В самой программе Демагог для каждого словаря dic индивидуально сделать выбор метода обработки для каждого словаря вместо одного глобального. В глобальных настройках убирая галочку по умолчанию пусть открывается окно: "Выбор алгоритма" - как отдельное окно, которое открывает текстовый файл со списком словарей dic и в нем выставить параметр true/ false. А демагог будет обращаться к этому файлу для получения информации по какому методу делать обработку словарями. Тогда в скрипте достаточно будет выбрать список словарей, а они уже отработают как в глобальных настройках, согласно файлу со списком алгоритмов.

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

Скрипты для Demagog

#47

Сообщение balaamster »

flegont писал(а):
29 окт 2018 07:53
у, и как мы укажем нашей функции, что "Какой-то_там_словарь.dic" надо применить к тексту по "быстрому алгоритму", а "Другой_словарь.dic" - "прямым перебором"?!
Можно попробовать передавать список словарей в виде вложенных таблиц.

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

dicts = {{"словарь1", true}, {"словарь2",false}, {"словарь3"},...}

for _, d in pairs(dicts) do
	dict = HomeFolder("dic")..d[1]
	if d[2] == nil then
		mode = true
	else
		mode = d[2]
	end
	print(dict,mode)
	--тут применяем словари
end
С учётом аналогичного поведения WFilter, если режим не указан, то mode=true, по умолчанию

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

Скрипты для Demagog

#48

Сообщение flegont »

Да, я пришел к той же идее. И чтобы упростить жизнь пользователю (в том числе себе), записывать список словарей как-то так:

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

diclist =
{
    'словарь1.dic',
    'словарь2.rex',
    'словарь3.dic',
    ...
    {'словарьX.dic',false},
    ...
   'словарьN.dic'
}
Чтобы в виде вложенной таблицы из 2-х элементов записывать лишь в том случае, когда dic-словарь применяется прямым перебором. Но, и указанная вами полная запись так же будет работать.

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

...
b = diclist[j]
if type(b) == 'table' then
    d = b[1]
    mode = b[2]
else
    d = b
    mode = true
end
...



Отправлено спустя 18 минут 10 секунд:
Хм... Тогда и еще более краткая краткая запись

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

diclist =
{
    'словарь1.dic',
    'словарь2.rex',
    'словарь3.dic',
    ...
    {'словарьX.dic'},
    ...
   'словарьN.dic'
}
будет означать алгоритм "прямого перебора"!
Получится: b[1] = 'словарьX.dic'; b[2] = nil
А значение nil эквивалентно false и получим mode = false -- алгоритм прямого перебора

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

Скрипты для Demagog

#49

Сообщение flegont »

Функция FilterToAll(folder, mask, diclist)
Применяет к файлам в папке folder, имена которых отвечают маске mask, словари, перечисленные в списке diclist.
Возвращает два значения: количество обработанных файлов и количество примененных словарей.
Список словарей задается в виде 2-мерной таблицы:
diclist = { {'словарь1', mode'}, {'словарь2', mode}, ... {'словарьN', mode} }
mode = true, если dic-словарь применяется по быстрому алгоритму и false, если прямым перебором. По умолчанию: true.
Допускается упрощенная запись списка словарей:
diclist = {'словарь1', ... {'словарьX'}, ... } - т.е. в фигурные скобки заключается только имя dic-словаря, применяемого прямым перебором.

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

function FilterToAll(folder, mask, diclist)
    local b, d, mode
    local k = #folder
    if string.sub(folder,k,k) ~= '/' and string.sub(folder,k,k) ~= '\\' then
        folder = folder..'\\'
    end
    local a = AllFiles(folder,mask)
    for i = 1,#a do
        WOpen(0,folder..a[i])
        for j = 1,#diclist do
            b = diclist[j]
            if type(b) == 'table' then
                d = b[1]
                mode = b[2]
            else
               d = b
               mode = true
            end
            WFilter(0,0,d,mode)
        end
        WSave(0,folder..a[i])
    end
    WNew(0)
    return #a, #diclist
end
Пример использования:

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

WSeries(11, [[d:/MP3]], 6000, true, 'Серия', 'Конец серии')
h = HomeFolder('dic')
diclist =
{
    h..'vse_vsyo.rex',
    {h..'Michel.dic'}
}
x, y = FilterToAll([[d:/MP3]], '0*.txt', diclist)
ShowMessage('Готово!\13Обработано файлов: '..x..'\13Применено словарей: '..y)
Важное замечание. Следует быть внимательным при указании папки назначения и маски выбора файлов. Стоит ошибиться в папке назначения или задать слишком свободную маску, например *.txt или вовсе *.*, как банда словарей зверски обработает то, что совершенно не нужно :sad:
Если указать несуществующую папку назначения, то удар будет нанесен по корневой папке Демагога :tongue2:
Возникает мысль о добавлении в эту функцию каких-то мер защиты от неосторожных действий пользователя :suspect:

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

Скрипты для Demagog

#50

Сообщение tonio_k »

Скажите пожалуйста мне показалось, или WAudio записывает текст в аудио с предварительной обработкой по активированным галочкой в самой программе словарям?
► Показать
т.е. перед каждым запуском скрипта нужно убирать галочки что бы не было двойной обработки (если словари до записи уже применялись в скрипте к тексту) + исключить риск неверного применения словарей

Ответить

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