///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// fixfpcxml utility to fix FPC XML files after edited with FPDocEditor or LazDE, by Zeljko Avramovic (c) 2021 //
// //
// When FPDocEditor or LazDE are used for editing FPC XML documentation files (like sysutils.xml from RTL), //
// encoding and formating of saved XML files are changed so much that creating a diff patch file is pointless. //
// This utility tries to fix that. Although not perfect, result XML is much closer to the original format. //
// Tested only on sysutils.xml. Feel free to improve it further. //
// //
// Dual license: //
// 1. FPC modified LGPL (chosen for compatibility with FreePascal and Lazarus) //
// 2. BSD3 (chosen for compatibility with everything else) //
// //
// Usage: //
// fixfpcxml <xmlfilename> //
// //
// Examples: //
// fixfpcxml sysutils.xml //
// fixfpcxml c:\Prg\Lazarus\fpdoctrunk\sysutils.xml //
// //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
program fixfpcxml;
{$mode objfpc} {$H+}
uses
classes, sysutils, strutils, dom, xmlwrite, xmlread;
procedure ShowHelpAndExit;
begin
WriteLn('');
WriteLn('Usage:');
WriteLn(' fixfpcxml <xmlfilename>');
WriteLn('');
WriteLn('Examples:');
WriteLn(' fixfpcxml sysutils.xml');
WriteLn(' fixfpcxml c:\Prg\Lazarus\fpdoctrunk\sysutils.xml');
WriteLn('');
Halt;
end;
const
CRLF: string = #13 + #10;
Blanks64 = ' ';
Blanks14 = ' ';
Blanks10 = ' ';
Blanks4 = ' ';
var
i: integer;
XmlFileName: string;
S: TFileStream;
W: TDOMWriter;
XmlDoc: TXMLDocument;
StrList: TStringList;
begin
try
try
WriteLn('fixfpcxml utility to fix FPC XML files after edited with FPDocEditor or LazDE, by Zeljko Avramovic (c) 2021');
if ParamCount() <> 1 then
ShowHelpAndExit;
XmlFileName := ParamStr(1);
if not FileExists(XmlFileName) then
begin
WriteLn('ERROR: File ', XmlFileName, ' does not exist');
Exit;
end;
if UpperCase(ExtractFileExt(Trim(XmlFileName))) <> '.XML' then
begin
WriteLn('ERROR: File ', XmlFileName, ' must have XML extension');
Exit;
end;
ReadXMLFile(XmlDoc, XmlFileName);
S := TFileStream.Create(XmlFileName, fmCreate);
W := TDOMWriter.Create(S, XmlDoc);
W.UseTab := false;
W.IndentSize := 0;
W.WriteNode(XmlDoc);
W.Free;
S.Free;
StrList := TStringList.Create;
StrList.LoadFromFile(XmlFileName);
StrList.Text := StringReplace(StrList.Text, 'encoding="utf-8"', 'encoding="ISO-8859-1"', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<descr>This documentation', '<descr>' + CRLF + 'This documentation', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '>', '>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<p>', '<p>' + CRLF, [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<td>', '<td>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '</th>', '</th>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '</tr>', '</tr>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '</td>', '</td>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '</dd>', '</dd>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<dd>', '<dd>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<dd>' + CRLF + '<var>', '<dd><var>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<tr><td>' + CRLF, '<tr><td>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, Blanks14 + CRLF, '', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, Blanks10 + CRLF, '', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, Blanks64, '', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, Blanks4, '', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<li>' + CRLF + '<link', '<li><link', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<var>PChar', '<var>PChar', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<var>TDateTime', '<var>TDateTime', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<var>DateTime', '<var>DateTime', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<var>ShortDate', '<var>ShortDate', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<var>LongTime', '<var>LongTime', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<printshort', '<printshort', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<errors>', '<errors>' + CRLF, [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + ' <var', ' <var', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + ' ' + CRLF + ' ', '', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + ' <var>', CRLF + '<var>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, ' ' + CRLF + '<var>', ' <var>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, ' ' + CRLF + ' <link', ' <link', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, ' ' + CRLF + '<link', ' <link', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '/' + CRLF + '<link', '/<link', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<seealso/>', '<seealso>' + CRLF + '</seealso>', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, CRLF + '<file>C:', ' <file>C:', [rfReplaceAll, rfIgnoreCase]);
StrList.Text := StringReplace(StrList.Text, '<remark>', '<remark>' + CRLF, [rfReplaceAll, rfIgnoreCase]);
StrList.SaveToFile(XmlFileName);
StrList.Free;
WriteLn('Finished fixing file ', XmlFileName);
except
on e: Exception do
WriteLn(e.Message);
end;
finally
;
end;
end.