Skip to content

Commit

Permalink
refactoring: fixes and odt support
Browse files Browse the repository at this point in the history
  • Loading branch information
salvadorbs committed Jan 30, 2023
1 parent 5400570 commit f114c36
Showing 1 changed file with 51 additions and 32 deletions.
83 changes: 51 additions & 32 deletions docxreplacerapp.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface

uses
Classes, SysUtils, CustApp, Zipper, XMLRead, DOM, fpjson, FileUtil, LazFileUtils,
XMLWrite, rcmdline;
XMLWrite, rcmdline, jsonparser;

type

Expand All @@ -15,18 +15,18 @@ interface
TDocxReplacerApp = class(TCustomApplication)
private
FCommandLineReader: TCommandLineReader;
FDocxPath: string;
FInputFilePath: string;
FPlaceholdersPath: string;
FOutputPath: string;
FXMLDocument: TXMLDocument;

function GetParamFile(AParam: String): String;
function GetDocxPath: string;
function GetInputFilePath: string;
function GetOutputPath: string;
function GetInternalDocXmlPath: string;
function GetPlaceholdersPath: string;
function GetTempPath: string;
procedure UncompressDocx;
function GetXMLDocument: TXMLDocument;
procedure IteratePlaceholders;
procedure IterateXMLDocument(APlaceholder, AReplacement: string);
procedure ReplacePlaceholder(Node: TDOMNode;
Expand All @@ -43,13 +43,18 @@ TDocxReplacerApp = class(TCustomApplication)
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;

property XMLDocument: TXMLDocument read GetXMLDocument;
property DocxPath: string read GetDocxPath;
property InputFilePath: string read GetInputFilePath;
property PlaceholdersPath: string read GetPlaceholdersPath;
property TempPath: string read GetTempPath;
property OutputPath: string read GetOutputPath;
property InternalDocXmlPath: string read GetInternalDocXmlPath;
end;

const
PARAM_INPUT_DOC = 'inputDoc';
PARAM_OUTPUT_DOC = 'outputDoc';
PARAM_TOKENS_JSON = 'placeholdersJson';

implementation

{ TDocxReplacerApp }
Expand All @@ -60,7 +65,7 @@ procedure TDocxReplacerApp.UncompressDocx;
begin
UnZip := TUnZipper.Create;
try
UnZip.FileName := DocxPath;
UnZip.FileName := InputFilePath;
UnZip.OutputPath := TempPath;
UnZip.Examine;
UnZip.UnZipAllFiles;
Expand All @@ -69,9 +74,9 @@ procedure TDocxReplacerApp.UncompressDocx;
end;
end;

function TDocxReplacerApp.GetDocxPath: string;
function TDocxReplacerApp.GetInputFilePath: string;
begin
Result := ConcatPaths([Location, FDocxPath]);
Result := CleanAndExpandFilename(FInputFilePath);
end;

function TDocxReplacerApp.GetParamFile(AParam: String): String;
Expand All @@ -85,7 +90,7 @@ function TDocxReplacerApp.GetParamFile(AParam: String): String;
if flagError then
WriteLn('Error: Parameter ' + AParam + ' is mandatory!' + LineEnding)
else
if not(FileExists(Result)) then
if not(FileExists(CleanAndExpandFilename(Result))) then
begin
Result := '';
WriteLn('Error: Filename ' + AParam + ' is not found!' + LineEnding);
Expand All @@ -99,7 +104,15 @@ function TDocxReplacerApp.GetOutputPath: string;

function TDocxReplacerApp.GetInternalDocXmlPath: string;
begin
Result := ConcatPaths([Location, 'temp', 'word/document.xml']);
if (LowerCase(ExtractFileExt(FInputFilePath)) = '.docx') then
Result := ConcatPaths([Location, 'temp', 'word', 'document.xml'])
else
Result := ConcatPaths([Location, 'temp', 'content.xml']);
end;

function TDocxReplacerApp.GetPlaceholdersPath: string;
begin
Result := CleanAndExpandFilename(FPlaceholdersPath);
end;

function TDocxReplacerApp.GetTempPath: string;
Expand All @@ -109,11 +122,6 @@ function TDocxReplacerApp.GetTempPath: string;
ForceDirectories(Result);
end;

function TDocxReplacerApp.GetXMLDocument: TXMLDocument;
begin
Result := FXMLDocument;
end;

procedure TDocxReplacerApp.IteratePlaceholders;
var
Placeholder, Replacement: string;
Expand All @@ -123,7 +131,7 @@ procedure TDocxReplacerApp.IteratePlaceholders;
jsonFile: TFileStream;
begin
// Load the JSON file containing the placeholder data
jsonFile := TFileStream.Create(FPlaceholdersPath, fmOpenRead);
jsonFile := TFileStream.Create(PlaceholdersPath, fmOpenRead);
json := GetJSON(jsonFile);
try
// Get the number of placeholders in the JSON file
Expand Down Expand Up @@ -169,10 +177,10 @@ procedure TDocxReplacerApp.IterateXMLDocument(APlaceholder, AReplacement: string
end;

begin
Assert(Assigned(Self.XMLDocument));
Assert(Assigned(Self.FXMLDocument));

// Iterate through all the nodes in the XML document
iNode := Self.XMLDocument.DocumentElement.FirstChild;
iNode := Self.FXMLDocument.DocumentElement.FirstChild;
while iNode <> nil do
begin
ProcessNode(iNode); // Recursive
Expand Down Expand Up @@ -251,13 +259,13 @@ procedure TDocxReplacerApp.CleanTemp;

procedure TDocxReplacerApp.DeclareParams;
begin
FCommandLineReader.declareFile('inputDocx', 'Filepath to input docx');
FCommandLineReader.declareFile(PARAM_INPUT_DOC, 'Filepath to input docx/odt');
FCommandLineReader.addAbbreviation('i');

FCommandLineReader.declareFile('placeholdersJson', 'Filepath to placeholders json file');
FCommandLineReader.declareFile(PARAM_TOKENS_JSON, 'Filepath to placeholders json file');
FCommandLineReader.addAbbreviation('p');

FCommandLineReader.declareFile('outputDocx', 'Filepath to output docx', 'newDocx.docx');
FCommandLineReader.declareFile(PARAM_OUTPUT_DOC, 'Filepath to output docx/odt', 'newDocx.docx');
FCommandLineReader.addAbbreviation('o');
end;

Expand All @@ -268,16 +276,16 @@ function TDocxReplacerApp.ParseParams: boolean;
try
FCommandLineReader.parse();

FDocxPath := GetParamFile('inputDocx');
FPlaceholdersPath := GetParamFile('placeholdersJson');
FOutputPath := FCommandLineReader.readString('outputDocx');
FInputFilePath := GetParamFile(PARAM_INPUT_DOC);
FPlaceholdersPath := GetParamFile(PARAM_TOKENS_JSON);
FOutputPath := FCommandLineReader.readString(PARAM_OUTPUT_DOC);
except
on E: Exception do
WriteLn(E.Message + LineEnding);
end;

finally
Result := (FDocxPath <> '') or (FPlaceholdersPath <> '');
Result := (FInputFilePath <> '') and (FPlaceholdersPath <> '');
end;
end;

Expand All @@ -288,6 +296,8 @@ procedure TDocxReplacerApp.WriteHelp;
end;

procedure TDocxReplacerApp.DoRun;
var
FileDocPath: String;
begin
DeclareParams;

Expand All @@ -301,15 +311,24 @@ procedure TDocxReplacerApp.DoRun;
UncompressDocx;
try
//Read xml in FXMLDocument
ReadXMLFile(FXMLDocument, InternalDocXmlPath);
FileDocPath := InternalDocXmlPath;
if (FileExists(FileDocPath)) then
begin
ReadXMLFile(FXMLDocument, InternalDocXmlPath);

//Iterate placeholders.json tokens to replace them in xml
IteratePlaceholders;
//Iterate placeholders.json tokens to replace them in xml
IteratePlaceholders;

//Compress again in a docx file
SaveDocx;
//Compress again in a docx file
SaveDocx;

CleanTemp;
CleanTemp;
end
else begin
WriteLn('Error: File document xml [' + InternalDocXmlPath + '] not found!');
Terminate;
Exit;
end;
finally
FXMLDocument.Free;
end;
Expand Down

0 comments on commit f114c36

Please sign in to comment.