spiegel-keyman/common/windows/delphi/tools/devtools/Keyman.System.DevTools.BuildMessageConstants.pas
2022-06-10 07:26:21 +10:00

130 lines
3.5 KiB
ObjectPascal

unit Keyman.System.DevTools.BuildMessageConstants;
interface
uses
System.Classes,
System.SysUtils,
Xml.XMLIntf,
Xml.XMLDoc;
type
TBuildMessageConstants = class
private
class procedure Write(doc: IXMLDocument; const Filename: string); static;
public
class function Run(const LocaleXmlFilename, FileName: string): Boolean; static;
end;
implementation
uses
Xml.Win.msxmldom,
Winapi.ActiveX,
System.StrUtils;
{ TBuildMessageConstants }
class function TBuildMessageConstants.Run(const LocaleXmlFilename, FileName: string): Boolean;
var
doc: IXMLDocument;
begin
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
try
Xml.Win.msxmldom.MSXMLDOMDocumentFactory.AddDOMProperty('ProhibitDTD', False);
doc := TXMLDocument.Create(nil);
doc.ParseOptions := [poResolveExternals]; // I902 - resolve externals when loading XML files
doc.LoadFromFile(LocaleXmlFilename);
Write(doc, FileName);
finally
CoUninitialize;
end;
Result := True;
end;
class procedure TBuildMessageConstants.Write(doc: IXMLDocument; const Filename: string);
var
f: TextFile;
stype, sconst: string;
node: IXMLNode;
HasPreviousNode: Boolean;
begin
AssignFile(f, FileName);
Rewrite(f);
writeln(f, '// Generated file - generated by devtools -buildmessageconstants at '+FormatDateTime('dd/mm/yyyy hh:nn:ss', Now));
writeln(f, 'unit '+ChangeFileExt(ExtractFileName(FileName), '')+';'#13#10'interface'#13#10);
// writeln(f, 'uses keymanapi_TLB;'#13#10);
stype := 'type TMessageIdentifier = (SKNull, '#13#10;
sconst := 'const MessageIdentifierNames: array[TMessageIdentifier] of string = (''SKNull'', '#13#10;
node := doc.DocumentElement.ChildNodes[0];
HasPreviousNode := False;
while Assigned(node) do
begin
if node.NodeName = 'String' then
begin
// Legacy locale.xml format (deprecated, will be removed later)
if HasPreviousNode then
begin
stype := stype + ','#13#10;
sconst := sconst + ','#13#10;
end;
stype := stype + ' '+node.Attributes['Id'];
sconst := sconst + ' '''+node.Attributes['Id']+'''';
HasPreviousNode := True;
end
else if node.NodeName = 'string' then
begin
// Android strings.xml format
if HasPreviousNode then
begin
stype := stype + ','#13#10;
sconst := sconst + ','#13#10;
end;
stype := stype + ' '+node.Attributes['name'];
sconst := sconst + ' '''+node.Attributes['name']+'''';
HasPreviousNode := True;
end;
node := node.NextSibling;
end;
stype := stype + #13#10');';
sconst := sconst + #13#10');';
writeln(f, stype);
writeln(f);
writeln(f, 'function MsgIdFromString(const msgid: WideString): TMessageIdentifier;');
writeln(f, 'function StringFromMsgId(const msgid: TMessageIdentifier): WideString;');
writeln(f);
writeln(f, 'implementation');
writeln(f);
writeln(f, sconst);
writeln(f);
writeln(f, 'function StringFromMsgId(const msgid: TMessageIdentifier): WideString;');
writeln(f, 'begin');
writeln(f, ' Result := MessageIdentifierNames[msgid];');
writeln(f, 'end;');
writeln(f);
writeln(f, 'function MsgIdFromString(const msgid: WideString): TMessageIdentifier;');
writeln(f, 'var i: TMessageIdentifier;');
writeln(f, 'begin');
writeln(f, ' for i := Low(TMessageIdentifier) to High(TMessageIdentifier) do');
writeln(f, ' if MessageIdentifierNames[i] = msgid then begin Result := i; Exit; end;');
writeln(f, ' Result := SKNull;');
writeln(f, 'end;');
writeln(f);
writeln(f, 'end.');
CloseFile(f);
end;
end.