Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   QuoteText parsen? (https://www.delphipraxis.net/182623-quotetext-parsen.html)

Bjoerk 5. Nov 2014 16:41

Delphi-Version: 2007

QuoteText parsen?
 
Das ist [clRed]ein[/clRed][fsBold]Test[/fsBold].

Wie soll ich das denn [clBlue][fsBold]machen[/clBlue][/fsBold]?

Hat jemand eine Idee wie man sowas elegant splitten kann (Pseudocode reicht völlig)? :gruebel:

haentschman 5. Nov 2014 16:56

AW: QuoteText parsen?
 
Moin...

Du möchtest quasi den Text ohne die "[...]"? Dann eine function gebaut welche genau diese Blöcke durch '' ersetzt.
Stichworte:
Copy
PosEx

DeddyH 5. Nov 2014 17:02

AW: QuoteText parsen?
 
Oder StringReplace oder reguläre Ausdrücke (müssten aber unter Delphi 2007 nachgerüstet werden IIRC).

Bjoerk 5. Nov 2014 17:13

AW: QuoteText parsen?
 
Zitat:

Zitat von haentschman (Beitrag 1278809)
Moin...

Du möchtest quasi den Text ohne die "[...]"? Dann eine function gebaut welche genau diese Blöcke durch '' ersetzt.
Stichworte:
Copy
PosEx

Fast. Das ganze soll gedruckt werden. Die Quotes verstehen sich als Canvas.Font Attribute.

Delphi-Quellcode:
type
  TWordInfo = record
    Value: string;
    Style: TFontStyles;
    Color: TColor;
    procedure Draw(Canvas: TCanvas; MMX, MMY: double);
  end;

  TWordLine = class
    ..
  end;

himitsu 5. Nov 2014 17:16

AW: QuoteText parsen?
 
Es gibt bestimmt irgendwo einen BBCode-Parser, welcher das in RTF umwandelt, was fertig formatiert gedruckt werden könnte.


Ansonsten gehst du halt hin:
* Text suchen, bis zum nächsten [ (bei [ ohne Zugehörigkeit zu einem SteuerCode einen Fehler werfen oder es als Text betrachten und weitersuchen)
* den Text drucken
* X-Position um Textbreite verschieben
* das zwischen [ und ] suchen/auswerten
* Font entsprechen umschalten
* von vorne beginnen, bis der Text zu Ende ist

Wenn es nicht zu viele Steuerbefehle sind und man die mit einem Bit speichern könnte, dann könnte man vorher die Befehle durch jeweils ein Zeichen ersetzen und hat dann beim Drucken weniger Aufwand das zu parsen (z.b. #1=fett #2=nicht mehr fett #3= (bis #31, außer #8, #10 und #13 und in Unicode gibt es ein paar nette freie User-Bereiche)
* nächstes Steuerzeichen ode Textende suchen
* Text davor drucken und X verschieben
* Font umschalten
* von vorne beginnen

Man kann das auch gerne in einen Baum zerlegen (mit Text/Steuerbefehlen) und den Baum dann abarbeiten, falls man auch auf Rekursionen reagieren will ... ineinander verschachtelte Befehle, bzw man verwendet eine Referenzzählung für das Aktivieren/Deaktivieren, bzw. eine Queue.

p80286 5. Nov 2014 17:21

AW: QuoteText parsen?
 
Delphi-Referenz durchsuchenAnsiReplaceText

Gruß
K-H

Oh Mann vergiß es

Sir Rufo 5. Nov 2014 18:23

AW: QuoteText parsen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Nur so zum Starten ein kleiner Parser (als State-Machine) quick und dirty.
Der kann auf jeden Fall das hier produzieren
Anhang 42107
Delphi-Quellcode:
unit Parser.BBCode;

interface

uses
  Vcl.Graphics, System.SysUtils, System.Generics.Collections;

type
  TTextPart = class
  private
    FFont: TFont;
    FText: string;
  public
    constructor Create( AFont: TFont; const AText: string );
    property Font: TFont read FFont;
    property Text: string read FText;
  end;

  TBBCodeParser = class
  private type
    TState = procedure( AChar: Char ) of object;
  private
    FParts: TList<TTextPart>;
    FCommandStack: TList<string>;
    FDefaultFont: TFont;
    FState: TState;
    FFont: TFont;
    FTextBuffer: TStringBuilder;
    FCommandBuffer: TStringBuilder;
    procedure InitParser;
    procedure ParseText( AChar: Char );
    procedure ParseCommand( AChar: Char );
    procedure ParseCloseCommand( AChar: Char );
    procedure HandleTextBuffer;
    procedure HandleCommandBuffer( Closing: Boolean = False );
  public
    constructor Create( ADefaultFont: TFont );
    destructor Destroy; override;

    procedure Parse( AText: string );
    property Parts: TList<TTextPart> read FParts;
  end;

implementation

uses
  System.StrUtils;

{ TBBCodeParser }

constructor TBBCodeParser.Create( ADefaultFont: TFont );
begin
  inherited Create;
  FDefaultFont := ADefaultFont;
  FFont := TFont.Create;
  FTextBuffer := TStringBuilder.Create;
  FCommandBuffer := TStringBuilder.Create;
  FParts := TObjectList<TTextPart>.Create;
  FCommandStack := TList<string>.Create;
end;

destructor TBBCodeParser.Destroy;
begin
  FFont.Free;
  FTextBuffer.Free;
  FCommandBuffer.Free;
  FParts.Free;
  FCommandStack.Free;
  inherited;
end;

procedure TBBCodeParser.HandleCommandBuffer( Closing: Boolean );
const
  FontStyle: array [TFontStyle] of string = ( 'fsBold', 'fsItalic', 'fsUnderline', 'fsStrikeOut' );
var
  LCommand: string;
  LIdx: Integer;
begin
  LCommand := FCommandBuffer.ToString;
  FCommandBuffer.Clear;

  if Closing
  then
    begin
      // von hinten aus dem Stack nehmen
      for LIdx := FCommandStack.Count - 1 downto 0 do
        if FCommandStack[LIdx] = LCommand
        then
          begin
            FCommandStack.Delete( LIdx );
            Break;
          end;
    end
  else
    // Einfach an den Stack anhängen
    FCommandStack.Add( LCommand );

  // Font einstellen
  FFont.Assign( FDefaultFont );

  for LCommand in FCommandStack do
    begin
      LIdx := IndexText( LCommand, FontStyle );
      if LIdx >= 0
      then
        FFont.Style := FFont.Style + [TFontStyle( LIdx )];

      if LCommand.StartsWith( 'cl', True )
      then
        FFont.Color := StringToColor( LCommand );
    end;
end;

procedure TBBCodeParser.HandleTextBuffer;
begin
  if FTextBuffer.Length > 0
  then
    begin
      FParts.Add( TTextPart.Create( FFont, FTextBuffer.ToString ) );
      FTextBuffer.Clear;
    end;
end;

procedure TBBCodeParser.InitParser;
begin
  FFont.Assign( FDefaultFont );
  FTextBuffer.Clear;
  FCommandBuffer.Clear;
  FCommandStack.Clear;
  FParts.Clear;
  FState := ParseText;
end;

procedure TBBCodeParser.Parse( AText: string );
var
  LChar: Char;
begin
  InitParser;
  for LChar in AText do
    FState( LChar );
  HandleTextBuffer;
end;

procedure TBBCodeParser.ParseCloseCommand( AChar: Char );
begin
  case AChar of
    ']':
      begin
        HandleTextBuffer;
        HandleCommandBuffer( True );
        FState := ParseText;
      end;
  else
    FCommandBuffer.Append( AChar );
  end;
end;

procedure TBBCodeParser.ParseCommand( AChar: Char );
begin
  case AChar of
    ']':
      begin
        HandleTextBuffer;
        HandleCommandBuffer( False );
        FState := ParseText;
      end;
    '/':
      FState := ParseCloseCommand;
  else
    FCommandBuffer.Append( AChar );
  end;
end;

procedure TBBCodeParser.ParseText( AChar: Char );
begin
  case AChar of
    '[':
      FState := ParseCommand;
  else
    FTextBuffer.Append( AChar );
  end;
end;

{ TTextPart }

constructor TTextPart.Create( AFont: TFont; const AText: string );
begin
  inherited Create;
  FFont := TFont.Create;
  FFont.Assign( AFont );
  FText := AText;
end;

end.
UPDATE
So mit der kleinen Änderung (CommandStack) können jetzt auch verschachtelte Commands verarbeitet werden.
So z.B.
Code:
normal [clRed]rot [clGreen]grün [/clGreen]wieder rot [/clRed]normal
normal [fsBold]fett [fsItalic]fett-kursiv [fsStrikeOut]fett-kursiv-durchgestrichen [fsUnderline]fett-kursiv-durchgestrichen-unterstrichen [/fsBold]kursiv-durchgestrichen-unterstrichen [/fsItalic]durchgestrichen-unterstrichen [/fsStrikeOut]unterstrichen [/fsUnderline]normal
Ist dann das gleiche Ergebnis:
Zitat:

normal rot grün wieder rot normal
normal fett fett-kursiv fett-kursiv-durchgestrichen fett-kursiv-durchgestrichen-unterstrichen kursiv-durchgestrichen-unterstrichen durchgestrichen-unterstrichen unterstrichen normal
wie hier mit den BBCodes
Code:
normal [COLOR="Red"]rot [COLOR="Green"]grün [/COLOR]wieder rot [/COLOR]normal
normal [B]fett [I]fett-kursiv [S]fett-kursiv-durchgestrichen [U]fett-kursiv-durchgestrichen-unterstrichen [/U][/S][/I][/B][I][S][U]kursiv-durchgestrichen-unterstrichen [/U][/S][/I][S][U]durchgestrichen-unterstrichen [/U][/S][U]unterstrichen [/U]normal

Bjoerk 5. Nov 2014 20:52

AW: QuoteText parsen?
 
Thanx. Wie immer genial deine Posts. Aber, den Code hab ich fast Null verstanden. Und Generics und TStringBuilder hab ich nich.. :oops:

Sir Rufo 5. Nov 2014 21:33

AW: QuoteText parsen?
 
Das du das nicht hast weiß ich, aber du willst ja auch etwas selber machen ;)

Eigentlich sind diese State-Machines als Parser super simpel zu erstellen:
  • Ein Parser geht Zeichen für Zeichen durch den String -> Wir brauchen eine Methode die einen Char entgegennimmt. Da aber je nach Status eine andere Methode benötigt wird brauchen wir erst mal so einen Methodentyp
    Delphi-Quellcode:
    TState = procedure(AChar:Char) of object;
  • Die erste Methode ist ganz simpel, es wird einfach jedes Zeichen an den
    Delphi-Quellcode:
    TextBuffer
    gehängt (das kann ein einfacher String sein, ein
    Delphi-Quellcode:
    TStringBuilder
    ist dafür nur schneller, mehr nicht). Nennen wir die einfach mal
    Delphi-Quellcode:
    ParseText
    . Trifft man hier nun auf das Zeichen
    Delphi-Quellcode:
    '['
    , dann kommt jetzt ein Kommando. Also müssen wir ab nun das aus einer anderen Sicht betrachten, denn der Status hat sich geändert. Wir parsen jetzt ein Kommando, also eine weitere Methode
    Delphi-Quellcode:
    ParseCommand
  • In
    Delphi-Quellcode:
    parseCommand
    werden alle eingehenden Zeichen an den
    Delphi-Quellcode:
    CommandBuffer
    gehängt, bis wir auf das Zeichen
    Delphi-Quellcode:
    ']'
    treffen.
  • Für weitere Stati verfährt man genauso und baut diese Schritt für Schritt auf.
Eigentlich ist es ein ganz stupides Abarbeiten der Vorgaben. Interessant wird dann der Teil, wo die Commands in den CommandStack ein- und ausgetragen werden und darüber der aktuelle Font "errechnet" wird.

Wichtig: Vor jeder Änderung durch ein Command muss der aktuelle TextBuffer mit dem aktuellen Font gespeichert werden (wenn der TextBuffer leer ist, dann brauchen wir auch nichts speichern).

Nimm dir am Besten einen kurzen Text
Code:
a[b]c[d]e[/b]f[/d]g
und gehe den Code auf dem Papier durch, dann sollte auch die Erkenntnis kommen :)

Jens01 5. Nov 2014 22:18

AW: QuoteText parsen?
 
Meinst Du das?
Das Ding hatte ich auch noch ein Stück bei mir erweitert, da ich es aber nicht mehr benötigte, habe ich es weggetan und finde es gerade nicht.

Dejan Vu 6. Nov 2014 07:34

AW: QuoteText parsen?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1278849)
Ein Parser geht Zeichen für Zeichen durch den String

Das ist -streng genommen- nicht richtig. Ein Parser geht Token für Token durch eine Eingabe und prüft die Syntax einer Sprache bzw. erstellt einen Syntaxbaum. Ein Scanner/Tokenizer geht Zeichen für Zeichen durch einen String und erstellt Token anhand des Alphabets der zu scannenden Eingabe. Das Alphabet besteht hier aus normalen Zeichen, sowie den Sonderzeichen '[','/' und ']'. Dies sind gleichzeitig die Terminalsymbole. Man könnte die Terminalsymbole auch als '[','[/' und ']' definieren (ein Symbol ist 2 Zeichen lang). Dann würde der Scanner mit einem Lookahead arbeiten, aber es macht die Sache einfacher. Ähnliches haben wir bei Delphi mit den Symbolen ':=', '..' '(*' , '*)' usw.

Der Scanner erkennt meist mit Hilfe eines Automaten (->State machine) die einzelnen Token. Die Token sind hier: CHARS, BEGIN-GROUP, GROUPNAME, END-GROUP.

Der Parser prüft nun, ob die vom Scanner gelieferten Token der zu prüfenden Grammatik entsprechen. Hier z.B.:
Code:
BBText  ::= <Literals> [<BBText>]
Literals ::= CHARS | <Group>
Group   ::= <BeginGroup> <BBText> <EndGroup>
BeginGroup ::= BEGIN-GROUP GROUPNAME
EndGroup ::= END-GROUP GROUPNAME
Während des Erkennens kann ein Syntaxbaum erstellt werden. Dieser Syntaxbaum kann Grundlage für einen Compiler sein, der die einzelnen Knoten des Baumes in die Zielsprache übersetzt. Hier wäre die Zielsprache eine Liste von 'TTextPart' Einträgen. Eine andere Zielsprache könnte 'RTF' sein. Oder 'DOCX', oder z.B. formatierter Quelltext etc.

Viele Parser spannen den Baum nicht mehr explizit auf (obwohl damit Codepfade analysiert werden können, Stichwort: Die Variable 'X' ist wahrscheinlich nicht initialisiert, Rückgabewert undefiniert etc.), sondern spucken direkt das Compilat aus.

Das alles hat Sir Rufo in die Klasse gepackt, alles andere wäre ein wenig oversized. Und da die Sprache so einfach ist, spannt er einen eindimensionalen Baum auf: Einen Stack.

Übrigens: Es gibt Programme (Compilergeneratoren), denen gibt man die Grammatik der Zielsprache sowie reguläre Ausdrücke zum Erkennen der Token und die spucken dann einen fertigen und garantiert fehlerfreien Parser aus. Füttert man den Generator noch mit Übersetzungsregeln, hat man einen Compiler.

Bjoerk 9. Nov 2014 17:05

AW: QuoteText parsen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab' den Parser jetzt doch (lieber) in "BjoerkStyle" gemacht. Tut. In diesem Zusammenhang ist bei mir eine andere Frage aufgetaucht. Ist TStringList.Text nicht dasselbe wie das Ganze in einen String aufsummiert? (Siehe auch FBBCParser.LineOut(PaintBox.Canvas, FSL.Text, ..))

p80286 10. Nov 2014 09:37

AW: QuoteText parsen?
 
Zitat:

Zitat von Bjoerk (Beitrag 1279229)
Ich hab' den Parser jetzt doch (lieber) in "BjoerkStyle" gemacht. Tut. In diesem Zusammenhang ist bei mir eine andere Frage aufgetaucht. Ist TStringList.Text nicht dasselbe wie das Ganze in einen String aufsummiert? (Siehe auch FBBCParser.LineOut(PaintBox.Canvas, FSL.Text, ..))

Wenn ich Dich richtig verstanden habe, ja das könnte man so sehen.

Gruß
K-H

Bjoerk 10. Nov 2014 14:45

AW: QuoteText parsen?
 
Ok. Thanx. Das war ja das: StringReplace(FSL.Text, sLineBreak, '', [rfReplaceAll]) :oops:

Die LinesOut (Strings) funktioniert übrigens nicht richtig. Die hab ich nochmal überarbeitet…

lbccaleb 10. Nov 2014 17:33

AW: QuoteText parsen?
 
Hier kannst du dir vllt auch noch was abschauen??

http://www.delphipraxis.net/126859-b...trichedit.html

Bjoerk 10. Nov 2014 19:47

AW: QuoteText parsen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ok. Thanx. Ich denke aber ich habs jetzt soweit. Etwas optimiert und mit korrekter LinesOut. Man kann übrigens auch von außen (FBBCParser.List.Add..) oder auch im constructor weitere BBCodes setzen. Die werden dann automatisch berücksichtigt.

Jens01 10. Nov 2014 20:33

AW: QuoteText parsen?
 
Cool ist, wenn der Parser noch sowas kann :
"F[sub]d[/sub]"
"N/mm[sup]2[/sup]"
:thumb:

himitsu 11. Nov 2014 00:22

AW: QuoteText parsen?
 
Parser können das, da es problemlos in die Syntax passt, aber es muß das Ziel auch diese Art ver Formatierung können und es benötigt bei der Auswertung des geparsten Textes noch die Funktion, das entsprechend zu übergeben.

Bjoerk 11. Nov 2014 07:51

AW: QuoteText parsen?
 
Gut. Machen kann man viel..

[SqrtSign]
[Picture]c:\...\.jpg[/Picture]

Sir Rufo 11. Nov 2014 10:27

AW: QuoteText parsen?
 
Zitat:

Zitat von Bjoerk (Beitrag 1279329)
[Picture]c:\...\.jpg[/Picture]

Das solltest du aber so nicht machen, logischer (und einfacher zu integrieren) wäre das
Code:
[font="Arial"]blabla[/font]
text [image="c:\...\foo.jpg"] text

DeddyH 11. Nov 2014 10:30

AW: QuoteText parsen?
 
Die Syntax ist aber soweit ich verstanden habe vorgegeben (BBCode).

Sir Rufo 11. Nov 2014 10:38

AW: QuoteText parsen?
 
Zitat:

Zitat von DeddyH (Beitrag 1279352)
Die Syntax ist aber soweit ich verstanden habe vorgegeben (BBCode).

Aus welchen Aussagen des TE liest du das heraus?

DeddyH 11. Nov 2014 10:54

AW: QuoteText parsen?
 
BBCParser, das klingt für mich nach "BBCode-Parser".

Bjoerk 11. Nov 2014 10:56

AW: QuoteText parsen?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von Sir Rufo (Beitrag 1279351)
Zitat:

Zitat von Bjoerk (Beitrag 1279329)
[Picture]c:\...\.jpg[/Picture]

Das solltest du aber so nicht machen, logischer (und einfacher zu integrieren) wäre das
Code:
[font="Arial"]blabla[/font]
text [image="c:\...\foo.jpg"] text

Richtig. Und DeddyH ebenso.

Deshalb hab ich's so gemacht.

Delphi-Quellcode:
  FBBCParser := TBBCParser.Create;
  FBBCParser.List.AddFont('_Delphi', 'Courier New', 10, clNavy, [fsBold]);
  FBBCParser.List.AddPicture('ATHENA', 'C:\Delphi2007\Abel2007\Sonstige\ATHENA.BMP');

  FSL := TStringList.Create;
  FSL.Add('Test');
  FSL.Add('[_Delphi]inherited[/_Delphi]');
  FSL.Add('f[fsSub]d[/fsSub] = 10 N/mm[fsSup]2[/fsSup]');
  FSL.Add('Picture: [ATHENA]0,5[/ATHENA] very nice '); // 0,5 = Zoom (StrechDraw);
  FSL.Add('Hier geht''''s weiter');

Jens01 11. Nov 2014 11:44

AW: QuoteText parsen?
 
:thumb:

Sir Rufo 11. Nov 2014 14:16

AW: QuoteText parsen?
 
Zitat:

Zitat von DeddyH (Beitrag 1279359)
BBCParser, das klingt für mich nach "BBCode-Parser".

Ja, das ist so betrachtet richtig. Zeige mir jedoch bitte eine Stelle im Thread wo der TE irgendetwas darüber sagt, dass er einen BBCParser haben möchte.

Ich finde die Stelle schon mal nicht.

Bitte erleuchte mich ...

... denn dann müssten wir den TE auch darauf hinweisen, dass
Code:
[clRed]in rot[/clRed]
nicht so wirklich BBCode ist.

DeddyH 11. Nov 2014 14:24

AW: QuoteText parsen?
 
In #24 hat er es bestätigt. Wollen wir uns jetzt noch länger daran hochziehen?

Bjoerk 11. Nov 2014 15:51

AW: QuoteText parsen?
 
Seh' ich auch so. Siehe z.B. auch Wikipedia: BBCode ist nicht offiziell reglementiert. Anyway. Für mich ist das auf alle Fälle ein "richtiger" BBCode Parser. :wink: Die BBCodes werden vorher beim Parser angemeldet und können dann (kumulativ) verwendet werden. Ich hab' zum Beispiel eine an Delphi TFont class angelehnte Syntax verwendet AddFontStyle('fsBold', [fsBold]), die kann aber auch völlig andere sein AddFontStyle('b', [fsBold]). Und, man kann z.B. die Konstanten cFirst und cLast in < bzw. > ändern. Dann hätte man <b>Text</b>.

Bjoerk 12. Nov 2014 13:18

AW: QuoteText parsen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wollte jetzt noch Blocksatz einbauen. Mach ich da was falsch? Der Unterschied zu rechtsbündig ist ziemlich groß?
Delphi-Quellcode:
procedure TBBCItem.JustifiedTextOut(Canvas: TCanvas; MMX, MMY, ppMM: double); // Blocksatz;
var
  TextMMWidth, DeltaMMX: double;
  I: integer;
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    TextMMWidth := Canvas.TextWidth(Text) / ppMM;
    SplitString(Text, SL);
    if SL.Count > 1 then
      DeltaMMX := Max((GetTextAlign.MMWidth - TextMMWidth) / (SL.Count - 1), 0)
    else
      DeltaMMX := 0;
    for I := 0 to SL.Count - 1 do
    begin
      Canvas.TextOut(Round(MMX * ppMM), Round(MMY * ppMM), SL[I]);
      MMX := MMX + Canvas.TextWidth(SL[I]) / ppMM + DeltaMMX;
    end;
  finally
    SL.Free;
  end;
end;

DeddyH 12. Nov 2014 13:28

AW: QuoteText parsen?
 
Auf die Schnelle gefunden, allerdings nur überflogen (Screenshots sehen aber gut aus): http://parnassus.co/drawing-fully-ju...t-to-a-canvas/

Bjoerk 12. Nov 2014 14:24

AW: QuoteText parsen?
 
Ok. Schau ich mir an. Vielleicht nochmal zu meinem Ansatz. Ich versteh ja wenn das mal 1 oder 2 Pixel Unterschied sind (ist bei Word ja auch) aber so ??? Ich splitte den String in eine Wortliste (übrigens mit deiner Splitspring) und drucke dann Wort für Wort. Das TextWidth jeweils dazu addiert zuzüglich der Länge Delta?

Code:
========== Bezugsbreite ==========
Test(__Delta__)Test(__Delta__)Test

DeddyH 12. Nov 2014 15:19

AW: QuoteText parsen?
 
Ich habe Deinen Code jetzt nicht bis ins Detail nachvollzogen, aber ein paar Gedanken dazu: aufzuteilende Breite = Anzeigebreite - Textbreite. Textbreite muss man aber erst einmal definieren, soll sie mit oder ohne die Leerzeichen sein? Ohne Leerzeichen könnte dazu führen, dass im ungünstigsten Fall der Zwischenraum kleiner als die Breite eines Leerzeichens wird, nicht so schön. Im anderen Fall muss man daran denken, außer beim letzten Wort bei der Anzeige noch ein Leerzeichen anzuhängen, wenn man die Stringliste abarbeitet.

p80286 12. Nov 2014 15:48

AW: QuoteText parsen?
 
Zitat:

Zitat von DeddyH (Beitrag 1279493)
Textbreite muss man aber erst einmal definieren, soll sie mit oder ohne die Leerzeichen sein?

Textbreite ergibt sich aus den darstellbaren Zeichen, Ausnahme ist das "definierteLeerzeichen" (weis jetzt die genaue Bezeichnung nicht), daß muß mitgezählt/gemessen werden.

Gruß
K-H

Bjoerk 12. Nov 2014 15:58

AW: QuoteText parsen?
 
Zitat:

Ich habe Deinen Code jetzt nicht bis ins Detail nachvollzogen, aber ein paar Gedanken dazu: aufzuteilende Breite = Anzeigebreite - Textbreite.
Hab ich.
Zitat:

Textbreite muss man aber erst einmal definieren, soll sie mit oder ohne die Leerzeichen sein?
Ist mit Leerzeichen.
Zitat:

[..] man daran denken, außer beim letzten Wort bei der Anzeige noch ein Leerzeichen anzuhängen, wenn man die Stringliste abarbeitet.
Wieso dieses Leerzeichen? Kapier ich nich?

Edit:
Stimmt übrigens. Mega Thanx!! Aber wieso?
Delphi-Quellcode:
MMX := MMX + Canvas.TextWidth(SL[I] + #32) / ppMM + DeltaMMX;

Sir Rufo 12. Nov 2014 16:10

AW: QuoteText parsen?
 
Non Breaking SPace
HTML-Code:
<p>
  Ich bin ein&nbspText in einem kurzen nichtssagendem Absatz.
</p>
hat beim Rendern ein feste Breite und an der Stelle wird nicht umgebrochen. Alle anderen Leerzeichen können in der Breite variieren um beim Blocksatz den Text bündig zu präsentieren.
Code:
|----------------------|
Ich...bin..ein_Text...in
einem.............kurzen
nichtssagendem.Absatz.

DeddyH 12. Nov 2014 16:47

AW: QuoteText parsen?
 
Zitat:

Zitat von Bjoerk (Beitrag 1279506)
Stimmt übrigens. Mega Thanx!! Aber wieso?

Nehmen wir doch mal das hier:
Code:
Ich_bin_ein_Satz.
(die _ sollen die Leerzeichen darstellen). Angenommen, es ergibt eine Textbreite von 50 Pixeln, die Ausgabebreite beträgt 122 Pixel, dann ist der aufzuteilende Abstand 72 Pixel. 3 Wortabstände (Leerzeichen), das macht dann 24 Pixel zusätzlichen Abstand zwischen 2 Worten. Du hast jetzt den Satz gesplittet, das ergibt
Code:
Ich
bin
ein
Satz.
Gibst Du das nun mit jeweils 24 Pixeln Zwischenabstand wieder aus, kommt dabei
Code:
IchXbinXeinXSatz.
(X = 24 Pixel Abstand) heraus. Das ist aber zu kurz, da die Breite der nun weggefallenen Leerzeichen fehlt, das muss wieder ergänzt werden:
Code:
Ich_Xbin_Xein_XSatz.
Deswegen entweder Leerzeichen an die einzelnen Worte wieder anhängen oder gleich die Textbreite ohne Leerzeichen errechnen (oder die Textbreite eines Leerzeichens einmalig ermitteln und auf den Abstand aufschlagen) ;)

Bjoerk 12. Nov 2014 17:05

AW: QuoteText parsen?
 
Achso. Die SplitString schmeißt ja den Delim (hier #32) raus. Dann isses klar. Danke! :oops: :thumb:

p80286 12. Nov 2014 17:47

AW: QuoteText parsen?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1279511)

Ich habs gefunden..RequestedSPace (IBM /370 EBCDIC Character Set).
Ist das gleiche aber IBM war ja schon immer ein wenig anders.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:19 Uhr.

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