JMP add-ins are great additions to JMP core capabilities, and sometimes, you may find yourself needing to automate add-in creation with JSL. I worked with automated add-in creation when building my JMP add-in, the JMP to R Custom Add-In Builder. Here’s a nifty JSL trick for auto-creation of add-ins.
The code in this tutorial is adapted from a wonderful script written by @Justin_Chilton, who built the Custom Add-In Builder.
A JMP add-in (.jmpaddin) is a Zip file (.zip). The three minimum components of a JMP add-in are the addin.def and addin.jmpcust files, as well as the JSL script that will run when the add-in is in use. You may add additional files as you would like—for example, other JSL scripts, JMP tables, PDF or Word documents (commonly used for documentation), and pictures (often used for the add-in thumbnail).
In the following script excerpts, anything customizable is in capital letters (e.g. YOUR_ADDIN_NAME).
First, create the string that is used in the addin.def file. You will need your add-in name and ID. The name is what will be displayed on the add-in menu, and the ID is a unique identifier for the add-in, commonly seen in the format com.companyname.username.addinname.
//create string for addin.def file
addinDefString = "id=com.YOUR_COMPANY.YOUR_ID.YOUR_ADDIN_NAME
name=YOUR ADDIN NAME
supportJmpSE=0";
If you know your add-in is only supported on Windows or Mac, respectively, then you should add a line at the end of this string with either:
"host=Win"
Or
“host=Mac”
Next, create the string for your addin.jmpcust file:
addinjmpcustString = "\[<!-- JMP Add-In Builder created --><MENU_AND_TOOLBAR_CUSTOMIZATIONS jm="http://www.jmp.com/ns/menu" version="3">
<INSERT_IN_MAIN_MENU>
<INSERT_IN_MENU>
<NAME>Add-Ins</NAME>
<INSERT_AFTER>
<NAME></NAME>
<COMMAND>
<NAME>YOUR ADDIN NAME</NAME>
Your Addin Name
<ACTION type="path">$ADDIN_HOME(com.YOUR_COMPANY.YOUR_ID.YOUR_ADDIN_NAME)\YOUR_SCRIPT.jsl</ACTION>
<ICON type="none"></ICON>
</COMMAND>
</INSERT_AFTER>
</INSERT_IN_MENU>
</INSERT_IN_MAIN_MENU>
</MENU_AND_TOOLBAR_CUSTOMIZATIONS>]\";
Then, in order to package your JSL script as a file, first load it as a text file:
addinScript = Load Text File("$SOME_PATH\YOUR_ADDIN_NAME.jsl");
Then, write all of your files to a zip archive:
//create a ZipArchive to write files to
za = Open("$DOCUMENTS\YOUR_ADDIN_NAME.jmpaddin", zip);
//write all necessary files to ZipArchive (which can also be binary blobs)
za << write("addin.def", addinDefString);
za << write("addin.jmpcust", addinjmpcustString);
za << write("YOUR_ADDIN_NAME.jsl", addinScript);
Finally, you can navigate to the folder you saved your files to and see your add-in, which can be installed upon double-click.
I also created a more “fill-in-the-blank” version of the script, in case you wanted to automate your add-in creation (if you need to create multiple and have variable names for your add-in name, files, directory, etc.), which is below.
The two variable names used in the script are addinName and dir, which are defined as follows:
addinName: the name of your add-in as a string, with spaces and title capitalization as you’d like it to appear in the add-in menu (e.g. “JMP to R Add-In Builder”)
dir: the directory under which you would like to save your add-in
addinDefStr = "id=com.YOUR_COMPANY.YOUR_ID" || addinName || "\!n name=" || addinName || "\!n supportJmpSE=0";
addinjmpcustStr = "\[<!-- JMP Add-In Builder created --><MENU_AND_TOOLBAR_CUSTOMIZATIONS jm="http://www.jmp.com/ns/menu" version="3">
<INSERT_IN_MAIN_MENU>
<INSERT_IN_MENU>
<NAME>Add-Ins</NAME>
<INSERT_AFTER>
<NAME></NAME>
<COMMAND>
<NAME>]\" || uppercase(addinName) || "\[</NAME>
]\" || addinName || "\[
<ACTION type="path">$ADDIN_HOME(com.jmp.]\" || lowercase(regex(addinName, "\s", "", globalreplace)) || "\[)\]\" || addinName || "\[.jsl</ACTION>
<ICON type="none"></ICON>
</COMMAND>
</INSERT_AFTER>
</INSERT_IN_MENU>
</INSERT_IN_MAIN_MENU>
</MENU_AND_TOOLBAR_CUSTOMIZATIONS>]\";
addinScript = Load Text File("$SOME_PATH\YOUR_ADDIN_NAME.jsl");
//create a ZipArchive to write files to
za = Open(dir || "/" || addinName || ".jmpaddin", zip);
//write all necessary files to ZipArchive (which can also be binary blobs)
za << write("addin.def", addinDefStr);
za << write("addin.jmpcust", addinjmpcustStr);
za << write(addinName || ".jsl", addinScript);
Hope these scripts can help make your add-in creation projects smoother!
You can try edit->encrypt on your script(s). Do some testing and be prepared to rework some JSL. If you only have a small bit of secret code, consider moving it to its own include file and encrypting just that. The rest of the code will run normally.
An encrypted script has a hard time looking at itself; if you use expression manipulation or convert expressions to strings, expect some re-writing. Use show globals(); after your script runs to get an idea of what might leak.
Keep your plain text version somewhere safe!
A JMP add-in (.jmpaddin) is a Zip file (.zip). The three minimum components of a JMP add-in are the addin.def and addin.jmpcust files, as well as the JSL script that will run when the add-in is in use.
We would like to provide an add-in to a vendor, but would like the code associated with it to be kept secret. The statement above suggests that the code would be viewable. Is there any way to make an add-in in binary form so it couldn't (easily) be reverse-engineered?
@vince_faller, the "SE" in "supportJmpSE" stands for "Student Edition," so you only need this to be set to 1 if you need the add-in to work with JMP Student Edition.
Thanks for putting this together, Julia!
I just wanted to add a few more options you can add to the addin.def file.
- addinVersion - the version number that appears in the View > Add-Ins... dialog.
- minJmpVersion - the minimum version of JMP the add-in can be installed.
- maxJmpVersion - the maximum version of JMP the add-in can be installed.
addinVersion=1.3
minJmpVersion=12
maxJmpVersion=13
And if you're interested in using one of JMP's built-in icons for a menu item in your add-in, check out my Built-In JMP Icons add-in for the icon names and use the format below in the addin.jmpcust file.
<jm:icon type="builtin">JMPProSmall</jm:icon>