Hello, if I copy a macro as XML → edit that XML → how do I reconvert the XML to a new macro, ie create a new macro based on that XML?
thanks in advance for your time and help
I would personally execute the km plist XML directly, by creating a macro with an Execute AppleScript, or Execute JavaScript for Automation action that
- calls the
do script
method of the Keyboard Maestro Engine application, - passing the plist XML string to it.
for example:
Make a noise from updated XML Macro (v10.1.1)
Make a noise from updated XML.kmmacros (2.6 KB)
Expand disclosure triangle to view JS Source
(() => {
"use strict";
const
kme = Application("Keyboard Maestro Engine"),
soundName = "Submarine";
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>ActionUID</key>
<integer>9487349</integer>
<key>DeviceID</key>
<string>DEFAULT</string>
<key>MacroActionType</key>
<string>PlaySound</string>
<key>Path</key>
<string>/System/Library/Sounds/${soundName}.aiff</string>
<key>TimeOutAbortsMacro</key>
<true/>
</dict>
</array>
</plist>`;
return (
kme.doScript(xml),
`Played: ${soundName}.aiff`
);
})();
extremely useful and well written reply and taking the time to write the example using a sound. Thanks very much !
If you have the patience, I have 2 follow-up questions
-
when I save a macro as XML and look at the resulting XML file, there is no trace of the comments in the original macro. Why would this be ? This suggests that the XML could not be reconverted to the original macro.
-
i pasted below a snippet of the XML file. which corresponds to the display text "Change Meeting Date" action shown below.
The million dollar question and the impetus for my original question:
Would there be any way to create a macro which would: -
ask the user to input a variable such as input_reminder_1 (easy to do)
-
create a new ready to use XML (or even better an execute text script action containing the new XML), in which the variable input_reminder_1 in the script is replaced by the user input of that variable.
thanks again very much
<dict>
<key>Action</key>
<string>DisplayBriefly</string>
<key>ActionUID</key>
<integer>9161086</integer>
<key>MacroActionType</key>
<string>InsertText</string>
<key>Text</key>
<string>Change Meeting Date</string>
</dict>
——————————————————————————
——————————————————————————
note in the XML below that Change Meeting Date is replaced with the user input variable input_reminder_1.
<dict>
<key>Action</key>
<string>DisplayBriefly</string>
<key>ActionUID</key>
<integer>9161086</integer>
<key>MacroActionType</key>
<string>InsertText</string>
<key>Text</key>
<string>input_reminder_1</string>
</dict>
no trace of the comments
Two thoughts:
- Make sure that you are selecting and copying a macro, rather than just one or more actions. (It's possible that you didn't copy the comment actions)
- If you have copied one or more comment blocks, remember that the comment field is a rich text field, so you may be looking at something which is not human-legible (Base64 encoded RTF), where you expected to see the plain text of your comment.
e.g. for a comment action like this:
you might be looking at XML like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>ActionUID</key>
<integer>9487876</integer>
<key>MacroActionType</key>
<string>Comment</string>
<key>StyledText</key>
<data>
cnRmZAAAAAADAAAAAgAAAAcAAABUWFQucnRmAQAAAC7bAQAAKwAAAAEAAADT
AQAAe1xydGYxXGFuc2lcYW5zaWNwZzEyNTJcY29jb2FydGYyNTgwClxjb2Nv
YXRleHRzY2FsaW5nMFxjb2NvYXBsYXRmb3JtMHtcZm9udHRibFxmMFxmc3dp
c3NcZmNoYXJzZXQwIEhlbHZldGljYTtcZjFcZnN3aXNzXGZjaGFyc2V0MCBI
ZWx2ZXRpY2EtQm9sZDt9CntcY29sb3J0Ymw7XHJlZDI1NVxncmVlbjI1NVxi
bHVlMjU1O1xyZWQwXGdyZWVuMFxibHVlMDt9CntcKlxleHBhbmRlZGNvbG9y
dGJsOztcY3NzcmdiXGMwXGMwXGMwXGM4NDcwNlxjbmFtZSBjb250cm9sVGV4
dENvbG9yO30KXHBhcmRcdHg1NjBcdHgxMTIwXHR4MTY4MFx0eDIyNDBcdHgy
ODAwXHR4MzM2MFx0eDM5MjBcdHg0NDgwXHR4NTA0MFx0eDU2MDBcdHg2MTYw
XHR4NjcyMFxwYXJkaXJuYXR1cmFsXHBhcnRpZ2h0ZW5mYWN0b3IwCgpcZjBc
ZnMzMFxmc21pbGxpMTUzNjQgXGNmMiBTb21lIApcZjFcYiByaWNoIHRleHQK
XGYwXGIwICBkZXRhaWwgaGVyZX0BAAAAIwAAAAEAAAAHAAAAVFhULnJ0ZhAA
AADxRKNitgEAAAAAAAAAAAAA
</data>
<key>Title</key>
<string>Some kind of comment title</string>
</dict>
</array>
</plist>
the variable input_reminder_1 in the script is replaced by the user input of that variable.
In the Execute JavaScript for Automation action in which you call .doScript(xml)
you can obtain a value for a given KM variable name with an incantation like:
const newValue = Application("Keyboard Maestro Engine").getvariable(
"input_reminder_1"
)
and if you look at the detail of the sound-playing example above, you will see that you can interpolate a named value into the XML between ${ ... }
(JavaScript Template literals (Template strings))
e.g.
<string>/System/Library/Sounds/${soundName}.aiff</string>
fantastic ! thanks very much !