AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

rtf zu plaintext (ohne TRichEdit)

Ein Thema von urs.liska · begonnen am 23. Jan 2005 · letzter Beitrag vom 24. Apr 2012
Antwort Antwort
Seite 1 von 2  1 2   
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#1

rtf zu plaintext (ohne TRichEdit)

  Alt 23. Jan 2005, 20:32
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
  Mit Zitat antworten Zitat
TStringlist

Registriert seit: 1. Dez 2003
360 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 23. Jan 2005, 22:06
Zitat von urs.liska:
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.
Zur Not könntest du eine TRichEdit-Komponente ja unsichtbar halten, sie also mit visible := false betreiben. Funktionieren müsste die dann im Prinzip nämlich noch genauso.
MfG (& Thx ggf.)
  Mit Zitat antworten Zitat
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#3

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 23. Jan 2005, 23:25
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
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
Ort: Oberreichenbach
14.323 Beiträge
 
Delphi XE6 Professional
 
#4

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 24. Jan 2005, 07:22
Zitat von urs.liska:
aber ich muss weitere Units einbinden und eine relativ komplexe Komponente instantiieren. Und das wahnsinnig oft, für jeden Datensatz mindestens einmal.
Du brauchst ja diese Instanz nicht jedesmal wieder zerstören. Was spricht dagegen eine Instanz der Komponente für die gesamte Laufzeit des Programms am leben zu erhalten?

Zitat von urs.liska:
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...
TRichEdit stellt nur einen Wrapper für die im System installierte RTF-Komponente dar. Dieser Wrapper ist auch noch relativ schlank gehalten.
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?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#5

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 24. Jan 2005, 08:00
Zitat von Bernhard Geyer:
Zitat von urs.liska:
aber ich muss weitere Units einbinden und eine relativ komplexe Komponente instantiieren. Und das wahnsinnig oft, für jeden Datensatz mindestens einmal.
Du brauchst ja diese Instanz nicht jedesmal wieder zerstören. Was spricht dagegen eine Instanz der Komponente für die gesamte Laufzeit des Programms am leben zu erhalten?
Ich werde dem mal nachgehen, aber ich fürchte, das könnte Probleme geben.
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 von Bernhard Geyer:
Zitat von urs.liska:
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...
TRichEdit stellt nur einen Wrapper für die im System installierte RTF-Komponente dar. Dieser Wrapper ist auch noch relativ schlank gehalten.
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?
Wenn Du Dir da relativ sicher bist, dass es eine "schlanke" implementierung ist, werde ich es mal probieren. Vielleicht ist ja alles gar nicht so schlimm...

Danke und fG
Urs
  Mit Zitat antworten Zitat
Delphi_Fanatic

Registriert seit: 24. Mär 2004
Ort: Hamburg
201 Beiträge
 
#6

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 24. Jan 2005, 08:03
Zitat:
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
Also, entschuldige mal, aber wenn Du bei jedem Datensatz irgendwelche Komponenten instantiierst und danach wieder frei gibst (und so zumindestens hört sich das an, was Du da schreibst) - dann hat das mit Effizienz nicht mehr viel zu tun.

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.
  Mit Zitat antworten Zitat
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#7

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 24. Jan 2005, 11:41
Zitat von Delphi_Fanatic:
Also, entschuldige mal, aber wenn Du bei jedem Datensatz irgendwelche Komponenten instantiierst und danach wieder frei gibst (und so zumindestens hört sich das an, was Du da schreibst) - dann hat das mit Effizienz nicht mehr viel zu tun.
Ich will ja nicht meckern, aber bei genauer Lektüre des Threads hättest Du wahrscheinlich gemerkt, dass es mir genau darum geht, das zu vermeiden. Deshalb bin ich ja auf der Suche nach einer entsprechenden Routine - ohne den VCL- bzw. Windows-Overhead.

Zitat von Delphi_Fanatic:
Hast Du Dir mal angeschaut, was tatsächlich in einem rtf-File so alles drin steckt ?
Nur so ungefähr. Mir scheint als Problem dazuzukommen, dass außer den Formatierungs-Steuerzeichen auch die Sonderzeichen umgewandelt werden (ähnlich der HTML-Codierung). D.h. diese müsste man auch noch alle rausfiltern bzw. zurückumwandeln. Da kommt man schon in Teufels Küche, und ich denke, das ist kaum selbst zu leisten.
Zitat von Delphi_Fanatic:
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.
Hmm, werde ich wohl oder übel probieren müssen.

Danke für die Meinungen
MfG
Urs
  Mit Zitat antworten Zitat
PeterP.
(Gast)

n/a Beiträge
 
#8

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 4. Feb 2005, 16:45
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.
http://sourceforge.net/projects/ticqlib

hier nun die funktion:
Code:
{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;
ich hoffe ich konnte helfen.

mfg
PeterP.
  Mit Zitat antworten Zitat
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#9

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 4. Feb 2005, 20:26
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
  Mit Zitat antworten Zitat
PeterP.
(Gast)

n/a Beiträge
 
#10

Re: rtf zu plaintext (ohne TRichEdit)

  Alt 5. Feb 2005, 15:04
Besser spät als nie, oder ?
Hab den Thread nur durch Zufall gesehen.

Aber sag mal bitte bescheid, ob diese Funktion auch einwandfrei funktioniert.


mfg
PeterP.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2014 by Daniel R. Wolf