![]() |
rtf zu plaintext (ohne TRichEdit)
Hallo liebe DPler,
ich bin auf der Suche nach einer Möglichkeit, aus rtf-Texten den einfachen Text zu extrahieren. Diverse Threads hier in der DP verwiesen immer auf die Möglichkeit der Konvertierung mittels TRIchEdit. Ich suche aber nach einer Möglichkeit, das ohne den großen Komponenten-Overhead zu realisieren, also mit einfachen Funktionen oder wenigstens einer nichtvisuellen Komponente. Denn es geht darum, eine Funktion für einen DB-Server (Firebird) zu schreiben, die bei jeder Datensatzänderung einige rtf-Memo-Felder parst. Das wird bei Firebird über Aufrufe einer DLL realisiert, es wäre also relativ aufwändig, jedesmal eine TRichEdit-Instanz zu erzeugen. Also: Kennt jemand einen Algorithmus, eine Funktionsbibliothek oder eine nichtvisuelle Komponente, die aus einem rtf-String die Tags entfernt und den bloßen Text zurückgibt. Wäre über jede Idee dankbar. MfG Urs |
Re: rtf zu plaintext (ohne TRichEdit)
Zitat:
|
Re: rtf zu plaintext (ohne TRichEdit)
Klar funktioniert die,
aber ich muss weitere Units einbinden und eine relativ komplexe Komponente instantiieren. Und das wahnsinnig oft, für jeden Datensatz mindestens einmal. Man muss vielleicht nicht immer ganz pingelig sein mit dem Versuch, alle Routinen so effizient wie möglich zu programmieren; aber eine Routine, die als externe Funktion in einen Datenbankserver integriert werden soll, sollte zumindest nicht die größten Komponenten auffahren, wenn die gar nicht benötigt werden... MfG Urs |
Re: rtf zu plaintext (ohne TRichEdit)
Zitat:
Zitat:
Wenn Du ihn nicht willst, heißt es du mußt den RTF-Stream parsen und entsprechende Formatierungskennzeichner von Textelementen trennen. Und ob diese schlanker wird als eine schon seid Win95 vorhandene Systemkomponente? |
Re: rtf zu plaintext (ohne TRichEdit)
Zitat:
Die Funktion ist in einer DLL, die vom Firebird-Server als UDF (User Defined Function) aufgerufen wird. Erstens bin ich mir nicht sicher, ob die DLL zwischen den Aufrufen überhaupt geladen ist bzw. Objekte behalten kann (lässt sich wahrscheinlich relativ leicht klären). Und zweitens müsste das ganze Thread-sicher sein, und das ist ja mit globalen Variablen/Objekten nicht so unproblematisch. Zitat:
Danke und fG Urs |
Re: rtf zu plaintext (ohne TRichEdit)
Zitat:
Hast Du Dir mal angeschaut, was tatsächlich in einem rtf-File so alles drin steckt ? Also wenn man sich z.B. eine eigene Delphi-Routine schreibt, die da diesen ganze Steuerzeichen-Kram raus filtert und nur noch reinen Text hinter lässt - dann sei es mal dahin gestellt, ob das dann wirklich weniger Binär-Code ergeben würde als die Instanz von TRichEdit. Ich würde einfach TRichEdit nehmen, und Möglichkeiten, die Dinge so effizient wie möglich zu gestalten wirst Du an anderer Stelle noch genug haben. |
Re: rtf zu plaintext (ohne TRichEdit)
Zitat:
Zitat:
Zitat:
Danke für die Meinungen MfG Urs |
Re: rtf zu plaintext (ohne TRichEdit)
Hi,
ich glaube ich habe da etwas. Ich hoffe es ist das wonach du suchst. Ich muss aber direkt dazu sagen, dass ich die funktion nicht getestet habe, da ich sie nur in der TICQLib Komponente gefunden hab. ![]() hier nun die funktion:
Code:
ich hoffe ich konnte helfen.
{Convert RTF enabled text to plain.}
function RTF2Plain (const aSource: string): string; var Source: string; NChar: Integer; function ProcessGroupRecursevly: string; procedure SkipStar; var BracesOpened: Integer; Escaped: Boolean; begin BracesOpened:=1; Escaped:=false; while BracesOpened>0 do begin Inc (NChar); case Source [NChar] of '{': if Escaped then Escaped:=false else Inc (BracesOpened); '}': if Escaped then Escaped:=false else Dec (BracesOpened); '\': Escaped:=not Escaped; else Escaped:=false; end; end; end; function UnicodeCharCode2ANSIChar (aCode: LongInt): Char; type TUnicode2ANSITable=array [$0410..$044f] of Char; const Unicode2ANSITable: TUnicode2AnsiTable=('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ'); begin if (Low (Unicode2ANSITable)<=aCode) and (aCode<=High (Unicode2ANSITable)) then UnicodeCharCode2ANSIChar:=Unicode2ANSITable [aCode] else UnicodeCharCode2ANSIChar:='?'; end; var Control, NumericValue, TextValue: string; begin Result:=''; Inc (NChar); while NChar<=Length (Source) do case Source [NChar] of '{': Result:=Result+ProcessGroupRecursevly; '}': begin Inc (NChar); Break; end; '\': begin Inc (NChar); case Source [NChar] of '''': begin Result:=Result+Chr (HexToInt (Copy (Source, NChar+1, 2))); Inc (NChar, 3); end; '~': Result:=Result+#$20; '*': SkipStar; 'a'..'z': begin Control:=''; while Source [NChar] in ['a'..'z'] do begin Control:=Control+Source [NChar]; Inc (NChar); end; if Source [NChar]='-' then begin NumericValue:=Source [NChar]; Inc (NChar); end else NumericValue:=''; while Source [NChar] in ['0'..'9'] do begin NumericValue:=NumericValue+Source [NChar]; Inc (NChar); end; if Source [NChar]='{' then ProcessGroupRecursevly; TextValue:=''; if not (Source [NChar] in ['a'..'z', '{', '}', '\']) then begin Inc (NChar); while not (Source [NChar] in ['{', '}', '\']) do begin TextValue:=TextValue+Source [NChar]; Inc (NChar); end; end; if (Control='line') or (Control='par') then Result:=Result+#$0D#$0A else if Control='tab' then Result:=Result+#$09 else if Control='u' then Result:=Result+UnicodeCharCode2ANSIChar (StrToInt (NumericValue)) else if Control='colortbl' then TextValue:=''; if Length (TextValue)>0 then if (not ((TextValue [Length (TextValue)]=';') and (Source [NChar]='}'))) then begin Result:=Result+TextValue; TextValue:=''; end; end; else begin Result:=Result+Source [NChar]; Inc (NChar); end; end; end; else begin Result:=Result+Source [NChar]; Inc (NChar); end; end; end; function InitSource: Boolean; var BracesCount: Integer; Escaped: Boolean; begin if Copy (aSource, 1, 5)<>'{\rtf' then InitSource:=false else begin Source:=''; BracesCount:=0; Escaped:=false; NChar:=1; while (NChar<=Length (aSource)) and (BracesCount>=0) do begin if not (aSource [NChar] in [#$0D, #$0A]) then begin Source:=Source+aSource [NChar]; case aSource [NChar] of '{': if not Escaped then Inc (BracesCount) else Escaped:=false; '}': if not Escaped then Dec (BracesCount) else Escaped:=false; '\': Escaped:=true; else Escaped:=false; end; end; Inc (NChar); end; InitSource:=BracesCount=0; end; end; begin if InitSource then begin NChar:=1; Result:=ProcessGroupRecursevly; end else Result:=aSource; end; mfg PeterP. |
Re: rtf zu plaintext (ohne TRichEdit)
Hoppla, das ist ja eine späte Überraschung.
@PeterP. Ich werde die Funktion mal näher ansehen und testen. Sollte sie korrekt arbeiten, wäre das tatsächlich ganz genau das, was ich gesucht habe! Danke Urs |
Re: rtf zu plaintext (ohne TRichEdit)
Besser spät als nie, oder ? :-D
Hab den Thread nur durch Zufall gesehen. Aber sag mal bitte bescheid, ob diese Funktion auch einwandfrei funktioniert. mfg PeterP. |
Re: rtf zu plaintext (ohne TRichEdit)
Zitat:
Ich habe die Funktion vorläufig zum Laufen bekommen. Eine Hilfsfunktion "HexToInt" fehlte, doch konnte ich die selbst ergänzen. Nun läuft die Funktion zumindest ohne Fehler, nach ersten Versuchen scheint sie auch bis auf winzige Unterschiede (Leerzeichen oder Zeilen-/Absatzwechsel?) alles richtig zu machen. Ich werde dem wohl noch etwas weiter nachgehen und mehr Tests machen. Nochmal vielen Dank Urs P.S. Wie ist das denn jetzt eigentlich? Ich habe nun diese Funktion aus einem OpenSource-Projekt genommen und um eine weitere Unterfunktion verändert. Darf ich das denn? :pale: |
AW: rtf zu plaintext (ohne TRichEdit)
Hallo,
langer her seit dem letzten Beitrag hier... Wir nutzen diese Funktion auch (Beitrag #8 in diesem Thread), mussten aber kürzlich feststellen, dass sie nur bedingt funktioniert - scheinbar nur wenn man mit ANSI-Inhalten arbeitet. Wenn man damit Unicode-Inhalte ermitteln will, z.B. den Text, den man auf Russisch (kyrillisch) oder chinesisch eingegeben hat, wird alles andere geliefert als das richtige Ergebnis. Hat vielleicht jemand diese Funktion schon mal auf Unicode "umgestellt"? Gibt es vielleicht inzwischen eine andere Möglichkeit, Plain-Text aus einem RTF-Text ohne TRichEdit zu ermitteln? |
AW: rtf zu plaintext (ohne TRichEdit)
Ist schon etwas länger her, daß ich mich mit RTF beschäftigt habe, aber zumindestens bei kyrillischen Buchstaben, sollte es "ausreichen" den richtigen Font mit der richtigen Chartable zu kombinieren.
Gruß K-H |
AW: rtf zu plaintext (ohne TRichEdit)
Zitat:
![]() |
AW: rtf zu plaintext (ohne TRichEdit)
und wie wird die Function aufgerufen?
|
AW: rtf zu plaintext (ohne TRichEdit)
Instanz erzeugen, mit ReadData RTF einlesen, mit der Property PlainText auf den reinen Text zugreifen, Instanz wieder freigeben, glücklich sein.
|
AW: rtf zu plaintext (ohne TRichEdit)
Hallo Detlev,
hast Du mal ein Beispiel für mich. |
AW: rtf zu plaintext (ohne TRichEdit)
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Classes, uRTFConverter; var test: TBytesStream; RTF2Plain: TRTF2PlainConverter; begin test := nil; RTF2Plain := nil; try test := TBytesStream.Create; test.LoadFromFile('Dokument.rtf'); RTF2Plain := TRTF2PlainConverter.Create; RTF2Plain.ReadData(test.Bytes); Write(RTF2Plain.Plaintext); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; test.Free; RTF2Plain.Free; end. |
AW: rtf zu plaintext (ohne TRichEdit)
Danke samso hat bestens funktioniert.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz