program linuxmagazin; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils, CustApp; type { TMyApplication } TMyApplication = class(TCustomApplication) protected FNotes : array [0..10000000] of string; FNotesIndex : array [0..10000000] of integer; FNotesMax : integer; FModeText : Boolean; procedure DoRun; override; procedure DumpLine (const aLine : string); procedure DumpFootnote; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; end; { TMyApplication } // Ausgabe einer Zeile nach stdout procedure TMyApplication.DumpLine (const aLine : string); begin writeln (aLine); end; // Ausgabe aller Fussnoten procedure TMyApplication.DumpFootnote; var i : integer; begin i := 0; while (i < FNotesMax) do begin DumpLine ('[' + IntToStr (i+1) + ']' + FNotes [i]); inc (i); end; end; // Diese Routine macht die ganze Arbeit procedure TMyApplication.DoRun; var lLine : string; lText : TextFile; // Trägt eine Fussnote in die Referenztabelle ein // \return Fussnote in Klammern function MappedNote (aNote : integer) : string; var ll : integer; begin if FNotesIndex[aNote] = -1 then begin FNotesIndex[aNote] := FNotesMax; inc (FNotesMax); end; Result := '[' + IntToStr (FNotesIndex[aNote]+1) + ']'; end; // Ein Token in einer Eingabezeile finden. // \return einen Teil der Eingabezeile oder eine aufbereitete Fussnote function GetNextToken (var aLine : string) : string; var lPos1 : integer; lPos2 : integer; lX : integer; begin Result:= ''; lPos1 := pos ('[', aLine); lPos2 := pos (']', aLine); if lPos1 = 1 then begin lX := StrToIntDef(system.copy (aLine, 2, lPos2-2), -1); if lX >= 0 then Result := MappedNote (lX) else begin lpos2 := lPos1 + 1; Result := system.copy (aLine, 1, lPos2); end; system.Delete (aLine, 1, lPos2); end else begin if lPos1 = 0 then lPos1 := length (aLine) + 1; Result := system.Copy (aLine, 1, lPos1 - 1); system.Delete(aLine, 1, lPos1-1); end; end; // Nimmt eine Textzeile entgegen und untersucht sie auf Fussnoten // oder den Separator für den Fussnoten-Teil function ParseLine (var aLine : string) : string; begin Result := ''; if SameText (aLine, '@footnote:') then begin FModeText := False; Result := aLine; end else begin while length (aLine) > 0 do Result := Result + GetNextToken (aLine); end; end; // Nimmt einen string entgegen und versucht diesen // als Fussnote abzulegen procedure ParseFootnote (var aLine : string); var lPos1 : integer; lPos2 : integer; lX : integer; begin lPos1 := pos ('[', aLine); lPos2 := pos (']', aLine); if lPos1 = 1 then begin lX := StrToIntDef(system.copy (aLine, 2, lPos2-2), -1); system.Delete (aLine, 1, lPos2); if FNotesIndex[lx] > -1 then FNotes [FNotesIndex[lx]] := aLine; end else ; // FUCK end; begin // parse parameters if HasOption('h','help') then begin WriteHelp; Halt; end; // Text einlesen & parsen bis zum Fussnoten Marker FNotesMax := 0; FModeText := True; AssignFile(lText, ParamStr(1)); Reset(lText); while not (eof (lText)) and (FModeText) do begin ReadLn (lText, lLine); lLine := ParseLine (lLine); DumpLine (lLine); end; // Jetzt Fussnoten parsen while not (eof (lText)) do begin ReadLn (lText, lLine); ParseFootnote (lLine); end; DumpFootnote; // stop program loop Terminate; end; constructor TMyApplication.Create(TheOwner: TComponent); var li : integer; begin inherited Create(TheOwner); StopOnException:=True; FNotesMax := 0; for li := 0 to high (FNotesIndex) do FNotesIndex [li] := -1; end; destructor TMyApplication.Destroy; begin inherited Destroy; end; procedure TMyApplication.WriteHelp; begin writeln('Usage: ',ExeName,' -h'); end; var Application: TMyApplication; begin Application:=TMyApplication.Create(nil); Application.Title:='My Application'; Application.Run; Application.Free; end.