Hyphenation and Language

General TRichView support forum. Please post your questions here
Post Reply
dex
Posts: 5
Joined: Tue Oct 22, 2013 9:19 pm

Hyphenation and Language

Post by dex »

Hi,

I am new here, and from what I have read so far, TRichView is quite an impressive product.

Here are two questions, I couldn't find answers myself:

1. Let's assume I have a function HyphenateWord which will take a word as parameter and insert soft hyphens in it at appropriate hyphenation points. What would be the best way to go to implement hyphenation with current version of TRichView. By implementing hyphenation I mean hyphenating selection/paragraph/document.

2. Hyphenation is heavily dependant on language, so is there a "language text attribute" determining the language a word belongs to? (E.g. in document written in more than one language)

Thanks!
Dejan
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

1. Do you want to implement it as undoable operation?

2. By default, there is no Language property. However, if you define RVLANGUAGEPROPERTY in RV_Defs.inc and recompile the source code, this language will appear. This property will be saved to RTF/DocX/RVF. However, it will not be assigned automatically basing on the keyboard layout.
This property is a feature reserved for future use.
dex
Posts: 5
Joined: Tue Oct 22, 2013 9:19 pm

Post by dex »

Yes, if it can be undoable even better. Unlike MS Word which hyphenates only few words located around end of line, I want to hyphenate every word from selection. Such text can be easily reused in DTP software (Illustrator, Quark, etc.)

In order to avoid changing of text formatting, I would like to do the following:

1. take all words from selection, one by one
2. hyphenate each word with separate HyphenateWord function
3. using the result just insert soft hyphens at appropriate locations directly in the word in text

Removing hyphenation should delete all soft hyphens from the selection.

If Language is the property which can be accessed for every word, then HyphenateWord would skip words not belonging to the desired Language.

How do I do this with RVE?
dex
Posts: 5
Joined: Tue Oct 22, 2013 9:19 pm

Post by dex »

Any thoughts?

I tried to insert soft hyphen manually (Ctrl + -) using your demo projects, no success.
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Here is an example how to hyphenate the selection.

Let we have a function
function HyphenateWords(var s: String; FirstIndex, LastIndex: Integer): Boolean;
This function hyphenates words in the substring of s from the FirstIndex-th to the LastIndex-th characters (index of the first character = 1). It must return True if the string is changed.

For example, I used this function for testing:

Code: Select all

function HyphenateWords(var s: String; FirstIndex, LastIndex: Integer): Boolean;
var i: Integer;
begin
  Result := False;
  for i := LastIndex-1 downto FirstIndex do
    if (s[i] in ['a'..'z']) and (s[i+1] in ['a'..'z']) then begin
      Insert('-', s, i+1);
      Result := True;
    end;
end;
This function adds '-' between lowercase English characters.

The following procedure hyphenates the selection:

Code: Select all

procedure HyphenateSelection(rve: TCustomRichViewEdit);

var Started: Boolean;

   procedure ChangeText(ItemNo: Integer; const s: String);
   begin
     if not Started then begin
       rve.BeginUpdate;
       rve.BeginUndoGroup(rvutModifyItem);
       rve.SetUndoGroupMode(True);
       Started := True;
     end;
     rve.SetItemTextEd(ItemNo, s);
   end;

var i, StartItemNo, StartOffs, EndItemNo, EndOffs, v: Integer;
    s: String;
begin
  rve := rve.TopLevelEditor;
  rve.GetSelectionBounds(StartItemNo, StartOffs, EndItemNo, EndOffs, True);
  if StartItemNo<0 then
    exit;
  Started := False;
  s := rve.GetItemText(StartItemNo);
  if StartItemNo=EndItemNo then begin
    v := Length(s)-(EndOffs-1);
    if HyphenateWords(s, StartOffs, EndOffs-1) then begin
      ChangeText(StartItemNo, s);
      rve.SetSelectionBounds(StartItemNo, StartOffs, EndItemNo, Length(s)-v+1);
    end;
    end
  else begin
    if HyphenateWords(s, StartOffs, Length(s)) then
      ChangeText(StartItemNo, s);
    for i := StartItemNo+1 to EndItemNo-1 do begin
      s := rve.GetItemText(i);
      if HyphenateWords(s, 1, Length(s)) then
        ChangeText(i, s);
    end;
    s := rve.GetItemText(EndItemNo);
    v := Length(s)-(EndOffs-1);
    if HyphenateWords(s, 1, EndOffs-1) then begin
      ChangeText(EndItemNo, s);
      rve.SetSelectionBounds(StartItemNo, StartOffs, EndItemNo, Length(s)-v+1);
    end;
  end;
  if Started then begin
    rve.SetUndoGroupMode(False);
    rve.EndUpdate;
  end;

end;
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

TRichViewEdit does not processes Ctrl+'-'.
You can process it itself (for example, by adding an action with this shortcut) and call RichViewEdit1.InsertTextW(WideChar($00AD));
alexander halser
Posts: 16
Joined: Mon Oct 31, 2005 5:31 pm
Location: Salzburg/Austria
Contact:

Post by alexander halser »

We implemented automatic hyphenation in our help authoring tool Help & Manual. The hyphenation is based on the free OpenOffice dictionaries and the open source spell checker Hunspell.

The Delphi implementation is available from our website:
http://www.helpandmanual.com/downloads_delphi.html

Once you have loaded a dicitionary, you can auto-hyphenate a word with this function:

Code: Select all

  procedure HyphenateWord(var AWord: string; const IntWordLen: integer);
  var
    l, k: integer;
    tmpWord: String;
  begin
    if intWordLen > 3 then
    try
      tmpWord := HyphenDictionary.Hyphenate(aWord)
      if (tmpWord <> aWord) then  //tmpWord has hyphenation breaks in the form of equal signs "="
      begin
        k := length(tmpWord);
        for l := 1 to k do
          case tmpWord[l] of
          '=': Insert(Char(UNI_SOFT_HYPHEN), AWord, l);
          end;
      end;
    except
    end;
  end;
dex
Posts: 5
Joined: Tue Oct 22, 2013 9:19 pm

Post by dex »

This is great!

Thanks, I'll give it a try.

Dejan
Post Reply