Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Text farbig darstellen (https://www.delphipraxis.net/194929-text-farbig-darstellen.html)

stahli 20. Jan 2018 00:43


Text farbig darstellen
 
Ich erzeuge Quelltext und will einzelne Abschnitte zur besseren Übersicht farbig markieren.
Vermutlich nur mit Hintergrundfarben, vielleicht aber auch mal mit kompletten Fonts.

Mit HTML-Styles und Darstellung im TWebBrowser kriege ich das schon hin, aber das ist mit den Zeilenumbrüchen und führenden Leerzeilen nicht so optimal.

Jetzt dachte ich an TRichEdit. Mit "Einfach mal so Farbtags in den Text setzen" wird das aber wohl nichts.
Das Dateiformat erschließt sich mir nicht wirklich.

Mein Text sähe - mit eigenen RTF-Tags - so aus:

Code:
(***************************)
(* Test-Unit for Optimizer *)
(***************************)

unit Unit2;

interface

uses
  System.Classes, Vcl.Graphics, System.Types, System.UITypes;

const
  aConst = 100;

type

  IIntf1 = interface;
[RTF FontName=arial; fcolor=#000000; bcolor: #ffffff"] TClass1 = class;[RTF/]

  IIntf1 = interface
    procedure Execute(NewVal: String); virtual;
    function TestFunc(var Val1: Integer): Boolean;
    prop PropString: string;
    prop PropInteger: Integer rf;
    prop PropBoolean: Boolean v ws vi;
    prop PropByte: Byte s;
    prop PropWord: Word c w rf;
    prop PropString2: string c vi;
  end;

[RTF FontName=arial; fcolor=#000000; bcolor: #ffffff"] TClass1 = class(TInterfacedObject, IIntf1)
  private
[RTF FontName=Courier New; fcolor=#ff0000; bcolor: #ffffff"]   procedure PrivProc; virtual; [RTF/]
  public
    constructor Create; virtual;
    destructor Destroy; override;
    prop XXX: string;
  end;
[RTF/]
implementation

end.

(***************************)
(* Test Unit for Optimizer *)
(***************************)

Der Text muss also verschachtelte Formatierungsanweisungen enthalten.
Das geht nicht anders, da der Gesamttext dynamisch blockweise erzeugt wird.

Ich würde also nochmal einen Parser bauen, der die Formatierungen heraussucht, dann das Ende zum passenden Anfang (also eingebette Blöcke überspringt), die Tags löscht und MyRichEdit.SelText den Font zuweist. Dann das Gleiche für die eingebetteten und nächsten Blöcke.

Gibt es da vielleicht eine einfachere/fertige Lösung?


Oder ist doch HTML und z.B. Leerzeichenwandlung in
Code:
&nbsp
die bessere Lösung? Plaintext bräuchte ich aber dann auch.

Fukiszo 20. Jan 2018 08:26

AW: Text farbig darstellen
 
Guten Morgen Stahli,

also wenn Du bereits eine lauffähige HTML version hast würd ich eher die nehmen da dort mehr möglichkeiten vorhanden sind.
Per RTF was einfärben, dazu brauch man ja nur ein wenig RichEditDemo's sich anschauen,
aber mit HTML könntest du ja auch sprungziele, externen krams, links etc etc etc einbinden.
....IMHO....

Sobald du dein parser fertig hast ist es ja im prinzip egal welche variante, da der ja was losschicken muss, ob der empfänger nun eine RTF oder HTML funktion aufruft ist dir überlassen.

Aber vielleicht hab ich auch alles falsch verstanden, kommt bei mir desöfteren vor, :pale:
in diesem Sinne....

Grüße

edit:
mit parser meint ich sowas hier in etwa: (definitionen lass ich mal weg da ich dein input nicht kenn)

Code:
function ParseText (Input) : Output;
 begin
  Analysiere(Input); <- hier dein input filtern
  Sortiere(Input); <- hier dein input pro zeile vorbereiten
  Formatiere(Input); <- hier dein output vorbereiten
  Result := VorbereiteterOutput; <- hier spuckt ers wieder aus in deinem wunschformat
 end;

Delphi.Narium 20. Jan 2018 09:31

AW: Text farbig darstellen
 
Kennst Du SynEdit? https://github.com/SynEdit/SynEdit

Kennt die Farbhervorhebung für viele Programmiersprachen ..., die Farbgestaltung ist vielfältig anpassbar.

Kann u. a. nach HTML, RTF, Tex exportieren, dabei bleibt dann die Farbgestaltung erhalten. Der Export sieht so aus, wie im Editor. Führende Leerzeichen ... bleiben erhalten.

Für eigene "Sprachen" kann man auch eigene Highlighter bauen.

stahli 20. Jan 2018 12:57

AW: Text farbig darstellen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Vielen Dank. Ihr hattet das schon richtig verstanden.

Ich habe mir aber doch lieber einen eigenen Formatierer gebaut, da ich so flexibler bin und später auch formatierte Darstellungen auf einem Canvas leichter realisieren kann.

Anbei mal als Anregung ein paar Codeschnipsel, falls das jemandem hilft.
Aktuell wird erst mal nur BackColor übernommen.
Ich werde das nach und nach weiter ausbauen. Falls Interesse besteht, werfe ich einen späteren Stand auch gern hier rein.


Delphi-Quellcode:
uses
  ..., Vcl.ComCtrls, Winapi.RichEdit;

procedure RE_SetSelBgColor(RichEdit: TRichEdit; AColor: TColor);
var
  Format: TCHARFORMAT2;
begin
  FillChar(Format, SizeOf(Format), 0);
  with Format do
  begin
    cbSize := SizeOf(Format);
    dwMask := CFM_BACKCOLOR;
    crBackColor := AColor;
    RichEdit.Perform(EM_SETCHARFORMAT, SCF_SELECTION, Longint(@Format));
  end;
end;

procedure RichFormat(const aRichEdit: TRichEdit);
var
  SearchStartPos, SearchLength: Integer;
  P1, P2, PE: Integer;
  P_, C_: Integer;
  sFormat: string;
  lSL: TStringList;
  lS: string;
  lColor: TColor;
begin
  SearchStartPos := 0;
  SearchLength := (Length(aRichEdit.Text) - SearchStartPos);
  aRichEdit.Lines.BeginUpdate;
  repeat
    sFormat := '';
    C_ := 0;
    P1 := aRichEdit.FindText('[RTF ', SearchStartPos, SearchLength, [stMatchCase]);
    if (P1 >= 0) then
    begin
      PE := aRichEdit.FindText(']', SearchStartPos, SearchLength, [stMatchCase]);
      aRichEdit.SelStart := P1;
      aRichEdit.SelLength := (PE - P1 + 1);
      sFormat := aRichEdit.SelText;
      aRichEdit.ClearSelection;
      SearchStartPos := P1;
      SearchLength := (Length(aRichEdit.Text) - SearchStartPos);
      repeat
        P2 := aRichEdit.FindText('[RTF/]', SearchStartPos, SearchLength, [stMatchCase]);
        if (P2 > P1) then
        begin
          P_ := aRichEdit.FindText('[RTF ', SearchStartPos, SearchLength, [stMatchCase]);
          if (P_ >= 0) and (P_ < P2) then
          begin
            Inc(C_);
            SearchStartPos := (P_ + 1);
            SearchLength := (Length(aRichEdit.Text) - SearchStartPos);
          end
          else
          begin
            Dec(C_);
            SearchStartPos := (P2 + 1);
            SearchLength := (Length(aRichEdit.Text) - SearchStartPos);
          end;
        end;
      until (C_ < 0);
      if (P2 > P1) then
      begin
        aRichEdit.SelStart := P2;
        aRichEdit.SelLength := (Length('[RTF/]'));
        aRichEdit.ClearSelection;
        aRichEdit.SelStart := P1;
        aRichEdit.SelLength := (P2 - P1);

        sFormat := StringReplace(sFormat, '[RTL ', '', [rfReplaceAll]);
        sFormat := StringReplace(sFormat, ']', '', [rfReplaceAll]);
        sFormat := StringReplace(sFormat, '; ', #13#10, [rfReplaceAll]);
        lSL := TStringList.Create;
        lSL.Text := sFormat;
        lS := lSL.Values['BackColor'];
        lColor := StrToInt(lS);
        FreeAndNil(lSL);

        RE_SetSelBgColor(aRichEdit, lColor);
        SearchStartPos := P1;
        SearchLength := (Length(aRichEdit.Text) - SearchStartPos);
      end
      else
        Break;
    end;
  until (P1 < 0);
  aRichEdit.Lines.EndUpdate;
end;

//

  Text := '-> [RTF FontName=Arial; FontColor=$0000ff; BackColor=$ff7777]hellblauer [RTF FontName=Arial; FontColor=$0000ff; BackColor=$7777ff]und dazwischen hellroter[RTF/] Text[RTF/]';
  RichEdit.SelText := Text;
  RichFormat(RichEdit);

Uwe Raabe 20. Jan 2018 13:56

AW: Text farbig darstellen
 
Funktioniert das auch z.B. bei 3-facher Schachtelungstiefe?

stahli 20. Jan 2018 14:16

AW: Text farbig darstellen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ja :-)

Delphi-Quellcode:
 Text := '-> [RTF FontName=Arial; FontColor=$0000ff; BackColor=$ff7777]hellblauer [RTF FontName=Arial; FontColor=$0000ff; BackColor=$7777ff]'
    + 'und dazwischen [RTF FontName=Arial; FontColor=$0000ff; BackColor=$77ffff]gelb-[RTF/] hellroter[RTF/] [RTF FontName=Arial; FontColor=$0000ff; BackColor=$77ffff](nochmal gelb)[RTF/] Text[RTF/]';

Ghostwalker 20. Jan 2018 14:29

AW: Text farbig darstellen
 
Wie Fukiszo schon sagte, würde auch ich das lieber über HTML/CSS lösen. Damit bist einfach flexibler.

Leerzeichen kannst du einfach mit &nbsp; ersetzen. Zeilenumbrüche einfach mit einem <br/> und jut. :)

Außerdem hättes du die Möglichkeit (spätere Erweiterung), das du über CSS-Klassen das ganze von "Außen" beinflussen kannst, ohne den Code anzufassen.

Fukiszo 20. Jan 2018 14:37

AW: Text farbig darstellen
 
Also ich hatte die aufgabe doch falsch verstanden. :(
Ich dacht dein endresultat soll deine "Text:=" konstante werden und nicht andersrum.
Also das Text reinkommt und du auf bestimmte wörter/symbole reagiesrt um sie zu färben. (wie SynEdit o.ä.)

Aber solange du happy bist bin ich es auch :)

stahli 20. Jan 2018 14:50

AW: Text farbig darstellen
 
Ach so, dann hatte ich falsch verstanden, dass Du mich richtig verstanden hattest. :roteyes:

So bin ich jetzt sehr zufrieden mit dem Ergebnis.

HTML wäre auch gegangen, aber so ist es für mich übersichtlicher.
Ich kann selbst benötigte Tags definieren und dann die entsprechenden Abschnitte über das RichEdit formatieren lassen (oder entsprechend in anderen Szenarien in anderer Form).

Keine Ahnung, warum RTF so kompliziert gestaltet ist. Das erscheint mir unnötig unübersichtlich.
Aber wenn das das alles intern im RichEdit abgewickelt wird, kann es mir egal sein.

Eine HTML-Datei mit Formatierungen zu erzeugen ist relativ einfach möglich, aber eine RTF erscheint mir zu komplex dafür.

Für mich passt es jetzt so super und der Aufwand ist ja auch nicht so hoch gewesen.

himitsu 20. Jan 2018 18:39

AW: Text farbig darstellen
 
RTF manuell ist nicht unbedingt empfehlenswert, aber wie bei HTML/DOC/usw. kann man auch Komponenten verwenden, welche als Schnittstelle dienen.

z.B. ganz billig ein TRichEdit, darüber den Text formatieren und dann den RTF-Code auslesen,
oder ein DOM wie bei JSON/XML/HTML, um darüber den HTML-Code zu generieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:08 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz