-
-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(developer): Support loading XML LDML keyboards in TIKE 🦕 #9963
Merged
Merged
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
857017f
chore(developer): remove obsolete project code
mcdurdin 1d3cb5e
chore(common): ldmlKeyboard3.dtd
mcdurdin 7b8fe32
feat(developer): Add basic LDML XML keyboard file support to TIKE pro…
mcdurdin befe2b8
refactor(developer): add xmlLdml types and form, rename ActiveEditor
mcdurdin 7c937e7
feat(developer): Split dmActionsDebugger out of dmActionsKeyboardEditor
mcdurdin a923537
feat(developer): Actions to support LdmlKeyboardEditor
mcdurdin b8dcc1b
Merge branch 'master' into feat/developer/9948-load-xml-ldml-files
mcdurdin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 184 additions & 0 deletions
184
developer/src/tike/project/Keyman.Developer.System.Project.xmlLdmlProjectFile.pas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
{ | ||
* Keyman is copyright (C) SIL International. MIT License. | ||
* | ||
* xmlLdmlProjectFile: LDML keyboard files | ||
} | ||
unit Keyman.Developer.System.Project.xmlLdmlProjectFile; | ||
|
||
interface | ||
|
||
uses | ||
System.SysUtils, | ||
Xml.XMLIntf, | ||
|
||
Keyman.Developer.System.Project.ProjectFile, | ||
Keyman.Developer.System.Project.ProjectFiles, | ||
Keyman.Developer.System.Project.ProjectFileType, | ||
UKeymanTargets; | ||
|
||
type | ||
TxmlLdmlProjectFile = class; | ||
|
||
TxmlLdmlProjectFile = class(TOpenableProjectFile) | ||
private | ||
FDebug: Boolean; | ||
FHeader_Name: WideString; | ||
FTargets: TKeymanTargets; | ||
FKVKFileName: string; | ||
|
||
function GetOutputFilename: string; | ||
function GetTargetFilename: string; | ||
function GetJSTargetFilename: string; | ||
protected | ||
function GetRelativeOrder: Integer; override; | ||
procedure GetFileParameters; override; | ||
|
||
property KVKFileName: string read FKVKFileName; | ||
property IsDebug: Boolean read FDebug; | ||
public | ||
class function IsFileTypeSupported(const Filename: string): Boolean; override; | ||
function IsCompilable: Boolean; override; | ||
procedure Load(node: IXMLNode); override; // I4698 | ||
procedure Save(node: IXMLNode); override; // I4698 | ||
procedure LoadState(node: IXMLNode); override; // I4698 | ||
procedure SaveState(node: IXMLNode); override; // I4698 | ||
|
||
property Debug: Boolean read FDebug write FDebug; | ||
|
||
property OutputFilename: string read GetOutputFilename; | ||
property TargetFilename: string read GetTargetFilename; | ||
property JSTargetFilename: string read GetJSTargetFilename; | ||
property Header_Name: WideString read FHeader_Name; | ||
property Targets: TKeymanTargets read FTargets; | ||
end; | ||
|
||
implementation | ||
|
||
uses | ||
System.Classes, | ||
System.Variants, | ||
Winapi.Windows, | ||
|
||
KeyboardParser, | ||
kmxfileconsts, | ||
KeyboardFonts, | ||
Keyman.System.KeyboardUtils, | ||
utilsystem; | ||
|
||
{------------------------------------------------------------------------------- | ||
- TxmlLdmlProjectFile - | ||
-------------------------------------------------------------------------------} | ||
|
||
function TxmlLdmlProjectFile.IsCompilable: Boolean; | ||
begin | ||
Result := True; | ||
end; | ||
|
||
class function TxmlLdmlProjectFile.IsFileTypeSupported(const Filename: string): Boolean; | ||
var | ||
ss: TStringStream; | ||
begin | ||
// Look for DTD in plain text as an adequate heuristic | ||
ss := TStringStream.Create('', TEncoding.UTF8); | ||
try | ||
ss.LoadFromFile(Filename); | ||
Result := ss.DataString.IndexOf('ldmlKeyboard3.dtd') > 0; | ||
finally | ||
ss.Free; | ||
end; | ||
end; | ||
|
||
procedure TxmlLdmlProjectFile.Save(node: IXMLNode); // I4698 | ||
begin | ||
inherited Save(node); // I4698 | ||
node := node.AddChild('Details'); | ||
if FHeader_Name <> '' then node.AddChild('Name').NodeValue := FHeader_Name; | ||
end; | ||
|
||
procedure TxmlLdmlProjectFile.SaveState(node: IXMLNode); // I4698 | ||
begin | ||
inherited SaveState(node); | ||
node.AddChild('Debug').NodeValue := FDebug; | ||
end; | ||
|
||
procedure TxmlLdmlProjectFile.Load(node: IXMLNode); // I4698 | ||
begin | ||
inherited Load(node); | ||
|
||
if node.ChildNodes.IndexOf('Details') < 0 then Exit; | ||
node := node.ChildNodes['Details']; | ||
if node.ChildNodes.IndexOf('Name') >= 0 then FHeader_Name := VarToWideStr(node.ChildValues['Name']); | ||
end; | ||
|
||
procedure TxmlLdmlProjectFile.LoadState(node: IXMLNode); // I4698 | ||
begin | ||
inherited LoadState(node); | ||
try | ||
if node.ChildNodes.IndexOf('Debug') >= 0 then FDebug := node.ChildValues['Debug']; | ||
except | ||
FDebug := False; | ||
end; | ||
end; | ||
|
||
function TxmlLdmlProjectFile.GetRelativeOrder: Integer; | ||
begin | ||
Result := 20; | ||
end; | ||
|
||
function TxmlLdmlProjectFile.GetTargetFilename: string; | ||
var | ||
FTempFileVersion: string; | ||
begin | ||
// https://github.com/keymanapp/keyman/issues/631 | ||
// This appears to be a Delphi compiler bug (RSP-20457) | ||
// Workaround is to make a copy of the parameter locally | ||
// which fixes the reference counting. | ||
FTempFileVersion := FileVersion; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this still around? Issue 631 was closed in 2018. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RSP-20457 is still not fixed. |
||
Result := OwnerProject.GetTargetFilename(OutputFileName, FileName, FTempFileVersion); | ||
end; | ||
|
||
procedure TxmlLdmlProjectFile.GetFileParameters; | ||
var | ||
j: Integer; | ||
value: WideString; | ||
FVersion: string; // I4701 | ||
begin | ||
FHeader_Name := ''; | ||
FKVKFileName := ''; | ||
SetFileVersion('1.0'); // I4701 | ||
FTargets := AllKeymanTargets; | ||
|
||
if not FileExists(FileName) then Exit; | ||
|
||
// TODO: Load from XML? | ||
end; | ||
|
||
function TxmlLdmlProjectFile.GetJSTargetFilename: string; | ||
begin | ||
if FTargets = [] then | ||
GetFileParameters; | ||
|
||
// There is no JS target if no target is specified | ||
if FTargets * KMWKeymanTargets = [] then | ||
Exit(''); | ||
|
||
Result := OwnerProject.GetTargetFilename(TKeyboardUtils.GetKeymanWebCompiledFileName(FileName), FileName, FileVersion); | ||
end; | ||
|
||
function TxmlLdmlProjectFile.GetOutputFilename: string; | ||
begin | ||
if FTargets = [] then | ||
GetFileParameters; | ||
|
||
// If no target is specified, we'll fall back to .kmx | ||
// so we always have at least one target filename | ||
if (FTargets <> []) and (FTargets * KMXKeymanTargets = []) then | ||
Exit(''); | ||
Result := ChangeFileExt(FileName, '.kmx'); | ||
end; | ||
|
||
|
||
initialization | ||
RegisterProjectFileType('.xml', TxmlLdmlProjectFile); | ||
end. | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I'm not quite following the inheritance and/or polymorphism patterns used here and in ProjectFile.pas (as noticed via commit 1), I can see a pretty strong correlation between the methods.
I'm mostly confused why these
procedure
s areoverride
here butvirtual
there; I don't see the inheritance path between the two, and personally would've expected them to be sibling derived classes of a common base. But those might be small nits and partly due to my inexperience with Delphi in particular.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation in ProjectFile.pas is the base class, hence it is virtual. The other classes are the overrides and extend the base functionality.