Difference between revisions of "TbUtf8"

From Lazarus wiki
Jump to navigationJump to search
 
(8 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
__TOC__
 
__TOC__
  
== Was ist TbUtf8? ==
+
== About ==
Mit der Bibliothek TbUtf8 kann man auf einfache Weise Utf8 Strings verändern.
+
 
 +
'''TbUtf8''' is a library to easily change UTF-8 encoded strings.
  
 
=== Problem ===
 
=== Problem ===
Bei Lazarus (Free Pascal) ist der String UTF8 kodiert. Allerdings ist der Type „String“ nichts anderes als ein dynamisches Byte- Array. Length liefert die Anzahl der Bytes im Array aber nicht die Anzahl der Zeichen. Bei UTF8 kann ein Zeichen 4Byte groß sein und mit kombinierten  Zeichen sogar 7 Byte.
+
With Lazarus (Free Pascal) the string UTF8 encoded. However, the "String" type is nothing more than a dynamic byte array. Length returns the number of bytes in the array but not the number of characters. With UTF8, a character can be 4 bytes long and even 7 bytes with combined characters. An example should illustrate this. 'Thomas' 6 characters, 6 bytes in size. 'Thömäs' 6 characters, 8 bytes in size.
Ein Beispiel soll das veranschaulichen.
 
‚Thomas‘ 6 Zeichen, 6 Byte groß.
 
‚Thömäs‘ 6 Zeichen, 8 Byte groß.
 
 
 
=== Lösung ===
 
Mit TbUtf8 kann man jetzt auf einfache Weise UTF8 Strings mit Sonder- und kombinierten  Zeichen, wie „üäößẶặǺǻǼǽǞǟǍǎḂḃÞþÇçĆćĊċ…“  verändern und durchsuchen. Im wesentlichen besteht die Bibliothek aus einer UTF8 String Klasse (TIbUtf8).
 
 
 
=== Vorteile ===
 
*TIbUtf8 ist eine Klasse vom Typ TInterfacedObject und muss nicht aufgeräumt werden.
 
*Alle Indexe sind Zeichen basiert.
 
*Alle Zeichen Rückgabewerte sind vom Typ String.
 
*Liefert Anzahl der Zeichen im String.
 
*Liefert Anzahl der Bytes im String.
 
*Löschen von Zeichen oder Zeichengruppen.
 
*Einfügen von Zeichen und Zeichengruppen.
 
*Anhängen von Zeichen und Zeichengruppen.
 
*Lesen / Schreiben von Zeichen und Zeichengruppen.
 
*Lesen / Schreiben in eine Datei.
 
*Lesen / Schreiben in einen Stream.
 
  
=== Nachteil ===
+
=== Solution ===
*Da UTF8 keinen konstanten Offset von Zeichen zu Zeichen hat, ist das Suchen nach Zeichen deutlich aufwendiger. Das Iterieren über die Zeichen ist ca. 20 x langsamer als beim String. (Komfort hat eben seinen Preis)
+
With TbUtf8 you can now easily change and search UTF8 strings with special and combined characters, such as "üäößẶặǺǻǼǽǞǟǍǎḂḃÞþÇçĆćĊċ...". Essentially, the library consists of a UTF8 string class (TIbUtf8).
*Es wird etwas mehr Speicher benötigt.
 
 
 
== DownLoad ==
 
* GitLab FpTuxe/TbUtf8 repository
 
[https://gitlab.com/FpTuxe/tbutf8 FpTuxe/TbUtf8]
 
* Git clone
 
<syntaxhighlight lang="bash">
 
git clone https://gitlab.com/FpTuxe/tbutf8.git
 
</syntaxhighlight>
 
  
== Installation ==
+
=== Benefits ===
;Varinate 1
+
*TIbUtf8 is a class type of TInterfacedObject and does not need to be cleaned up with free.
:Lazarus->Datei->öffnen
+
*All indexes are character based.
:  dein Pfad /tbutf8/src/tb_utf8.pas -> Öffnen
+
*All returned characters are of type String.
:Lazarus->Projekte->Datei im Editor ins Projekt aufnehmen.
+
*Returns the number of characters in the string.
 +
*Returns the number of bytes in the string.
 +
*Delete characters or character groups.
 +
*Insertion of characters and character groups.
 +
*Appending characters and character groups.
 +
*Reading / writing of characters and character groups.
 +
*Read from file / write to a file.
 +
*Read from stream / write to a stream.  
  
;Varinate 2
+
=== Disadvantage ===
:Lazarus->Package->Package-Datei (.lpk) öffen
+
*Since UTF8 does not have a constant offset from character to character, searching for characters is much more complex. Iterating over the characters is about 20 times slower than with the string. (Comfort has its price)
:  dein Pfad /tbutf8/src/tbutf8.lpk -> Öffnen
+
*Slightly more memory is required.
:Verwenden->Zum Projekt hinzufügen.
 
:Package Fenster schliessen.
 
  
== Funktionsbeschreibung ==
 
=== Allgemein ===
 
Alle Indexe halten sich an die Pascal- Notation.
 
Erste Zeichen hat den Index 1, letzte Zeichen hat den Index NumberOfChars.
 
Nach dem Erzeugen einer Instanz hat Options den Wert [ut8Combining].
 
Nach dem Zuweisen von Text hat CurrentIndex den Wert 1.
 
  
=== Instanz erzeugen ===
+
=== Example ===
Es wird immer eine Variable vom Typ „IbUtf8“ benötigt. NICHT vom Type TIbUtf8!!!
 
Das ‚I‘ in  IbUtf8 steht für Interface.
 
Das ‚I‘ in TIbUtf8 steht für InterfacedObject.
 
Beispiel:
 
<syntaxhighlight lang="pascal">
 
procedure Demo01;
 
var Name:  IbUtf8;
 
begin
 
  Name:= TIbUtf8.Create('Boris');
 
end;
 
</syntaxhighlight>
 
oder
 
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
procedure Demo02;
 
var Name:  IbUtf8;
 
begin
 
  Name:= TIbUtf8.Create;
 
  Name.Text:= 'Boris';
 
end;
 
</syntaxhighlight>
 
Beim Verlassen der Procedure wird die Instanz automatisch aufgelöst.
 
 
=== Options ===
 
*ut8Combining: Ist dieser Wert gesetzt, werden Zeichen mit kombinierten Zeichen als ein Zeichen interpretiert.
 
*ut8InclusiveCurrentChar: Dieser Wert verändert das Verhalten von NextChar und BackChar. Ist der Wert gesetzt, liefert NextChar und BackChar immer das aktuelle Zeichen (CurrentIndex) und geht dann zum nächsten Zeichen. Ist der Wert nicht gesetzt, bekommt man immer das nächste Zeichen.
 
Beispiel:
 
<syntaxhighlight lang="pascal">
 
procedure Demo03;
 
 
var
 
var
   Name: IbUtf8;
+
   u: IbUtf8;
begin
+
   i: Integer;
  Name:= TIbUtf8.Create('Hello');
 
  Name.CurrentIndex:= 1;
 
   Name.Options:=  Name.Options + [Ut8InclusiveCurrentChar];
 
  while (not Name.IsStringEnd) and (Name.NextChar <> 'l') do;
 
  if Name.CurrentChar = 'l' then begin
 
  WriteLn('Richtig'):
 
  end;
 
end;
 
</syntaxhighlight>
 
 
 
=== NumberOfChars ===
 
Liefert die Anzahl der Zeichen. Dieser Wert ist abhängig von der Option Ut8Combining.
 
Siehe auch Options.
 
 
 
=== Length ===
 
Liefert  Anzahl der Bytes die der Text im Buffer belegt.
 
 
 
=== IsEmpty ===
 
Ist der String leer, so ist der Rückgabewert True.
 
 
 
=== IsEqual(aText) ===
 
Ist der Text (aText) gleich dem Text in der Instanz, dann ist der Rückgabewert True.
 
 
 
=== IsStringEnd ===
 
Ist CurrentIndex am Stringende (CurrentIndex >= NumberOfChars), oder ist der String leer, dann ist der Rückgabewert True.
 
 
 
=== IsStringFront ===
 
Ist CurrentIndex = 1 oder der String ist leer, dann ist der Rückgabewert True.
 
 
 
=== FirstChar ===
 
Liefert das erste Zeichen des Strings. Ist der String leer, gibt es eine Exception.
 
 
 
=== LastChar ===
 
Liefert das Letzte Zeichen in dem String. Ist der String leer, gibt es eine Exception.
 
 
 
=== NextChar ===
 
Liefert das nächste Zeichen. Das Verhalten ist abhängig von der Option Ut8InclusiveCurrentChar.
 
Siehe auch Options
 
Ist der String leer, oder CurrentIndex am Ende des Strings, wird ein Leerstring zurückgegeben.
 
CurrentIndex wird um 1 erhöht.
 
 
 
=== BackChar ===
 
Liefert das vorige Zeichen. Das Verhalten ist abhängig von der Option Ut8InclusiveCurrentChar.
 
Siehe auch Options
 
Ist der String leer oder CurrentIndex am Anfang des Strings, wird ein Leerstring zurück gegeben.
 
CurrentIndex wird um 1 erniedrigt.
 
 
 
=== Text ===
 
Lesend: Liefert den String.
 
Schreibend: Speichert den Text in der Instanz. Ist es kein Leerstring wird CurrentIndex auf 1 gesetzt, ansonsten auf 0.
 
 
 
=== CurrentIndex ===
 
Lesend: Gibt die aktuelle Indexposition zurück.
 
Schreibend: Setzt die neue  Indexposition. Ist die Indexposition außerhalb des zulässigen Bereiches, gibt es eine Exception.
 
 
 
=== CurrentChar ===
 
Liefert das Zeichen, wo CurrentIndex drauf verweist. Ist der Text leer, wird ein Leerstring zurückgegeben.
 
 
 
=== Chars[Index] ===
 
Lesend: Liefert ein Zeichen, welches durch den Index angegeben ist.
 
Schreibend: Ersetzt das Zeichen, welches durch den Index angegeben wird. Es können auch mehrere Zeichen angegeben werden.
 
Ist die Indexposition außerhalb des zulässigen Bereiches, gibt es eine Exception.
 
Beispiel:
 
<syntaxhighlight lang="pascal">
 
procedure Demo04;
 
var  Name: IbUtf8;
 
 
begin
 
begin
   Name:= TIbUtf8.Create('Heko');
+
   u:= TIbUtf8.Create('Thömäß');
   Name.Chars[3]:= 'll';
+
   for i:= 1 to u.NumberOfChars do begin
  if Name.Text = 'Hello' then begin
+
    case u.Chars[i] of
    WriteLn('Richtig');
+
      'ö': u.Chars[i]:= 'o';
 +
      'ä': u.Chars[i]:= 'a';
 +
      'ß': u.Chars[i]:= 's';
 +
    end;
 
   end;
 
   end;
end;
+
   if u.Text = 'Thomas' then begin
</syntaxhighlight>
+
     WriteLn('That''s right!');
 
 
=== Copy ===
 
Erzeugt eine neue Instanz mit gleichem Inhalt.
 
 
 
=== Copy(StartIndex, nChars) ===
 
Erzeugt eine neue Instanz mit dem Text von StartIndex bis nChars.
 
Ist StartIndex außerhalb des zulässigen Bereiches, gibt es eine Exception.
 
Ist nCharts = 0, wird ein Leerstring zurück gegeben.
 
Ist nChars > Stringende werden die Zeichen bis Stringende kopiert.
 
 
 
Beispiel:
 
<syntaxhighlight lang="pascal">
 
procedure Demo05;
 
var  Name, Nachname: IbUtf8;
 
begin
 
  Name:= TIbUtf8.Creatre('Boris Weber')
 
  Nachname:= Name.Copy(7, 5);
 
   if Nachname.Text = 'Weber' then begin
 
     WriteLn('Richtig');
 
 
   end;
 
   end;
end;
+
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== CopyAsString(StartIndex, nChars) ===
+
== Download ==
Verhält sich wie Copy(StartIndex, nChars), nur wird hier ein String zurückgegeben.
+
* GitLab repository: [https://gitlab.com/FpTuxe/tbutf8 FpTuxe/TbUtf8]
 
+
* Git clone:
=== Delete(CharIndex: Cardinal) ===
+
<syntaxhighlight lang="bash">
Löscht ein Zeichen.
+
git clone https://gitlab.com/FpTuxe/tbutf8.git
Ist CharIndex außerhalb des zulässigen Bereiches, gibt es eine Exception.
 
 
 
=== Delete(StartIndex, nChars) ===
 
Löscht nChars ab dem StartIndex.
 
Bei StartIndex außerhalb des zulässigen Bereiches, gibt es eine Exception.
 
Ist nCharts = 0, wird nichts gelöscht.
 
Ist nChars > Stringende wird bis zum Stringende gelöscht.
 
 
 
Beispiel:
 
<syntaxhighlight lang="pascal">
 
procedure Demo06;
 
var  Name: IbUtf8;
 
begin
 
  Name:= TIbUtf8.Create('Boris Weber');
 
  Name.Delete(1, 6);
 
  if Name.Text = 'Weber' then begin
 
    WriteLn('Richtig');
 
  end;
 
end;
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Insert(StartIndex, aValue) ===
+
== Installation ==
Insert gibt es zweimal. Einmal kann man ein String einfügen, das andere mal eine IbUtf8 Instanz.
+
;Variant  1
StartIndex legt fest, ab welcher Position der Text eingefügt wird.
+
:Start Lazarus and open your project.
Bei StartIndex = 0, gibt es eine Exception.
+
:Lazarus->File->Open your workspace/tbutf8/src/tb_utf8.pas
Bei StartIndex > Stringende wird der Text am Ende angehängt.
+
:Lazarus->Project->Add Editor File to Project
 
 
Beispiel:
 
<syntaxhighlight lang="pascal">
 
procedure Demo07;
 
var  Name: IbUtf8;
 
begin
 
  Name:= TIbUtf8.Create('Bor');
 
  Name.Insert(4, 'is Weber');
 
  if Name.Text = 'Boris Weber' then begin
 
    WriteLn('Richtig');
 
  end;
 
end;
 
</syntaxhighlight>
 
 
 
=== Kombinierte Zeichen ===
 
Sollten die kombinierten Zeichen, die in „tb_utf8_combinings.pas“ definiert sind, nicht ausreichen, so kann einfach die Tabelle „C_COMBINIGS“ um die neuen Werte oder Wertebereiche erweitert werden. Zur Zeit sind 4 Blöcke definiert.
 
  
 +
;Variant  2
 +
:Start Lazarus and open your project.
 +
:Lazarus->Package->Open Package File (.lpk) your workspace/tbutf8/src/tbutf8.lpk
 +
:Now, click Use->Add to Project
 +
:Close then Package window.
  
[[Category:Unicode]]
+
== Functional Description ==
 +
The functional description, you can found under the project folder "doc/".

Latest revision as of 22:26, 15 April 2022

Deutsch (de) English (en)

About

TbUtf8 is a library to easily change UTF-8 encoded strings.

Problem

With Lazarus (Free Pascal) the string UTF8 encoded. However, the "String" type is nothing more than a dynamic byte array. Length returns the number of bytes in the array but not the number of characters. With UTF8, a character can be 4 bytes long and even 7 bytes with combined characters. An example should illustrate this. 'Thomas' 6 characters, 6 bytes in size. 'Thömäs' 6 characters, 8 bytes in size.

Solution

With TbUtf8 you can now easily change and search UTF8 strings with special and combined characters, such as "üäößẶặǺǻǼǽǞǟǍǎḂḃÞþÇçĆćĊċ...". Essentially, the library consists of a UTF8 string class (TIbUtf8).

Benefits

  • TIbUtf8 is a class type of TInterfacedObject and does not need to be cleaned up with free.
  • All indexes are character based.
  • All returned characters are of type String.
  • Returns the number of characters in the string.
  • Returns the number of bytes in the string.
  • Delete characters or character groups.
  • Insertion of characters and character groups.
  • Appending characters and character groups.
  • Reading / writing of characters and character groups.
  • Read from file / write to a file.
  • Read from stream / write to a stream.

Disadvantage

  • Since UTF8 does not have a constant offset from character to character, searching for characters is much more complex. Iterating over the characters is about 20 times slower than with the string. (Comfort has its price)
  • Slightly more memory is required.


Example

var
  u: IbUtf8;
  i: Integer;
begin
  u:= TIbUtf8.Create('Thömäß');
  for i:= 1 to u.NumberOfChars do begin
    case u.Chars[i] of
      'ö': u.Chars[i]:= 'o';
      'ä': u.Chars[i]:= 'a';
      'ß': u.Chars[i]:= 's';
    end;
  end;
  if u.Text = 'Thomas' then begin
    WriteLn('That''s right!');
  end;
end.

Download

git clone https://gitlab.com/FpTuxe/tbutf8.git

Installation

Variant 1
Start Lazarus and open your project.
Lazarus->File->Open your workspace/tbutf8/src/tb_utf8.pas
Lazarus->Project->Add Editor File to Project
Variant 2
Start Lazarus and open your project.
Lazarus->Package->Open Package File (.lpk) your workspace/tbutf8/src/tbutf8.lpk
Now, click Use->Add to Project
Close then Package window.

Functional Description

The functional description, you can found under the project folder "doc/".