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
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">');
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.


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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

746 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now