trichview.com Forum Index trichview.com
TRichView support forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[Examples] Count of characters and words

 
Post new topic   Reply to topic    trichview.com Forum Index -> Examples, Demos
View previous topic :: View next topic  
Author Message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Sun Aug 28, 2005 11:42 am    Post subject: [Examples] Count of characters and words Reply with quote

Calculating a number of characters

Code:
uses CRVData;

function GetCharCount(RVData: TCustomRVData): Integer;
var i,r,c: Integer;
     table: TRVTableItemInfo;
begin
Result := 0;
for i := 0 to RVData.Items.Count-1 do
  if RVData.GetItemStyle(i)>=0 then begin // this is a text item
    inc(Result, RVData.ItemLength(i))
  else if RVData.GetItemStyle(i)=rvsTab then
    inc(Result)
  else if RVData.GetItemStyle(i)=rvsTable then begin
    table := TRVTableItemInfo(RVData.GetItem(i));
    for r := 0 to table.Rows.Count-1 do
      for c := 0 to table.Rows[r].Count-1 do
        if table.Cells[r,c]<>nil then
          inc(Result, GetCharCount(table.Cells[r,c].GetRVData));
  end;
end;


Call:

Code:
r := GetCharCount(RichView.RVData);


This function does not count images, etc.


Last edited by Sergey Tkachenko on Thu Jun 22, 2006 3:33 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Sun Aug 28, 2005 11:43 am    Post subject: Reply with quote

Calculating a number of words

You can use a class from
http://www.trichview.com/resources/spell/rvspell.zip .
You need a unit RVWordEnum.pas from there (other files are specific for some spell checkers).

Create a class

Code:
TWordCounter = class(TRVWordEnumerator)
private
    FCounter: Integer;
protected
    function ProcessWord: Boolean; override;
public
   function GetWordCount(rve: TCustomRichViewEdit): Integer;
end;

function TWordCounter.ProcessWord: Boolean;
begin
  inc(FCounter);
  Result := True;
end;

function TWordCounter.GetWordCount(rve: TCustomRichViewEdit): Integer;
begin
  FCounter := 0;
  Run(rve, rvesFromStart);
  Result := FCounter;
end;

(this function treats word written with two different fonts as two words)

Call:
Code:
var wcnt: TWordCounter;

wcnt := TWordCounter.Create;
r := wcnt.GetWordCount(RichViewEdit1);
wcnt.Free;
Back to top
View user's profile Send private message Visit poster's website
christopher00



Joined: 21 Jun 2006
Posts: 2

PostPosted: Wed Jun 21, 2006 9:13 pm    Post subject: Re: [Examples] Count of characters and words Reply with quote

Sergey Tkachenko wrote:
Calculating a number of characters

Code:
uses CRVData;

function GetCharCount(RVData: TCustomRVData): Integer;
var i,r,c: Integer;
     table: TRVTableItemInfo;
begin
Result := 0;
for i := 0 to RVData.Items.Count-1 do
  if RVData.GetItemStyle(i)>=0 then begin // this is a text item
    inc(Result, RVData.ItemLength(i))
  else if RVData.GetItemStyle(i)=rvsTable then begin
    table := TRVTableItemInfo(RVData.GetItem(i));
    for r := 0 to table.Rows.Count-1 do
      for c := 0 to table.Rows[r].Count-1 do
        if table.Cells[r,c]<>nil then
          inc(Result, GetCharCount(table.Cells[r,c].GetRVData));
  end;
end;


Call:

Code:
r := GetCharCount(RichView.RVData);


This function does not count images, etc.


Will this function count the characters in a TRichViewEdit? The word count function looks like it would.
Back to top
View user's profile Send private message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Thu Jun 22, 2006 3:34 pm    Post subject: Reply with quote

Yes, it can be used for TRichViewEdit too.

PS: I just modified it to take tab characters into account. Line breaks are still not counted.
Back to top
View user's profile Send private message Visit poster's website
beboyle



Joined: 23 Oct 2005
Posts: 1

PostPosted: Sun Jul 30, 2006 7:43 pm    Post subject: Calculating Words and Characters Reply with quote

This pair of functions counts the number of words and characters in a TRichViewEdit control. The WordCount function is just a generic routine to return word count from any text. The second is fired when the text changes. It loops through the text items in the RVE and passes each to WordCount and totals up the results.
Code:

// Function to provide word count from memo or text field
function WordCount(t: String): LongInt;
var
  ws: Boolean;
  wc: Integer;
  i: Integer;
begin
  ws := True; // In whitespace
  wc := 0;
  for i := 0 to Length(t) - 1 do
  begin
    if t[i] in [' ', #9, #10, #13] then
         ws := True
    else if ws then
      begin
        ws := False;
        Inc(wc);
      end;
  end;
    Result := wc;
end;

// Change in text - count words and characters.
procedure Tform1.RVEChange(Sender: TObject);
var
  wc, cc: LongInt;
  I: Integer;
begin
  cc := 0;
  wc := 0;
  with RVE do
  begin
    for I := 0 to RVData.Items.Count - 1 do
      if RVData.GetItemStyle(I) >= 0 then
      begin
        inc (cc, RVData.ItemLength(I));
        inc (wc, WordCount(RVData.GetItemTextA(I)));
      end;
  end;
  lbCount.Caption := IntToStr(cc) + ' characters, ' + IntToStr(wc) + ' words.';
end;
Back to top
View user's profile Send private message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Sat Jul 21, 2007 6:08 pm    Post subject: Reply with quote

Calculating a number of words in the selection.

Parsers for spellcheckers v1.9.1 (2007-Jul-21) are required:
http://www.trichview.com/resources/spell/rvspell.zip

Code:

uses RVWordEnum, RVTable, CRVFData;

type
  TSelWordCounter = class(TRVWordEnumerator)
  private
    FCounter: Integer;
    FSelRVData: TCustomRVFormattedData;
    FSelStartItemNo, FSelStartOffs, FSelEndItemNo, FSelEndOffs: Integer;
  protected
    function ProcessWord: Boolean; override;
  public
    function GetWordCount(rve: TCustomRichViewEdit): Integer;
  end;

function TSelWordCounter.ProcessWord: Boolean;
begin
  Result :=
    not
    (
     (FRVData=FSelRVData) and
     ((FItemNo>FSelEndItemNo) or ((FItemNo=FSelEndItemNo) and (FStartOffs>=FSelEndOffs)))
    );
  if Result then
    inc(FCounter);
end;

function TSelWordCounter.GetWordCount(rve: TCustomRichViewEdit): Integer;
var table: TRVTableItemInfo;
    r, c: Integer;
begin
  Result   := 0;
  FCounter := 0;
  rve := rve.TopLevelEditor;
  if rve.RVData.PartialSelectedItem<>nil then begin
    // multicell selection
    FSelRVData := nil;
    table := rve.RVData.PartialSelectedItem as TRVTableItemInfo;
    for r := 0 to table.RowCount-1 do
      for c := 0 to table.ColCount-1 do
        if (table.Cells[r,c]<>nil) and table.IsCellSelected(r, c) then
          RunRVData(rve, table.Cells[r,c], 0, table.Cells[r,c].GetOffsBeforeItem(0));
    end
  else begin
    if not rve.SelectionExists then
      exit;
    // normal selection
    FSelRVData := rve.RVData;
    FSelRVData.GetSelectionBoundsEx(FSelStartItemNo, FSelStartOffs,
      FSelEndItemNo, FSelEndOffs, True);
    RunRVData(rve, rve.RVData, FSelStartItemNo, FSelStartOffs);
  end;
  Result := FCounter;
end;
Back to top
View user's profile Send private message Visit poster's website
sr1111



Joined: 31 Jan 2008
Posts: 27

PostPosted: Sun Jan 18, 2009 3:54 am    Post subject: Reply with quote

I used this function in the delphi2009 error

[DCC Warning] Unit3.pas(777): W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit.

can you fix this function


function WordCount(t: String): LongInt;
var
ws: Boolean;
wc: Integer;
i: Integer;
begin
ws := True; // In whitespace
wc := 0;
for i := 0 to Length(t) - 1 do
begin
if t[i] in [' ', #9, #10, #13] then
ws := True
else if ws then
begin
ws := False;
Inc(wc);
end;
end;
Result := wc;
end;
Back to top
View user's profile Send private message
chmichael



Joined: 27 Aug 2005
Posts: 9
Location: Greece

PostPosted: Sun Jan 18, 2009 3:35 pm    Post subject: Reply with quote

It is possible to save both counts into the RVF file for performance reasons ?
Back to top
View user's profile Send private message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Sun Jan 18, 2009 6:20 pm    Post subject: Reply with quote

You can save any additional information in DocProperties
Back to top
View user's profile Send private message Visit poster's website
chmichael



Joined: 27 Aug 2005
Posts: 9
Location: Greece

PostPosted: Sun Jan 18, 2009 7:40 pm    Post subject: Reply with quote

Thanks!
Back to top
View user's profile Send private message
Petko



Joined: 06 Sep 2005
Posts: 89

PostPosted: Wed Mar 10, 2010 4:09 pm    Post subject: Reply with quote

It is possible to count lines and paragraphs too, and if yes, do you think that it will be too time consuming when working with large documents (compared to char and word count)?
Back to top
View user's profile Send private message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Wed Mar 10, 2010 8:34 pm    Post subject: Reply with quote

No, it will be fast.
Count of lines - do you mean lines that depend on word wrapping?

How do you want to calculate the count of paragraphs and lines for tables?
Back to top
View user's profile Send private message Visit poster's website
Petko



Joined: 06 Sep 2005
Posts: 89

PostPosted: Thu Mar 11, 2010 9:47 am    Post subject: Reply with quote

I need something similar to Word's word count. I've made a test and it seems to work like this:

* Lines - they depend on word wrapping and each table cell is counted as a line, if the cell is empty
* Paragraphs - it seems that only items, containing text are counted as paragraphs (empty table cells are not)

You can see my test file here:
http://www.box.net/shared/v9ximbdj0f

Anyway, absolute accuracy is not necessary, speed is priority here. People using a word count function need accuracy in the word and character counts more.
Back to top
View user's profile Send private message
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Thu Mar 11, 2010 7:14 pm    Post subject: Reply with quote

I created functions calculating these values in the most natural way for TRichView. It may be different from Word.

Paragraph count

Code:
uses CRVData, RVTable;

function GetParagraphCount(RVData: TCustomRVData): Integer;
var i,r,c: Integer;
  table: TRVTableItemInfo;
begin
  Result := 0;
  for i := 0 to RVData.ItemCount-1 do begin
    if RVData.IsParaStart(i) then
      inc(Result);
    if RVData.GetItemStyle(i)=rvsTable then begin
      table := TRVTableItemInfo(RVData.GetItem(i));
      for r := 0 to table.RowCount-1 do
        for c := 0 to table.ColCount-1 do
          if table.Cells[r,c]<>nil then
            inc(Result, GetParagraphCount(table.Cells[r,c].GetRVData));
    end;
  end;
end;


Use: Count := GetParagraphCount(RichViewEdit1.RVData);
In the show-special-characters mode, you can see pilcrow characters at the end of paragraphs. GetParagraphCount returns the count of these characters. Note that they are displayed in places where MS Word does not display them:
- at the end of table cells
- at the end of tables.


Last edited by Sergey Tkachenko on Thu Mar 11, 2010 7:24 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Sergey Tkachenko
Site Admin


Joined: 27 Aug 2005
Posts: 6576

PostPosted: Thu Mar 11, 2010 7:19 pm    Post subject: Reply with quote

Line count

Code:
uses CRVFData, RVTable, DLines;

function GetLineCount(RVData: TCustomRVFormattedData): Integer;
var i,r,c: Integer;
  table: TRVTableItemInfo;
begin
  Result := 0;
  for i := 0 to RVData.DrawItems.Count-1 do begin
    if RVData.DrawItems[i].FromNewLine then
      inc(Result);
    if RVData.GetItemStyle(RVData.DrawItems[i].ItemNo)=rvsTable then begin
      table := TRVTableItemInfo(RVData.GetItem(RVData.DrawItems[i].ItemNo));
      for r := 0 to table.RowCount-1 do
        for c := 0 to table.ColCount-1 do
          if table.Cells[r,c]<>nil then
            inc(Result, GetLineCount(TCustomRVFormattedData(table.Cells[r,c].GetRVData)));
    end;
  end;
end;


Use: Count := GetLineCount(RichViewEdit1.RVData);

This code uses some undocumented methods.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    trichview.com Forum Index -> Examples, Demos All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group