1
0
mirror of https://github.com/bia-technologies/snippet-transform.git synced 2025-07-02 19:56:47 +02:00

ONECICD-19 Первая версия

This commit is contained in:
aleksey.koryakin
2019-03-25 14:20:57 +03:00
committed by Maxmov Valery
parent f99f0558b2
commit e5d06afe0e
34 changed files with 3311 additions and 2 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
bdd-log.xml
*.ospx
*.orig
exec.log
ignore/**
tests.xml

View File

@ -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

91
README.md Normal file
View File

@ -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" "Плохая группа\."`
Удалит из шаблона группы "Плохая группа" и "очень плохая группа"

View File

@ -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", СтрокаГдеИщем, СтрокаРасхождений);
Ожидаем.Что(Истина, СтрокаРасхождений).ЭтоЛожь();
КонецЕсли;
КонецПроцедуры

View File

@ -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" в рабочем каталоге содержит
"""
ТекущаяДата = '<?"n1", ДатаВремя, ""ДФ=dd.MM.yyyy"">'
"""

View File

@ -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" в рабочем каталоге содержит
"""
ТекущаяДата = '<?"n1", ДатаВремя, ""ДФ=dd.MM.yyyy"">'
"""

View File

@ -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" в рабочем каталоге содержит
"""
<?xml version="1.0" encoding="utf-8"?>
<templates/>
"""

View File

@ -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,"Модуль[Общий]","//©///////////////////////////////////////////////////////////////////////////©//
"""

13
installlocalhost.bat Normal file
View File

@ -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

14
packagedef Normal file
View File

@ -0,0 +1,14 @@
ПутьКСценариюПараметров = ОбъединитьПути(ТекущийСценарий().Каталог, "src", "Модули", "ПараметрыПриложения.os");
ПараметрыСистемы_ЛокальнаяВерсия = ЗагрузитьСценарий(ПутьКСценариюПараметров);
ИмяПродукта = НРег(ПараметрыСистемы_ЛокальнаяВерсия.ИмяПродукта());
Описание.Имя(ИмяПродукта)
.ВерсияСреды("1.0.21")
.Версия(ПараметрыСистемы_ЛокальнаяВерсия.ВерсияПродукта())
.ЗависитОт("logos", "1.2")
.ЗависитОт("cmdline", "1.0")
.ВключитьФайл("src")
.ВключитьФайл("README.md")
.ВключитьФайл("LICENSE")
.ИсполняемыйФайл("src/main.os", ИмяПродукта);

49
src/main.os Normal file
View File

@ -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.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// Рекомендованная структура модуля точки входа приложения
//
///////////////////////////////////////////////////////////////////////////////
#Использовать "."
///////////////////////////////////////////////////////////////////////////////
Приложение = МенеджерПриложения.Инициализировать(ПараметрыПриложения);
Попытка
Приложение.ЗавершитьРаботуПриложения(Приложение.ЗапуститьВыполнение());
Исключение
Приложение.ЗавершитьРаботуПриложенияСОшибкой(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

View File

@ -0,0 +1,37 @@
///////////////////////////////////////////////////////////////////////////////
//
// Модуль команды разделения шаблона
//
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ИзменяемыйШаблон", "Имя файла шаблона, который хотим разделить");
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ШаблонНаименования", "Регулярное выражение для проверки полного наименования шаблона (Группа.Шаблон)");
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "НовыйШаблон", "Имя файла шаблона, в который будут записаны отделенные элементы");
Парсер.ДобавитьПараметрФлагКоманды(Команда, "-r", "Переносить элементы, у которых наименование не совпадает с шаблоном");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
ИзменяемыйШаблон = ПараметрыКоманды["ИзменяемыйШаблон"];
НовыйШаблон = ПараметрыКоманды["НовыйШаблон"];
ШаблонНаименования = ПараметрыКоманды["ШаблонНаименования"];
ПереноситьНесовпадения = ПараметрыКоманды["-r"] = Истина;
Конвертер.РазделитьШаблон(ИзменяемыйШаблон, ШаблонНаименования, ПереноситьНесовпадения, НовыйШаблон);
Лог.Отладка("Выполнено разделение шаблонов");
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -0,0 +1,33 @@
///////////////////////////////////////////////////////////////////////////////
//
// Служебный модуль с реализацией работы команды help
//
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ВходнойФайл", "Имя конвертируемого шаблона");
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ВыходнойФайл", "Имя файла нового шаблона, в который будут перенесены элементы из первого файла");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
ВходнойФайл = ПараметрыКоманды["ВходнойФайл"];
ВыходнойФайл = ПараметрыКоманды["ВыходнойФайл"];
Конвертер.ПреобразоватьШаблон(ВходнойФайл, ВыходнойФайл);
Лог.Информация("Преобразование выполнено. %1 ==> %2", ВходнойФайл, ВыходнойФайл);
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -0,0 +1,37 @@
///////////////////////////////////////////////////////////////////////////////
//
// Модуль команды соединения двух файлов
//
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ИзменяемыйШаблон", "Имя файла шаблона, в который будут добавлены элементы из второго файла");
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "ДобавляемыйШаблон", "Имя файла шаблона, из которого будут добавлены элементы в первый файл");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
ИзменяемыйШаблон = ПараметрыКоманды["ИзменяемыйШаблон"];
ДобавляемыйШаблон = ПараметрыКоманды["ДобавляемыйШаблон"];
ВходныеФайлы = Новый Массив();
ВходныеФайлы.Добавить(Новый Файл(ИзменяемыйШаблон));
ВходныеФайлы.Добавить(Новый Файл(ДобавляемыйШаблон));
Конвертер.СоединитьШаблоны(ВходныеФайлы, ИзменяемыйШаблон);
Лог.Отладка("Файлы объединены");
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -0,0 +1,33 @@
///////////////////////////////////////////////////////////////////////////////
//
// Модуль команды соединения каталога шаблонов
//
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "КаталогШаблонов", "Каталог содержащий шаблоны кода, которые необходимо объединить");
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "РезультирующийШаблон", "Имя файла итогового шаблона");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
КаталогШаблонов = ПараметрыКоманды["КаталогШаблонов"];
РезультирующийШаблон = ПараметрыКоманды["РезультирующийШаблон"];
Конвертер.СоединитьШаблоны(НайтиФайлы(КаталогШаблонов, "*", Истина), РезультирующийШаблон);
Лог.Отладка("Шаблоны каталога объединены");
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -0,0 +1,27 @@
///////////////////////////////////////////////////////////////////////////////
//
// Служебный модуль с реализацией работы команды version
//
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
Сообщить(Приложение.ВерсияПродукта());
Лог.Отладка("Вывод версии приложения");
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -0,0 +1,41 @@
///////////////////////////////////////////////////////////////////////////////
//
// Служебный модуль с реализацией работы команды help
//
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "Команда");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
КомандаДляСправки = ПараметрыКоманды["Команда"];
Если КомандаДляСправки = Неопределено Тогда
Приложение.ВывестиСправкуПоКомандам();
Лог.Отладка("Вывод справки по командам");
Иначе
Приложение.ВывестиСправкуПоКоманде(КомандаДляСправки);
Лог.Отладка(СтрШаблон("Вывод справки по команде %1", КомандаДляСправки));
КонецЕсли;
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -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;
Возврат;
ИначеЕсли ТекСимвол = "," Тогда // добавление элемента текущего списка
Если НЕ (ПредСимвол = "}" ИЛИ ПредСимвол = "") Тогда
ЭлементДляЗаполнения.Значения.Добавить(ТекСтрока);
ТекСтрока = "";
КонецЕсли;
Иначе
ТекСтрока = ТекСтрока + ТекСимвол;
КонецЕсли;
ПредСимвол = ТекСимвол;
КонецЦикла;
СчетчикСимволов = НомерСимвола;
КонецПроцедуры // ПрочитатьДанныеСтроки()

View File

@ -0,0 +1,236 @@
///////////////////////////////////////////////////////////////////
//
// Методы конвертации шаблонов кода
//
// (с) BIA Technologies, LLC
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Программный интерфейс
///////////////////////////////////////////////////////////////////
// Метод преобразования формата шаблона
//
// Параметры:
// ИмяВходногоФайла - Строка - Имя файла базового шаблона
// ИмяВыходногоФайла - Строка - Имя файла нового шаблона
//
Процедура ПреобразоватьШаблон(ИмяВходногоФайла, ИмяВыходногоФайла) Экспорт
МодульЧтение = ПолучитьМодульРаботыСШаблоном(ИмяВходногоФайла);
ДанныеШаблона = МодульЧтение.ПрочитатьШаблон(ИмяВходногоФайла);
ЗаписатьСПроверкойДоступныхТипов(ДанныеШаблона, ИмяВыходногоФайла);
КонецПроцедуры
// Метода объединения нескольких шаблонов в один
//
// Параметры:
// МассивВходныхФайлов - Массив - Массив файлов (тип:Файл) шаблонов, которые необходимо объединить
// ИмяВыходногоФайла - Строка - Имя файла нового шаблона
//
Процедура СоединитьШаблоны(МассивВходныхФайлов, ИмяВыходногоФайла) Экспорт
Лог = МенеджерПриложения.ПолучитьЛог();
Читатели = Новый Соответствие();
Шаблон = Неопределено;
Для Каждого Файл Из МассивВходныхФайлов Цикл
Если НЕ Файл.ЭтоФайл() Тогда
Продолжить;
КонецЕсли;
Если Читатели[Файл.Расширение] = Неопределено Тогда
Читатель = ПолучитьМодульРаботыСШаблоном(Файл.ПолноеИмя);
Если Читатель = Неопределено Тогда
Лог.Предупреждение("Формат шаблона не поддерживается. Файл пропущен %1", Файл.Имя);
Продолжить;
КонецЕсли;
Читатели.Вставить(Файл.Расширение, Читатель);
КонецЕсли;
ШаблонФайла = Читатели[Файл.Расширение].ПрочитатьШаблон(Файл.ПолноеИмя);
Если Шаблон = Неопределено Тогда // Первый шаблон будет основным, необходимо для сохранения имени шаблона конфигуратора, при объединении двух шаблонов
Шаблон = ШаблонФайла;
Иначе
Для Каждого Элемент Из ШаблонФайла.Элементы Цикл // Последующие шаблоны будут закидываться в основной
Шаблон.Элементы.Добавить(Элемент);
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЗаписатьСПроверкойДоступныхТипов(Шаблон, ИмяВыходногоФайла);
КонецПроцедуры
// Метод для переноса части элементов шаблона в отдельный файл
// Анализ необходимости переноса выполняется по полному наименованию(включая иерархию)
// на соответствие регулярному выражению
//
// Параметры:
// ИзменяемыйШаблон - Строку - Имя файла анализируемого шаблона
// ШаблонНаименования - Строка - Шаблон регулярного для проверки наименования элемента
// РежимОбработкиНаименования - Строка - Способ обработки элементов
// * equal - совпадающий элемент переносится в новый файл
// * notequal - не совпадающий элемент переносится в новый файл
// УдаляемыеДанныеПоложитьВ - Строка - Имя файла, в который происходит перенос
//
Процедура РазделитьШаблон(ИзменяемыйШаблон, ШаблонНаименования, ПереносПриНеСовпадении, УдаляемыеДанныеПоложитьВ = Неопределено) Экспорт
Модуль = ПолучитьМодульРаботыСШаблоном(ИзменяемыйШаблон);
Шаблон = Модуль.ПрочитатьШаблон(ИзменяемыйШаблон);
НовыйШаблон = ШаблоныБазовый.КорневойЭлемент();
РегулярноеВыражение = Новый РегулярноеВыражение(ШаблонНаименования);
РазделитьШаблонПоРегулярномуВыражению(Шаблон, РегулярноеВыражение, НовыйШаблон, НЕ ПереносПриНеСовпадении, "");
Модуль.ЗаписатьШаблон(Шаблон, ИзменяемыйШаблон);
Если УдаляемыеДанныеПоложитьВ <> Неопределено Тогда
ЗаписатьСПроверкойДоступныхТипов(НовыйШаблон, УдаляемыеДанныеПоложитьВ);
КонецЕсли;
КонецПроцедуры
///////////////////////////////////////////////////////////////////
// Программный интерфейс
///////////////////////////////////////////////////////////////////
Процедура ЗаписатьСПроверкойДоступныхТипов(Шаблон, ИмяФайла, МодульЗаписи = Неопределено)
Если МодульЗаписи = Неопределено Тогда
МодульЗаписи = ПолучитьМодульРаботыСШаблоном(ИмяФайла);
КонецЕсли;
ДоступныеТипыПодстановок = МодульЗаписи.ДоступныеТипыПодстановок();
ФлагиТипов = Утилиты.СоответствиеФлагов(ДоступныеТипыПодстановок);
УдалитьНедоступныеШаблоны(Шаблон, ФлагиТипов);
МодульЗаписи.ЗаписатьШаблон(Шаблон, ИмяФайла);
КонецПроцедуры
Процедура УдалитьНедоступныеШаблоны(ДанныеШаблона, ДоступныеТипыПодстановок)
Лог = МенеджерПриложения.ПолучитьЛог();
Количество = ДанныеШаблона.Элементы.Количество();
Для Инд = 1 По Количество Цикл
Элемент = ДанныеШаблона.Элементы[Количество - Инд];
Если Элемент.Тип = "Элемент" Тогда
Для Каждого ЭлементШаблона Из Элемент.Шаблон Цикл
Если ТипЗнч(ЭлементШаблона) = Тип("Структура") И ДоступныеТипыПодстановок[ЭлементШаблона.Тип] = Неопределено Тогда
Лог.Предупреждение("Шаблон замены ""%1"" пропущен, так имеет неподдерживаемый тип ""%2""", Элемент.Наименование, ЭлементШаблона.Тип);
ДанныеШаблона.Элементы.Удалить(Количество - Инд);
Прервать;
КонецЕсли;
КонецЦикла;
ИначеЕсли Элемент.Тип = "Группа" Тогда
УдалитьНедоступныеШаблоны(Элемент, ДоступныеТипыПодстановок);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьМодульРаботыСШаблоном(ИмяФайла)
РасширениеФайла = (Новый Файл(ИмяФайла)).Расширение;
Если РасширениеФайла = ".st" Тогда
Возврат ШаблоныКонфигуратора;
ИначеЕсли РасширениеФайла = ".json" ИЛИ РасширениеФайла = ".code-snippets" Тогда
Возврат ШаблоныVSCode;
ИначеЕсли РасширениеФайла = ".xml" Тогда
Возврат ШаблоныEDT;
Иначе
МенеджерПриложения.ПолучитьЛог().Ошибка("Не поддерживаемый формат файла: %1" + РасширениеФайла);
КонецЕсли;
КонецФункции
Функция РазделитьШаблонПоРегулярномуВыражению(Шаблон, РегулярноеВыражение, НовыйШаблон, ПереносПриСовпадении, ПрефиксИмени)
КУдалению = Новый Массив();
Лог = МенеджерПриложения.ПолучитьЛог();
Для Каждого Элемент Из Шаблон.Элементы Цикл
Наименование = ПрефиксИмени + ?(Элемент.Тип = "Группа", Элемент.Наименование + ".", Элемент.Наименование);
НаименованиеСовпадаетСШаблоном = РегулярноеВыражение.Совпадает(Наименование);
Если (ПереносПриСовпадении И НаименованиеСовпадаетСШаблоном) ИЛИ (НЕ ПереносПриСовпадении И НЕ НаименованиеСовпадаетСШаблоном) Тогда
НовыйШаблон.Элементы.Добавить(Элемент);
КУдалению.Добавить(Элемент);
Лог.Информация("Элемент шаблона ""%1%2"" перенесен в другой файл", ПрефиксИмени, Элемент.Наименование)
ИначеЕсли Элемент.Тип = "Группа" Тогда
НоваяГруппа = ШаблоныБазовый.Группа();
Если РазделитьШаблонПоРегулярномуВыражению(Элемент, РегулярноеВыражение, НоваяГруппа, ПереносПриСовпадении, Наименование) Тогда
НовыйШаблон.Элементы.Добавить(НоваяГруппа);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого Элемент Из КУдалению Цикл
Шаблон.Элементы.Удалить(Шаблон.Элементы.Найти(Элемент));
КонецЦикла;
Возврат КУдалению.Количество();
КонецФункции

View File

@ -0,0 +1,296 @@
///////////////////////////////////////////////////////////////////////////////
//
// Служебный модуль с набором методов работы с командами приложения
//
// В большинстве проектов изменять данный модуль не требуется
//
///////////////////////////////////////////////////////////////////////////////
#Использовать logos
#Использовать cmdline
///////////////////////////////////////////////////////////////////////////////
Перем Лог;
Перем ПарсерКоманд;
Перем ИсполнителиКоманд;
Перем ОбъектНастроек;
///////////////////////////////////////////////////////////////////////////////
// СЛУЖЕБНЫЙ ОТКРЫТЫЙ ПРОГРАММНЫЙ ИНТЕРФЕЙС
///////////////////////////////////////////////////////////////////////////////
// Инициализирует и настраивает приложение
//
// Параметры:
// Настройка - Модуль - Модуль, в котором определены настройки приложения
//
// Возвращаемое значение:
// Модуль - Модуль менеджера приложения
//
Функция Инициализировать(Знач МенеджерНастроек) Экспорт
// Служебные переменные
ПарсерКоманд = Новый ПарсерАргументовКоманднойСтроки();
ИсполнителиКоманд = Новый Соответствие;
ОбъектНастроек = МенеджерНастроек;
// Логирование
Лог = Логирование.ПолучитьЛог(ОбъектНастроек.ИмяЛогаСистемы());
Лог.УстановитьРаскладку(ОбъектНастроек);
// Инициализация команд
ОбъектНастроек.НастроитьКомандыПриложения(ЭтотОбъект);
Возврат ЭтотОбъект;
КонецФункции
// Добавляет команду в приложение
//
// Параметры:
// ИмяКоманды - Строка - Имя команды
// КлассРеализации - Строка - Имя файла класса, в котором реализована команда
// ОписаниеКоманды - Строка - краткое описание назначения команды
//
Процедура ДобавитьКоманду(Знач ИмяКоманды, Знач КлассРеализации, Знач ОписаниеКоманды) Экспорт
Попытка
РеализацияКоманды = Новый(КлассРеализации);
Команда = ПарсерКоманд.ОписаниеКоманды(ИмяКоманды, ОписаниеКоманды);
ПарсерКоманд.ДобавитьКоманду(Команда);
РеализацияКоманды.НастроитьКоманду(Команда, ПарсерКоманд);
ИсполнителиКоманд.Вставить(ИмяКоманды, РеализацияКоманды);
Исключение
ЗавершитьРаботуПриложенияСОшибкой(СтрШаблон("Не удалось инициализировать команду '%1' для класса '%2' по причине:
|%3", ИмяКоманды, КлассРеализации, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
КонецПопытки;
КонецПроцедуры
// Аварийно завершает работу приложения с ошибкой
//
// Параметры:
// Сообщение - Строка - Сообщение, которое будет выведено пользователю перед завершением
// КодВозврата (не обязательный) - Число - Код возврата с которым будет закрыто приложение
// Значение по умолчанию: "ОшибкаВремениВыполнения" -- 1
//
Процедура ЗавершитьРаботуПриложенияСОшибкой(Знач Сообщение, Знач КодВозврата = Неопределено) Экспорт
Если КодВозврата = Неопределено Тогда
КодВозврата = РезультатыКоманд().ОшибкаВремениВыполнения;
КонецЕсли;
Лог.КритичнаяОшибка(Сообщение);
ЗавершитьРаботу(КодВозврата);
КонецПроцедуры
// Завершает работу приложения
//
// Параметры:
// КодВозврата (не обязательный) - Число - Код возврата с которым будет закрыто приложение
// Значение по умолчанию: "Успех" -- 0
//
Процедура ЗавершитьРаботуПриложения(Знач КодВозврата = Неопределено) Экспорт
Если КодВозврата = Неопределено Тогда
КодВозврата = РезультатыКоманд().Успех;
КонецЕсли;
ЗавершитьРаботу(КодВозврата);
КонецПроцедуры
// Осуществляет запуск приложения на выполнение
//
// Возвращаемое значение:
// Число - Код возврата выполнения команды приложения
//
Функция ЗапуститьВыполнение() Экспорт
Попытка
ПараметрыЗапуска = ПарсерКоманд.Разобрать(АргументыКоманднойСтроки);
Исключение
Лог.Отладка(ОписаниеОшибки());
Лог.Ошибка("Не удалось определить требуемое действие.");
ВывестиСправкуПоКомандам();
Возврат РезультатыКоманд().НеверныеПараметры;
КонецПопытки;
Команда = "";
ЗначенияПараметров = Неопределено;
Если ПараметрыЗапуска = Неопределено ИЛИ ПараметрыЗапуска.Количество() = 0 Тогда
ВывестиВерсию();
ВывестиСправкуПоКомандам();
Возврат РезультатыКоманд().НеверныеПараметры;
ИначеЕсли ТипЗнч(ПараметрыЗапуска) = Тип("Структура") Тогда
// это команда
Команда = ПараметрыЗапуска.Команда;
ЗначенияПараметров = ПараметрыЗапуска.ЗначенияПараметров;
Лог.Отладка("Выполняю команду продукта %1", Команда);
ИначеЕсли ЗначениеЗаполнено(ОбъектНастроек.ИмяКомандыПоУмолчанию()) Тогда
// это команда по-умолчанию
Команда = ОбъектНастроек.ИмяКомандыПоУмолчанию();
ЗначенияПараметров = ПараметрыЗапуска;
Лог.Отладка("Выполняю команду продукта по умолчанию %1", Команда);
Иначе
Возврат НекорректныеПараметры();
КонецЕсли;
Если Команда <> ОбъектНастроек.ИмяКомандыВерсия() Тогда
ВывестиВерсию();
КонецЕсли;
Возврат ВыполнитьКоманду(Команда, ЗначенияПараметров);
КонецФункции // ЗапуститьВыполнение()
// Осуществляет запуск на выполнение указанной команды приложения
//
// Параметры:
// ИмяКоманды - Строка - Имя команды, которую необходимо запустить
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
//
Функция ВыполнитьКоманду(Знач ИмяКоманды, Знач ПараметрыКоманды) Экспорт
Команда = ПолучитьКоманду(ИмяКоманды);
КодВозврата = Команда.ВыполнитьКоманду(ПараметрыКоманды, ЭтотОбъект);
Если КодВозврата = Неопределено Тогда
КодВозврата = РезультатыКоманд().Успех;
КонецЕсли;
Возврат КодВозврата;
КонецФункции // ВыполнитьКоманду
///////////////////////////////////////////////////////////////////////////////
// ПРОГРАММНЫЙ ИНТЕРФЕЙС
///////////////////////////////////////////////////////////////////////////////
// Возвращает лог приложения
Функция ПолучитьЛог() Экспорт
Возврат Лог;
КонецФункции // ПолучитьЛог
// Возвращает версию продукта
Функция ВерсияПродукта() Экспорт
Возврат ОбъектНастроек.ВерсияПродукта();
КонецФункции // ВерсияПродукта
// Возвращает имя продукта
Функция ИмяПродукта() Экспорт
Возврат ОбъектНастроек.ИмяПродукта();
КонецФункции // ИмяПродукта
// Возвращает путь к исполняемому файлу
Функция ПутьКИсполняемомуФайлу() Экспорт
Возврат ОбъектНастроек.ПутьКИсполняемомуФайлу();
КонецФункции // ПутьКИсполняемомуФайлу
// Возвращает путь к каталогу основного скрипта
Функция ПутьКРодительскомуКаталогу() Экспорт
Возврат ОбъектНастроек.ПутьКРодительскомуКаталогу();
КонецФункции // ПутьКРодительскомуКаталогу
// Возвращает путь к каталогу сценариев
Функция КаталогСценариев() Экспорт
Возврат ОбъектНастроек.КаталогСценариев();
КонецФункции // КаталогСценариев
// Выводит справку по всем командам приложения
Процедура ВывестиСправкуПоКомандам() Экспорт
ПарсерКоманд.ВывестиСправкуПоКомандам();
КонецПроцедуры // ВывестиСправкуПоКомандам
// Выводит справку по указанной команде приложения.
Процедура ВывестиСправкуПоКоманде(Знач ИмяКоманды) Экспорт
ПарсерКоманд.ВывестиСправкуПоКоманде(ИмяКоманды);
КонецПроцедуры // ВывестиСправкуПоКоманде
///////////////////////////////////////////////////////////////////////////////
// ПЕРЕЧИСЛЕНИЯ
///////////////////////////////////////////////////////////////////////////////
// Возвращает стандартные коды возврата приложения
Функция РезультатыКоманд() Экспорт
РезультатыКоманд = Новый Структура;
РезультатыКоманд.Вставить("Успех", 0);
РезультатыКоманд.Вставить("НеверныеПараметры", 5);
РезультатыКоманд.Вставить("ОшибкаВремениВыполнения", 1);
Возврат РезультатыКоманд;
КонецФункции // РезультатыКоманд
///////////////////////////////////////////////////////////////////////////////
// СЛУЖЕБНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ
///////////////////////////////////////////////////////////////////////////////
// Получает объект класса с реализацией указанной команды
Функция ПолучитьКоманду(Знач ИмяКоманды)
КлассРеализации = ИсполнителиКоманд[ИмяКоманды];
Если КлассРеализации = Неопределено Тогда
ВызватьИсключение СтрШаблон("Неверная операция. Команда '%1' не предусмотрена.", ИмяКоманды);
КонецЕсли;
Возврат КлассРеализации;
КонецФункции // ПолучитьКоманду
// Осуществляет вывод полной версии продукта
Процедура ВывестиВерсию()
Сообщить(СтрШаблон("%1 v%2", ИмяПродукта(), ВерсияПродукта()));
КонецПроцедуры // ВывестиВерсию
// Вывод ошибки и справки по параметрам
Функция НекорректныеПараметры()
Лог.Ошибка("Некорректные аргументы командной строки");
ВывестиСправкуПоКомандам();
Возврат РезультатыКоманд().НеверныеПараметры;
КонецФункции // НекорректныеПараметры()

View File

@ -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", "Выполняет разделение шаблона, на основании регулярного выражения");
КонецПроцедуры // ПриРегистрацииКомандПриложения

View File

@ -0,0 +1,41 @@
///////////////////////////////////////////////////////////////////
//
// Модуль-перечисления, типы блоков подставновки шаблонов
//
// (с) BIA Technologies, LLC
//
///////////////////////////////////////////////////////////////////
Перем Неизвестный Экспорт;
Перем УстановкаКурсора Экспорт;
Перем ВыборВарианта Экспорт;
Перем ДатаВремя Экспорт;
///////////////////////////////////////////////////////////////////
// Программный интерфейс
///////////////////////////////////////////////////////////////////
// Возвращает список всех доступных типов, тип "Неизвестный" не включен
//
// Возвращаемое значение:
// Массив - Коллекция строк-идентификаторов доступных типов
//
Функция ВсеТипы() Экспорт
ТипыШаблонов = Новый Массив();
ТипыШаблонов.Добавить(УстановкаКурсора);
ТипыШаблонов.Добавить(ВыборВарианта);
ТипыШаблонов.Добавить(ДатаВремя);
Возврат ТипыШаблонов;
КонецФункции
///////////////////////////////////////////////////////////////////
Неизвестный = "Неизвестный";
УстановкаКурсора = "Установка курсора";
ВыборВарианта = "Выбор варианта";
ДатаВремя = "Дата время";

View File

@ -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А-Яа-я]+"));

View File

@ -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;
КонецЦикла;
Возврат Вывод.Закрыть();
КонецФункции

View File

@ -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");
Для Каждого Элемент Из Замены Цикл
Результат = СтрЗаменить(Результат, Элемент.Значение, "$" + Элемент.Представление);
КонецЦикла;
Возврат Результат;
КонецФункции

View File

@ -0,0 +1,49 @@
///////////////////////////////////////////////////////////////////
//
// Базовые методы для работы с шаблонами
//
// (с) BIA Technologies, LLC
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Программный интерфейс
///////////////////////////////////////////////////////////////////
// Инициализирует структуру корневого элемента шаблона
//
// Возвращаемое значение:
// Структура - Описание корневого элемента
//
Функция КорневойЭлемент() Экспорт
Возврат Новый Структура("Тип, Наименование, Элементы", "Корень", "Корень", Новый Массив());
КонецФункции
// Инициализирует структуру группы шаблона
//
// Возвращаемое значение:
// Структура - Описание группы шаблона
//
Функция Группа() Экспорт
Возврат Новый Структура("Тип, Наименование, Элементы", "Группа", "", Новый Массив());
КонецФункции
// Инициализирует структуру элемента шаблона
//
// Возвращаемое значение:
// Структура - Описание элемента шаблона
//
Функция Элемент() Экспорт
Возврат Новый Структура("Тип, Наименование, ТекстЗамены, Шаблон", "Элемент");
КонецФункции
///////////////////////////////////////////////////////////////////
// Служебный функционал
///////////////////////////////////////////////////////////////////

View File

@ -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();
Вывод.УстановитьСтроку();
Для Каждого Элемент Из ДанныеШаблона Цикл
Если ТипЗнч(Элемент) = Тип("Строка") Тогда
Вывод.ЗаписатьБезОбработки(ОбработатьКавычкиПриЗаписи(Элемент));
Продолжить;
КонецЕсли;
Вывод.ЗаписатьБезОбработки("<?");
Если Элемент.Свойство("Подсказка") Тогда
Вывод.ЗаписатьБезОбработки(СтрШаблон("""%1""", Элемент.Подсказка));
КонецЕсли;
Если Элемент.Тип = ТипПодстановки.ВыборВарианта Тогда
Вывод.ЗаписатьБезОбработки(", ВыборВарианта");
Для Каждого ЭлементВыбора Из Элемент.СписокВыбора Цикл
Если ЗначениеЗаполнено(ЭлементВыбора.Представление) Тогда
Вывод.ЗаписатьБезОбработки(", " + ЭлементВыбора.Представление);
Иначе
Вывод.ЗаписатьБезОбработки(", " + ЭлементВыбора.Значение);
КонецЕсли;
Вывод.ЗаписатьБезОбработки(", " + ЭлементВыбора.Значение);
КонецЦикла;
ИначеЕсли Элемент.Тип = ТипПодстановки.ДатаВремя Тогда
Если Элемент.Свойство("Формат") Тогда
Вывод.ЗаписатьБезОбработки(СтрШаблон(", ДатаВремя, """"ДФ=%1""""", Элемент.Формат));
Иначе
Вывод.ЗаписатьБезОбработки(", ДатаВремя");
КонецЕсли;
КонецЕсли;
Вывод.ЗаписатьБезОбработки(">");
КонецЦикла;
Возврат Вывод.Закрыть();
КонецФункции
Функция ОбработатьКавычкиПриЗаписи(Текст)
Текст = СтрЗаменить(Текст, """", """""");
Возврат Текст;
КонецФункции

18
tasks/test-feature.os Normal file
View File

@ -0,0 +1,18 @@
#Использовать ".."
#Использовать 1bdd
КаталогФич = ОбъединитьПути(".", "features");
ПутьФичи = ОбъединитьПути(".", "features", АргументыКоманднойСтроки[0]);
Файл_КаталогФич = Новый Файл(КаталогФич);
ФайлФичи = Новый Файл(ПутьФичи);
ИсполнительБДД = Новый ИсполнительБДД;
РезультатВыполнения = ИсполнительБДД.ВыполнитьФичу(ФайлФичи, Файл_КаталогФич);
ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатВыполнения);
Сообщить(ИтоговыйРезультатВыполнения);
Если ИтоговыйРезультатВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался Тогда
ВызватьИсключение 1;
КонецЕсли;

82
tasks/test.os Normal file
View File

@ -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>
|", ТестыПрошли));
КонецЕсли;

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<template autoinsert="true" context="com._1c.g5.v8.dt.bsl.Bsl.AddHandlerStatement" deleted="false" description="DEPRECATED" enabled="true" name="ЗапретитьИспользование">#Если НЕ ВебКлиент Тогда
Выполнить(СервисныйОбщегоНазначенияПовтИсп.ЗапретитьИспользованиеФункционала(
"${ЗапрещенныйФункционалМетод}", // Запрещенный функционал, метод
"${ФункционалДляЗаменыНеобязательно}", // Функционал для замены
"${КомментарийПояснениеНеобязательно}", // Комментарий / пояснение
${ДатаЗапретаВТестовойНеобязательноВидДатаГГГГММДД}, // Дата запрета в тестовой
${ДатаЗапретаВРабочейНеобязательноВидДатаГГГГММДД}) // Дата запрета в рабочей
);
#КонецЕсли </template>
<template autoinsert="true" context="com._1c.g5.v8.dt.bsl.Bsl.AddHandlerStatement" deleted="false" description="Инкремент" enabled="true" name="++">${Операнд} = ${Операнд} + 1;</template>
<template autoinsert="true" context="com._1c.g5.v8.dt.bsl.Bsl.AddHandlerStatement" deleted="false" description="ТекущаяДата" enabled="true" name="ТекущаяДата">ТекущаяДата = '${n1:date(dd.MM.yyyy)}';</template>
</templates>

View File

@ -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,"",""}
}
}
}

View File

@ -0,0 +1,18 @@
{1,
{3,
{"ЧастичноПоддерживаемыйФункционал",1,0,"",""},
{0,
{"#Если",0,0,"№Ес[ли]","#Если <?"""", ВыборВарианта, ""Клиент"", ""Клиент"", ""Сервер"", ""Сервер"", ""ВнешнееСоединение"", ""ВнешнееСоединение"" ,""ТолстыйКлиентОбычноеПриложение"", ""ТолстыйКлиентОбычноеПриложение"", ""ТолстыйКлиентУправляемоеПриложение"",""ТолстыйКлиентУправляемоеПриложение"", ""ТонкийКлиент"", ""ТонкийКлиент"", ""ВебКлиент"", ""ВебКлиент""> Тогда
<?>
#КонецЕсли"}
},
{0,
{"Формат",0,0,"Формат","Формат(<?>, ""<?, ФорматнаяСтрока>"")"}
},
{0,
{"УстановитьЗначениеКонстанты",0,0,"УстановитьЗнач[ениеКонстанты]","ОбщегоНазначенияСервер.УстановитьЗначениеКонстанты(""<?""Выберите константу"", Константа>"", <?>);"}
}
}
}

View File

@ -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);
Текст = Чтение.Прочитать();
Чтение.Закрыть();
Возврат Текст;
КонецФункции

View File

@ -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} - установка курсора по окончании ввода шаблона