WPCubed Product Support

How to auto-capitalize first char of new sentence?

support

Re: How to auto-capitalize first char of new sentence

This code uses the BeforeInitializePar. It expects the start of a sentence at the start of the paragraph and after .?! + space.

The line
if WPRichText1.ActiveParagraph = par then
avoids that the complete text is updated after loading.

procedure TForm1.WPRichText1BeforeInitializePar(Sender: TObject;
  RTFEngine: TWPRTFEngineBasis; RTFDataBlock: TWPRTFDataBlock;
  par: TParagraph);
var i : Integer;
    sentenceend1,sentenceend2 : Boolean;
begin
  sentenceend1 := TRUE;
  sentenceend2:= TRUE;
  if WPRichText1.ActiveParagraph = par then // Only when working with cursor paragraph!
  for i:=0 to par.CharCount-1 do
  begin
     if par.ANSIChr[i] in ['a'..'z'] then
     begin
       if (sentenceend1=true) and (sentenceend2=true) then
       begin
           par.CharItem[i] := WideChar(Integer(par.CharItem[i]) - 32);
       end;
       sentenceend1 := FALSE;
       sentenceend2 := FALSE;
     end else if par.ANSIChr[i] in ['.','!','?'] then
     begin
         sentenceend1 := TRUE;
         sentenceend2 := FALSE;
     end else
     if par.ANSIChr[i] in [#32,#9] then
     begin
       if sentenceend1 then
            sentenceend2 := TRUE;
     end
     else 
     begin
       sentenceend1 := FALSE;
       sentenceend2 := FALSE;
     end;
  end;
end;
#1 ♥ 0
12.5k Views 1 users read 2 min
support

This following code is a new approach. It seems to work pretty nice and allows it to undo the auto change - something I find important. It handles abbreviations!

procedure TForm1.WPRichText1BeforeInitializePar(Sender: TObject;
  RTFEngine: TWPRTFEngineBasis; RTFDataBlock: TWPRTFDataBlock;
  par: TParagraph);
var pos_wstart, i : Integer; s : string;
begin
  // Current paragraph
  if par = WPRichText1.ActivePar then
  begin
     i := WPRichText1.ActivePosInPar;
     // 1. Overread spaces to the left
     while (i>0) and par.IsSpace(i) do dec(i);

     // 2. Overread a word
     pos_wstart := -1;
     if not par.IsWordDelimiter(i) and (par.IsSpace(i+1)) then
     begin
         while (i>=0) and not par.IsWordDelimiter(i) do begin pos_wstart := i; dec(i); end;
         // 3. Overread spaces
         while (i>0) and par.IsSpace(i) do dec(i);

         // Now, if . ! ? or start of par uppercase it!
         if  (pos_wstart>=0) and
             ((i<=0) or  (par.CharItem[i]='.') or
                      (par.CharItem[i]='!') or
                      (par.CharItem[i]='?'))
             // Check for abbreviation (simplified - only check a..z
             and ((par.IsSpace(i-1) or (par.CharItem[i]<>'.') or
                  ((par.CharItem[i-1]>='a') and (par.CharItem[i-1]<='z'))))
             then
            begin
                if Integer(par.CharItem[pos_wstart])<256 then
                begin
                      s := AnsiUpperCase(Char(par.CharItem[pos_wstart]));
                      if s<>'' then par.CharItem[pos_wstart] := WideChar(s[1]);
                end
                else  par.CharItem[pos_wstart] := WideUpperCase(par.CharItem[pos_wstart])[1];
            end;
     end;
  end;
end;
#2 ♥ 0