
{$MODE OBJFPC}{$H+}

uses
  SysUtils, RegExpr;

(* ================================================================== *)

function ReadText(const AFileName: string): string;
var
  f: file;
  i: integer;
begin
  Assign(f, AFileName);
  Reset(f, 1);
  i := FileSize(f);
  SetLength(result, i);
  BlockRead(f, result[1], i);
  Close(f);
end;

procedure WriteText(const AFileName, AText: string);
var
  f: file;
  i: integer;
begin
  Assign(f, AFileName);
  Rewrite(f, 1);
  i := Length(AText) * SizeOf(char);
  BlockWrite(f, AText[1], i);
  Close(f);
end;

(* ================================================================== *)

type
  TTextCleaner = class
    function ReplaceFunc(AExpr: TRegExpr): string;
    function CleanText(const AText, AExpr: string): string;
  end;

function TTextCleaner.ReplaceFunc(AExpr: TRegExpr): string;
begin
  WriteLn(ErrOutput, 'DEBUG ', AExpr.Match[0]);
  result := EmptyStr;
end;

function TTextCleaner.CleanText(const AText, AExpr: string): string;
var
  LExpr: TRegExpr;
begin
  LExpr := TRegExpr.Create(AExpr);
  try
    result := LExpr.Replace(AText, @ReplaceFunc);
  finally
    LExpr.Free;
  end;
end;

(* ================================================================== *)

procedure Demo;
const
  CSource = {$I %FILE%};
var
  LText: string;
begin
  LText := ReadText(CSource);
  
  with TTextCleaner.Create do
  try
    LText := CleanText(LText, '\([^)]*\)');
    
    WriteText(CSource, LText);
  finally
    Free;
  end;
end;

const
  NNBSP = #$E2 + #$80 + #$AF;

var
  LText: string;
  LSource, LDest: TFileName;
  
begin
  if (ParamCount >= 1) and FileExists(ParamStr(1)) then
  begin
    LSource := ParamStr(1);
    if ParamCount > 1 then
      LDest := ParamStr(2)
    else
      LDest := LSource;
    
    LText := ReadText(LSource);
    
(*
    LText := ReplaceRegExpr('\xC2\xA0', LText, '', FALSE); // The proper code for the non-breaking space in the UTF-8 encoding is 0xC2A0, it consists of two bytes - 0xC2 (194) and 0xA0 (160)
    LText := ReplaceRegExpr('\xC2\xA0\x0A', LText, '', FALSE);
    LText := ReplaceRegExpr('[\x0A]{3,}', LText, LineEnding + LineEnding, FALSE);
    LText := ReplaceRegExpr('(' + CBefore + ')\x0A(' + CAfter + ')', LText, '$1 $2', TRUE);
    LText := ReplaceRegExpr('([IVX]+)\^\(e\) siècle', LText, '\\textsc{\L$1}\\ieme~siècle', TRUE);
*)
  
  { Remplacer les guillemets («» au lieu de ""). }
    LText := ReplaceRegExpr('"([^"]+)"', LText, '« $1 »', TRUE);
    
  { Remplacer les espaces par des espaces insécables avant ou après certains caractères. }
    LText := ReplaceRegExpr(' ([;:!?]|»)', LText, NNBSP + '$1', TRUE);
    LText := StringReplace(LText , '« ', '«' + NNBSP, [rfReplaceAll, rfIgnoreCase]);
    
    WriteText(LDest, LText);
  end else
    WriteLn('Usage:' + LineEnding + '  ' + ExtractFileName(ParamStr(0)) + ' FILE1 [FILE2]');
end.
