From e5d06afe0e2b3575ffd2203f0d0cf5a7458ad4d8 Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Mon, 25 Mar 2019 14:20:57 +0300 Subject: [PATCH 1/2] =?UTF-8?q?ONECICD-19=20=D0=9F=D0=B5=D1=80=D0=B2=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 + LICENSE | 5 +- README.md | 91 ++++ ...20\273\320\276\320\275\320\276\320\262.os" | 97 ++++ ...1\320\273\320\276\320\275\320\260.feature" | 29 ++ ...0\320\273\320\276\320\263\320\260.feature" | 29 ++ ...3\320\276\320\275\320\276\320\262.feature" | 52 ++ ...0\320\261\320\273\320\276\320\275.feature" | 33 ++ installlocalhost.bat | 13 + packagedef | 14 + src/main.os | 49 ++ ...0\260\320\275\320\264\320\260Apportion.os" | 37 ++ ...320\260\320\275\320\264\320\260Convert.os" | 33 ++ ...0\260\320\275\320\264\320\260JoinFiles.os" | 37 ++ ...20\260\320\275\320\264\320\260JoinPath.os" | 33 ++ ...320\260\320\275\320\264\320\260Version.os" | 27 + ...20\265\321\202\321\200\320\260\320\274.os" | 41 ++ ...1\200\320\274\320\260\321\2021\320\241.os" | 297 +++++++++++ ...20\265\321\200\321\202\320\265\321\200.os" | 236 +++++++++ ...20\266\320\265\320\275\320\270\321\217.os" | 296 +++++++++++ ...20\266\320\265\320\275\320\270\321\217.os" | 156 ++++++ ...20\275\320\276\320\262\320\272\320\270.os" | 41 ++ ...20\270\320\273\320\270\321\202\321\213.os" | 185 +++++++ ...261\320\273\320\276\320\275\321\213EDT.os" | 324 ++++++++++++ ...\320\273\320\276\320\275\321\213VSCode.os" | 208 ++++++++ ...20\267\320\276\320\262\321\213\320\271.os" | 49 ++ ...20\260\321\202\320\276\321\200\320\260.os" | 469 ++++++++++++++++++ tasks/test-feature.os | 18 + tasks/test.os | 82 +++ ...60\320\261\320\273\320\276\320\275EDT.xml" | 14 + ...20\260\321\202\320\276\321\200\320\260.st" | 85 ++++ ...20\270\320\277\320\260\320\274\320\270.st" | 18 + ...20\260\321\202\320\276\321\200\320\260.os" | 133 +++++ ...20\273\320\276\320\275\320\276\320\262.md" | 76 +++ 34 files changed, 3311 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 "features/step_definitions/\320\220\320\275\320\260\320\273\320\270\320\267\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.os" create mode 100644 "features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" create mode 100644 "features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" create mode 100644 "features/\320\237\321\200\320\265\320\276\320\261\321\200\320\260\320\267\320\276\320\262\320\260\320\275\320\270\320\265-\321\210\320\260\320\261\320\273\320\276\320\275\320\276\320\262.feature" create mode 100644 "features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" create mode 100644 installlocalhost.bat create mode 100644 packagedef create mode 100644 src/main.os create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Apportion.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Convert.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinFiles.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinPath.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Version.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\241\320\277\321\200\320\260\320\262\320\272\320\260\320\237\320\276\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\260\320\274.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\247\321\202\320\265\320\275\320\270\320\265\320\222\320\275\321\203\321\202\321\200\320\265\320\275\320\275\320\270\320\271\320\244\320\276\321\200\320\274\320\260\321\2021\320\241.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\320\237\320\276\320\264\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\270.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\243\321\202\320\270\320\273\320\270\321\202\321\213.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213EDT.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213VSCode.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\221\320\260\320\267\320\276\320\262\321\213\320\271.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" create mode 100644 tasks/test-feature.os create mode 100644 tasks/test.os create mode 100644 "tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275EDT.xml" create mode 100644 "tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.st" create mode 100644 "tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260\320\241\320\235\320\265\320\277\320\276\320\264\320\264\320\265\321\200\320\266\320\270\320\262\320\260\320\265\320\274\321\213\320\274\320\270\320\242\320\270\320\277\320\260\320\274\320\270.st" create mode 100644 "tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" create mode 100644 "\320\237\320\276\320\264\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.md" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4918cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +bdd-log.xml +*.ospx +*.orig +exec.log +ignore/** +tests.xml diff --git a/LICENSE b/LICENSE index df96360..0753288 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ -MIT License +The MIT License (MIT) -Copyright (c) 2019 orais / tools +Copyright (c) 2016 Andrei Ovsiankin +Copyright (c) 2019 BIA Technologies, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 0000000..1af6109 --- /dev/null +++ b/README.md @@ -0,0 +1,91 @@ +# Скрипт для работы с шаблонами кода + +- [Скрипт для работы с шаблонами кода](#%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82-%D0%B4%D0%BB%D1%8F-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B-%D1%81-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B0%D0%BC%D0%B8-%D0%BA%D0%BE%D0%B4%D0%B0) + - [Установить приложение, алгоритм установки стандартный](#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D1%82%D1%8C-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8-%D1%81%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82%D0%BD%D1%8B%D0%B9) + - [Использование](#%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) + - [Конвертация шаблонов](#%D0%BA%D0%BE%D0%BD%D0%B2%D0%B5%D1%80%D1%82%D0%B0%D1%86%D0%B8%D1%8F-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%BE%D0%B2) + - [Объединение шаблонов](#%D0%BE%D0%B1%D1%8A%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%BE%D0%B2) + - [Разделение шаблонов](#%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%BE%D0%B2) + +## Установить приложение, алгоритм установки стандартный + +- склонировать репозиторий или +- распаковать в нужный каталог архив репозитория +- для Windows запустить [installlocalhost.bat](/installlocalhost.bat) + +## Использование + +### Конвертация шаблонов + +1. Шаблоны конфигуратора в шаблоны VS Code +2. Шаблоны конфигуратора в шаблоны EDT +3. Шаблоны EDT в шаблоны конфигуратора + +Поддерживаемые расширения файлов + +- ".st" - шаблон конфигуратора +- ".json" - шаблон языка VSCode +- ".code-snippets" - глобальный шаблон VSCode +- ".xml" - шаблон EDT + +Определение типа преобразования происходит на основании расширения файла. + +Для запуска преобразования используется команда: + +`snippet-transform convert Исходный-шаблон Новый-шаблон` + +Примеры: + +- `snippet-transform convert "Мой любимый шаблон.st" "bsl.code-snippets"` + Команда выполнить преобразование шаблона конфигуратор в глобальный шаблон VSCode + +- `snippet-transform convert "Мой любимый шаблон.xml" "bsl.st"` + Команда выполнить преобразование шаблона EDT в шаблон конфигуратора + +### Объединение шаблонов + +`snippet-transform join-files Изменяемый-шаблон Добавляемый-шаблон` + +- `Изменяемый-шаблон` - Имя файла шаблона, в который будут добавлены записи из второго файла +- `Добавляемый-шаблон` - Имя файла, в котором содержатся добавляемые записи + +`snippet-transform join-path Каталог-шаблонов Результирующий-шаблон` + +- `Каталог-шаблонов` - Имя каталога, в котором лежат шаблоны, которые нужно соединить. +- `Результирующий-шаблон` - Имя файла, в который будет сохранен результат + +Примеры: + +- `snippet-transform join-files "Мой любимый шаблон.xml" "Мой второй любимый шаблон.st"` + Команда выполнить объединение шаблонов EDT и конфигуратора и запишет результат в шаблон EDT c именем "Мой любимый шаблон.xml" + +- `snippet-transform join-path "Каталог любимый шаблонов" "Супер шаблон.code-snippets"` + Команда выполнить объединение всех поддерживаемых шаблонов каталога и запишет результат в новый шаблон + +### Разделение шаблонов + +`snippet-transform apportion Изменяемый-шаблон Выражение-поиска [Новый-шаблон] [-r]` + +Удаляет (переносит в новый файл) элементы шаблона, полное наименование которых совпадает с `Выражение-поиска` + +- `Изменяемый-шаблон` - Имя файла шаблона, из которого будет вырезана часть +- `Выражение-поиска` - Регулярное выражение для проверки наименования элемента шаблона. Если выражение совпадает с наименованием, то такой элемент переносится в новый файл. +- `Новый-шаблон` - Имя файла шаблона, в который будут помещены исключенные записи +- `-r` Переносить элементы, у которых наименование не совпадает с шаблоном + +Примеры: + +- `snippet-transform apportion "Мой любимый шаблон.st" "алгоритм"` + Удалит из шаблона элементы, в наименовании которых есть слово "алгоритм" + +- `snippet-transform apportion "Мой любимый шаблон.st" "алгоритм" Алгоритмы.st` + Перенесет из шаблона "Мой любимый шаблон.st" в шаблон "Алгоритмы.st" элементы, в наименовании которых есть слово "алгоритм" + +- `snippet-transform apportion "Мой любимый шаблон.st" "оставить" -r` + Удалит из шаблона все элементы, в наименовании которых нет слова "оставить" + +- `snippet-transform apportion "Мой любимый шаблон.st" "^Супер группа\." -r` + Удалит из шаблона все элементы, кроме группы первого уровня "Супер группа" + +- `snippet-transform apportion "Мой любимый шаблон.st" "Плохая группа\."` + Удалит из шаблона группы "Плохая группа" и "очень плохая группа" diff --git "a/features/step_definitions/\320\220\320\275\320\260\320\273\320\270\320\267\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.os" "b/features/step_definitions/\320\220\320\275\320\260\320\273\320\270\320\267\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.os" new file mode 100644 index 0000000..f3872b9 --- /dev/null +++ "b/features/step_definitions/\320\220\320\275\320\260\320\273\320\270\320\267\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.os" @@ -0,0 +1,97 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ФайлВРабочемКаталогеСодержитСтроки"); + ВсеШаги.Добавить("ФайлВРабочемКаталогеНеСодержитСтроки"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//Файл "result/vscode1.code-snippets" в рабочем каталоге содержит строки +//| "scope": "bsl" | +//| "prefix": "Общий модуль" | +//| "prefix": "DEPRECATED" | +//| "prefix": "Инкремент" | +Процедура ФайлВРабочемКаталогеСодержитСтроки(Знач ФайлРабочегоКаталога, Знач ТаблицаСтрок) Экспорт + + ФайлРабочегоКаталога = БДД.ПолучитьПутьФайлаСУчетомПеременныхКонтекста(ФайлРабочегоКаталога); + + Чтение = Новый ЧтениеТекста(ОбъединитьПути(БДД.ПолучитьИзКонтекста("РабочийКаталог"), ФайлРабочегоКаталога), КодировкаТекста.UTF8); + СтрокаГдеИщем = Чтение.Прочитать(); + Чтение.Закрыть(); + + СтрокаРасхождений = ""; + Для Каждого СтрТаблицы Из ТаблицаСтрок Цикл + + СтрокаЧтоИщем = СтрТаблицы[0]; + Если Найти(СтрокаГдеИщем, СтрокаЧтоИщем) = 0 Тогда + СтрокаРасхождений = СтрШаблон( + "%1 + | Не найдена подстрока <%2>", СтрокаРасхождений, СтрокаЧтоИщем); + КонецЕсли; + + КонецЦикла; + Если Не ПустаяСтрока(СтрокаРасхождений) Тогда + СтрокаРасхождений = СтрШаблон( + "Не нашли одну из подстрок таблицы: + |%2 + |в строке: + |%1", СтрокаГдеИщем, СтрокаРасхождений); + Ожидаем.Что(Истина, СтрокаРасхождений).ЭтоЛожь(); + КонецЕсли; + +КонецПроцедуры + +//Файл "result/vscode1.code-snippets" в рабочем каталоге не содержит строки +//| "scope": "bsl" | +//| "prefix": "Общий модуль" | +//| "prefix": "DEPRECATED" | +//| "prefix": "Инкремент" | +Процедура ФайлВРабочемКаталогеНеСодержитСтроки(Знач ФайлРабочегоКаталога, Знач ТаблицаСтрок) Экспорт + + ФайлРабочегоКаталога = БДД.ПолучитьПутьФайлаСУчетомПеременныхКонтекста(ФайлРабочегоКаталога); + + Чтение = Новый ЧтениеТекста(ОбъединитьПути(БДД.ПолучитьИзКонтекста("РабочийКаталог"), ФайлРабочегоКаталога), КодировкаТекста.UTF8); + СтрокаГдеИщем = Чтение.Прочитать(); + Чтение.Закрыть(); + + СтрокаРасхождений = ""; + Для Каждого СтрТаблицы Из ТаблицаСтрок Цикл + + СтрокаЧтоИщем = СтрТаблицы[0]; + Если Найти(СтрокаГдеИщем, СтрокаЧтоИщем) <> 0 Тогда + СтрокаРасхождений = СтрШаблон( + "%1 + | Найдена подстрока <%2>", СтрокаРасхождений, СтрокаЧтоИщем); + КонецЕсли; + + КонецЦикла; + Если Не ПустаяСтрока(СтрокаРасхождений) Тогда + СтрокаРасхождений = СтрШаблон( + "Нашли одну из подстрок таблицы: + |%2 + |в строке: + |%1", СтрокаГдеИщем, СтрокаРасхождений); + Ожидаем.Что(Истина, СтрокаРасхождений).ЭтоЛожь(); + КонецЕсли; + +КонецПроцедуры diff --git "a/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" new file mode 100644 index 0000000..3b07a06 --- /dev/null +++ "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" @@ -0,0 +1,29 @@ +#language: ru + +Функциональность: Объединение шаблонов кода + +Как разработчик +Я хочу получить единый файл шаблона кода +Чтоб проще распространять и подключать его + +Контекст: + Допустим Я очищаю параметры команды "oscript" в контексте + И я включаю отладку лога с именем "oscript.app.snippet-transform" + И я создаю временный каталог и сохраняю его в контекст + И я устанавливаю временный каталог как рабочий каталог + И я установил рабочий каталог как текущий каталог + И я создаю каталог "snippets" в рабочем каталоге + И я копирую файл "ШаблонКонфигуратора.st" из каталога "tests/fixtures//snippets" проекта в подкаталог "snippets" рабочего каталога + И я копирую файл "ШаблонEDT.xml" из каталога "tests/fixtures//snippets" проекта в подкаталог "snippets" рабочего каталога + +Сценарий: Объединение двух шаблонов + Когда я выполняю команду "oscript" с параметрами "<КаталогПроекта>/src/main.os join-files snippets/ШаблонКонфигуратора.st snippets/ШаблонEDT.xml" + Тогда Код возврата равен 0 + И Файл "snippets/ШаблонКонфигуратора.st" в рабочем каталоге содержит + """ + {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + """ + И Файл "snippets/ШаблонКонфигуратора.st" в рабочем каталоге содержит + """ + ТекущаяДата = '' + """ diff --git "a/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" new file mode 100644 index 0000000..d589a6a --- /dev/null +++ "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" @@ -0,0 +1,29 @@ +#language: ru + +Функциональность: Объединение шаблонов кода + +Как разработчик +Я хочу получить единый файл шаблона кода +Чтоб проще распространять и подключать его + +Контекст: + Допустим Я очищаю параметры команды "oscript" в контексте + И я включаю отладку лога с именем "oscript.app.snippet-transform" + И я создаю временный каталог и сохраняю его в контекст + И я устанавливаю временный каталог как рабочий каталог + И я установил рабочий каталог как текущий каталог + И я создаю каталог "snippets" в рабочем каталоге + И я копирую файл "ШаблонКонфигуратора.st" из каталога "tests/fixtures/snippets" проекта в подкаталог "snippets" рабочего каталога + И я копирую файл "ШаблонEDT.xml" из каталога "tests/fixtures/snippets" проекта в подкаталог "snippets" рабочего каталога + +Сценарий: Объединение шаблонов каталога + Когда я выполняю команду "oscript" с параметрами "<КаталогПроекта>/src/main.os join-path snippets result.st" + Тогда Код возврата равен 0 + И Файл "result.st" в рабочем каталоге содержит + """ + {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + """ + И Файл "result.st" в рабочем каталоге содержит + """ + ТекущаяДата = '' + """ diff --git "a/features/\320\237\321\200\320\265\320\276\320\261\321\200\320\260\320\267\320\276\320\262\320\260\320\275\320\270\320\265-\321\210\320\260\320\261\320\273\320\276\320\275\320\276\320\262.feature" "b/features/\320\237\321\200\320\265\320\276\320\261\321\200\320\260\320\267\320\276\320\262\320\260\320\275\320\270\320\265-\321\210\320\260\320\261\320\273\320\276\320\275\320\276\320\262.feature" new file mode 100644 index 0000000..558c845 --- /dev/null +++ "b/features/\320\237\321\200\320\265\320\276\320\261\321\200\320\260\320\267\320\276\320\262\320\260\320\275\320\270\320\265-\321\210\320\260\320\261\320\273\320\276\320\275\320\276\320\262.feature" @@ -0,0 +1,52 @@ +#language: ru + +Функциональность: Преобразование шаблонов + +Как разработчик я хочу иметь возможность конвертировать шаблоны в различные форматы +Чтобы подключать их к различным IDE + +Контекст: + Допустим Я очищаю параметры команды "oscript" в контексте + И я включаю отладку лога с именем "oscript.app.snippet-transform" + И я создаю временный каталог и сохраняю его в контекст + И я устанавливаю временный каталог как рабочий каталог + И я установил рабочий каталог как текущий каталог + И Я копирую каталог "snippets" из каталога "tests/fixtures" проекта в рабочий каталог + И я создаю каталог "result" в рабочем каталоге + +Сценарий: Преобразование шаблона конфигуратора в шаблон VSCode + Когда я выполняю команду "oscript" с параметрами "<КаталогПроекта>/src/main.os convert snippets/ШаблонКонфигуратора.st result/vscode.code-snippets" + Тогда Код возврата равен 0 + И Файл "result/vscode.code-snippets" в рабочем каталоге содержит строки + | "scope": "bsl" | + | "prefix": "МодульОбщий" | + | "prefix": "ЗапретитьИспользование" | + | "prefix": "++" | +Сценарий: Преобразование шаблона конфигуратора в шаблон EDT + Когда я выполняю команду "oscript" с параметрами "<КаталогПроекта>/src/main.os convert snippets/ШаблонКонфигуратора.st result/edt.xml" + Тогда Код возврата равен 0 + И Файл "result/edt.xml" в рабочем каталоге содержит строки + | name="МодульОбщий" | + | name="ЗапретитьИспользование" | + | name="++" | +Сценарий: Преобразование шаблона конфигуратора с неподдерживаемыми типами в шаблон VSCode + Когда я выполняю команду "oscript" с параметрами "<КаталогПроекта>/src/main.os convert snippets/ШаблонКонфигуратораСНеподдерживаемымиТипами.st result/vscode.code-snippets" + Тогда Код возврата равен 0 + И Файл "result/vscode.code-snippets" в рабочем каталоге содержит строки + | "scope": "bsl" | + | "prefix": "№Если" | + И Файл "result/vscode.code-snippets" в рабочем каталоге не содержит строки + | "prefix": "УстановитьЗначениеКонстанты" | + | "prefix": "Формат" | +Сценарий: Преобразование шаблона конфигуратора с неподдерживаемыми в шаблон EDT + Когда я выполняю команду "oscript" с параметрами "<КаталогПроекта>/src/main.os convert snippets/ШаблонКонфигуратораСНеподдерживаемымиТипами.st result/edt.xml" + Тогда Код возврата равен 0 + И Файл "result/edt.xml" в рабочем каталоге не содержит строки + | name="Формат" | + | name="УстановитьЗначениеКонстанты" | + | name="№Если" | + И Файл "result/edt.xml" в рабочем каталоге содержит + """ + + + """ \ No newline at end of file diff --git "a/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" "b/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" new file mode 100644 index 0000000..e2a0ba7 --- /dev/null +++ "b/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" @@ -0,0 +1,33 @@ +#language: ru + +Функциональность: Разделение шаблона кода + +Как разработчик +Я хочу получить разделить файл шаблона + +Контекст: + Допустим Я очищаю параметры команды "oscript" в контексте + И я включаю отладку лога с именем "oscript.app.snippet-transform" + И я создаю временный каталог и сохраняю его в контекст + И я устанавливаю временный каталог как рабочий каталог + И я установил рабочий каталог как текущий каталог + И я копирую файл "snippets/ШаблонКонфигуратора.st" из каталога "tests\fixtures" проекта в рабочий каталог + +Сценарий: Объединение двух шаблонов + Когда я выполняю команду "oscript" с параметрами + """ + <КаталогПроекта>/src/main.os apportion ШаблонКонфигуратора.st "^Группа.*" result.st -r + """ + Тогда Код возврата равен 0 + И Файл "ШаблонКонфигуратора.st" в рабочем каталоге не содержит + """ + {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + """ + И Файл "ШаблонКонфигуратора.st" в рабочем каталоге содержит + """ + = + 1; + """ + И Файл "result.st" в рабочем каталоге содержит + """ + {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + """ diff --git a/installlocalhost.bat b/installlocalhost.bat new file mode 100644 index 0000000..f627dd6 --- /dev/null +++ b/installlocalhost.bat @@ -0,0 +1,13 @@ +@echo off +call del "*.ospx" + +for /f %%i in ('"oscript -version"') do set result=%%i + +if %result%==1.0.19.105 ( + call opm build . -mf ./packagedef -out . +) else ( + call opm build -m ./packagedef -o . +) + +rem // TODO: наименование приложения и версия +call opm install -f *.ospx \ No newline at end of file diff --git a/packagedef b/packagedef new file mode 100644 index 0000000..715ee79 --- /dev/null +++ b/packagedef @@ -0,0 +1,14 @@ +ПутьКСценариюПараметров = ОбъединитьПути(ТекущийСценарий().Каталог, "src", "Модули", "ПараметрыПриложения.os"); +ПараметрыСистемы_ЛокальнаяВерсия = ЗагрузитьСценарий(ПутьКСценариюПараметров); + +ИмяПродукта = НРег(ПараметрыСистемы_ЛокальнаяВерсия.ИмяПродукта()); + +Описание.Имя(ИмяПродукта) + .ВерсияСреды("1.0.21") + .Версия(ПараметрыСистемы_ЛокальнаяВерсия.ВерсияПродукта()) + .ЗависитОт("logos", "1.2") + .ЗависитОт("cmdline", "1.0") + .ВключитьФайл("src") + .ВключитьФайл("README.md") + .ВключитьФайл("LICENSE") + .ИсполняемыйФайл("src/main.os", ИмяПродукта); diff --git a/src/main.os b/src/main.os new file mode 100644 index 0000000..d2f4c00 --- /dev/null +++ b/src/main.os @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// CLI-интерфейс для oscript-app +// +//The MIT License (MIT) +// +// Copyright (c) 2016 Andrei Ovsiankin +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// +// Рекомендованная структура модуля точки входа приложения +// +/////////////////////////////////////////////////////////////////////////////// + +#Использовать "." + +/////////////////////////////////////////////////////////////////////////////// + +Приложение = МенеджерПриложения.Инициализировать(ПараметрыПриложения); + +Попытка + + Приложение.ЗавершитьРаботуПриложения(Приложение.ЗапуститьВыполнение()); + +Исключение + + Приложение.ЗавершитьРаботуПриложенияСОшибкой(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); + +КонецПопытки; diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Apportion.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Apportion.os" new file mode 100644 index 0000000..d077db4 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Apportion.os" @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Модуль команды разделения шаблона +// +/////////////////////////////////////////////////////////////////////////////// + +Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт + + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ИзменяемыйШаблон", "Имя файла шаблона, который хотим разделить"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ШаблонНаименования", "Регулярное выражение для проверки полного наименования шаблона (Группа.Шаблон)"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "НовыйШаблон", "Имя файла шаблона, в который будут записаны отделенные элементы"); + Парсер.ДобавитьПараметрФлагКоманды(Команда, "-r", "Переносить элементы, у которых наименование не совпадает с шаблоном"); + +КонецПроцедуры // НастроитьКоманду + +// Выполняет логику команды +// +// Параметры: +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// Приложение - Модуль - Модуль менеджера приложения +// +Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт + + Лог = Приложение.ПолучитьЛог(); + + ИзменяемыйШаблон = ПараметрыКоманды["ИзменяемыйШаблон"]; + НовыйШаблон = ПараметрыКоманды["НовыйШаблон"]; + ШаблонНаименования = ПараметрыКоманды["ШаблонНаименования"]; + ПереноситьНесовпадения = ПараметрыКоманды["-r"] = Истина; + + Конвертер.РазделитьШаблон(ИзменяемыйШаблон, ШаблонНаименования, ПереноситьНесовпадения, НовыйШаблон); + + Лог.Отладка("Выполнено разделение шаблонов"); + + Возврат Приложение.РезультатыКоманд().Успех; + +КонецФункции // ВыполнитьКоманду diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Convert.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Convert.os" new file mode 100644 index 0000000..2eb214d --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Convert.os" @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Служебный модуль с реализацией работы команды help +// +/////////////////////////////////////////////////////////////////////////////// + +Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт + + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ВходнойФайл", "Имя конвертируемого шаблона"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ВыходнойФайл", "Имя файла нового шаблона, в который будут перенесены элементы из первого файла"); + +КонецПроцедуры // НастроитьКоманду + +// Выполняет логику команды +// +// Параметры: +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// Приложение - Модуль - Модуль менеджера приложения +// +Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт + + Лог = Приложение.ПолучитьЛог(); + + ВходнойФайл = ПараметрыКоманды["ВходнойФайл"]; + ВыходнойФайл = ПараметрыКоманды["ВыходнойФайл"]; + + Конвертер.ПреобразоватьШаблон(ВходнойФайл, ВыходнойФайл); + + Лог.Информация("Преобразование выполнено. %1 ==> %2", ВходнойФайл, ВыходнойФайл); + + Возврат Приложение.РезультатыКоманд().Успех; + +КонецФункции // ВыполнитьКоманду diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinFiles.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinFiles.os" new file mode 100644 index 0000000..8b5b58a --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinFiles.os" @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Модуль команды соединения двух файлов +// +/////////////////////////////////////////////////////////////////////////////// + +Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт + + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ИзменяемыйШаблон", "Имя файла шаблона, в который будут добавлены элементы из второго файла"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ДобавляемыйШаблон", "Имя файла шаблона, из которого будут добавлены элементы в первый файл"); + +КонецПроцедуры // НастроитьКоманду + +// Выполняет логику команды +// +// Параметры: +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// Приложение - Модуль - Модуль менеджера приложения +// +Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт + + Лог = Приложение.ПолучитьЛог(); + + ИзменяемыйШаблон = ПараметрыКоманды["ИзменяемыйШаблон"]; + ДобавляемыйШаблон = ПараметрыКоманды["ДобавляемыйШаблон"]; + + ВходныеФайлы = Новый Массив(); + ВходныеФайлы.Добавить(Новый Файл(ИзменяемыйШаблон)); + ВходныеФайлы.Добавить(Новый Файл(ДобавляемыйШаблон)); + + Конвертер.СоединитьШаблоны(ВходныеФайлы, ИзменяемыйШаблон); + + Лог.Отладка("Файлы объединены"); + + Возврат Приложение.РезультатыКоманд().Успех; + +КонецФункции // ВыполнитьКоманду diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinPath.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinPath.os" new file mode 100644 index 0000000..a056816 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260JoinPath.os" @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Модуль команды соединения каталога шаблонов +// +/////////////////////////////////////////////////////////////////////////////// + +Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт + + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "КаталогШаблонов", "Каталог содержащий шаблоны кода, которые необходимо объединить"); + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "РезультирующийШаблон", "Имя файла итогового шаблона"); + +КонецПроцедуры // НастроитьКоманду + +// Выполняет логику команды +// +// Параметры: +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// Приложение - Модуль - Модуль менеджера приложения +// +Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт + + Лог = Приложение.ПолучитьЛог(); + + КаталогШаблонов = ПараметрыКоманды["КаталогШаблонов"]; + РезультирующийШаблон = ПараметрыКоманды["РезультирующийШаблон"]; + + Конвертер.СоединитьШаблоны(НайтиФайлы(КаталогШаблонов, "*", Истина), РезультирующийШаблон); + + Лог.Отладка("Шаблоны каталога объединены"); + + Возврат Приложение.РезультатыКоманд().Успех; + +КонецФункции // ВыполнитьКоманду diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Version.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Version.os" new file mode 100644 index 0000000..1a131c0 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260Version.os" @@ -0,0 +1,27 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Служебный модуль с реализацией работы команды version +// +/////////////////////////////////////////////////////////////////////////////// + +Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт + +КонецПроцедуры // НастроитьКоманду + +// Выполняет логику команды +// +// Параметры: +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// Приложение - Модуль - Модуль менеджера приложения +// +Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт + + Лог = Приложение.ПолучитьЛог(); + + Сообщить(Приложение.ВерсияПродукта()); + + Лог.Отладка("Вывод версии приложения"); + + Возврат Приложение.РезультатыКоманд().Успех; + +КонецФункции // ВыполнитьКоманду diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\241\320\277\321\200\320\260\320\262\320\272\320\260\320\237\320\276\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\260\320\274.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\241\320\277\321\200\320\260\320\262\320\272\320\260\320\237\320\276\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\260\320\274.os" new file mode 100644 index 0000000..e00d787 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\241\320\277\321\200\320\260\320\262\320\272\320\260\320\237\320\276\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\260\320\274.os" @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Служебный модуль с реализацией работы команды help +// +/////////////////////////////////////////////////////////////////////////////// + +Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт + + Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "Команда"); + +КонецПроцедуры // НастроитьКоманду + +// Выполняет логику команды +// +// Параметры: +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// Приложение - Модуль - Модуль менеджера приложения +// +Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт + + Лог = Приложение.ПолучитьЛог(); + + КомандаДляСправки = ПараметрыКоманды["Команда"]; + + Если КомандаДляСправки = Неопределено Тогда + + Приложение.ВывестиСправкуПоКомандам(); + + Лог.Отладка("Вывод справки по командам"); + + Иначе + + Приложение.ВывестиСправкуПоКоманде(КомандаДляСправки); + + Лог.Отладка(СтрШаблон("Вывод справки по команде %1", КомандаДляСправки)); + + КонецЕсли; + + Возврат Приложение.РезультатыКоманд().Успех; + +КонецФункции // ВыполнитьКоманду diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\247\321\202\320\265\320\275\320\270\320\265\320\222\320\275\321\203\321\202\321\200\320\265\320\275\320\275\320\270\320\271\320\244\320\276\321\200\320\274\320\260\321\2021\320\241.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\247\321\202\320\265\320\275\320\270\320\265\320\222\320\275\321\203\321\202\321\200\320\265\320\275\320\275\320\270\320\271\320\244\320\276\321\200\320\274\320\260\321\2021\320\241.os" new file mode 100644 index 0000000..8177c2a --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\247\321\202\320\265\320\275\320\270\320\265\320\222\320\275\321\203\321\202\321\200\320\265\320\275\320\275\320\270\320\271\320\244\320\276\321\200\320\274\320\260\321\2021\320\241.os" @@ -0,0 +1,297 @@ +/////////////////////////////////////////////////////////////////// +// +// Чтение файлов во внутреннем формате 1с +// За основу взята разработка https://github.com/arkuznetsov/yabr +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Выполняет чтение файла во внутреннем формате 1с(скобочном) +// +// Параметры: +// ПутьКФайлу - Строка - путь к файлу для чтения +// НачальнаяСтрока - Число - номер начальной строки файла для чтения +// +// Возвращаемое значение: +// Структура - Новый элемент +// *Родитель - Структура - ссылка на элемент-родитель +// *Уровень - Число - уровень иерархии элемента +// *Индекс - Число - индекс элемента в массиве значений родителя +// *НачСтрока - Число - номер первой строки из которой был прочитан элемент и его дочерние элементы +// *КонСтрока - Число - номер последней строки из которой был прочитан элемент и его дочерние элементы +// *Значения - Массив(Структура) - массив дочерних элементов +// +Функция ПрочитатьФайл(ПутьКФайлу, НачальнаяСтрока = 1) Экспорт + + СтруктураЧтения = ИнициализироватьЭлемент(Неопределено); + + Текст = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8NoBOM); + + ДанныеСтроки = Текст.ПрочитатьСтроку(); + + Начало = ТекущаяУниверсальнаяДатаВМиллисекундах(); + ТекНачало = Начало; + НачКоличество = 0; + + НомерСтроки = 1; + + Пока НЕ ДанныеСтроки = Неопределено Цикл + + Если НомерСтроки < НачальнаяСтрока И НЕ НачальнаяСтрока < 1 Тогда + ДанныеСтроки = Текст.ПрочитатьСтроку(); + НомерСтроки = НомерСтроки + 1; + Продолжить; + КонецЕсли; + + СтрокаДляОбработки = ""; + СтрокаДляОбработкиПрочитана = Ложь; + КавычкиОткрыты = Ложь; + + // сборка "завершенной" строки, где кавычки закрыты и последний символ = "," или "}" + Пока НЕ (СтрокаДляОбработкиПрочитана ИЛИ ДанныеСтроки = Неопределено) Цикл + + СтрокаДляОбработкиПрочитана = ДополнитьСтрокуДляОбработки(СтрокаДляОбработки, ДанныеСтроки, КавычкиОткрыты); + + Если НЕ СтрокаДляОбработкиПрочитана Тогда + + Если КавычкиОткрыты Тогда + СтрокаДляОбработки = СтрокаДляОбработки + Символы.ПС; + КонецЕсли; + + ДанныеСтроки = Текст.ПрочитатьСтроку(); + НомерСтроки = НомерСтроки + 1; + + КонецЕсли; + + КонецЦикла; + + СчетчикСимволов = 1; + + ПрочитатьДанныеСтроки(СтруктураЧтения, СтрокаДляОбработки, СчетчикСимволов); + + ДанныеСтроки = Текст.ПрочитатьСтроку(); + + НомерСтроки = НомерСтроки + 1; + + КонецЦикла; + + Текст.Закрыть(); + + Если НЕ ПустаяСтрока(СтрокаДляОбработки) Тогда + ПрочитатьДанныеСтроки(СтруктураЧтения, СтрокаДляОбработки, СчетчикСимволов); + КонецЕсли; + + НачальнаяСтрока = НомерСтроки; + + // переход к корневому элементу структуры чтения + Пока НЕ СтруктураЧтения.Родитель = Неопределено Цикл + СтруктураЧтения = СтруктураЧтения.Родитель; + КонецЦикла; + + Результат = СтруктураЧтения; + + Возврат Результат; + +КонецФункции // ПрочитатьФайл() + +/////////////////////////////////////////////////////////////////// +// Служебный функционал +/////////////////////////////////////////////////////////////////// + +// Функция - добавляет строку к исходной и возвращает признак завершенности строки +// исходя из закрытия кавычек и окончания строки на "," или "}" +// +// Параметры: +// ДополняемаяСтрока - Строка - исходная строка +// Дополнение - Строка - добавляемая строка +// КавычкиОткрыты - Булево - Истина - кавычки открыты; Ложь - кавычки закрыты +// +// Возвращаемое значение: +// Булево - Истина - строка завершена; Ложь - строка не завершена +// +Функция ДополнитьСтрокуДляОбработки(ДополняемаяСтрока, Дополнение, КавычкиОткрыты) + + КоличествоКавычек = СтрЧислоВхождений(Дополнение, """"); + + Если КавычкиОткрыты Тогда + КавычкиОткрыты = (КоличествоКавычек % 2 = 0); + Иначе + КавычкиОткрыты = (КоличествоКавычек % 2 = 1); + КонецЕсли; + + ДополняемаяСтрока = ДополняемаяСтрока + Дополнение; + + ПоследнийСимвол = Сред(Дополнение, СтрДлина(Дополнение), 1); + + // строка завершена если кавычки закрыты и последний символ = "," или "}" + Возврат (НЕ КавычкиОткрыты) И (ПоследнийСимвол = "}" ИЛИ ПоследнийСимвол = ","); + +КонецФункции // ДополнитьСтрокуДляОбработки() + +// Функция - создает структуру нового элемента +// +// Параметры: +// Родитель - Структура - ссылка на элемент-родитель (для корневого элемента "Неопределено") +// +// Возвращаемое значение: +// Структура - Новый элемент +// *Родитель - Структура - ссылка на элемент-родитель +// *Уровень - Число - уровень иерархии элемента +// *Индекс - Число - индекс элемента в массиве значений родителя +// *НачСтрока - Число - номер первой строки из которой был прочитан элемент и его дочерние элементы +// *КонСтрока - Число - номер последней строки из которой был прочитан элемент и его дочерние элементы +// *Значения - Массив(Структура) - массив дочерних элементов +// +Функция ИнициализироватьЭлемент(Знач Родитель) + + Уровень = 0; + Если ТипЗнч(Родитель) = Тип("Структура") Тогда + Если Родитель.Свойство("Уровень") Тогда + Уровень = Родитель.Уровень + 1; + КонецЕсли; + КонецЕсли; + + Индекс = 0; + Если ТипЗнч(Родитель) = Тип("Структура") Тогда + Если Родитель.Свойство("Значения") Тогда + Индекс = Родитель.Значения.ВГраница() + 1; + КонецЕсли; + КонецЕсли; + + Результат = Новый Структура("Родитель, + |Уровень, + |Индекс, + |НачСтрока, + |КонСтрока, + |Значения", + Родитель, + Уровень, + Индекс, + 0, + 0, + Новый Массив()); + + + Возврат Результат; + +КонецФункции // ИнициализироватьЭлемент() + +// Процедура - Читает, разбирает данные из переданной строки и добавляет результат в иерархию массива структур +// +// Параметры: +// ЭлементДляЗаполнения - Структура - структура элемента +// *Родитель - Структура - ссылка на элемент-родитель +// *Уровень - Число - уровень иерархии элемента +// *Индекс - Число - индекс элемента в массиве значений родителя +// *НачСтрока - Число - номер первой строки из которой был прочитан элемент и его дочерние элементы +// *КонСтрока - Число - номер последней строки из которой был прочитан элемент и его дочерние элементы +// *Значения - Массив(Структура) - массив дочерних элементов +// ДанныеСтроки - Строка - строка для разбора +// СчетчикСимволов - Число - счетчик прочитанных символов переданной строки +// +Процедура ПрочитатьДанныеСтроки(ЭлементДляЗаполнения, ДанныеСтроки, СчетчикСимволов) + + ТекСтрока = ""; + КавычкиОткрыты = Ложь; + ПредСимвол = ""; + + ДлинаСтроки = СтрДлина(ДанныеСтроки); + + // посимвольное чтение строки + Для НомерСимвола = СчетчикСимволов По ДлинаСтроки Цикл + + ТекСимвол = Сред(ДанныеСтроки, НомерСимвола, 1); + + Если КавычкиОткрыты Тогда // обработка строки внутри кавычек + + Если ТекСимвол = """" Тогда + + Если Сред(ДанныеСтроки, НомерСимвола, 2) = """""" Тогда // это экранированные кавычки внутри строки + + ТекСтрока = ТекСтрока + Сред(ДанныеСтроки, НомерСимвола, 2); + НомерСимвола = НомерСимвола + 1; + + Иначе // закрытие кавычек + + ТекСтрока = ТекСтрока + ТекСимвол; + КавычкиОткрыты = Ложь; + + КонецЕсли; + + Иначе // любой символ добавляется к строке + + ТекСтрока = ТекСтрока + ТекСимвол; + + КонецЕсли; + + ИначеЕсли ТекСимвол = """" Тогда // открытие кавычек + + ТекСтрока = ТекСтрока + ТекСимвол; + КавычкиОткрыты = Истина; + + ИначеЕсли ТекСимвол = "{" Тогда // открытие вложенного списка + + Если ЭлементДляЗаполнения = Неопределено Тогда + + ВремЭлементДляЗаполнения = ИнициализироватьЭлемент(Неопределено); + ЭлементДляЗаполнения = ВремЭлементДляЗаполнения; + + Иначе + + ВремЭлементДляЗаполнения = ИнициализироватьЭлемент(ЭлементДляЗаполнения); + ЭлементДляЗаполнения.Значения.Добавить(ВремЭлементДляЗаполнения); + + КонецЕсли; + + НомерСимвола = НомерСимвола + 1; + + ПрочитатьДанныеСтроки(ВремЭлементДляЗаполнения, ДанныеСтроки, НомерСимвола); + + Если НомерСимвола > СтрДлина(ДанныеСтроки) Тогда + + ЭлементДляЗаполнения = ВремЭлементДляЗаполнения; // если строка закончилась, то "наверх" поднимается элемент текущего уровня + Возврат; + + КонецЕсли; + + ИначеЕсли ТекСимвол = "}" Тогда // закрытие вложенного списка + + Если НЕ (ПредСимвол = "{" ИЛИ ПредСимвол = "}" ИЛИ ПредСимвол = "") Тогда + + ЭлементДляЗаполнения.Значения.Добавить(ТекСтрока); + ТекСтрока = ""; + + КонецЕсли; + + ЭлементДляЗаполнения = ЭлементДляЗаполнения.Родитель; + + СчетчикСимволов = НомерСимвола + 1; + Возврат; + + ИначеЕсли ТекСимвол = "," Тогда // добавление элемента текущего списка + + Если НЕ (ПредСимвол = "}" ИЛИ ПредСимвол = "") Тогда + + ЭлементДляЗаполнения.Значения.Добавить(ТекСтрока); + ТекСтрока = ""; + + КонецЕсли; + + Иначе + + ТекСтрока = ТекСтрока + ТекСимвол; + + КонецЕсли; + + ПредСимвол = ТекСимвол; + + КонецЦикла; + + СчетчикСимволов = НомерСимвола; + +КонецПроцедуры // ПрочитатьДанныеСтроки() diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200.os" new file mode 100644 index 0000000..ed6070a --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200.os" @@ -0,0 +1,236 @@ +/////////////////////////////////////////////////////////////////// +// +// Методы конвертации шаблонов кода +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Метод преобразования формата шаблона +// +// Параметры: +// ИмяВходногоФайла - Строка - Имя файла базового шаблона +// ИмяВыходногоФайла - Строка - Имя файла нового шаблона +// +Процедура ПреобразоватьШаблон(ИмяВходногоФайла, ИмяВыходногоФайла) Экспорт + + МодульЧтение = ПолучитьМодульРаботыСШаблоном(ИмяВходногоФайла); + + ДанныеШаблона = МодульЧтение.ПрочитатьШаблон(ИмяВходногоФайла); + + ЗаписатьСПроверкойДоступныхТипов(ДанныеШаблона, ИмяВыходногоФайла); + +КонецПроцедуры + +// Метода объединения нескольких шаблонов в один +// +// Параметры: +// МассивВходныхФайлов - Массив - Массив файлов (тип:Файл) шаблонов, которые необходимо объединить +// ИмяВыходногоФайла - Строка - Имя файла нового шаблона +// +Процедура СоединитьШаблоны(МассивВходныхФайлов, ИмяВыходногоФайла) Экспорт + + Лог = МенеджерПриложения.ПолучитьЛог(); + + Читатели = Новый Соответствие(); + + Шаблон = Неопределено; + + Для Каждого Файл Из МассивВходныхФайлов Цикл + + Если НЕ Файл.ЭтоФайл() Тогда + + Продолжить; + + КонецЕсли; + + Если Читатели[Файл.Расширение] = Неопределено Тогда + + Читатель = ПолучитьМодульРаботыСШаблоном(Файл.ПолноеИмя); + + Если Читатель = Неопределено Тогда + + Лог.Предупреждение("Формат шаблона не поддерживается. Файл пропущен %1", Файл.Имя); + Продолжить; + + КонецЕсли; + + Читатели.Вставить(Файл.Расширение, Читатель); + + КонецЕсли; + + ШаблонФайла = Читатели[Файл.Расширение].ПрочитатьШаблон(Файл.ПолноеИмя); + + Если Шаблон = Неопределено Тогда // Первый шаблон будет основным, необходимо для сохранения имени шаблона конфигуратора, при объединении двух шаблонов + + Шаблон = ШаблонФайла; + + Иначе + + Для Каждого Элемент Из ШаблонФайла.Элементы Цикл // Последующие шаблоны будут закидываться в основной + + Шаблон.Элементы.Добавить(Элемент); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + + ЗаписатьСПроверкойДоступныхТипов(Шаблон, ИмяВыходногоФайла); + +КонецПроцедуры + +// Метод для переноса части элементов шаблона в отдельный файл +// Анализ необходимости переноса выполняется по полному наименованию(включая иерархию) +// на соответствие регулярному выражению +// +// Параметры: +// ИзменяемыйШаблон - Строку - Имя файла анализируемого шаблона +// ШаблонНаименования - Строка - Шаблон регулярного для проверки наименования элемента +// РежимОбработкиНаименования - Строка - Способ обработки элементов +// * equal - совпадающий элемент переносится в новый файл +// * notequal - не совпадающий элемент переносится в новый файл +// УдаляемыеДанныеПоложитьВ - Строка - Имя файла, в который происходит перенос +// +Процедура РазделитьШаблон(ИзменяемыйШаблон, ШаблонНаименования, ПереносПриНеСовпадении, УдаляемыеДанныеПоложитьВ = Неопределено) Экспорт + + Модуль = ПолучитьМодульРаботыСШаблоном(ИзменяемыйШаблон); + Шаблон = Модуль.ПрочитатьШаблон(ИзменяемыйШаблон); + + НовыйШаблон = ШаблоныБазовый.КорневойЭлемент(); + РегулярноеВыражение = Новый РегулярноеВыражение(ШаблонНаименования); + + РазделитьШаблонПоРегулярномуВыражению(Шаблон, РегулярноеВыражение, НовыйШаблон, НЕ ПереносПриНеСовпадении, ""); + + Модуль.ЗаписатьШаблон(Шаблон, ИзменяемыйШаблон); + + Если УдаляемыеДанныеПоложитьВ <> Неопределено Тогда + + ЗаписатьСПроверкойДоступныхТипов(НовыйШаблон, УдаляемыеДанныеПоложитьВ); + + КонецЕсли; + +КонецПроцедуры + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +Процедура ЗаписатьСПроверкойДоступныхТипов(Шаблон, ИмяФайла, МодульЗаписи = Неопределено) + + Если МодульЗаписи = Неопределено Тогда + + МодульЗаписи = ПолучитьМодульРаботыСШаблоном(ИмяФайла); + + КонецЕсли; + + ДоступныеТипыПодстановок = МодульЗаписи.ДоступныеТипыПодстановок(); + ФлагиТипов = Утилиты.СоответствиеФлагов(ДоступныеТипыПодстановок); + УдалитьНедоступныеШаблоны(Шаблон, ФлагиТипов); + + МодульЗаписи.ЗаписатьШаблон(Шаблон, ИмяФайла); + +КонецПроцедуры + +Процедура УдалитьНедоступныеШаблоны(ДанныеШаблона, ДоступныеТипыПодстановок) + + Лог = МенеджерПриложения.ПолучитьЛог(); + + Количество = ДанныеШаблона.Элементы.Количество(); + + Для Инд = 1 По Количество Цикл + + Элемент = ДанныеШаблона.Элементы[Количество - Инд]; + + Если Элемент.Тип = "Элемент" Тогда + + Для Каждого ЭлементШаблона Из Элемент.Шаблон Цикл + + Если ТипЗнч(ЭлементШаблона) = Тип("Структура") И ДоступныеТипыПодстановок[ЭлементШаблона.Тип] = Неопределено Тогда + + Лог.Предупреждение("Шаблон замены ""%1"" пропущен, так имеет неподдерживаемый тип ""%2""", Элемент.Наименование, ЭлементШаблона.Тип); + ДанныеШаблона.Элементы.Удалить(Количество - Инд); + Прервать; + + КонецЕсли; + + КонецЦикла; + + ИначеЕсли Элемент.Тип = "Группа" Тогда + + УдалитьНедоступныеШаблоны(Элемент, ДоступныеТипыПодстановок); + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Функция ПолучитьМодульРаботыСШаблоном(ИмяФайла) + + РасширениеФайла = (Новый Файл(ИмяФайла)).Расширение; + + Если РасширениеФайла = ".st" Тогда + + Возврат ШаблоныКонфигуратора; + + ИначеЕсли РасширениеФайла = ".json" ИЛИ РасширениеФайла = ".code-snippets" Тогда + + Возврат ШаблоныVSCode; + + ИначеЕсли РасширениеФайла = ".xml" Тогда + + Возврат ШаблоныEDT; + + Иначе + + МенеджерПриложения.ПолучитьЛог().Ошибка("Не поддерживаемый формат файла: %1" + РасширениеФайла); + + КонецЕсли; + +КонецФункции + +Функция РазделитьШаблонПоРегулярномуВыражению(Шаблон, РегулярноеВыражение, НовыйШаблон, ПереносПриСовпадении, ПрефиксИмени) + + КУдалению = Новый Массив(); + Лог = МенеджерПриложения.ПолучитьЛог(); + + Для Каждого Элемент Из Шаблон.Элементы Цикл + + Наименование = ПрефиксИмени + ?(Элемент.Тип = "Группа", Элемент.Наименование + ".", Элемент.Наименование); + НаименованиеСовпадаетСШаблоном = РегулярноеВыражение.Совпадает(Наименование); + + Если (ПереносПриСовпадении И НаименованиеСовпадаетСШаблоном) ИЛИ (НЕ ПереносПриСовпадении И НЕ НаименованиеСовпадаетСШаблоном) Тогда + + НовыйШаблон.Элементы.Добавить(Элемент); + КУдалению.Добавить(Элемент); + Лог.Информация("Элемент шаблона ""%1%2"" перенесен в другой файл", ПрефиксИмени, Элемент.Наименование) + + ИначеЕсли Элемент.Тип = "Группа" Тогда + + НоваяГруппа = ШаблоныБазовый.Группа(); + + Если РазделитьШаблонПоРегулярномуВыражению(Элемент, РегулярноеВыражение, НоваяГруппа, ПереносПриСовпадении, Наименование) Тогда + + НовыйШаблон.Элементы.Добавить(НоваяГруппа); + + КонецЕсли; + + КонецЕсли; + + КонецЦикла; + + Для Каждого Элемент Из КУдалению Цикл + + Шаблон.Элементы.Удалить(Шаблон.Элементы.Найти(Элемент)); + + КонецЦикла; + + Возврат КУдалению.Количество(); + +КонецФункции diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" new file mode 100644 index 0000000..3be5b05 --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -0,0 +1,296 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Служебный модуль с набором методов работы с командами приложения +// +// В большинстве проектов изменять данный модуль не требуется +// +/////////////////////////////////////////////////////////////////////////////// + +#Использовать logos +#Использовать cmdline + +/////////////////////////////////////////////////////////////////////////////// + +Перем Лог; + +Перем ПарсерКоманд; +Перем ИсполнителиКоманд; +Перем ОбъектНастроек; + +/////////////////////////////////////////////////////////////////////////////// +// СЛУЖЕБНЫЙ ОТКРЫТЫЙ ПРОГРАММНЫЙ ИНТЕРФЕЙС +/////////////////////////////////////////////////////////////////////////////// + +// Инициализирует и настраивает приложение +// +// Параметры: +// Настройка - Модуль - Модуль, в котором определены настройки приложения +// +// Возвращаемое значение: +// Модуль - Модуль менеджера приложения +// +Функция Инициализировать(Знач МенеджерНастроек) Экспорт + + // Служебные переменные + ПарсерКоманд = Новый ПарсерАргументовКоманднойСтроки(); + ИсполнителиКоманд = Новый Соответствие; + ОбъектНастроек = МенеджерНастроек; + + // Логирование + Лог = Логирование.ПолучитьЛог(ОбъектНастроек.ИмяЛогаСистемы()); + Лог.УстановитьРаскладку(ОбъектНастроек); + + // Инициализация команд + ОбъектНастроек.НастроитьКомандыПриложения(ЭтотОбъект); + + Возврат ЭтотОбъект; + +КонецФункции + +// Добавляет команду в приложение +// +// Параметры: +// ИмяКоманды - Строка - Имя команды +// КлассРеализации - Строка - Имя файла класса, в котором реализована команда +// ОписаниеКоманды - Строка - краткое описание назначения команды +// +Процедура ДобавитьКоманду(Знач ИмяКоманды, Знач КлассРеализации, Знач ОписаниеКоманды) Экспорт + + Попытка + РеализацияКоманды = Новый(КлассРеализации); + + Команда = ПарсерКоманд.ОписаниеКоманды(ИмяКоманды, ОписаниеКоманды); + ПарсерКоманд.ДобавитьКоманду(Команда); + + РеализацияКоманды.НастроитьКоманду(Команда, ПарсерКоманд); + + ИсполнителиКоманд.Вставить(ИмяКоманды, РеализацияКоманды); + Исключение + ЗавершитьРаботуПриложенияСОшибкой(СтрШаблон("Не удалось инициализировать команду '%1' для класса '%2' по причине: + |%3", ИмяКоманды, КлассРеализации, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); + КонецПопытки; + +КонецПроцедуры + +// Аварийно завершает работу приложения с ошибкой +// +// Параметры: +// Сообщение - Строка - Сообщение, которое будет выведено пользователю перед завершением +// КодВозврата (не обязательный) - Число - Код возврата с которым будет закрыто приложение +// Значение по умолчанию: "ОшибкаВремениВыполнения" -- 1 +// +Процедура ЗавершитьРаботуПриложенияСОшибкой(Знач Сообщение, Знач КодВозврата = Неопределено) Экспорт + + Если КодВозврата = Неопределено Тогда + КодВозврата = РезультатыКоманд().ОшибкаВремениВыполнения; + КонецЕсли; + + Лог.КритичнаяОшибка(Сообщение); + + ЗавершитьРаботу(КодВозврата); + +КонецПроцедуры + +// Завершает работу приложения +// +// Параметры: +// КодВозврата (не обязательный) - Число - Код возврата с которым будет закрыто приложение +// Значение по умолчанию: "Успех" -- 0 +// +Процедура ЗавершитьРаботуПриложения(Знач КодВозврата = Неопределено) Экспорт + + Если КодВозврата = Неопределено Тогда + КодВозврата = РезультатыКоманд().Успех; + КонецЕсли; + + ЗавершитьРаботу(КодВозврата); + +КонецПроцедуры + +// Осуществляет запуск приложения на выполнение +// +// Возвращаемое значение: +// Число - Код возврата выполнения команды приложения +// +Функция ЗапуститьВыполнение() Экспорт + + Попытка + ПараметрыЗапуска = ПарсерКоманд.Разобрать(АргументыКоманднойСтроки); + Исключение + Лог.Отладка(ОписаниеОшибки()); + + Лог.Ошибка("Не удалось определить требуемое действие."); + ВывестиСправкуПоКомандам(); + + Возврат РезультатыКоманд().НеверныеПараметры; + КонецПопытки; + + Команда = ""; + ЗначенияПараметров = Неопределено; + + Если ПараметрыЗапуска = Неопределено ИЛИ ПараметрыЗапуска.Количество() = 0 Тогда + + ВывестиВерсию(); + ВывестиСправкуПоКомандам(); + + Возврат РезультатыКоманд().НеверныеПараметры; + + ИначеЕсли ТипЗнч(ПараметрыЗапуска) = Тип("Структура") Тогда + + // это команда + Команда = ПараметрыЗапуска.Команда; + ЗначенияПараметров = ПараметрыЗапуска.ЗначенияПараметров; + Лог.Отладка("Выполняю команду продукта %1", Команда); + + ИначеЕсли ЗначениеЗаполнено(ОбъектНастроек.ИмяКомандыПоУмолчанию()) Тогда + + // это команда по-умолчанию + Команда = ОбъектНастроек.ИмяКомандыПоУмолчанию(); + ЗначенияПараметров = ПараметрыЗапуска; + Лог.Отладка("Выполняю команду продукта по умолчанию %1", Команда); + + Иначе + + Возврат НекорректныеПараметры(); + + КонецЕсли; + + Если Команда <> ОбъектНастроек.ИмяКомандыВерсия() Тогда + + ВывестиВерсию(); + + КонецЕсли; + + Возврат ВыполнитьКоманду(Команда, ЗначенияПараметров); + +КонецФункции // ЗапуститьВыполнение() + +// Осуществляет запуск на выполнение указанной команды приложения +// +// Параметры: +// ИмяКоманды - Строка - Имя команды, которую необходимо запустить +// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений +// +Функция ВыполнитьКоманду(Знач ИмяКоманды, Знач ПараметрыКоманды) Экспорт + + Команда = ПолучитьКоманду(ИмяКоманды); + КодВозврата = Команда.ВыполнитьКоманду(ПараметрыКоманды, ЭтотОбъект); + + Если КодВозврата = Неопределено Тогда + КодВозврата = РезультатыКоманд().Успех; + КонецЕсли; + + Возврат КодВозврата; + +КонецФункции // ВыполнитьКоманду + +/////////////////////////////////////////////////////////////////////////////// +// ПРОГРАММНЫЙ ИНТЕРФЕЙС +/////////////////////////////////////////////////////////////////////////////// + +// Возвращает лог приложения +Функция ПолучитьЛог() Экспорт + + Возврат Лог; + +КонецФункции // ПолучитьЛог + +// Возвращает версию продукта +Функция ВерсияПродукта() Экспорт + + Возврат ОбъектНастроек.ВерсияПродукта(); + +КонецФункции // ВерсияПродукта + +// Возвращает имя продукта +Функция ИмяПродукта() Экспорт + + Возврат ОбъектНастроек.ИмяПродукта(); + +КонецФункции // ИмяПродукта + +// Возвращает путь к исполняемому файлу +Функция ПутьКИсполняемомуФайлу() Экспорт + + Возврат ОбъектНастроек.ПутьКИсполняемомуФайлу(); + +КонецФункции // ПутьКИсполняемомуФайлу + +// Возвращает путь к каталогу основного скрипта +Функция ПутьКРодительскомуКаталогу() Экспорт + + Возврат ОбъектНастроек.ПутьКРодительскомуКаталогу(); + +КонецФункции // ПутьКРодительскомуКаталогу + +// Возвращает путь к каталогу сценариев +Функция КаталогСценариев() Экспорт + + Возврат ОбъектНастроек.КаталогСценариев(); + +КонецФункции // КаталогСценариев + +// Выводит справку по всем командам приложения +Процедура ВывестиСправкуПоКомандам() Экспорт + + ПарсерКоманд.ВывестиСправкуПоКомандам(); + +КонецПроцедуры // ВывестиСправкуПоКомандам + +// Выводит справку по указанной команде приложения. +Процедура ВывестиСправкуПоКоманде(Знач ИмяКоманды) Экспорт + + ПарсерКоманд.ВывестиСправкуПоКоманде(ИмяКоманды); + +КонецПроцедуры // ВывестиСправкуПоКоманде + +/////////////////////////////////////////////////////////////////////////////// +// ПЕРЕЧИСЛЕНИЯ +/////////////////////////////////////////////////////////////////////////////// + +// Возвращает стандартные коды возврата приложения +Функция РезультатыКоманд() Экспорт + + РезультатыКоманд = Новый Структура; + РезультатыКоманд.Вставить("Успех", 0); + РезультатыКоманд.Вставить("НеверныеПараметры", 5); + РезультатыКоманд.Вставить("ОшибкаВремениВыполнения", 1); + + Возврат РезультатыКоманд; + +КонецФункции // РезультатыКоманд + +/////////////////////////////////////////////////////////////////////////////// +// СЛУЖЕБНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ +/////////////////////////////////////////////////////////////////////////////// + +// Получает объект класса с реализацией указанной команды +Функция ПолучитьКоманду(Знач ИмяКоманды) + + КлассРеализации = ИсполнителиКоманд[ИмяКоманды]; + Если КлассРеализации = Неопределено Тогда + + ВызватьИсключение СтрШаблон("Неверная операция. Команда '%1' не предусмотрена.", ИмяКоманды); + + КонецЕсли; + + Возврат КлассРеализации; + +КонецФункции // ПолучитьКоманду + +// Осуществляет вывод полной версии продукта +Процедура ВывестиВерсию() + + Сообщить(СтрШаблон("%1 v%2", ИмяПродукта(), ВерсияПродукта())); + +КонецПроцедуры // ВывестиВерсию + +// Вывод ошибки и справки по параметрам +Функция НекорректныеПараметры() + + Лог.Ошибка("Некорректные аргументы командной строки"); + ВывестиСправкуПоКомандам(); + + Возврат РезультатыКоманд().НеверныеПараметры; + +КонецФункции // НекорректныеПараметры() diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" new file mode 100644 index 0000000..59b2da8 --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -0,0 +1,156 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Служебный модуль с набором служебных параметров приложения +// +// При создании нового приложения обязательно внести изменение +// в ф-ии ИмяПродукта, указав имя вашего приложения. +// +// При выпуске новой версии обязательно изменить ее значение +// в ф-ии ВерсияПродукта +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// СВОЙСТВА ПРОДУКТА +/////////////////////////////////////////////////////////////////////////////// + +// ВерсияПродукта +// Возвращает текущую версию продукта +// +// Возвращаемое значение: +// Строка - Значение текущей версии продукта +// +Функция ВерсияПродукта() Экспорт + + Возврат "1.0.1"; + +КонецФункции // ВерсияПродукта + +// ИмяПродукта +// Возвращает имя продукта +// +// Возвращаемое значение: +// Строка - Значение имени продукта +// +Функция ИмяПродукта() Экспорт + + Возврат "snippet-transform"; + +КонецФункции // ИмяПродукта + +// ПутьКИсполняемомуФайлу +// Возвращает путь к исполняемому файлу +// +// Возвращаемое значение: +// Строка - Путь к исполняемому файлу скрипта +// +Функция ПутьКИсполняемомуФайлу() Экспорт + + Возврат ОбъединитьПути(ПутьКРодительскомуКаталогу(), "src", "main.os"); + +КонецФункции // ПутьКИсполняемомуФайлу + +// ПутьКРодительскомуКаталогу +// Возвращает путь к каталогу основного скрипта +// +// Возвращаемое значение: +// Строка - Путь к каталогу основного скрипта +// +Функция ПутьКРодительскомуКаталогу() Экспорт + + Файл = Новый Файл(ОбъединитьПути(ТекущийСценарий().Каталог, "..", "..")); + Возврат Файл.ПолноеИмя; + +КонецФункции // ПутьКРодительскомуКаталогу + +// КаталогСценариев +// Возвращает путь к каталогу сценариев +// +// Возвращаемое значение: +// Строка - Путь к каталогу сценариев +// +Функция КаталогСценариев() Экспорт + + Возврат ОбъединитьПути(ПутьКРодительскомуКаталогу(), "src", "СценарииОбработки"); + +КонецФункции // КаталогСценариев + +/////////////////////////////////////////////////////////////////////////////// +// ЛОГИРОВАНИЕ +/////////////////////////////////////////////////////////////////////////////// + +// Форматирование логов +// См. описание метода "УстановитьРаскладку" библиотеки logos +// +Функция Форматировать(Знач Уровень, Знач Сообщение) Экспорт + + Возврат СтрШаблон("%1: %2 - %3", ТекущаяДата(), УровниЛога.НаименованиеУровня(Уровень), Сообщение); + +КонецФункции + +// ИмяЛогаСистемы +// Возвращает идентификатор лога приложения +// +// Возвращаемое значение: +// Строка - Значение идентификатора лога приложения +// +Функция ИмяЛогаСистемы() Экспорт + + Возврат "oscript.app." + ИмяПродукта(); + +КонецФункции // ИмяЛогаСистемы + +/////////////////////////////////////////////////////////////////////////////// +// НАСТРОЙКА КОМАНД +/////////////////////////////////////////////////////////////////////////////// + +// Возвращает имя команды "version" (ключ командной строки) +// +// Возвращаемое значение: +// Строка - имя команды +// +Функция ИмяКомандыВерсия() Экспорт + + Возврат "version"; + +КонецФункции // ИмяКомандыВерсия + +// Возвращает имя команды "help" (ключ командной строки) +// +// Возвращаемое значение: +// Строка - имя команды +// +Функция ИмяКомандыПомощь() Экспорт + + Возврат "help"; + +КонецФункции // ИмяКомандыПомощь() + +// ИмяКомандыПоУмолчанию +// Одна из команд может вызываться неявно, без указания команды. +// Иными словами, здесь указывается какой обработчик надо вызывать, если приложение запущено без какой-либо команды +// myapp /home/user/somefile.txt будет аналогично myapp default-action /home/user/somefile.txt +// +// Возвращаемое значение: +// Строка - имя команды по умолчанию +Функция ИмяКомандыПоУмолчанию() Экспорт + + Возврат "convert"; + +КонецФункции // ИмяКомандыПоУмолчанию + +// НастроитьКомандыПриложения +// Регистрирует классы обрабатывающие команды приложения +// +// Параметры: +// Приложение - Модуль - Модуль менеджера приложения +Процедура НастроитьКомандыПриложения(Знач Приложение) Экспорт + + Приложение.ДобавитьКоманду(ИмяКомандыПомощь(), "КомандаСправкаПоПараметрам", "Выводит справку по командам"); + Приложение.ДобавитьКоманду(ИмяКомандыВерсия(), "КомандаVersion", "Выводит версию приложения"); + Приложение.ДобавитьКоманду("convert", "КомандаConvert", "Преобразование шаблона кода, с автоматическим определением форматов на основании расширения"); + Приложение.ДобавитьКоманду("join-files", "КомандаJoinFiles", "Выполняет объединение двух файлов шаблонов"); + Приложение.ДобавитьКоманду("join-path", "КомандаJoinPath", "Выполняет объединение каталога файлов шаблонов"); + Приложение.ДобавитьКоманду("apportion", "КомандаApportion", "Выполняет разделение шаблона, на основании регулярного выражения"); + +КонецПроцедуры // ПриРегистрацииКомандПриложения diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\320\237\320\276\320\264\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\270.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\320\237\320\276\320\264\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\270.os" new file mode 100644 index 0000000..71f8183 --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\320\237\320\276\320\264\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\270.os" @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////// +// +// Модуль-перечисления, типы блоков подставновки шаблонов +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + +Перем Неизвестный Экспорт; +Перем УстановкаКурсора Экспорт; +Перем ВыборВарианта Экспорт; +Перем ДатаВремя Экспорт; + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Возвращает список всех доступных типов, тип "Неизвестный" не включен +// +// Возвращаемое значение: +// Массив - Коллекция строк-идентификаторов доступных типов +// +Функция ВсеТипы() Экспорт + + ТипыШаблонов = Новый Массив(); + + ТипыШаблонов.Добавить(УстановкаКурсора); + ТипыШаблонов.Добавить(ВыборВарианта); + ТипыШаблонов.Добавить(ДатаВремя); + + Возврат ТипыШаблонов; + +КонецФункции + +/////////////////////////////////////////////////////////////////// + +Неизвестный = "Неизвестный"; +УстановкаКурсора = "Установка курсора"; +ВыборВарианта = "Выбор варианта"; +ДатаВремя = "Дата время"; + diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\243\321\202\320\270\320\273\320\270\321\202\321\213.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\243\321\202\320\270\320\273\320\270\321\202\321\213.os" new file mode 100644 index 0000000..e01975c --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\243\321\202\320\270\320\273\320\270\321\202\321\213.os" @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////////////////////// +// +// Модуль-перечисления, типы блоков подставновки шаблонов +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + +Перем Кэш; + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Проверяет, является ли строка числом +// +// Параметры: +// Строка - Строка - Проверяемая строка +// +// Возвращаемое значение: +// Булево - Истина - число, Ложь - нет +// +Функция ЭтоЧисло(Строка) Экспорт + + Возврат Кэш["ПроверкаЧисло"].Совпадает(Строка); + +КонецФункции + +// Удаляет последовательности символов в начале и конце строки +// +// Параметры: +// Текст - Строка - Анализируемый текст +// Символы - Строка - Строка удаляемых символов +// +// Возвращаемое значение: +// Строка - Строка с удаленными символами +// +Функция УдалитьСимволыВНачалеИКонце(Знач Текст, Символы) Экспорт + + Ключ = "УдалитьСимволыВНачалеИКонце-" + Символы; + + Если Кэш[Ключ] = Неопределено Тогда + + Шаблон = СтрШаблон("^[%1]*(.*?)[%1]*$", ЭкранироватьСлужебныеСимволыRegExp(Символы)); + + Кэш.Вставить(Ключ, Новый РегулярноеВыражение(Шаблон)); + + КонецЕсли; + + Возврат Кэш[Ключ].Заменить(Текст, "$1"); + +КонецФункции + +// Удаляет из строки символы +// +// Параметры: +// Текст - Строка - Анализируемый текст +// Символы - Строка - Строка удаляемых символов +// +// Возвращаемое значение: +// Строка - Строка с удаленными символами +// +Функция УдалитьСимволы(Знач Текст, УдаляемыеСимволы) Экспорт + + // Не корректно работает СтрРазделить https://github.com/EvilBeaver/OneScript/pull/851/commits + // Должно заработать на следующем релизе oscript 1.0.22 + // Части = СтрРазделить(Текст, УдаляемыеСимволы); + + // Возврат СтрСоединить(Части, ""); + + Ключ = "УдалитьСимволы" + УдаляемыеСимволы; + Если Кэш[Ключ] = Неопределено Тогда + + Шаблон = СтрШаблон("[%1]", ЭкранироватьСлужебныеСимволыRegExp(УдаляемыеСимволы)); + + Кэш.Вставить(Ключ, Новый РегулярноеВыражение(Шаблон)); + + КонецЕсли; + + Возврат Кэш[Ключ].Заменить(Текст, ""); + +КонецФункции + +// На основании массива значений формирует соответствие, в качестве значения используется "ЗначениеФлага" +// +// Параметры: +// Массив - Массив - Коллекция произвольных значений +// ЗначениеФлага - Произвольный - Значение соответствия +// +// Возвращаемое значение: +// Соответствие - Соответствие флагов +// +Функция СоответствиеФлагов(Массив, ЗначениеФлага = Истина) Экспорт + + Результат = Новый Соответствие(); + + Для Каждого Элемент Из Массив Цикл + + Результат.Вставить(Элемент, ЗначениеФлага); + + КонецЦикла; + + Возврат Результат; + +КонецФункции + +// Формирует имя переменной в формате CamelCase +// +// Параметры: +// Текст - Строка - Текст на основании, которого будет сформировано имя переменной +// +// Возвращаемое значение: +// Строка - Имя переменной +// +Функция СформироватьИдентификатор(Текст) Экспорт + + Строка = ""; + + Для Каждого Совпадение Из Кэш["Слова"].НайтиСовпадения(Текст) Цикл + + Строка = Строка + ВРег(Лев(Совпадение.Значение, 1)) + Сред(Совпадение.Значение, 2); + + КонецЦикла; + + Возврат Строка; + +КонецФункции + +// Выделяет из текста слова +// +// Параметры: +// Строка - Строка - Анализируемый тест +// ВернутьТакжеПозицию - Булево - Истина - формирует массив структур, содержащих инф о положении слова в тексте +// +// Возвращаемое значение: +// Массив - Массив слов +// +Функция ПолучитьСлова(Строка, ВернутьТакжеПозицию = Ложь) Экспорт + + Слова = Новый Массив(); + + Для Каждого Совпадение Из Кэш["Слова"].НайтиСовпадения(Строка) Цикл + + Если ВернутьТакжеПозицию Тогда + Слова.Добавить(Новый Структура("Слово, Начало, Окончание", Совпадение.Значение, Совпадение.Индекс, Совпадение.Индекс + Совпадение.Длина)); + Иначе + Слова.Добавить(Совпадение.Значение); + КонецЕсли; + + КонецЦикла; + + Возврат Слова; + +КонецФункции + +Функция ЭкранироватьСлужебныеСимволыRegExp(Символы) + + СлужебныеСимволыРегулярногоВыражения = "^$.[]\"; + + Результат = ""; + + Для Инд = 1 По СтрДлина(Символы) Цикл + + Символ = Сред(Символы, Инд, 1); + + Если СтрНайти(СлужебныеСимволыРегулярногоВыражения, Символ) Тогда + + Результат = СтрШаблон("%1\%2", Результат, Символ); + + Иначе + + Результат = Результат + Символ; + + КонецЕсли; + + КонецЦикла; + + Возврат Результат; + +КонецФункции + +Кэш = Новый Соответствие(); +Кэш.Вставить("ПроверкаЧисло", Новый РегулярноеВыражение("\d+")); +Кэш.Вставить("ФиксТекстЗамены", Новый РегулярноеВыражение("[\[\]]")); +Кэш.Вставить("Слова", Новый РегулярноеВыражение("[\w\dА-Яа-я]+")); diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213EDT.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213EDT.os" new file mode 100644 index 0000000..2868b43 --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213EDT.os" @@ -0,0 +1,324 @@ +/////////////////////////////////////////////////////////////////// +// +// Методы работы с шаблонами EDT +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Считывает шаблон кода в структуру +// +// Параметры: +// ИмяФайлаШаблона - Строка - Имя файла шаблона +// РазбиратьБлокиПодстановки - Булево - Выполнять ли разбор текста шаблона +// Если выполняется объединение/разделение без изменения типа шаблона, то рекомендуется не выполнять анализ текста шаблона +// +// Возвращаемое значение: +// Структура - Данные шаблона +// Тип - ТИп узла шаблона +// Наименование - имя узла +// Значения - подчиненные узлы +// +Функция ПрочитатьШаблон(ИмяФайлаШаблона, РазбиратьБлокиПодстановки = Истина) Экспорт + + Чтение = Новый ЧтениеXML; + Чтение.ОткрытьФайл(ИмяФайлаШаблона); + + ДанныеШаблона = ШаблоныБазовый.КорневойЭлемент(); + + Пока Чтение.Прочитать() Цикл + + Если Чтение.Имя = "template" И Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда + + Если Чтение.ЗначениеАтрибута("deleted") <> "false" ИЛИ Чтение.ЗначениеАтрибута("enabled") <> "true" Тогда + + Продолжить; + + КонецЕсли; + + Элемент = ШаблоныБазовый.Элемент(); + Элемент.Наименование = Чтение.ЗначениеАтрибута("description"); + Элемент.ТекстЗамены = Чтение.ЗначениеАтрибута("name"); + Элемент.Наименование = Чтение.ЗначениеАтрибута("description"); + + Чтение.Прочитать(); + + Если РазбиратьБлокиПодстановки Тогда + Элемент.Шаблон = ПрочитатьСтруктуруТекстаШаблона(Чтение.Значение, 1, Ложь); + Иначе + Элемент.Шаблон = Чтение.Значение; + КонецЕсли; + + ДанныеШаблона.Элементы.Добавить(Элемент); + + КонецЕсли; + + КонецЦикла; + + Чтение.Закрыть(); + + Возврат ДанныеШаблона; + +КонецФункции + +// Сохраняет шаблон в файл +// +// Параметры: +// Шаблон - Структура - Данные шаблона +// ИмяФайла - Строка - Имя файла шаблона +// +Процедура ЗаписатьШаблон(Шаблон, ИмяФайла) Экспорт + + Запись = Новый ЗаписьXML(); + Запись.ОткрытьФайл(ИмяФайла); + + Запись.ЗаписатьОбъявлениеXML(); + Запись.ЗаписатьНачалоЭлемента("templates"); + + РекурсивнаяЗаписьДереваШаблонов(Шаблон, Запись); + Запись.ЗаписатьКонецЭлемента(); + Запись.Закрыть(); + +КонецПроцедуры + +// Возвращает список поддерживаемых типов блоков подстановки +// +// Возвращаемое значение: +// Массив - Массив строка, элементов перечисления ТипПодстановки +// +Функция ДоступныеТипыПодстановок() Экспорт + + ДоступныеТипыПодстановок = Новый Массив(); + + ДоступныеТипыПодстановок.Добавить(ТипПодстановки.УстановкаКурсора); + ДоступныеТипыПодстановок.Добавить(ТипПодстановки.ДатаВремя); + + Возврат ДоступныеТипыПодстановок; + +КонецФункции + +/////////////////////////////////////////////////////////////////// +// Служебный функционал +/////////////////////////////////////////////////////////////////// + +// Чтение + +Функция ПрочитатьСтруктуруТекстаШаблона(Текст, Позиция, ЧитаемВложенныйЭлемент = Ложь) + + ПараметрыЧтения = Новый Структура(); + ПараметрыЧтения.Вставить("КавычкаОткрыта", Ложь); + ПараметрыЧтения.Вставить("БлокЗамены", ЧитаемВложенныйЭлемент); + ПредыдущийСимвол = ""; + + ТекущаяСтрока = ""; + + Данные = Новый Массив(); + + ДлиннаСтроки = СтрДлина(Текст); + + Пока Позиция <= ДлиннаСтроки Цикл + + Символ = Сред(Текст, Позиция, 1); + Позиция = Позиция + 1; + + Если Символ = Неопределено Тогда + Прервать; + КонецЕсли; + + СимволОбработан = Ложь; + + Если Символ = "{" И ПредыдущийСимвол = "$" Тогда + + ТекущаяСтрока = Лев(ТекущаяСтрока, СтрДлина(ТекущаяСтрока) - 1); + Данные.Добавить(?(ПараметрыЧтения.БлокЗамены, СокрЛП(ТекущаяСтрока), ТекущаяСтрока)); + ТекущаяСтрока = ""; + + СимволОбработан = Истина; + ВложенныйЭлемент = ПрочитатьСтруктуруТекстаШаблона(Текст, Позиция, Истина); + Данные.Добавить(ВложенныйЭлемент); + + ИначеЕсли Символ = "}" И ПараметрыЧтения.БлокЗамены Тогда + + Если ЗначениеЗаполнено(ТекущаяСтрока) Тогда + Данные.Добавить(?(ПараметрыЧтения.БлокЗамены, СокрЛП(ТекущаяСтрока), ТекущаяСтрока)); + КонецЕсли; + + СимволОбработан = Истина; + ПараметрыУправляющейКонструкции1с = ПрочитатьПараметрыПодстановки(Данные); + Возврат ПараметрыУправляющейКонструкции1с; + + ИначеЕсли Символ = "," И ПараметрыЧтения.БлокЗамены И НЕ ПараметрыЧтения.КавычкаОткрыта Тогда + + Данные.Добавить(?(ПараметрыЧтения.БлокЗамены, СокрЛП(ТекущаяСтрока), ТекущаяСтрока)); + ТекущаяСтрока = ""; + СимволОбработан = Истина; + + ИначеЕсли Символ = """" И ПредыдущийСимвол <> "\" Тогда + + ПараметрыЧтения.КавычкаОткрыта = НЕ ПараметрыЧтения.КавычкаОткрыта; + + КонецЕсли; + + Если Не СимволОбработан Тогда + + ТекущаяСтрока = ТекущаяСтрока + Символ; + + КонецЕсли; + + ПредыдущийСимвол = Символ; + + КонецЦикла; + + Если ЗначениеЗаполнено(ТекущаяСтрока) Тогда + Данные.Добавить(?(ПараметрыЧтения.БлокЗамены, СокрЛП(ТекущаяСтрока), ТекущаяСтрока)); + КонецЕсли; + + Возврат Данные; + +КонецФункции + +Функция ПрочитатьПараметрыПодстановки(Данные) + + Параметры = Новый Структура("Тип", ТипПодстановки.Неизвестный); + + Если Данные.Количество() = 0 Тогда + + Возврат Параметры; + + КонецЕсли; + + ИмяТип = Данные[0]; + + СоответствиеТипов = Новый Соответствие(); + СоответствиеТипов.Вставить("date", ТипПодстановки.ДатаВремя); + + Если СтрНайти(ИмяТип, ":") Тогда + + Слова = Утилиты.ПолучитьСлова(ИмяТип, Истина); + + Имя = Слова[0].Слово; + Тип = Слова[1].Слово; + + Если СоответствиеТипов[Тип] <> Неопределено Тогда + Тип = СоответствиеТипов[Тип]; + КонецЕсли; + + Параметры.Тип = Тип; + Параметры.Вставить("Подсказка", Имя); + + Аргументы = Сред(ИмяТип, Слова[1].Окончание + 1); + + Иначе + + Тип = СоответствиеТипов[ИмяТип]; + + Если Тип = Неопределено Тогда + + Параметры.Тип = ТипПодстановки.УстановкаКурсора; + Параметры.Вставить("Подсказка", ИмяТип); + + Иначе + + Параметры.Тип = Тип; + + КонецЕсли; + + Аргументы = ""; + + КонецЕсли; + + Если Параметры.Тип = ТипПодстановки.ДатаВремя Тогда + + Параметры.Вставить("Формат", Утилиты.УдалитьСимволыВНачалеИКонце(Аргументы, "()")); + + КонецЕсли; + + Возврат Параметры; + +КонецФункции + +// Запись + +Процедура РекурсивнаяЗаписьДереваШаблонов(Шаблон, Запись) + + Для Каждого Элемент Из Шаблон.Элементы Цикл + + Если Элемент.Тип = "Группа" Тогда + + РекурсивнаяЗаписьДереваШаблонов(Элемент, Запись); + Продолжить; + + КонецЕсли; + + Запись.ЗаписатьНачалоЭлемента("template"); + Запись.ЗаписатьАтрибут("autoinsert", "true"); + Запись.ЗаписатьАтрибут("context", "com._1c.g5.v8.dt.bsl.Bsl.AddHandlerStatement"); + Запись.ЗаписатьАтрибут("deleted", "false"); + Запись.ЗаписатьАтрибут("description", Элемент.Наименование); + Запись.ЗаписатьАтрибут("enabled", "true"); + Запись.ЗаписатьАтрибут("name", Элемент.ТекстЗамены); + Запись.ЗаписатьТекст(СобратьТекстШаблона(Элемент.Шаблон)); + + Запись.ЗаписатьКонецЭлемента(); + + КонецЦикла; + +КонецПроцедуры + +Функция СобратьТекстШаблона(ДанныеШаблона) + + Если ТипЗнч(ДанныеШаблона) = Тип("Строка") Тогда + + Возврат ДанныеШаблона; + + КонецЕсли; + + Вывод = Новый ЗаписьJSON(); + Вывод.УстановитьСтроку(); + НомерЭлемента = 1; + + Для Каждого Элемент Из ДанныеШаблона Цикл + + Если ТипЗнч(Элемент) = Тип("Строка") Тогда + + Вывод.ЗаписатьБезОбработки(Элемент); + Продолжить; + + ИначеЕсли Элемент.Тип = ТипПодстановки.УстановкаКурсора Тогда + + Если Элемент.Свойство("Подсказка") Тогда + + Вывод.ЗаписатьБезОбработки(СтрШаблон("${%1}", Утилиты.СформироватьИдентификатор(Элемент.Подсказка))); + + Иначе + + Вывод.ЗаписатьБезОбработки("${cursor}"); + + КонецЕсли; + + ИначеЕсли Элемент.Тип = ТипПодстановки.ДатаВремя Тогда + + Если Элемент.Свойство("Подсказка") Тогда + + Вывод.ЗаписатьБезОбработки(СтрШаблон("${%1:date(%2)}", Утилиты.СформироватьИдентификатор(Элемент.Подсказка), Элемент.Формат)); + + Иначе + + Вывод.ЗаписатьБезОбработки(СтрШаблон("${n%1:date(%2)}", НомерЭлемента, Элемент.Формат)); + + КонецЕсли; + + КонецЕсли; + + НомерЭлемента = НомерЭлемента + 1; + + КонецЦикла; + + Возврат Вывод.Закрыть(); + +КонецФункции diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213VSCode.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213VSCode.os" new file mode 100644 index 0000000..ba9d282 --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213VSCode.os" @@ -0,0 +1,208 @@ +/////////////////////////////////////////////////////////////////// +// +// Методы работы с шаблонами VS Code +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + +// Некоторые описание шаблонов VS code https://github.com/1c-syntax/vsc-language-1c-bsl/wiki/Динамические-шаблоны + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Считывает шаблон кода в структуру +// +// Параметры: +// ИмяФайлаШаблона - Строка - Имя файла шаблона +// РазбиратьБлокиПодстановки - Булево - Выполнять ли разбор текста шаблона +// Если выполняется объединение/разделение без изменения типа шаблона, то рекомендуется не выполнять анализ текста шаблона +// +// Возвращаемое значение: +// Структура - Данные шаблона +// Тип - ТИп узла шаблона +// Наименование - имя узла +// Значения - подчиненные узлы +// +Функция ПрочитатьШаблон(ИмяФайла, РазбиратьБлокиПодстановки = Истина) Экспорт + + ВызватьИсключение "Метод не поддерживается"; + +КонецФункции + +// Сохраняет шаблон в файл +// +// Параметры: +// Шаблон - Структура - Данные шаблона +// ИмяФайла - Строка - Имя файла шаблона +// +Процедура ЗаписатьШаблон(Шаблон, ИмяФайла) Экспорт + + ВставлятьИдентификаторЯзыка = (Новый Файл(ИмяФайла)).Расширение = ".code-snippets"; + + ДанныеДляЗаписи = СформироватьОбъектШаблона(Шаблон, ВставлятьИдентификаторЯзыка); + + Запись = Новый ЗаписьJSON(); + Запись.ОткрытьФайл(ИмяФайла); + + ЗаписатьJSON(Запись, ДанныеДляЗаписи); + + Запись.Закрыть(); + +КонецПроцедуры + +// Возвращает список поддерживаемых типов блоков подстановки +// +// Возвращаемое значение: +// Массив - Массив строка, элементов перечисления ТипПодстановки +// +Функция ДоступныеТипыПодстановок() Экспорт + + ДоступныеТипыПодстановок = Новый Массив(); + + ДоступныеТипыПодстановок.Добавить(ТипПодстановки.УстановкаКурсора); + ДоступныеТипыПодстановок.Добавить(ТипПодстановки.ВыборВарианта); + ДоступныеТипыПодстановок.Добавить(ТипПодстановки.ДатаВремя); + + Возврат ДоступныеТипыПодстановок; + +КонецФункции + +/////////////////////////////////////////////////////////////////// +// Служебный функционал +/////////////////////////////////////////////////////////////////// + +Функция СформироватьОбъектШаблона(Шаблон, ВставлятьИдентификаторЯзыка, ШаблонVSCode = Неопределено) + + Если ШаблонVSCode = Неопределено Тогда + + ШаблонVSCode = Новый Соответствие(); + + КонецЕсли; + + Для Каждого Элемент Из Шаблон.Элементы Цикл + + Если Элемент.Тип = "Группа" Тогда + + СформироватьОбъектШаблона(Элемент, ВставлятьИдентификаторЯзыка, ШаблонVSCode); + Продолжить; + + КонецЕсли; + + ЭлементШаблона = Новый Структура(); + ЭлементШаблона.Вставить("prefix", Элемент.ТекстЗамены); + ЭлементШаблона.Вставить("body", СобратьТекстШаблона(Элемент.Шаблон)); + ЭлементШаблона.Вставить("description", Элемент.Наименование); + + Если ВставлятьИдентификаторЯзыка Тогда + + ЭлементШаблона.Вставить("scope", "bsl"); + + КонецЕсли; + + ШаблонVSCode.Вставить(Элемент.Наименование, ЭлементШаблона); + + КонецЦикла; + + Возврат ШаблонVSCode; + +КонецФункции + +Функция СобратьТекстШаблона(ДанныеШаблона) + + Параметры = Новый Структура("Номер", 1); + + Вывод = Новый ЗаписьJSON(); + Вывод.УстановитьСтроку(); + + Для Каждого Элемент Из ДанныеШаблона Цикл + + Если ТипЗнч(Элемент) = Тип("Строка") Тогда + + Вывод.ЗаписатьБезОбработки(Элемент); + Продолжить; + + ИначеЕсли Элемент.Тип = ТипПодстановки.УстановкаКурсора Тогда + + Если Элемент.Свойство("Подсказка") Тогда + + Вывод.ЗаписатьБезОбработки(СтрШаблон("${%1:%2}", Параметры.Номер, ОбработатьКавычки(Элемент.Подсказка))); + + Иначе + + Вывод.ЗаписатьБезОбработки(СтрШаблон("$%1", Параметры.Номер)); + + КонецЕсли; + + ИначеЕсли Элемент.Тип = ТипПодстановки.ВыборВарианта Тогда + + Вывод.ЗаписатьБезОбработки(СтрШаблон("${%1|", Параметры.Номер)); + + Первый = Истина; + Для Каждого ЭлементВыбора Из Элемент.СписокВыбора Цикл + + Если Первый Тогда + Вывод.ЗаписатьБезОбработки(ОбработатьКавычки(ЭлементВыбора.Значение)); + Первый = Ложь; + Иначе + Вывод.ЗаписатьБезОбработки("," + ОбработатьКавычки(ЭлементВыбора.Значение)); + КонецЕсли; + + КонецЦикла; + + Вывод.ЗаписатьБезОбработки("|}"); + + ИначеЕсли Элемент.Тип = ТипПодстановки.ДатаВремя Тогда + + Вывод.ЗаписатьБезОбработки(ВыводТекущейДаты(Элемент.Формат)); + + КонецЕсли; + + Параметры.Номер = Параметры.Номер + 1; + + КонецЦикла; + + Возврат Вывод.Закрыть(); + +КонецФункции + +Функция ОбработатьКавычки(Знач Текст) + + Текст = СтрЗаменить(Текст, "\""", """"); + + Если Лев(Текст, 1) = """" Тогда + + Текст = Сред(Текст, 2, СтрДлина(Текст) - 1); + + КонецЕсли; + + Если Прав(Текст, 1) = """" Тогда + + Текст = Сред(Текст, 1, СтрДлина(Текст) - 1); + + КонецЕсли; + + Возврат Текст; + +КонецФункции + +Функция ВыводТекущейДаты(Формат) + + Результат = Формат; + Замены = Новый СписокЗначений(); + Замены.Добавить("dd", "CURRENT_DATE"); + Замены.Добавить("MM", "CURRENT_MONTH"); + Замены.Добавить("yyyy", "CURRENT_YEAR"); + Замены.Добавить("yyy", "CURRENT_YEAR"); + Замены.Добавить("yy", "CURRENT_YEAR_SHORT"); + + Для Каждого Элемент Из Замены Цикл + + Результат = СтрЗаменить(Результат, Элемент.Значение, "$" + Элемент.Представление); + + КонецЦикла; + + Возврат Результат; + +КонецФункции \ No newline at end of file diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\221\320\260\320\267\320\276\320\262\321\213\320\271.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\221\320\260\320\267\320\276\320\262\321\213\320\271.os" new file mode 100644 index 0000000..e06d49e --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\221\320\260\320\267\320\276\320\262\321\213\320\271.os" @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////// +// +// Базовые методы для работы с шаблонами +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Инициализирует структуру корневого элемента шаблона +// +// Возвращаемое значение: +// Структура - Описание корневого элемента +// +Функция КорневойЭлемент() Экспорт + + Возврат Новый Структура("Тип, Наименование, Элементы", "Корень", "Корень", Новый Массив()); + +КонецФункции + +// Инициализирует структуру группы шаблона +// +// Возвращаемое значение: +// Структура - Описание группы шаблона +// +Функция Группа() Экспорт + + Возврат Новый Структура("Тип, Наименование, Элементы", "Группа", "", Новый Массив()); + +КонецФункции + +// Инициализирует структуру элемента шаблона +// +// Возвращаемое значение: +// Структура - Описание элемента шаблона +// +Функция Элемент() Экспорт + + Возврат Новый Структура("Тип, Наименование, ТекстЗамены, Шаблон", "Элемент"); + +КонецФункции + +/////////////////////////////////////////////////////////////////// +// Служебный функционал +/////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" new file mode 100644 index 0000000..3d5d5af --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\250\320\260\320\261\320\273\320\276\320\275\321\213\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" @@ -0,0 +1,469 @@ +/////////////////////////////////////////////////////////////////// +// +// Методы работы с шаблонами конфигуратора +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + +#Использовать strings + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +// Считывает шаблон кода в структуру +// +// Параметры: +// ИмяФайлаШаблона - Строка - Имя файла шаблона +// РазбиратьБлокиПодстановки - Булево - Выполнять ли разбор текста шаблона +// Если выполняется объединение/разделение без изменения типа шаблона, то рекомендуется не выполнять анализ текста шаблона +// +// Возвращаемое значение: +// Структура - Данные шаблона +// Тип - ТИп узла шаблона +// Наименование - имя узла +// Значения - подчиненные узлы +// +Функция ПрочитатьШаблон(ИмяФайлаШаблона, РазбиратьБлокиПодстановки = Истина) Экспорт + + Читатель = Новый ЧтениеВнутреннийФормат1С(); + Дерево = Читатель.ПрочитатьФайл(ИмяФайлаШаблона); + + КорневойЭлемент = ШаблоныБазовый.КорневойЭлемент(); + ПрочитатьУзелШаблона(Дерево.Значения[0], КорневойЭлемент, РазбиратьБлокиПодстановки); + + Возврат КорневойЭлемент.Элементы[0]; + +КонецФункции + +// Сохраняет шаблон в файл +// +// Параметры: +// Шаблон - Структура - Данные шаблона +// ИмяФайла - Строка - Имя файла шаблона +// +Процедура ЗаписатьШаблон(Шаблон, ИмяФайла) Экспорт + + Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8); + Запись.ЗаписатьСтроку("{1,"); + + ЗаписатьГруппуШаблона(Шаблон, Запись); + + Запись.Записать(Символы.ПС + "}"); + + Запись.Закрыть(); + +КонецПроцедуры + +// Возвращает список поддерживаемых типов блоков подстановки +// +// Возвращаемое значение: +// Массив - Массив строка, элементов перечисления ТипПодстановки +// +Функция ДоступныеТипыПодстановок() Экспорт + + ДоступныеТипыПодстановок = ТипПодстановки.ВсеТипы(); + + Возврат ДоступныеТипыПодстановок; + +КонецФункции + +/////////////////////////////////////////////////////////////////// +// Служебный функционал +/////////////////////////////////////////////////////////////////// + +// Чтение + +Функция ПрочитатьУзелШаблона(Знач Элемент, Знач Родитель, РазбиратьБлокиПодстановки) + + КоллекцияЭлементов = Элемент.Значения; + + ЭтоКоллекция = Утилиты.ЭтоЧисло(КоллекцияЭлементов[0]); + ЭтоГруппа = НЕ ЭтоКоллекция И КоллекцияЭлементов[1] = "1"; + ЭтоЭлемент = НЕ ЭтоКоллекция И КоллекцияЭлементов[1] = "0"; + + Если ЭтоГруппа Тогда + + ОписаниеЭлемента = ШаблоныБазовый.Группа(); + ОписаниеЭлемента.Вставить("Наименование", ОбработатьКавычкиПриЧтении(КоллекцияЭлементов[0])); + Родитель.Элементы.Добавить(ОписаниеЭлемента); + + Возврат ОписаниеЭлемента; + + ИначеЕсли ЭтоЭлемент Тогда + + ОписаниеЭлемента = ШаблоныБазовый.Элемент(); + ОписаниеЭлемента.Наименование = ОбработатьКавычкиПриЧтении(КоллекцияЭлементов[0]); + ОписаниеЭлемента.ТекстЗамены = Утилиты.УдалитьСимволы(ОбработатьКавычкиПриЧтении(КоллекцияЭлементов[3]), "[]"); + ОписаниеЭлемента.Вставить("ТекстЗаменыБазовый", ОбработатьКавычкиПриЧтении(КоллекцияЭлементов[3])); + + Если РазбиратьБлокиПодстановки Тогда + ОписаниеЭлемента.Шаблон = ПрочитатьСтруктуруТекстаШаблона(ОбработатьКавычкиПриЧтении(КоллекцияЭлементов[4]), 1); + Иначе + ОписаниеЭлемента.Шаблон = ОбработатьКавычкиПриЧтении(КоллекцияЭлементов[4]); + КонецЕсли; + + Родитель.Элементы.Добавить(ОписаниеЭлемента); + + Возврат ОписаниеЭлемента; + + ИначеЕсли ЭтоКоллекция Тогда + + Для Инд = 1 По КоллекцияЭлементов.ВГраница() Цикл + + Элемент = ПрочитатьУзелШаблона(КоллекцияЭлементов[Инд], Родитель, РазбиратьБлокиПодстановки); + + Если Элемент <> Неопределено И Элемент.Тип = "Группа" Тогда + + Родитель = Элемент; + + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + +КонецФункции + +Функция ПрочитатьСтруктуруТекстаШаблона(Текст, Позиция, ЧитаемВложенныйЭлемент = Ложь) + + ПараметрыЧтения = Новый Структура(); + ПараметрыЧтения.Вставить("КавычкаОткрыта", Ложь); + ПараметрыЧтения.Вставить("БлокЗамены", ЧитаемВложенныйЭлемент); + ПараметрыЧтения.Вставить("ПредыдущийСимвол", ""); + + ТекущаяСтрока = ""; + + ДанныеТекстаШаблона = Новый Массив(); + ДлиннаСтроки = СтрДлина(Текст); + + Пока Позиция <= ДлиннаСтроки Цикл + + Символ = Сред(Текст, Позиция, 1); + + Позиция = Позиция + 1; + + ПараметрыСимвола = ПолучитьПараметрыСимвола(Символ, ПараметрыЧтения); + + Если ПараметрыСимвола.ФиксацияТекущейСтроки.Фиксировать Тогда + + Если ПараметрыСимвола.ФиксацияТекущейСтроки.УдалитьПрошлыйСимвол Тогда + + СтроковыеФункции.УдалитьПоследнийСимволВСтроке(ТекущаяСтрока); + + КонецЕсли; + + Если НЕ ПараметрыСимвола.ФиксацияТекущейСтроки.ПроверятьЗаполненность ИЛИ ЗначениеЗаполнено(ТекущаяСтрока) Тогда + + ДобавитьЭлементТекстаШаблон(ДанныеТекстаШаблона, ТекущаяСтрока, ПараметрыЧтения); // Фиксируем то, что было до блока + + КонецЕсли; + + ТекущаяСтрока = ""; + + КонецЕсли; + + Если ПараметрыСимвола.Тип = "НачалоБлокаПодстановки" Тогда + + ВложенныйЭлемент = ПрочитатьСтруктуруТекстаШаблона(Текст, Позиция, Истина); + ДобавитьЭлементТекстаШаблон(ДанныеТекстаШаблона, ВложенныйЭлемент, ПараметрыЧтения); + + ИначеЕсли ПараметрыСимвола.Тип = "ОкончаниеБлокаПодстановки" Тогда + + ПараметрыПодстановки = РазобратьПараметрыПодстановки(ДанныеТекстаШаблона); + Возврат ПараметрыПодстановки; + + ИначеЕсли ПараметрыСимвола.Тип = "РазделительПараметровБлока" Тогда + + ИначеЕсли ПараметрыСимвола.Тип = "Кавычка" Тогда + + ПараметрыЧтения.КавычкаОткрыта = НЕ ПараметрыЧтения.КавычкаОткрыта; + + ИначеЕсли НЕ ПараметрыСимвола.Тип = "Неизвестный" Тогда + + ВызватьИсключение "Неизвестный тип символа"; + + КонецЕсли; + + Если ПараметрыСимвола.ЗаписатьВПоток Тогда + + ТекущаяСтрока = ТекущаяСтрока + Символ; + + КонецЕсли; + + ПараметрыЧтения.ПредыдущийСимвол = Символ; + + КонецЦикла; + + Если ЗначениеЗаполнено(ТекущаяСтрока) Тогда // Фиксируем последний блок текста + + ДобавитьЭлементТекстаШаблон(ДанныеТекстаШаблона, ТекущаяСтрока, ПараметрыЧтения); + + КонецЕсли; + + Возврат ДанныеТекстаШаблона; + +КонецФункции + +Функция ПолучитьПараметрыСимвола(Символ, ПараметрыЧтения) + + Параметры = Новый Структура("Тип, ЗаписатьВПоток", "Неизвестный", Истина); + Параметры.Вставить("ФиксацияТекущейСтроки", Новый Структура("Фиксировать, ПроверятьЗаполненность, УдалитьПрошлыйСимвол", Ложь, Истина, Ложь)); + + Если Символ = "?" И ПараметрыЧтения.ПредыдущийСимвол = "<" Тогда + + Параметры.Тип = "НачалоБлокаПодстановки"; + Параметры.ЗаписатьВПоток = Ложь; + Параметры.ФиксацияТекущейСтроки.Фиксировать = Истина; + Параметры.ФиксацияТекущейСтроки.УдалитьПрошлыйСимвол = Истина; + + ИначеЕсли Символ = """" И ПараметрыЧтения.ПредыдущийСимвол <> "\" Тогда + + Параметры.Тип = "Кавычка"; + + КонецЕсли; + + Если ПараметрыЧтения.КавычкаОткрыта Тогда + Возврат Параметры; + КонецЕсли; + + Если Символ = ">" И ПараметрыЧтения.БлокЗамены Тогда // Завершение блока замены + + Параметры.Тип = "ОкончаниеБлокаПодстановки"; + Параметры.ЗаписатьВПоток = Ложь; + Параметры.ФиксацияТекущейСтроки.Фиксировать = Истина; + + ИначеЕсли Символ = "," И ПараметрыЧтения.БлокЗамены Тогда + + Параметры.Тип = "РазделительПараметровБлока"; + Параметры.ЗаписатьВПоток = Ложь; + Параметры.ФиксацияТекущейСтроки.Фиксировать = Истина; + Параметры.ФиксацияТекущейСтроки.ПроверятьЗаполненность = Ложь; + + КонецЕсли; + + Возврат Параметры; + +КонецФункции + +Процедура ДобавитьЭлементТекстаШаблон(ДанныеТекстаШаблона, Элемент, ПараметрыЧтения) + + Если ТипЗнч(Элемент) = Тип("Структура") Тогда + + ДанныеТекстаШаблона.Добавить(Элемент); + + ИначеЕсли НЕ ПараметрыЧтения.БлокЗамены Тогда + + ДанныеТекстаШаблона.Добавить(Элемент); + + Иначе + + ДанныеТекстаШаблона.Добавить(СокрЛП(Элемент)); + + КонецЕсли; + +КонецПроцедуры + +Функция РазобратьПараметрыПодстановки(Данные) + + Параметры = Новый Структура("Тип", ТипПодстановки.Неизвестный); + КоличествоЭлементов = Данные.Количество(); + + Если КоличествоЭлементов = 0 Тогда // Пустой блок подстановки - установка курсора + + Параметры.Тип = ТипПодстановки.УстановкаКурсора; + Возврат Параметры; + + КонецЕсли; + + Параметры.Вставить("Подсказка", Данные[0]); + + Если КоличествоЭлементов = 1 Тогда + + Параметры.Тип = ТипПодстановки.УстановкаКурсора; + Возврат Параметры; + + КонецЕсли; + + Тип = Данные[1]; + + Если Тип = "ВыборВарианта" Тогда + + Параметры.Тип = ТипПодстановки.ВыборВарианта; + + Параметры.Вставить("СписокВыбора", Новый СписокЗначений()); + Для Инд = 2 По КоличествоЭлементов - 1 Цикл + + Параметры.СписокВыбора.Добавить(Данные[Инд + 1], Данные[Инд]); + Инд = Инд + 1; + + КонецЦикла; + + ИначеЕсли Тип = "ДатаВремя" Тогда + + Параметры.Тип = ТипПодстановки.ДатаВремя; + Формат = Данные[2]; + ПозРавно = СтрНайти(Формат, "="); + + Если ПозРавно Тогда + ПозТчкЗпт = СтрНайти(Формат, ";", , ПозРавно); + ПозТчкЗпт = ?(ПозТчкЗпт = 0, СтрДлина(Формат), ПозТчкЗпт); + Формат = Сред(Формат, ПозРавно + 1, ПозТчкЗпт - ПозРавно - 1); + КонецЕсли; + + Параметры.Вставить("Формат", Формат); + + Иначе + + Параметры.Тип = Тип; + + КонецЕсли; + + Возврат Параметры; + +КонецФункции + +Функция ОбработатьКавычкиПриЧтении(Знач Текст) + + Текст = СтрЗаменить(Текст, """""", """"); + + Если Лев(Текст, 1) = """" Тогда + + Текст = Сред(Текст, 2, СтрДлина(Текст) - 1); + + КонецЕсли; + + Если Прав(Текст, 1) = """" Тогда + + Текст = Сред(Текст, 1, СтрДлина(Текст) - 1); + + КонецЕсли; + + Возврат Текст; + +КонецФункции + +// Запись + +Процедура ЗаписатьГруппуШаблона(Данные, Запись) + + // запишем начало блока + количество дочерних элементов + Запись.ЗаписатьСтроку(СтрШаблон( + "{%1,", Данные.Элементы.Количество())); + + ЗаписатьЗаголовокГруппы(Данные, Запись); // Заголовок блока + + Для Индекс = 0 По Данные.Элементы.ВГраница() Цикл + + Элемент = Данные.Элементы[Индекс]; + + Запись.ЗаписатьСтроку(","); + + Если Элемент.Тип = "Группа" Тогда + + ЗаписатьГруппуШаблона(Элемент, Запись); + + Иначе // Элемент + + ЗаписатьЭлементШаблона(Элемент, Запись); + + КонецЕсли; + + КонецЦикла; + + Запись.ЗаписатьСтроку(""); + Запись.Записать("}"); // Конец блока + +КонецПроцедуры + +Процедура ЗаписатьЗаголовокГруппы(ОписаниеГруппы, Запись) + + Запись.Записать(СтрШаблон("{""%1"",1,0,"""",""""}", ОписаниеГруппы.Наименование)); + +КонецПроцедуры + +Процедура ЗаписатьЭлементШаблона(ОписаниеЭлемента, Запись) + + Запись.ЗаписатьСтроку("{0,"); + + Если ОписаниеЭлемента.Свойство("ТекстЗаменыБазовый") И ЗначениеЗаполнено(ОписаниеЭлемента.ТекстЗаменыБазовый) Тогда + ТекстЗамены = ОписаниеЭлемента.ТекстЗаменыБазовый; + ИначеЕсли СтрНайти(ОписаниеЭлемента.ТекстЗамены, "[") Тогда + ТекстЗамены = ОписаниеЭлемента.ТекстЗамены; + Иначе + ТекстЗамены = СтрШаблон("%1[%2]", Лев(ОписаниеЭлемента.ТекстЗамены, 1), Сред(ОписаниеЭлемента.ТекстЗамены, 2)); + КонецЕсли; + + ТелоШаблон = СобратьТекстШаблона(ОписаниеЭлемента.Шаблон); + + Запись.Записать(СтрШаблон("{""%1"",0,0,""%2"",""%3""}", ОписаниеЭлемента.Наименование, ТекстЗамены, ТелоШаблон)); + + Запись.ЗаписатьСтроку(""); + Запись.Записать("}"); + +КонецПроцедуры + +Функция СобратьТекстШаблона(ДанныеШаблона) + + Если ТипЗнч(ДанныеШаблона) = Тип("Строка") Тогда + + Возврат ОбработатьКавычкиПриЗаписи(ДанныеШаблона); + + КонецЕсли; + + Вывод = Новый ЗаписьJSON(); + Вывод.УстановитьСтроку(); + + Для Каждого Элемент Из ДанныеШаблона Цикл + + Если ТипЗнч(Элемент) = Тип("Строка") Тогда + Вывод.ЗаписатьБезОбработки(ОбработатьКавычкиПриЗаписи(Элемент)); + Продолжить; + КонецЕсли; + + Вывод.ЗаписатьБезОбработки(""); + + КонецЦикла; + + Возврат Вывод.Закрыть(); + +КонецФункции + +Функция ОбработатьКавычкиПриЗаписи(Текст) + + Текст = СтрЗаменить(Текст, """", """"""); + + Возврат Текст; + +КонецФункции diff --git a/tasks/test-feature.os b/tasks/test-feature.os new file mode 100644 index 0000000..ece94e0 --- /dev/null +++ b/tasks/test-feature.os @@ -0,0 +1,18 @@ +#Использовать ".." +#Использовать 1bdd + +КаталогФич = ОбъединитьПути(".", "features"); +ПутьФичи = ОбъединитьПути(".", "features", АргументыКоманднойСтроки[0]); +Файл_КаталогФич = Новый Файл(КаталогФич); +ФайлФичи = Новый Файл(ПутьФичи); + +ИсполнительБДД = Новый ИсполнительБДД; +РезультатВыполнения = ИсполнительБДД.ВыполнитьФичу(ФайлФичи, Файл_КаталогФич); +ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатВыполнения); + +Сообщить(ИтоговыйРезультатВыполнения); +Если ИтоговыйРезультатВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался Тогда + + ВызватьИсключение 1; + +КонецЕсли; diff --git a/tasks/test.os b/tasks/test.os new file mode 100644 index 0000000..0576ba5 --- /dev/null +++ b/tasks/test.os @@ -0,0 +1,82 @@ +#Использовать "../src" +#Использовать 1bdd +#Использовать 1testrunner + +Функция ПрогнатьТесты() + + Тестер = Новый Тестер; + + ПутьКТестам = ОбъединитьПути(ТекущийСценарий().Каталог, "..", "tests"); + ПутьКОтчетуJUnit = ОбъединитьПути(ТекущийСценарий().Каталог, ".."); + + КаталогТестов = Новый Файл(ПутьКТестам); + Если Не КаталогТестов.Существует() Тогда + Сообщить(СтрШаблон("Не найден каталог тестов %1", ПутьКТестам)); + Возврат Истина; + КонецЕсли; + + РезультатТестирования = Тестер.ТестироватьКаталог( + КаталогТестов, + Новый Файл(ПутьКОтчетуJUnit) + ); + + Успешно = РезультатТестирования = 0; + + Возврат Успешно; +КонецФункции // ПрогнатьТесты() + +Функция ПрогнатьФичи() + + ПутьОтчетаJUnit = "./bdd-log.xml"; + + КаталогФич = ОбъединитьПути(".", "features"); + + Файл_КаталогФич = Новый Файл(КаталогФич); + Если Не Файл_КаталогФич.Существует() Тогда + Сообщить(СтрШаблон("Не найден каталог фич %1", КаталогФич)); + Возврат Истина; + КонецЕсли; + + ИсполнительБДД = Новый ИсполнительБДД; + РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(Файл_КаталогФич, Файл_КаталогФич); + ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); + + СтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся; + Если РезультатыВыполнения.Строки.Количество() > 0 Тогда + + СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); + + КонецЕсли; + + ГенераторОтчетаJUnit = Новый ГенераторОтчетаJUnit; + ГенераторОтчетаJUnit.Сформировать(РезультатыВыполнения, СтатусВыполнения, ПутьОтчетаJUnit); + + Сообщить(СтрШаблон("Результат прогона фич <%1> + |", ИтоговыйРезультатВыполнения)); + + Возврат ИтоговыйРезультатВыполнения <> ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался; +КонецФункции // ПрогнатьФичи() + +Попытка + ТестыПрошли = ПрогнатьТесты(); + +Исключение + ТестыПрошли = Ложь; + Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно + |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); +КонецПопытки; + +Попытка + ФичиПрошли = ПрогнатьФичи(); +Исключение + ФичиПрошли = Ложь; + Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно + |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); +КонецПопытки; + +Если Не ТестыПрошли Или Не ФичиПрошли Тогда + ВызватьИсключение "Тестирование завершилось неудачно!"; +Иначе + Сообщить(СтрШаблон("Результат прогона тестов <%1> + |", ТестыПрошли)); +КонецЕсли; diff --git "a/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275EDT.xml" "b/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275EDT.xml" new file mode 100644 index 0000000..a2424aa --- /dev/null +++ "b/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275EDT.xml" @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git "a/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.st" "b/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.st" new file mode 100644 index 0000000..1d87256 --- /dev/null +++ "b/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.st" @@ -0,0 +1,85 @@ +{1, +{3, +{"Тест",1,0,"",""}, +{0, +{"Общий модуль",0,0,"Модуль[Общий]","//⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟ ⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪ ⇫ ⇬ ⇭ ⇮ ⇯ ⇰ ⇱ ⇲ ⇳ ⇴ ⇵ ⇶ ⇷ ⇸ ⇹ ⇺ // +// +// © ООО ""Моя компания"" (My company). 1234-5678. +// Все права защищены. +// +// Все торговые марки являются собственностью их правообладателей. +// +// Настоящий результат интеллектуальной деятельности является собственностью +// ООО ""Моя компания"" (UID 337c95d2-d846-4822-8cb4-79abc804dd95), и только +// ее, а не кого-то иного. +// +// Любые действия (бездействие, наплевательского отношение, порча имущества), +// направленные на использование (неиспользование, отрицание) настоящего +// результата интеллектуальной (и не очень) деятельности, включая +// (но не ограничиваясь) изучение, исследование, курение, медитацию, поиск кошек +// в темной комнате, испытание его функционирования; воспроизводство +// и преобразование объектного кода в исходный текст (это так юридически +// зовется декомпилирование); смотрение и использование; еще какой-то бред; +// результата интеллектуальной деятельности с иным программным обеспечением, +// возможны только с предварительного согласия правообладателя (побожиться). +// +// Нарушение прав ООО ""Моя компания"" на данный результат интеллектуальной +// деятельности будет преследоваться и пресекаться правообладателем +// в соответствии с законом, а если не получится, то караться в соответствии с +// моральными принципами и устоями конкретного безумца. +// +//ℋ ℌ ℍ ℎ ℏ ℐ ℑ ℒ ℓ ℔ ℕ № ℗ ℘ ℙ ℚ ℛ ℜ ℝ ℞ ℟ ℠ ℡ ™ ℣ ℤ ℥ Ω ℧ ℨ ℩ K Å ℬ ℭ ℮ ℯ ℰ ℱ// + +///////////////////////////////////////////////////////////////////////////////// +// ""> +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// Экспортные процедуры и функции, предназначенные для использования другими +// объектами конфигурации или другими программами +///////////////////////////////////////////////////////////////////////////////// + +#Область ПрограммныйИнтерфейс + +#КонецОбласти + +///////////////////////////////////////////////////////////////////////////////// +// Экспортные процедуры и функции для служебного использования внутри подсистемы +///////////////////////////////////////////////////////////////////////////////// + +#Область СлужебныйПрограммныйИнтерфейс + +#КонецОбласти + +///////////////////////////////////////////////////////////////////////////////// +// Процедуры и функции, составляющие внутреннюю реализацию модуля +///////////////////////////////////////////////////////////////////////////////// + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти + "} +}, +{2, +{"Группа",1,0,"",""}, +{0, +{"DEPRECATED",0,0,"Запре[титьИспользование]","#Если НЕ ВебКлиент Тогда + Выполнить(СервисныйОбщегоНазначенияПовтИсп.ЗапретитьИспользованиеФункционала( + """", // Запрещенный функционал, метод + """", // Функционал для замены + """", // Комментарий / пояснение + , // Дата запрета в тестовой + ) // Дата запрета в рабочей + ); +#КонецЕсли "} +}, +{0, +{"Инкремент",0,0,"++"," = + 1;"} +} +}, +{0, +{"Пустая группа",1,0,"",""} +} +} +} \ No newline at end of file diff --git "a/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260\320\241\320\235\320\265\320\277\320\276\320\264\320\264\320\265\321\200\320\266\320\270\320\262\320\260\320\265\320\274\321\213\320\274\320\270\320\242\320\270\320\277\320\260\320\274\320\270.st" "b/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260\320\241\320\235\320\265\320\277\320\276\320\264\320\264\320\265\321\200\320\266\320\270\320\262\320\260\320\265\320\274\321\213\320\274\320\270\320\242\320\270\320\277\320\260\320\274\320\270.st" new file mode 100644 index 0000000..9e89a49 --- /dev/null +++ "b/tests/fixtures/snippets/\320\250\320\260\320\261\320\273\320\276\320\275\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260\320\241\320\235\320\265\320\277\320\276\320\264\320\264\320\265\321\200\320\266\320\270\320\262\320\260\320\265\320\274\321\213\320\274\320\270\320\242\320\270\320\277\320\260\320\274\320\270.st" @@ -0,0 +1,18 @@ +{1, +{3, +{"ЧастичноПоддерживаемыйФункционал",1,0,"",""}, +{0, +{"#Если",0,0,"№Ес[ли]","#Если Тогда + + + +#КонецЕсли"} +}, +{0, +{"Формат",0,0,"Формат","Формат(, """")"} +}, +{0, +{"УстановитьЗначениеКонстанты",0,0,"УстановитьЗнач[ениеКонстанты]","ОбщегоНазначенияСервер.УстановитьЗначениеКонстанты("""", );"} +} +} +} \ No newline at end of file diff --git "a/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" "b/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" new file mode 100644 index 0000000..34ed8e3 --- /dev/null +++ "b/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" @@ -0,0 +1,133 @@ +/////////////////////////////////////////////////////////////////// +// +// Тестирование основной функциональности пакета +// Проверка на соответствие выгрузки эталону +// +// (с) BIA Technologies, LLC +// +/////////////////////////////////////////////////////////////////// + +#Использовать asserts +#Использовать tempfiles +#Использовать ".." + +/////////////////////////////////////////////////////////////////// + +Перем МенеджерВременныхФайлов; + +/////////////////////////////////////////////////////////////////// +// Программный интерфейс +/////////////////////////////////////////////////////////////////// + +Функция ПолучитьСписокТестов(Знач ЮнитТестирование) Экспорт + + МассивТестов = Новый Массив; + МассивТестов.Добавить("ТестПрочитатьШаблон"); + МассивТестов.Добавить("ТестЗаписатьШаблон"); + МассивТестов.Добавить("ТестПрочитатьИЗаписатьШаблон"); + + Возврат МассивТестов; + +КонецФункции + +Процедура ПередЗапускомТеста() Экспорт + + МенеджерВременныхФайлов = Новый МенеджерВременныхФайлов; + +КонецПроцедуры + +Процедура ПослеЗапускаТеста() Экспорт + + МенеджерВременныхФайлов.Удалить(); + +КонецПроцедуры + +/////////////////////////////////////////////////////////////////// +// Шаги +/////////////////////////////////////////////////////////////////// + +Процедура ТестПрочитатьШаблон() Экспорт + + Шаблон = ШаблоныКонфигуратора.ПрочитатьШаблон(ОбъединитьПути(КаталогФикстур(), "snippets", "ШаблонКонфигуратора.st")); + + Утверждения.ПроверитьРавенство(Шаблон.Элементы.Количество(), 3, "Количество элементов шаблона равно 3"); + +КонецПроцедуры + +Процедура ТестЗаписатьШаблон() Экспорт + + Шаблон = ШаблоныБазовый.КорневойЭлемент(); + + Группа = ШаблоныБазовый.Группа(); + Группа.Наименование = "Группа"; + Шаблон.Элементы.Добавить(Группа); + + Элемент = ШаблоныБазовый.Элемент(); + Элемент.Наименование = "Сообщить"; + Элемент.ТекстЗамены = "Соо[бщить]"; + Элемент.Шаблон = "Сообщить();"; + Шаблон.Элементы.Добавить(Элемент); + + Элемент = ШаблоныБазовый.Элемент(); + Элемент.Наименование = "Сообщить2"; + Элемент.ТекстЗамены = "Соо[бщить2]"; + Элемент.Шаблон = "Сообщить(2);"; + Группа.Элементы.Добавить(Элемент); + + ИмяФайла = МенеджерВременныхФайлов.НовоеИмяФайла("st"); + ШаблоныКонфигуратора.ЗаписатьШаблон(Шаблон, ИмяФайла); + + ТекстФайла = ПрочитатьФайл(ИмяФайла); + + Эталон = + "{1, + |{2, + |{""Корень"",1,0,"""",""""}, + |{1, + |{""Группа"",1,0,"""",""""}, + |{0, + |{""Сообщить2"",0,0,""Соо[бщить2]"",""Сообщить(2);""} + |} + |}, + |{0, + |{""Сообщить"",0,0,""Соо[бщить]"",""Сообщить();""} + |} + |} + |}"; + Утверждения.ПроверитьРавенство(ТекстФайла, Эталон, "Текст шаблона не соответствует ожидаемому"); + +КонецПроцедуры + +Процедура ТестПрочитатьИЗаписатьШаблон() Экспорт + + ИмяБазовогоШаблона = ОбъединитьПути(КаталогФикстур(), "snippets", "ШаблонКонфигуратора.st"); + ИмяНовогоШаблона = МенеджерВременныхФайлов.НовоеИмяФайла("st"); + + Шаблон = ШаблоныКонфигуратора.ПрочитатьШаблон(ИмяБазовогоШаблона); + + ШаблоныКонфигуратора.ЗаписатьШаблон(Шаблон, ИмяНовогоШаблона); + + Утверждения.ПроверитьРавенство(ПрочитатьФайл(ИмяБазовогоШаблона), ПрочитатьФайл(ИмяНовогоШаблона), "Текст шаблона не должен измениться"); + +КонецПроцедуры + +/////////////////////////////////////////////////////////////////// +// Служебный функционал +/////////////////////////////////////////////////////////////////// + +Функция КаталогФикстур() + + Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "..", "tests", "fixtures"); + +КонецФункции + +Функция ПрочитатьФайл(Файл) + + Чтение = Новый ЧтениеТекста(Файл, КодировкаТекста.UTF8NoBOM); + Текст = Чтение.Прочитать(); + Чтение.Закрыть(); + + Возврат Текст; + +КонецФункции + diff --git "a/\320\237\320\276\320\264\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.md" "b/\320\237\320\276\320\264\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.md" new file mode 100644 index 0000000..aaa1574 --- /dev/null +++ "b/\320\237\320\276\320\264\320\272\320\273\321\216\321\207\320\265\320\275\320\270\320\265\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262.md" @@ -0,0 +1,76 @@ +# Инструкция по подключению шаблонов кода + +## Подключение к VS Code + +Есть несколько вариантов подключения шаблонов(фрагментов) кода к VS Code + +1. Редактирования файла шаблонов конкретного языка, для 1c это файл bsl.json + Для этого необходимо выполнить команду (нажав Ctrl+P) "Настроить пользовательские фрагменты кода" и выбрав в списке языков "BSL" + +2. Создание глобальных файлов шаблонов, которые могут в себя включать различные языки. + Для этого необходимо выполнить команду (нажав Ctrl+P) "Настроить пользовательские фрагменты кода" и выбрать "Новый файл с глобальным фрагментом кода" + +3. Можно руками создавать файлы с расширением "code-snippets" в каталоге "%appdata%\Code\User\snippets", это эквивалентно второму варианту. + +Основное отличие первого и второго вариантов в том, что по первому варианту может быть только один файл. Для второго - множество, но в нем придется указывать язык для каждого шаблона замены для какого он языка. +Третий - тоже самое, что и второй, но руками. + +### Как писать шаблоны VSCode + +Шаблон - это JSON файл. +Он не поддерживает иерархии и групп. +Все шаблоны - это свойства корневого элемента. + +* Имя свойства - имя шаблона, должно быть уникальным. +* prefix - заменяемая строка +* body - тело шаблона +* description - описание шаблона, отображается если заполнено и не равно имени + +```json +{ + "DEPRECATED": { + "prefix": "ЗапретитьИспользование", + "body": "#Если НЕ ВебКлиент Тогда\n\tВыполнить(СервисныйОбщегоНазначенияПовтИсп.ЗапретитьИспользованиеФункционала(\n\t\t\"${1:Запрещенный функционал, метод}\", \/\/ Запрещенный функционал, метод\n\t\t\"${2:Функционал для замены (необязательно)}\", \/\/ Функционал для замены\n\t\t\"${3:Комментарий \/ пояснение (необязательно)}\", \/\/ Комментарий \/ пояснение\n\t\t${4:Дата запрета в тестовой (необязательно, вид Дата(ГГГГ, ММ, ДД))}, \/\/ Дата запрета в тестовой\n\t\t${5:Дата запрета в рабочей (необязательно, вид Дата(ГГГГ, ММ, ДД))}) \/\/ Дата запрета в рабочей\n\t\t);\n#КонецЕсли ", + "description": "DEPRECATED" + }, + "Инкремент": { + "prefix": "++", + "body": "${1:Операнд} = ${2:Операнд} + 1;", + "description": "Инкремент" + } +} +``` + +В поле `body` (тело шаблона) можно использовать подстановочные символы + +* $1, $2... - места остановки для ввода текста +* $0 - установка курсора по окончании ввода шаблона +* ${1:Операнд} - места остановки для ввода текста со значением по умолчанию + +Например `Сообщить("${1:Тест сообщения}");` +Для ввода многострочного шаблона необходимо использовать спецсимволы `\n`, либо оформлять тело как массив строк. + +Также можно использовать шаблон выбора и различные переменные, подробнее [здесь](https://code.visualstudio.com/docs/editor/userdefinedsnippets) + +## Подключение шаблонов EDT + +Заходим в настройки шаблонов: + +1. Меню → Окно → Параметры → V8 → Встроенный язык → Макеты +2. Быстрый доступ (Ctrl+3), набираем "параметры макеты" + +Откроется окно работы с шаблонами. В нем есть возможность создавать новые, редактировать существующие и импортировать шаблоны + +### Создание + +1. Нажимаем создать +2. Не меняем поле контекст! +3. Указываем имя, оно будет использоваться для поиска шаблона +4. Заполняем описание +5. Заполняем поле шаблон + +В тексте шаблона можно использовать подстановочные символы + +* ${} - места остановки для ввода текста +* ${имя_переменной} - места остановки для ввода текста, имя переменной является значение по-умолчанию, также если в шаблоне переменная используется несколько раз, то значение будет установлено для всех мест +* ${cursor} - установка курсора по окончании ввода шаблона From 6c52c39bd577b4445ba79f259e892584d33d3391 Mon Sep 17 00:00:00 2001 From: Maxmov Valery Date: Fri, 5 Apr 2019 19:16:24 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BF=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B8=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D0=B8=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\320\260\320\261\320\273\320\276\320\275\320\260.feature" | 2 +- ...0\321\202\320\260\320\273\320\276\320\263\320\260.feature" | 2 +- ...-\321\210\320\260\320\261\320\273\320\276\320\275.feature" | 4 ++-- ...21\203\321\200\320\260\321\202\320\276\321\200\320\260.os" | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git "a/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" index 3b07a06..fadbeae 100644 --- "a/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" +++ "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\320\264\320\262\320\260-\321\210\320\260\320\261\320\273\320\276\320\275\320\260.feature" @@ -21,7 +21,7 @@ Тогда Код возврата равен 0 И Файл "snippets/ШаблонКонфигуратора.st" в рабочем каталоге содержит """ - {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + {"Общий модуль",0,0,"Модуль[Общий]","//⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟ ⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪ ⇫ ⇬ ⇭ ⇮ ⇯ ⇰ ⇱ ⇲ ⇳ ⇴ ⇵ ⇶ ⇷ ⇸ ⇹ ⇺ // """ И Файл "snippets/ШаблонКонфигуратора.st" в рабочем каталоге содержит """ diff --git "a/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" index d589a6a..51595d4 100644 --- "a/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" +++ "b/features/\320\236\320\261\321\212\320\265\320\264\320\270\320\275\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275\321\213-\320\272\320\260\321\202\320\260\320\273\320\276\320\263\320\260.feature" @@ -21,7 +21,7 @@ Тогда Код возврата равен 0 И Файл "result.st" в рабочем каталоге содержит """ - {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + {"Общий модуль",0,0,"Модуль[Общий]","//⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟ ⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪ ⇫ ⇬ ⇭ ⇮ ⇯ ⇰ ⇱ ⇲ ⇳ ⇴ ⇵ ⇶ ⇷ ⇸ ⇹ ⇺ // """ И Файл "result.st" в рабочем каталоге содержит """ diff --git "a/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" "b/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" index e2a0ba7..5669f92 100644 --- "a/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" +++ "b/features/\320\240\320\265\320\267\320\264\320\265\320\273\320\270\321\202\321\214-\321\210\320\260\320\261\320\273\320\276\320\275.feature" @@ -21,7 +21,7 @@ Тогда Код возврата равен 0 И Файл "ШаблонКонфигуратора.st" в рабочем каталоге не содержит """ - {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + {"Общий модуль",0,0,"Модуль[Общий]","//⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟ ⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪ ⇫ ⇬ ⇭ ⇮ ⇯ ⇰ ⇱ ⇲ ⇳ ⇴ ⇵ ⇶ ⇷ ⇸ ⇹ ⇺ // """ И Файл "ШаблонКонфигуратора.st" в рабочем каталоге содержит """ @@ -29,5 +29,5 @@ """ И Файл "result.st" в рабочем каталоге содержит """ - {"Общий модуль",0,0,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©// + {"Общий модуль",0,0,"Модуль[Общий]","//⇗ ⇘ ⇙ ⇚ ⇛ ⇜ ⇝ ⇞ ⇟ ⇠ ⇡ ⇢ ⇣ ⇤ ⇥ ⇦ ⇧ ⇨ ⇩ ⇪ ⇫ ⇬ ⇭ ⇮ ⇯ ⇰ ⇱ ⇲ ⇳ ⇴ ⇵ ⇶ ⇷ ⇸ ⇹ ⇺ // """ diff --git "a/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" "b/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" index 34ed8e3..196c94d 100644 --- "a/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" +++ "b/tests/\320\242\320\265\321\201\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\250\320\260\320\261\320\273\320\276\320\275\320\276\320\262\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200\320\260.os" @@ -9,7 +9,6 @@ #Использовать asserts #Использовать tempfiles -#Использовать ".." /////////////////////////////////////////////////////////////////// @@ -130,4 +129,3 @@ Возврат Текст; КонецФункции -