Раскрашивание кода (реинкарнация обработки с ИТС)
Отзывы
Для тех, кому лень качать - делюсь своей реализацией функции раскраски кода
//Вспомогательная, используется в "РаскраситьКод1С8"
Процедура ДобавитьСлово(Код, Слово, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, ТипСлова=Неопределено)
Если ПустаяСтрока(Слово) Тогда
Код = Код + СтрЗаменить(СтрЗаменить(СтрЗаменить(Слово, " ", " "), Символы.НПП, " "), Символы.Таб, " ");
Возврат;
ИначеЕсли ТипСлова=Неопределено Тогда
нсл = НРег(СокрП(Слово));
Если Найти(СписокКлючевыхСлов, нсл)>0 Тогда
ТипСлова = "<keywrd>";
ИначеЕсли Слово = "0" или мОписаниеТипаЧисло.ПривестиЗначение(Слово)<>0 Тогда
ТипСлова = "<num>";
Иначе
ТипСлова = "<text>";
ЭтоЧисло = Истина;
Для сч=1 по СтрДлина(нсл) Цикл
ТекСимв=Сред(нсл, сч, 1);
Если Найти(ДопустимыеЗнаки, ТекСимв)=0 Тогда
ТипСлова="<unwn>";
Прервать;
ИначеЕсли ТекСимв<>"0" Тогда
ЭтоЧисло = Ложь;
КонецЕсли;
КонецЦикла;
Если ЭтоЧисло Тогда
ТипСлова = "<num>";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Код = Код + ?(ТекТипСлова=ТипСлова, "", ТипСлова) + СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Слово, "<", "<"), ">", ">"), " ", " "), Символы.НПП, " "), Символы.Таб, " ");
ТекТипСлова = ТипСлова;
Слово = "";
КонецПроцедуры
//Реализует функционал "Оформить фрагмент кода"
Функция РаскраситьКод1С8(ТекстКод) Экспорт
мОписаниеТипаЧисло = Новый ОписаниеТипов("Число");
Таб = Символы.Таб;
НПП = Символы.НПП;
ДопустимыеЗнаки = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789abcdefghijklmnop qrstyvwxyz_";
СписокКлючевыхСлов = "асинх|async|ждать|await|if|если|then|тогда|elsif|иначеесли|else|иначе|endif|конецесли|do|цикл|for|для|to|по|each|каждого|in|из|while|пока|enddo|конеццикла|procedure|процедура|endprocedure|конецпроцедуры|function|функция|endfunction|конецфункции|var|перем|export|экспорт|goto|перейти|and|и|or|или|not|не|val|знач|break|прервать|continue|продолжить|return|возврат|try|попытка|except|исключение|endtry|конецпопытки|raise|вызватьисключение|false|ложь|true|истина|undefined|неопределено|null|new|новый|execute|выполнить|";
Ответ = "<span style=""text-align: left; font-family: courier new,courier; color: blue; font-size: 10pt; white-space: pre; display: inline-block; ""><font>";
ТекТипСлова = "<text>";
Для нс=1 По СтрЧислоСтрок(ТекстКод) Цикл
ТекСтрока = СокрП(СтрПолучитьСтроку(ТекстКод, нс));
дл = СтрДлина(ТекСтрока);
сч = 0;
ТекСлово = "";
КодНеНачался = Истина;
Пока сч<дл Цикл
сч = сч + 1;
ТекущийСимвол = Сред(ТекСтрока, сч, 1);
Если КодНеНачался Тогда
Если ТекущийСимвол=" " Или ТекущийСимвол=Таб Или ТекущийСимвол=НПП Тогда
//ТекущийСимвол = ?(ТекущийСимвол=" " или ТекущийСимвол=НПП, " ", " ");
Ответ = Ответ + ТекущийСимвол;
Продолжить;
ИначеЕсли ТекущийСимвол="#" или ТекущийСимвол="&" Тогда
ТекСлово = "";
ДобавитьСлово(Ответ, Сред(ТекСтрока, сч), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<dir>");
Прервать;
КонецЕсли;
КонецЕсли;
КодНеНачался = Ложь;
Если ТекущийСимвол=" " Или ТекущийСимвол=Таб Или ТекущийСимвол=НПП Тогда
Если КодНеНачался Тогда
Ответ = Ответ + ТекущийСимвол;
Продолжить;
КонецЕсли;
//ТекущийСимвол = ?(ТекущийСимвол=" " или ТекущийСимвол=НПП, " ", " ");
ДобавитьСлово(Ответ, ТекСлово+ТекущийСимвол, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
ТекСлово = "";
Продолжить;
ИначеЕсли Найти("():;.,=+-*<>?[]%/", ТекущийСимвол) > 0 Тогда
ДобавитьСлово(Ответ, ТекСлово, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
ТекСлово = "";
//Проверяем на комментарий
Если ТекущийСимвол="/" и Сред(ТекСтрока, сч+1, 1)="/" Тогда
ТекСлово = "";
ДобавитьСлово(Ответ, СокрП(Сред(ТекСтрока, сч)), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<cmnt>");
Прервать;
КонецЕсли;
ДобавитьСлово(Ответ, ТекущийСимвол, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<symb>");
Продолжить;
ИначеЕсли ТекущийСимвол="""" или ТекущийСимвол="|" Тогда
ДобавитьСлово(Ответ, ТекСлово, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
// найти закрывающую кавычку
нач = сч;
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Пока сч<дл Цикл
сч = сч + 1;
ТекущийСимвол = СледующийСимвол;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Если ТекущийСимвол="""" Тогда
Если СледующийСимвол="""" Тогда
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Иначе
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТекСлово = "";
ДобавитьСлово(Ответ, Сред(ТекСтрока, нач, сч-нач), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<str>");
сч = сч - 1;
Продолжить;
ИначеЕсли ТекущийСимвол="'" Тогда
нач = сч;
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Пока сч<дл Цикл
сч = сч + 1;
ТекущийСимвол = СледующийСимвол;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Если ТекущийСимвол="'" Тогда
Если СледующийСимвол="'" Тогда
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Иначе
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТекСлово = "";
ДобавитьСлово(Ответ, Сред(ТекСтрока, нач, сч-нач), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<str>");
сч = сч - 1;
Продолжить;
КонецЕсли;
ТекСлово = ТекСлово + ТекущийСимвол;
КонецЦикла;
Если Не ПустаяСтрока(ТекСлово) Тогда
ДобавитьСлово(Ответ,СокрП(ТекСлово), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
КонецЕсли;
Ответ = Ответ + "";
КонецЦикла;
Ответ = Ответ + Символы.ПС+"</font></span>";
Ответ = СтрЗаменить(Ответ, "<keywrd>", "</font><font color=red>");
Ответ = СтрЗаменить(Ответ, "<text>", "</font><font color=blue>");
Ответ = СтрЗаменить(Ответ, "<str>", "</font><font color=black>");
Ответ = СтрЗаменить(Ответ, "<num>", "</font><font color=black>");
Ответ = СтрЗаменить(Ответ, "<unwn>", "</font><font color=black>");
Ответ = СтрЗаменить(Ответ, "<symb>", "</font><font color=red>");
Ответ = СтрЗаменить(Ответ, "<cmnt>", "</font><font color=green>");
Ответ = СтрЗаменить(Ответ, "<dir>", "</font><font color=brown>");
Ответ = СтрЗаменить(Ответ, Символы.Таб, " ");
Возврат Ответ;
КонецФункции
Показать
(17) В функции "РаскраситьКод1С8"
после будет цикл.
После цикла - добавьте
после
// найти закрывающую кавычку
После цикла - добавьте
Если ТекущийСимвол<>"""" или СледующийСимвол="""" Тогда
сч = сч + 1;
КонецЕсли;
Прикрепленные файлы:
ТестРаскраскиКода1Сv8.epf
Остальные комментарии
В избранное
Подписаться на ответы
Сортировка:
Древо развёрнутое
Свернуть все
(2) Да сервисов то даже особо не надо) Было дело баловался в детстве с библиотекой highlight.js https://26226.selcdn.ru/paint_1c/export.html но это было давно. Тогда ключевые слова сами добавляли и собирали библиотеку, теперь 1с уже зашит в библиотеку.
Для тех, кому лень качать - делюсь своей реализацией функции раскраски кода
//Вспомогательная, используется в "РаскраситьКод1С8"
Процедура ДобавитьСлово(Код, Слово, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, ТипСлова=Неопределено)
Если ПустаяСтрока(Слово) Тогда
Код = Код + СтрЗаменить(СтрЗаменить(СтрЗаменить(Слово, " ", " "), Символы.НПП, " "), Символы.Таб, " ");
Возврат;
ИначеЕсли ТипСлова=Неопределено Тогда
нсл = НРег(СокрП(Слово));
Если Найти(СписокКлючевыхСлов, нсл)>0 Тогда
ТипСлова = "<keywrd>";
ИначеЕсли Слово = "0" или мОписаниеТипаЧисло.ПривестиЗначение(Слово)<>0 Тогда
ТипСлова = "<num>";
Иначе
ТипСлова = "<text>";
ЭтоЧисло = Истина;
Для сч=1 по СтрДлина(нсл) Цикл
ТекСимв=Сред(нсл, сч, 1);
Если Найти(ДопустимыеЗнаки, ТекСимв)=0 Тогда
ТипСлова="<unwn>";
Прервать;
ИначеЕсли ТекСимв<>"0" Тогда
ЭтоЧисло = Ложь;
КонецЕсли;
КонецЦикла;
Если ЭтоЧисло Тогда
ТипСлова = "<num>";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Код = Код + ?(ТекТипСлова=ТипСлова, "", ТипСлова) + СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Слово, "<", "<"), ">", ">"), " ", " "), Символы.НПП, " "), Символы.Таб, " ");
ТекТипСлова = ТипСлова;
Слово = "";
КонецПроцедуры
//Реализует функционал "Оформить фрагмент кода"
Функция РаскраситьКод1С8(ТекстКод) Экспорт
мОписаниеТипаЧисло = Новый ОписаниеТипов("Число");
Таб = Символы.Таб;
НПП = Символы.НПП;
ДопустимыеЗнаки = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789abcdefghijklmnop qrstyvwxyz_";
СписокКлючевыхСлов = "асинх|async|ждать|await|if|если|then|тогда|elsif|иначеесли|else|иначе|endif|конецесли|do|цикл|for|для|to|по|each|каждого|in|из|while|пока|enddo|конеццикла|procedure|процедура|endprocedure|конецпроцедуры|function|функция|endfunction|конецфункции|var|перем|export|экспорт|goto|перейти|and|и|or|или|not|не|val|знач|break|прервать|continue|продолжить|return|возврат|try|попытка|except|исключение|endtry|конецпопытки|raise|вызватьисключение|false|ложь|true|истина|undefined|неопределено|null|new|новый|execute|выполнить|";
Ответ = "<span style=""text-align: left; font-family: courier new,courier; color: blue; font-size: 10pt; white-space: pre; display: inline-block; ""><font>";
ТекТипСлова = "<text>";
Для нс=1 По СтрЧислоСтрок(ТекстКод) Цикл
ТекСтрока = СокрП(СтрПолучитьСтроку(ТекстКод, нс));
дл = СтрДлина(ТекСтрока);
сч = 0;
ТекСлово = "";
КодНеНачался = Истина;
Пока сч<дл Цикл
сч = сч + 1;
ТекущийСимвол = Сред(ТекСтрока, сч, 1);
Если КодНеНачался Тогда
Если ТекущийСимвол=" " Или ТекущийСимвол=Таб Или ТекущийСимвол=НПП Тогда
//ТекущийСимвол = ?(ТекущийСимвол=" " или ТекущийСимвол=НПП, " ", " ");
Ответ = Ответ + ТекущийСимвол;
Продолжить;
ИначеЕсли ТекущийСимвол="#" или ТекущийСимвол="&" Тогда
ТекСлово = "";
ДобавитьСлово(Ответ, Сред(ТекСтрока, сч), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<dir>");
Прервать;
КонецЕсли;
КонецЕсли;
КодНеНачался = Ложь;
Если ТекущийСимвол=" " Или ТекущийСимвол=Таб Или ТекущийСимвол=НПП Тогда
Если КодНеНачался Тогда
Ответ = Ответ + ТекущийСимвол;
Продолжить;
КонецЕсли;
//ТекущийСимвол = ?(ТекущийСимвол=" " или ТекущийСимвол=НПП, " ", " ");
ДобавитьСлово(Ответ, ТекСлово+ТекущийСимвол, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
ТекСлово = "";
Продолжить;
ИначеЕсли Найти("():;.,=+-*<>?[]%/", ТекущийСимвол) > 0 Тогда
ДобавитьСлово(Ответ, ТекСлово, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
ТекСлово = "";
//Проверяем на комментарий
Если ТекущийСимвол="/" и Сред(ТекСтрока, сч+1, 1)="/" Тогда
ТекСлово = "";
ДобавитьСлово(Ответ, СокрП(Сред(ТекСтрока, сч)), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<cmnt>");
Прервать;
КонецЕсли;
ДобавитьСлово(Ответ, ТекущийСимвол, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<symb>");
Продолжить;
ИначеЕсли ТекущийСимвол="""" или ТекущийСимвол="|" Тогда
ДобавитьСлово(Ответ, ТекСлово, ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
// найти закрывающую кавычку
нач = сч;
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Пока сч<дл Цикл
сч = сч + 1;
ТекущийСимвол = СледующийСимвол;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Если ТекущийСимвол="""" Тогда
Если СледующийСимвол="""" Тогда
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Иначе
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТекСлово = "";
ДобавитьСлово(Ответ, Сред(ТекСтрока, нач, сч-нач), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<str>");
сч = сч - 1;
Продолжить;
ИначеЕсли ТекущийСимвол="'" Тогда
нач = сч;
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Пока сч<дл Цикл
сч = сч + 1;
ТекущийСимвол = СледующийСимвол;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Если ТекущийСимвол="'" Тогда
Если СледующийСимвол="'" Тогда
сч = сч + 1;
СледующийСимвол = Сред(ТекСтрока, сч, 1);
Иначе
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТекСлово = "";
ДобавитьСлово(Ответ, Сред(ТекСтрока, нач, сч-нач), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло, "<str>");
сч = сч - 1;
Продолжить;
КонецЕсли;
ТекСлово = ТекСлово + ТекущийСимвол;
КонецЦикла;
Если Не ПустаяСтрока(ТекСлово) Тогда
ДобавитьСлово(Ответ,СокрП(ТекСлово), ТекТипСлова, СписокКлючевыхСлов, ДопустимыеЗнаки, мОписаниеТипаЧисло);
КонецЕсли;
Ответ = Ответ + "";
КонецЦикла;
Ответ = Ответ + Символы.ПС+"</font></span>";
Ответ = СтрЗаменить(Ответ, "<keywrd>", "</font><font color=red>");
Ответ = СтрЗаменить(Ответ, "<text>", "</font><font color=blue>");
Ответ = СтрЗаменить(Ответ, "<str>", "</font><font color=black>");
Ответ = СтрЗаменить(Ответ, "<num>", "</font><font color=black>");
Ответ = СтрЗаменить(Ответ, "<unwn>", "</font><font color=black>");
Ответ = СтрЗаменить(Ответ, "<symb>", "</font><font color=red>");
Ответ = СтрЗаменить(Ответ, "<cmnt>", "</font><font color=green>");
Ответ = СтрЗаменить(Ответ, "<dir>", "</font><font color=brown>");
Ответ = СтрЗаменить(Ответ, Символы.Таб, " ");
Возврат Ответ;
КонецФункции
Показать
(6) Чтобы избежать ошибок при раскраске кода, содержащего html-сущности, которые могут сломать разметку, добавьте в начало функции РаскраситьКод1С8 следующие строки:
ТекстКод= СтрЗаменить(ТекстКод, "<", "& lt;");
ТекстКод= СтрЗаменить(ТекстКод, ">", "& gt;");
(11) Не в начале функции "РаскраситьКод1С8", а в функции "ДобавитьСлово"
Это на самом деле было реализовано, просто верстка кода на сайте Инфостарта немного скорректировала некоторые символы.
В итоге получилась вот такая глупость: СтрЗаменить(Слово, "<", "<"), ">", ">"), " ", " ")...
Тестовую обработку прилагаю - она делает нормальный HTML-код.
Это на самом деле было реализовано, просто верстка кода на сайте Инфостарта немного скорректировала некоторые символы.
В итоге получилась вот такая глупость: СтрЗаменить(Слово, "<", "<"), ">", ">"), " ", " ")...
Тестовую обработку прилагаю - она делает нормальный HTML-код.
(17) В функции "РаскраситьКод1С8"
после будет цикл.
После цикла - добавьте
после
// найти закрывающую кавычку
После цикла - добавьте
Если ТекущийСимвол<>"""" или СледующийСимвол="""" Тогда
сч = сч + 1;
КонецЕсли;
Прикрепленные файлы:
ТестРаскраскиКода1Сv8.epf
(7) Исправил. Справедливости ради замечу, что сервис, ссылку на который вы давали выше тоже выдает ошибку на данном коде. Вернее отображает раскрашенный код он правильно, а вот код для вставки содержит ошибку. Вся проблема в том, что такие HTML-сущности как <> не преобразуются в соответствующие символы. Алгоритм от DrAku1a (6) имеет ту же проблему.
(9) Теперь не корректно красит где в тексте знаки сравнения (<>). Из-за:
Код = СтрЗаменить(Код, "<", "<");
Код = СтрЗаменить(Код, ">", ">");
Но если закомментировать эти замены, ожидаемо сносит html.
По мне так очень сложно пофиксить данный баг. Одни и те же символы выполняют разные роли. Тут даже логику не применить никак
Код = СтрЗаменить(Код, "<", "<");
Код = СтрЗаменить(Код, ">", ">");
Но если закомментировать эти замены, ожидаемо сносит html.
По мне так очень сложно пофиксить данный баг. Одни и те же символы выполняют разные роли. Тут даже логику не применить никак
(20) Для раскрашивания в режиме реального времени лучше использовать эту разработку или, например, решения на основе библиотек SyntaxHighlighter и highlight.js
Вакансии
Программист 1С
Краснознаменск (Московская обл.)
зарплата от 150 000 руб. до 250 000 руб.
Полный день
Краснознаменск (Московская обл.)
зарплата от 150 000 руб. до 250 000 руб.
Полный день
Специалист техподдержки
Краснознаменск (Московская обл.)
зарплата от 50 000 руб. до 100 000 руб.
Полный день
Краснознаменск (Московская обл.)
зарплата от 50 000 руб. до 100 000 руб.
Полный день