rtf.Append (@"\red" + c.R + @"\green" + c.G + @"\blue" + c.B + ";");
}
}
// Повторите цикл и выберите цвета из коллекции комментариев (highlighter.Comments)
}
Имея таблицу colorTable, вы в любой момент можете окрасить ключевое слово, используя такой алгоритм:
Keyword w = FindKeyword (word); // Метод FindKeyword надо разработать
if (w.Word != null)
{
if (w.Color != Color.Black)
rtf.Append ("\\cf" + colorTable[w.Color] + ' ' + word +
"\\cf" + colorTable[ForeColor] + ' ');
}
else
rtf.Append (word);
Здесь мы включили цвет, вывели слово и вновь восстановили (выключили) цвет. Такой же алгоритм справедлив для комментариев. Предположим, что в процессе разбора текста (свойство Text элемента типа RichTextBox) вы обнаружили комментарий (точнее, его OpenTag). Для обработки этого случая создадим новый метод:
private void ProcessComment (Comment com)
{
rtf.Append ("\\cf" + colorTable[com.Color] + ' '); // Включаем цвет комментария
if (com.CloseTag == null) // Это значит, что комментарий действует лишь до конца строки
{
// Цикл перебора и вставки символов до конца строки (пока не найден символ '\n')
}
else // Сложнее с многострочным комментарием
{
rtf.Append (com.OpenTag);
pos += com.OpenTag.Length;
while (pos < TextLength && !IsTagClosed (com))
;
}
rtf.Append ("\\cf" + colorTable[ForeColor] + ' '); // Восстанавливаем цвет текста
}
Метод IsTagClosed необходимо разработать. У меня он имеет такую схему. Заметьте, что CloseTag — это не один символ, а строка произвольной длины, в частном случае: "*/".
private bool IsTagClosed (Comment com)
{
if (!MoveToCloseTag (com))
return false;
int last = com.CloseTag.Length, i = 1;
bool valid = true;
for (Цикл перебора и вставки символов пока они совпадают с символами CloseTag)
{
c = AppendChar ();
valid &= // Условие совпадения с символами CloseTag
}
return valid;
}
Метод MoveToCloseTag также надо разработать. Подскажу примерную схему.
private bool MoveToCloseTag (Comment com)
{
bool found = false;
for (char c = '\0'; // пока не найден CloseTag[0] и еще что-то; pos++)
c = AppendChar ();
return found;
}
Формат RTF имеет некоторые особенности. Например, он помечает абзацы специальным тегом: \\par\n. Символы фигурных скобок: { и } являются для него служебными. Для того, чтобы использовать их по прямому назначению, надо перед ними вставить символ \. Для избежания коллизии с синтаксисом языка С (и C#) нам надо использовать двойные символы \\. Приведу текст метода AppendChar, который решает все эти проблемы.
private char AppendChar()
{
char c = Text[pos];
if (c == '\n')
rtf.Append ("\\par");
else if (c == '{' || c == '}')
rtf.Append ('\\');
rtf.Append (c);
if (c == '\\')
rtf.Append (c);
return c;
}
Напомню, что Text — это свойство класса RichTextBox, а значит и SyntaxBox. Оно имеет тип string и дает доступ к массиву символов неразмеченного текста RTF-документа.
Для реализации функциональности, которая выводит и использует список подсказок, надо затратить значительно меньше усилий, чем для реализации цветовой окраски текста.
¨ Во-первых, надо обеспечить реакцию на нажатие комбинации клавиш Ctrl+Space.
¨ Затем надо проанализировать слово (или часть слова) слева от курсора.
¨ Если слева откурсора стоит разделитель, то надо показать список со всеми ключевыми словами.
¨ Если слева откурсора стоит лексема, например, st, надо в списке ключевых слов найти все слова, которые начинаются на st (например: stackalloc, static, string, struct) и показать их в специальном окне.
¨ Если найдено только одно слово, то его надо автоматически завершить (AutoComplete).
¨ Если не найдено ни одного слова, а текст слева от курсора существует и не является разделителем, то список не отображается.
¨ Роль специального окна может выполнять обычный ListBox или отдельная форма со встроенным ListBox.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.