Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Подсветка синтаксиса

Delphi , Компоненты и Классы , TMemo и TRichEdit

Подсветка синтаксиса


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    procedure RichEdit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure HighLight;
    function CheckList(InString: string): boolean;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.CheckList(InString: string): boolean;
const TheList: array[1..13] of string = ('begin', 'or', 'end','end.',
'end;', 'then', 'var', 'for', 'do', 'if', 'to', 'string', 'while');
var X: integer;
begin
  Result := false;
  X := 1;
  InString := StringReplace(InString, ' ', '',[rfReplaceAll]);
  InString := StringReplace(InString, #$A, '',[rfReplaceAll]);
  InString := StringReplace(InString, #$D, '',[rfReplaceAll]);
  while X < High(TheList) + 1 do
  if TheList[X] = lowercase(InString) then
  begin
    Result := true;
    X := High(TheList) + 1;
  end
  else inc(X);
end;

procedure TForm1.RichEdit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var WEnd, WStart, BCount: integer;
  Mark: string;
begin
  if (ssCtrl in Shift) and (Key = ord('V')) then Button2Click(Self);
  if (Key = VK_Return) or (Key = VK_Back) or (Key = VK_Space) then
  begin
    if RichEdit1.SelStart > 1 then
    begin
      WStart := 0;
      WEnd := RichEdit1.SelStart;
      BCount := WEnd - 1;
      while BCount <> 0 do
      begin
        Mark := copy(RichEdit1.Text, BCount, 1);
        if (Mark = ' ') or (Mark = #$A) then
        begin
          WStart := BCount;
          BCount := 1;
        end;
        dec(BCount);
      end;
      RichEdit1.SelStart := WEnd - (WEnd - WStart);
      RichEdit1.SelLength := WEnd - WStart;
      if CheckList(RichEdit1.SelText) then
        RichEdit1.SelAttributes.Style := [fsBold]
      else RichEdit1.SelAttributes.Style := [];
      RichEdit1.SelStart := WEnd;
      RichEdit1.SelAttributes.Style := [];
    end;
  end;
end;

function SearchFor(WorkSpace, Search: string; Start: integer): integer;
var Temp: string;
begin
  Temp := copy(WorkSpace, Start, length(WorkSpace));
  Result := pos(Search, Temp);
end;

procedure TForm1.HighLight;
var WStart, WEnd, WEnd2: integer;
  WorkSpace, SWord: string;
begin
  WStart  :=  1;
  WEnd  :=  1;
  with  RichEdit1 do
  begin
    WorkSpace  :=  Text + ' ' + #$D#$A;
    while WEnd > 0 do
    begin
      WEnd := SearchFor(WorkSpace, ' ', WStart);
      WEnd2 := SearchFor(WorkSpace, #$A, WStart);
      if WEnd2 < WEnd then WEnd := WEnd2;
      SWord := copy(WorkSpace, WStart, WEnd - 1);
      if (SWord <> ' ') and (SWord <>'') then
        if CheckList(SWord) then
        begin
          SelStart  := WStart - 1;
          SelLength := length(SWord);
          SelAttributes.Style := [fsBOLD];
          SelStart := WStart + length(SWord) + 1;
          SelAttributes.Style := [];
        end;
      WStart := WStart + WEnd;
    end;
    SelStart := length(Text);
    SetFocus;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
    HighLight;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  RichEdit1.PasteFromClipboard;
  HighLight;
end;

end.

Here's the translation of the content into Russian:

Код - это приложение Delphi, которое предлагает синтаксическое подсветку в富текстовом редакторе (RichEdit1). Программа проверяет конкретные ключевые слова и фразы в тексте и если их находит, то подчеркивает их жирным шрифтом.

Вот разбивка кода:

  • Функция CheckList сравнивает заданный строку с массивом предопределенных ключевых слов. Если есть совпадение, она возвращает True.
  • В обработчике события RichEdit1KeyUp, программа проверяет конкретные события клавиатуры (Возврат, Backspace, Space) и если их находит, то поискает выбранное текст в списке ключевых слов и подчеркивает его соответственно.
  • Процедура HighLight проходит через текст в RichEdit1, поиская пробелы (' ') и переносы строк (#$A). Для каждого случая, она проверяет, есть ли совпадение с любым ключевым словом в списке. Если найдено, то она выбирает и подчеркивает соответствующий текст жирным шрифтом.
  • В обработчике события Button1Click, программа загружает содержимое открытого файла в RichEdit1 и вызывает процедуру HighLight для подчеркивания синтаксиса.
  • В обработчике события Button2Click, программа вставляет содержимое буфера обмена в RichEdit1 и также вызывает процедуру HighLight.

Для улучшения кода:

  1. Добавьте больше ключевых слов в список в функции CheckList для более полного подчеркивания.
  2. Рассмотрите добавление кнопки "Сброс подчеркивания" или горячей клавиши для сброса подчеркивания, когда это нужно.
  3. Возможно, вам нужно будет изменить стиль подчеркивания (например, шрифт, цвет) в зависимости от языка программирования, который вы хотите подчеркнуть.
  4. Если вы планируете поддерживать несколько языков программирования, рассмотрите создание отдельных списков ключевых слов для каждого языка и использование более сложной механики парсинга.
  5. Используйте обработку ошибок в вашем коде для обработки случаев, когда загруженный файл или вставленное содержимое буфера обмена является недопустимым.
  6. Возможно, вам нужно будет добавить опцию сохранения подчеркнутого текста в новый файл.

Альтернативное решение:

Вместо ручного поиска конкретных ключевых слов, вы можете использовать регулярные выражения (regex) для поиска и подчеркивания синтаксических элементов в вашем коде. Delphi имеет встроенную поддержку regex через компонент TRegex или модуль RegExpr.

Вот пример использования regex:

function TForm1.CheckList(InString: string): boolean;
var X, ResultIndex: integer;
  TheList: array[1..13] of string = ('begin', 'or', 'end', 'end.', 'end;', 'then', 'var', 'for', 'do', 'if', 'to', 'string', 'while');
  RegExpr: TRegExpr;
begin
  Result := false;
  X := 1;
  InString := StringReplace(InString, ' ', '', [rfReplaceAll]);
  InString := StringReplace(InString, #$A, '', [rfReplaceAll]);
  while X < High(TheList) + 1 do
    if TheList[X] = lowercase(InString) then
    begin
      Result := true;
      X := High(TheList) + 1;
    end
    else inc(X);
end;

procedure TForm1.RichEdit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var WEnd, WStart, BCount: integer;
  Mark: string;
begin
  if (ssCtrl in Shift) and (Key = ord('V')) then Button2Click(Self);
  if (Key = VK_Return) or (Key = VK_Back) or (Key = VK_Space) then
  begin
    if RichEdit1.SelStart > 1 then
    begin
      WStart := 0;
      WEnd := RichEdit1.SelStart;
      BCount := WEnd - 1;
      while BCount <> 0 do
      begin
        Mark := copy(RichEdit1.Text, BCount, 1);
        if (Mark = ' ') or (Mark = #$A) then
        begin
          WStart := BCount;
          BCount := 1;
        end;
        dec(BCount);
      end;
      RichEdit1.SelStart := WEnd - (WEnd - WStart);
      RichEdit1.SelLength := WEnd - WStart;
      if CheckList(RichEdit1.SelText) then
        RichEdit1.SelAttributes.Style := [fsBold]
      else RichEdit1.SelAttributes.Style := [];
      RichEdit1.SelStart := WEnd;
      RichEdit1.SelAttributes.Style := [];
    end;
  end;
end;

procedure TForm1.HighLight;
var WStart, WEnd, WEnd2: integer;
  WorkSpace, SWord: string;
begin
  WStart := 1;
  WEnd := 1;
  with RichEdit1 do
  begin
    WorkSpace := Text + ' ' + #$D#$A;
    while WEnd > 0 do
    begin
      WEnd := SearchFor(WorkSpace, ' ', WStart);
      WEnd2 := SearchFor(WorkSpace, #$A, WStart);
      if WEnd2 < WEnd then WEnd := WEnd2;
      SWord := copy(WorkSpace, WStart, WEnd - 1);
      if (SWord <> ' ') and (SWord<> '') then
        if CheckList(SWord) then
        begin
          SelStart := WStart - 1;
          SelLength := length(SWord);
          SelAttributes.Style := [fsBOLD];
          SelStart := WStart + length(SWord) + 1;
          SelAttributes.Style := [];
        end;
      WStart := WStart + WEnd;
    end;
    SelStart := length(Text);
    SetFocus;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
    HighLight;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  RichEdit1.PasteFromClipboard;
  HighLight;
end;

В этом альтернативном решении функция CheckList была изменена для использования регулярного выражения pattern matching вместо ручного поиска каждого ключевого слова. Это позволяет легко расширять список ключевых слов добавлением более паттернов без изменения кода.

Для дальнейшего улучшения функциональности подчеркивания, рассмотрите использование отдельного компонента или библиотеки для синтаксического подсветки, которая может обрабатывать несколько языков программирования и предоставлять болееadvanced функции, такие как настраиваемый стиль подчеркивания и поддержка вложенных конструкций.

В статье рассматривается пример программирования на языке Pascal, где создается текстовый редактор с функцией подсветки синтаксиса для списка ключевых слов.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TMemo и TRichEdit ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:38:21/0.0069119930267334/1