AbetoDesign_FactuGES2/Database/udfs/funciones.pas

298 lines
11 KiB
ObjectPascal
Raw Normal View History

unit funciones;
interface
function RtfToText(Cadena: PChar): PChar; cdecl; export;
implementation
uses
Forms, Classes, SysUtils, StdCtrls, ComCtrls,
RVRTF, RVRTFErr, Menus, RVTypes;
type
TConversor = class(TObject)
private
FirstLine: Boolean;
procedure DoReaderText(Sender: TRVRTFReader; const Text: TRVAnsiString;
Position: TRVRTFPosition);
public
RTFText: TRVAnsiString;
function ExtractTextFromRTF(const AStream: TStream): Boolean;
end;
{ TConversor }
procedure TConversor.DoReaderText(Sender: TRVRTFReader;
const Text: TRVAnsiString; Position: TRVRTFPosition);
begin
if (Position <> rtf_ts_ContinuePara) and not FirstLine then
RTFText := RTFText+#13#10;
FirstLine := False;
RTFText := RTFText+Text;
end;
function TConversor.ExtractTextFromRTF(const AStream: TStream): Boolean;
var
Parser: TRVRTFReader;
begin
{FirstLine := True;}
parser := TRVRTFReader.Create(nil);
try
Parser.OnNewText := DoReaderText;
Result := (Parser.ReadFromStream(AStream) = rtf_ec_OK);
finally
Parser.Free;
end;
end;
function RtfToText(Cadena: PChar): PChar;
var
AStream : TStringStream;
AConversor : TConversor;
begin
AStream := TStringStream.Create(Cadena);
AConversor := TConversor.Create;
try
AConversor.ExtractTextFromRTF(AStream);
Result := PChar(AConversor.RTFText);
finally
FreeAndNil(AConversor);
FreeAndNIL(AStream);
end;
end;
// NO USAR LAS FUNCIONES QUE VIENEN A CONTINUACI<43>N
// Esta funci<63>n falla cuando hay caracteres especiales en el texto (<28>, por ejemplo).
// Mejor la de abajo.
function RtfToText2(Cadena: PChar): PChar;
var
i: integer;
CadenaAux1: String;
begin
//Si no tiene ninguna llave no esta guardado como rtf
if (Pos('{', Cadena) = 0) then
Result := Cadena
else
//Esta guardado con rtf
begin
//Quitamos todo lo que est<73> antes de \fs1x
i := Pos('\fs', Cadena);
CadenaAux1 := Copy(Cadena, i, StrLen(Cadena)-1);
//Quitamos la parte de delante \fs1x
i:= Pos(' ', CadenaAux1);
CadenaAux1 := Copy(PChar(CadenaAux1), i+1, StrLen(PChar(CadenaAux1))-1);
//Quitamos todo lo de la parte de atras a partir de la primera barra \ que tengamos
i:= Pos('\', CadenaAux1);
CadenaAux1 := Copy(PChar(CadenaAux1), 0, i-1);
Result := PChar(CadenaAux1);
end;
end;
{
Convert RTF enabled text to plain.
http://www.delphipraxis.net/topic45179.html
}
// Esta funci<63>n falla porque se come letras del final de cada l<>nea (<28>?)
// HAY QUE LIMPIAR LA CADENA DE ENTRADA DE SALTOS DE L<>NEA (#$D#$A) POR QUE
// SI NO, NO ES UNA CADENA CON TEXTO RTF V<>LIDO
function RtfToText3(Cadena: PChar): PChar;
const
SaltoLinea = #13#10; //--> #$D#$A
var
aSource: string; // <- Para almacenar la cadena de entrada sin saltos de l<>nea
Source: string;
NChar: Integer;
function ProcessGroupRecursevly: string;
function HexToInt(HexStr: String): Integer;
begin
result := StrToInt('$' + HexStr);
end;
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=('<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
'<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>');
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
// Hay que quitar el salto de l<>nea al final de la aSource RTF
aSource := Copy(Cadena, 1, length(Cadena)-2);
// Cambiar los saltos de l<>nea que no son de RTF por un caracter para
// que se limpien.
// aSource := StringReplace(aSource, SaltoLinea, '^', [rfreplaceall]);
if InitSource then
begin
NChar:=1;
Result:= PChar(ProcessGroupRecursevly);
end
else
Result := PChar(aSource);
end;
end.