{Licensing:
By downloading this software you accept the following
                        Disclaimer of Warranty
-----------------------------------------------------------------------------
This software is provided AS IS without warranty of any kind, either
express or implied. There is no warranty as to merchantable quality or
fitness for a particular purpose. The entire risk as to the quality and
performance of this software is with you. Should the software prove defective,
you assume the cost of all necessary servicing, repair, or correction.
In no event shall I, the author, be liable for any damages of any kind
whether direct, indirect, or otherwise, arising out of the delivery,
performance or use of this software. This software has been written with
great care but it is not warranted to be error free. Downloading the software
does not confer any right whatsoever to support.

You are free to use this software for any purpose. If you publish sourcecode
which includes the unit this license agreement must be included, and you may not
pretend that you wrote it.

If you change it or make additions to it, I would be grateful for a copy.
Please send it to h@hjkm.dk or km@vordingborg-gym.dk
                          ------------------------

{Usage: Add this (RegExHighLight) unit to the form's uses declaration.
Add a TTimer to the form, enable the timer
(set the refresh interval to what you want in the timer's interval property)
The OnTimer Eventhandler should look somewhat like this:

  begin
  GoRegExHighLight(YourRichEdit,YourTimer);
  end;

The basic idea is to keep literals in black (unless they are enclosed
in square brackets) - everything else is colourized.
Of course this is indeed a very basic way of doing it - but since Regular 
Expressions are very short strings it works. Highlighting large chunks of text 
in this way is by no means recommended.

You can see an example of the use of this unit at 

http://www.hjkm.dk/PhraseContext/regexp.jpg

Copyright: Hans J. Klarskov Mortensen, 2004
Comments on it are welcome at h@hjkm.dk or km@vordingborg-gym.dk
------------------------------------------------------------------------------------}
unit RegExHighLight;

interface

uses
  Windows, Messages, SysUtils, Classes,
  Graphics, Controls,
  StdCtrls, ComCtrls, Richedit, ExtCtrls;

type
  ARichedit = TRichedit;

procedure HighLight(ARichEdit: TRichedit; start, laengde: integer; farve:
  TColor);
procedure Square(rx: TRichEdit);
procedure Curley(rx: TRichedit);
procedure GoRegExHighlight(ARichedit: TRichedit; ATimer: TTimer);
procedure FindWhatToHighlight(rx: TRichedit);

implementation

procedure HighLight(ARichEdit: TRichedit; start, laengde: integer; farve:
  TColor);
begin
  with ARichEdit do
    begin
      selstart := start;
      sellength := laengde;
      SelAttributes.Color := farve;
    end;
end;

procedure FindWhatToHighlight(rx: TRichedit);
var
  i: integer;
begin
  for i := 0 to length(rx.text) do
    begin
      if rx.text[i] = ']' then
        Square(rx)
      else if rx.text[i] = '}' then
        Curley(rx)

      else if (rx.text[i] = '\') and
        (rx.text[i + 1] in ['b', 'n', 'r', 't', 'd', 'w', 's', 'D', 'W', 'S'])
          then
        highlight(rx, i - 1, 2, clRed)
      else if (rx.text[i] in ['*', '.', '?', '+', '(', ')','^']) and
          not (rx.text[i- 1] in ['\']) then
        highlight(rx, i - 1, 1, clGreen)
      else if rx.text[i] = '\' then
        highlight(rx, i - 1, 1, clRed);
    end;
end;

procedure Square(rx: TRichedit);
var
  i: integer;
  j: integer;
  start: Integer;
begin
  i := 0;
  j := 0;
  while i < length(rx.text) - 1 do
    begin
      if rx.text[i] = '[' then
        begin
          start := i;
          repeat
            inc(j);
            inc(i);
          until (rx.text[j] = ']') or (rx.text[j] = #10);
          HighLight(rx, start - 1, j - start + 1, clMaroon);
          i := start + 1;
        end
      else
        inc(i);
    end;
end;

procedure Curley(rx: TRichEdit);
var
  i: integer;
  j: integer;
  start: Integer;
begin
  i := 0;
  j := 0;
  while i < length(rx.text) - 1 do
    begin
      if rx.text[i] = '{' then
        begin
          start := i;
          repeat
            inc(j);
            inc(i);
          until rx.text[j] = '}';
          HighLight(rx, start - 1, j - start + 1, clBlue);
          i := start + 1;
        end
      else
        inc(i);
    end;
end;

procedure GoRegExHighlight(ARichedit: TRichedit; ATimer: TTimer);
var
  start: integer;
  tmpselstart: integer;
  tmpsellength: integer;

begin
  ATimer.enabled := false;
  with ARichedit do
    begin
      start := selstart;
      tmpselstart := start;
      tmpsellength := sellength;
      SendMessage(Handle, EM_HIDESELECTION,
        LongInt(true), LongInt(false));

      selstart := 0;
      sellength := length(ARichEdit.text);
      SelAttributes.color := clBlack;
      try
        FindWhatToHighlight(ARichedit);

      finally
        ATimer.enabled := true;
        selstart := start;
        SelStart := tmpselstart;
        sellength := tmpSellength;

        SendMessage(Handle, EM_HIDESELECTION,
          LongInt(false), LongInt(false));
      end;
    end;
end;

end.

