Replacing code in Editor

Posted on 2004-04-23
Last Modified: 2013-12-03
I am writing a HTML Editor. I want the user to choose the font face from a listbox such as this:

Default Font
Arial, Helvetica, sans-serif
Times New Roman, Times, serif
Courier New, Courier, mono
Georgia, Times New Roman, Times, serif
Verdana, Arial, Helvetica, sans-serif
Geneva, Arial, Helvetica, sans-serif

and have their choice added to the page, such as:  <font face="Verdana, Arial, Helvetica, sans-serif"></font> (or whatever)

I can replace "<body>" with "<body> + the selected item in the listbox" easy enough. However, how can I delete any previous entries (if any) to avoid the following every time the user changes the font:

<font face="Times New Roman, Times, serif"></font><font face="Courier New, Courier, mono"></font><font face="Georgia, Times New Roman, Times, serif"></font>

Note that it is not possible for the user to position the cursor in the code.  I can delete the previous entry if there is a way of determining it's length but how (and how can the program determine if there IS a previous entry?). Maybe there is a replace function/procedure?

I am using Delphi 6.  I am giving the maximum 500 points for this as it is URGENT. Many thanks for your help.

Question by:rincewind666
  • 3
  • 2
  • 2
  • +1
LVL 12

Expert Comment

ID: 10897437

   If you are using TRichEdit for Editor use SelStart and SelText properties to determine where to insert the tags.

   for Replace use StringReplace function or find some implementation of regular expressions for Delphi...
LVL 12

Expert Comment

ID: 10897449

   Regular expressions in Delphi :

   This technique will provide you enough powerful text search (and replace).

Expert Comment

ID: 10898221
You will have to write a bit of fuzzy searching.

1) find '<' then work through string till you hit a 'Font' or another character if it is 'font ' then move onto 2
(the reason for this is that there may be the word font in the text of the document)

2) Continue through string till you hit 'FACE' or '>'. if 'FACE' then move onto 3
(the reason for this is that there may be other atributes of the 'font' section you do nto want to change (like size))

3) next look for '=' or '>' if '=' found them move onto 4
(this is just to be safe)

4) look for " and hunt down its ending ".
(this will give you the ending position of the entry if you want to replace it with yours, if you want to delete then just record down where you found the 'Face' and delete up to the final ")

The reasons for all of this is that there may be other details in the '<font >' section, which I expect you do not want to write over.

I will knock up a little code in a sec
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

LVL 10

Expert Comment

ID: 10898340
Hi there,

Here is a sample how to do it using Pos and PosEx. It works because there can be no ">" in good html without it being the end of a tag. Using PosEx you can easily find the end of a tag you are on. This sample only works if there is no whitespace (CR/LF or space) between the <BODY> and the <FONT> tag. If there is whitespace this needs to be deleted first.

Let me know if this works for you!

Regards Jacco


function ReplaceBodyFont(aHTML, aFont: string): string;
  liStart, liEnd: Integer;
  Result := aHTML;
  aHTML := UpperCase(aHTML); // this makes sure you find FoNt as well
  liStart := Pos('<BODY><FONT', aHTML) + 6;
  if liStart <> 0 then
    liEnd := PosEx('>', aHTML, liStart);
    Delete(Result, liStart, liEnd - liStart + 1);
    Insert(aFont, Result, liStart);

procedure TForm1.Button1Click(Sender: TObject);
  Memo2.Text := ReplaceBodyFont(Memo1.Text, '<FONT face="Arial">');

Accepted Solution

Molando earned 500 total points
ID: 10898619
Ok, typed off the top of my head, as no version of delphi on this computer. Should work, but trace through it once
if will copy with:

  '<font'  '<     font'   '< FoNt' (spaces and capitalization)
 '<font size=12 face = "Arial"    (other attribs)
 '<font size=12>' (no face in font section)
 '>  font face = 12' (text containing any of the words)

Should let you replace or delete. have fun

    FontFaceStart  : integer;
    FontFaceMiddle : integer;
    FontFaceEnd    : integer;

    cnt := 1;
    FontFaceStart  := 0;
    FontFaceEnd    := 0;
    FontFaceMiddle := 0;
while cnt < length(memo1.text) do begin
   //first check to see if a '<'
   if memo1.text[cnt] = '<' then begin //finds the bracket open bit
      while memo1.text[cnt] = ' ' do inc(cnt); //this will cope with (<Font and <    <Font)
      if (uppercase(memo1.text[cnt]) = 'F') //forced uppercase as could be in lower
        and (uppercase(memo1.text[cnt+1]) = 'O')
        and (uppercase(memo1.text[cnt+2]) = 'N')
        and (uppercase(memo1.text[cnt+3]) = 'T')
        and (uppercase(memo1.text[cnt+4]) = ' ') then begin
           cnt := cnt + 5; //we now point just past the word font
           //we now know we are in a <font place
           while uppercase(memo1.text[cnt]) <> '>' do begin  //this stops us breaking out of <font>
             if (uppercase(memo1.text[cnt]) = 'F') //forced uppercase as could be in lower
               and (uppercase(memo1.text[cnt+1]) = 'A')
               and (uppercase(memo1.text[cnt+2]) = 'C')
               and (uppercase(memo1.text[cnt+3]) = 'E') then begin
                 //ok nearly there now, lets storedown where we found the 'F  of face'
                 FontFaceStart := cnt;
                 cnt := cnt + 4;
                 //next we search for the equals sign
                 while memo1.text[cnt] = ' ' do inc(cnt);
                 if memo1.text[cnt] = '=' then begin
                   //now we hunt for the first speach marks
                   while memo1.text[cnt] = ' ' do inc(cnt);
                   if memo1.text[cnt] = '"' then begin
                     //lets store this down
                     FontFaceMiddle := cnt;
                     while memo1.text[cnt] <> '"' do inc(cnt);
                     FontFaceEnd := cnt;
                     //ok, you have found it all, up to you what you do with it now
                     // delete(memo1.text,fontfacestart,fontfaceend) will remove the entry
                     // or
                     // delete(memo1.text,fontfacemiddle+1,fontfaceend-1)
                     // and insert('myfont name'.memo1.text,fontfacemiddle+1)
                 end else inc(cnt);


Expert Comment

ID: 10900541
'if will copy with:'
  should read
'it will cope with:'

Author Comment

ID: 10916454
Many thank for your help.  Much appreciated.
LVL 10

Expert Comment

ID: 10920281
The routine supplied by Molanda finds/replaces all appearances of <font ... face  =  "xxx" ...> by <font ... face  =  "yyy" ...> asked was only the one following <BODY>.

Why is the longer routine favoured?

Regards Jacco

Featured Post

Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question