Version 2.3
January 14, 2011
Copyright 2005 - 2011 by Jamal Mazrui
GNU Lesser General Public License (LGPL)

Contents

Description


JAWS Script Exchange (JSX) is a free, open source program intended to assist and promote the sharing of script files among users of the JAWS screen reader (from freedomScientific.com). JSX facilitates both the installation and packaging of script files. If a set of script files are available in a zip archive, JSX will help you install them to the appropriate JAWS folder on your computer. If you have script files you want to share with others, JSX will help you package them into either a zip archive or a self-installing executable.

Installation


The installation program for JSX, itself, is called jsxSetup.exe. When executed, it prompts for an installation folder for the program. The default folder is c:\jsx. Although this is not a standard location for programs on a Windows computer, a benefit is fewer keystrokes to type whenever you manually enter the path to a zip archive (JSX always works with a "zip folder," which is c:\jsx\zip by default). If you want a standard installation folder, however, respond to the prompt by entering
C:\Program Files\JAWS Script Exchange

The installation process creates a program group for JSX on the Windows start menu, containing choices to launch JSX, read JSX documentation, or uninstall JSX. Also created is a desktop shortcut with an associated hot key, enabling JSX to be conveniently launched by pressing Control+Alt+Shift+J. Another shortcut is placed in the Send To folder so that a zip archive may be loaded into JSX via the context menu in Windows Explorer. Finally, the installation program silently installs--if not already present--the freely distributable "Inno Setup" program by Jordan Russell (from JRSoftware.org), which JSX uses whenever you create executable packages of scripts.
At the end of the installation process for the complete JSX application, six script sets are offerred. These options are unchecked by default. You can check one ore more of them to install their zip archives with JSX, i.e.,

BX, the Jaws toolbox, by Doug Lee (BSD license)

HomerKit, the Homer script library and editor interface, by Jamal Mazrui (LGPL license)

JFW Technical, menu-driven inspector of Windows environment, by Michael Curran

JLS Utilities, advanced alternative to JAWS home row mode, by Jim Snowbarger

Script Template, a template for event-based scripting of JAWS, by Jamal Mazrui (LGPL license)

Scripts for Microsoft Visual Studio 2005 or 2008, by contributors from the blind programming community (public domain)

The zip archives are stored in a zip subfolder of the JSX program folder. Shortcuts for installing them are included in the JSX program group on the Start Menu, so they may be installed at a later point, not just during installation of JSX.

A shortcut and zip archive are also made available for reading full documentation of JAWS, itself, in "structured text format." These are .txt files with organizational conventions that add navigational benefits of .chm files (the help format installed with JAWS). EdSharp, a powerful, speech-friendly editor, recognizes structured text format, and has hotkeys for efficiently searching topics or navigating sections within it. This free editor is available at
http://EmpowermentZone.com/edsetup.exe

Shortcuts to open zip archives of four other development tools for JAWS scripting are also available. They are by this author under the LGPL license:

AppStamp, utility for updating a package from a web server

HomerJax, registration-free COM server with web client and XML support

IniForm, utility for creating a dialog from an ini file

InPy, custom Python interpreter

Choosing the ZIP Archive


After JSX is setup, launching it activates a dialog called "JSX Installer." This collects information in preparation for installing JAWS script files from a zip archive. First, you are asked the name of the archive. You can either type its full path manually in the edit box, or tab once to the "Select Archive" button and invoke it with Enter or Spacebar. This invokes a standard "file open" dialog that defaults to the last folder used or a "\zip" subfolder of the folder containing the running jsx.exe program. (Alternatively, you can specify the zip archive as a command-line parameter to jsx.exe when it is launched--enclosing the name with quotes if it is a long file name containing spaces.)

Choosing the JAWS version and Language


Next in the Installer dialog are two list boxes for selecting the version and language of JAWS, based on what JSX finds available on your computer. If you have more than one version or language, it is up to you to decide which to use. By default, JSX selects the currently running version of JAWS (or if not running, the latest installed version), and the first language in alphabetical order. (If you only have the U.S. English version of JAWS installed, then "ENU" will be the only language abbreviation in the list of languages.) The language list adjusts automatically according to the JAWS version currently selected. The language list box will be visible but disabled if there is not more than one choice available.

Choosing the User


Next are a pair of radio buttons that let you decide whether to install for the "current user" of the computer or for "All Users." Current User is the default, and the particular name is shown (e.g., "Jamal.Mazrui"). It is generally not advisable to install into the All Users folder, since this involves more sweeping changes that are harder to undo. Also, Freedom Scientific discourages this because the JAWS online update feature may no longer work properly if that folder is changed. The option was introduced in an earlier JAWS version before this feature was available.

Choosing the Exe Association


The next controls are similar to the earlier ones that request a zip archive and provide a button to select one. Instead, these let you specify the name of the application's .exe file to associate with the scripts being installed. This is only necessary if the base name of the script files differs from the base name of the application for which they should be loaded. For example, if you want NoteTab.* scripts to work with the professional version of NoteTab, which has the name NotePro.exe, then you would enter NotePro.exe in the edit box, or use the Find button to locate the desired application name on your computer. The association is stored in ConfigNames.ini in the Settings subfolder. If modified, this file is included in a backup archive. More than one name is actually permitted in the "Exe association" edit box, and the .exe extension is optional. For example, a (fictional) delimited list could be entered as follows:
NoteLite|NotePro|NoteSuper

Configuration Check Boxes


Next are three check boxes entitled "Backup before replace," "Recompile new scripts," and "View zip folder after." The Backup choice is checked by default, causing JSX to zip any files that would be replaced by installing the new scripts. If any files exist with the same names, a backup zip archive is created in the same folder as the zip archive being used for installation. The name will be the same except for a numeric suffix before the .zip extension. For example, if the installation archive is skype.zip, then the first backup will be skype_01.zip. If a file by that name already exists, then JSX will try the name skype_02.zip, and so on.

The Recompile choice is unchecked by default. If checked, JSX will use the JAWS command-line compiler to produce new binary, .jsb files from the source, .jss files. This ensures the scripts are optimized for the JAWS version that you chose. If the script files are not compatible with that version, however, you may be informed of a compilation error. If you cannot manually correct the source files so they properly compile, then you may wish to install the scripts from the backup archive, if one was created.

The View choice is unchecked by default. If checked, JSX will launch Windows Explorer after the script installation process, browsing the folder of zip archives.

The Merge Option


A pair of radio buttons supports an advanced, merge feature, which enables a script developer to enhance an existing set of scripts (e.g., ones installed with JAWS) rather than replace them. By default, the radio button labeled "New scripts are complete" is checked, causing new scripts to completely replace any existing ones with the same names. If the radio button labeled "Merge new and existing scripts" is checked instead, then JSX will apply a relatively straightforward yet powerful merging algorithm described as follows.

JSX examines each file in the zip archive of new scripts to be installed. If an existing file with the same name is not found in the scripts folder, then JSX copies the new file there. If an existing file is found and it has an extension of jss, jsl, or jsd, then the new file is appended to the existing one--its content is placed at the end. On the other hand, if an existing file has an extension of jkm, jcf, or jgf, then JSX writes all key values of the new file into the existing one--either adding or replacing values depending on whether they already exist.

Since recompiling would be necessary after such a merging of script files, JSX automatically checks the Recompile check box if you select the Merge radio button. Conversely, JSX automatically deslects the Merge radio button if you uncheck the Recompile check box.

JSX 1.4 introduced a second, usually better way of merging. The Merge radio button should not be selected for this. In this example, the file HomerIE.jss contains enhancements to the Internet Explorer scripts supplied with JAWS. Place the following line at the top of the file:

;Merge "BrowseUI"

This tells JSX to merge HomerIE.jss into the script set associated with the base name BrowsUI (the file name is BrowseUI.dll). JSX looks up the association in ConfigNames.ini. With JAWS 8 and above, the main file of the script set is "Internet Explorer.jss." With lower JAWS versions, it is "Internet Explorer 5-6.jss."

JSX creates a container file with a set of Use statements that load script components in a particular order, thereby governing the inheritance chain of scripts and functions. The file also contains a dummy function at the bottom, which is needed so that the JAWS script compiler considers the file to be a valid script file, thus creating a valid .jsb version after compilation. The factory-supplied version of the .jsb is copied from the All Users script folder to a file in the user script folder with a modified name. A suffix of _fs (standing for Freedom Scientific) is added to the base name, e.g., Internet Explorer.jsb would become Internet Explorer_fs.jsb, or default.jsb would become default_fs.jsb. If a file with the same name as the container file already exists, it is backed up with a numeric suffix, e.g., to Default_01.jss.

The order of Use statements in the generated container file is determined by the following algorithm. If there is an existing container file, its component order is the starting sequence; otherwise it is an empty string. If there is a vertical bar (|) delimited list of components after the Merge word on the top line, its sequence is appended to the starting sequence after removing any duplicate items from the starting sequence. If the resulting sequence does not contain the _fs component, it is prepended to the sequence (so it serves as base functionality at the top level of the inheritance chain). If the current script component is not contained in the sequence, it is appended.

In our example, a container file called Internet Explorer.jss would be created and compiled with the following content:

; This is a container file, structured with conventions to support merging by the JAWS Script Exchange program.
; Rather than code of its own, the file contains a sequence of Use statements, followed by a dummy function to satisfy the JAWS script compiler.

Use "Internet Explorer_fs.Jsb"
Use "HomerIE.jsb"

Void Function _Filler()
SayString("This is to complete a container .jss so that it compiles to a valid .jsb")
EndFunction

Suppose we wanted to add AnotherIE.jsb to the sequence. We could do so with the following syntax on the top line:

;Merge AnotherIE.jsb "BrowseUI"

Now the container file would begin with the following statements:

Use "Internet Explorer_fs.Jsb"
Use "AnotherIE.jsb"
Use "HomerIE.jsb"

The merge algorithm is intended to accomplish several objectives:

* Previous JSX syntax for merging remains compatible.

* If no container file already exists, the component sequence will be the _FS file followed by the current file.

* If a container file already exists and no post sequence is specified, the existing sequence will be preserved.

* If a post sequence is specified, it can override the existing sequence.

JSX would also merge related .jkm and .jcf files, which are in .ini format, as follows. It iterates through all sections of the new file, and all keys within each section, writing the key/value pair to the existing file. Thus, if a key already exists, its value is replaced. If it does not already exist, it is created.

The merge target may be a delimited list of files rather than a single file, e.g.,

;Merge "BrowseUI|IEFrame"

If a question mark follows the semicolon, JSX asks for confirmation about whether to perform the merge, prompting with a warning on the remainder of the line, e.g.,

;?Merge "Microsoft Outlook.jss|Microsoft Outlook XP-2003.jss" For Homer benefits that require configuring Outlook for plain text email,

Push Buttons


The remaining controls ar push buttons. The first is Install, which is the default in the dialog--the one that will be activated by pressing Enter on any control except for another button. The Quit button exits JSX without taking any action. Escape does the same thing. The Help button displays a screen of usage tips for the dialog, a shortened version of this documentation. The Defaults button lets you restore JSX settings to their original values . Finally, the Packager button lets you switch to the other interface of JSX, intended for creating script packages rather than installing from existing ones.

The Packager Dialog


Most of the controls in the Packager dialog are the same as those in the Installer dialog. The last one by the way, is a button that toggles back to the Installer dialog. In the Packager dialog, the initial edit box lets you specify a zip archive. If it does not exist already, then use the next button to select script files to zip. You will be presented with a multi-select list box of script files and subfolders in the scripts folder of JAWS corresponding to the version, language, and user selections in subsequent controls of the dialog. The files and subfolders are alphabetized, so you can press a letter to go to the first item beginning with that letter. Press Spacebar to select it, or toggle Spacebar again if you change your mind. Since related script files generally have the same root name and different extensions, the other files you desire will probably be next in the list.

Press Enter (for the OK button) to accept the selections, or Escape to abort. If you had specified a name for the zip archive, it will be used for the new archive based on the files you selected. If you did not specify a name, then JSX will pick a name corresponding to the root name of the last .jss file you selected (e.g., skype.zip will be created based on skype.jss). If a zip archive with the same name already exists, JSX will ask whether to add files to that archive. Answer Yes to do so, or No to create a new archive based only on the items you just selected. You can also press Escape to abort the operation.

If you included a subfolder in your selection, e.g., one called skype containing additional support files for the skype scripts, the contents of the subfolder will be included in the zip archive, including relative paths to the lower items in the folder tree. The JSX Installer will recreate this subfolder from the zip archive.

If you only want to create a package in the form of a zip archive, then you are done. More likely, however, you will want to create a package in the form of a self-installing executable. The default, Package button creates this. Using the command-compiler of Inno Setup, it creates a compressed executable containing both the zip archive you specified and a copy of the JSX utility. For example, you might create the skype.exe package in the same folder as skype.zip. You can email skype to others or post it on a web site. When executed, it launches the included jsx.exe with the included skype.zip as the choice for the zip archive to install.

Installing from an Executable Package


In this mode of the JSX Installer dialog, the Packager button is not included, and the edit box for zip archive is read-only. Also, the button for selecting an archive is replaced by a check box for keeping a copy of the archive embedded in the executable. This choice is unchecked by default. If checked, the Install button not only places scripts in the appropriate JAWS folder, but places a copy of the zip archive in the same folder as the executable (e.g., skype.zip would be placed in the same folder as the setup program, skype.exe). In this way, you also have a copy of the zip archive that the author created. It may be easier to look for documentation files in it rather than in the JAWS scripts folder.

JSX does try to display documentation automatically, however, at the end of installation. It looks for a .htm or .txt file with the same root name as the archive e.g., skype.htm or skype.txt. If not found, it looks for one with the same root name as the last .jss file in the archive. If found, JSX opens it with the default program for that file extension, e.g., the default web browser or text editor.

Guiding Installation Choices
One more control deserves mention in the JSX Packager dialog. A check box before the Package button lets you recommend settings to the end-user during installation of the packaged scripts. This control, labeled "Guide package with current settings," is unchecked by default. If checked, the following JSX settings will be transmitted as starting values when the resulting package is executed: JAWS version, Language, Current/All Users, Exe association, Backup, Recompile, View, and Keep copy. The user can press the Defaults button (Alt+D) to set those values instead.

The CUSTOM.ISS Option


An advanced packaging feature involves a custom script file, custom.iss. This is not a JAWS script file, but an Inno Setup script file that JSX appends to the file scripts.iss before passing it to the Inno Setup compiler. Located in the JSX program folder, scripts.iss contains the template for an executable that bundles the JSX program, jsx.exe, with the zip archive to be installed. During installation, these files will be extracted to a temporary folder, and then jsx.exe will be run with the zip archive passed to it on the command line.

Adding functionality to the base template, a custom.iss file can contain nearly any Inno Setup sections except the initial [Setup] section. a developer may add custom.iss to a zip archive so that the resulting executable package performs tasks in addition to installing JAWS scripts to the scripts folder. For example, a help file for the JAWS scripts could be installed in another folder, or a configuration file for the application could be installed in the folder that it examines for such files.

An example custom.iss file is located in the JSX program folder, containing Inno Setup commands to install a .NET Framework assembly (lbc.dll) in the JFW program folder, a Microsoft Excel spreadsheet (timesheet.xls) in the My Documents folder, and an associated JAWS personalized settings file (timesheet.jsi) in the PersonalizedSettings subfolder of the scripts folder. Other commands run a .NET utility (regasm.exe) to register the assembly as a COM server, and launch a program (Notepad.exe) at the end of installation. Note that the custom.iss commands can make use of values for the JFW, scripts, and .NET folders (previously determined by code in the scripts.iss file). This sample custom.iss contains the following eight lines (which are long and may wrap in your viewing program):

[Files]
Source: "c:\jsx\tmp\timesheet.xls"; DestDir: "{userdocs}"; Flags: IgnoreVersion; Check: DirExists(ExpandConstant('{code:ScriptDir}'));
Source: "c:\jsx\tmp\timesheet.jsi"; DestDir: "{code:ScriptDir}\PersonalizedSettings"; Flags: IgnoreVersion; Check: DirExists(ExpandConstant('{code:ScriptDir}'));
Source: "c:\jsx\lbc.dll"; DestDir: "{code:JFWDir}"; Flags: IgnoreVersion; Check: DirExists(ExpandConstant('{code:JFWDir}'));

[Run]
FileName:"{code:NETDir}\regasm.exe"; Parameters: "/nologo /silent ""{code:JFWDir}\lbc.dll"" /tlb"; Description: "Install Layout by Code COM library"; Flags: runhidden
FileName:"Notepad.exe"; Flags: postinstall nowait

When creating an executable, JSX replaces the string "c:\jsx\tmp\" with the path to the temporary folder that it creates in the current session for unzipping the archive of script and other files to be installed. Based on scripts.iss, custom.iss, and string replacements at run time, JSX creates a temporary file, temp.iss, which it passes to Inno Setup for compilation. You can examine temp.iss in the JSX program folder to check what was used the last time JSX tried to create an executable. If JSX cannot create an executable, you may wish to debug temp.iss within the Inno Setup editor, then create a revised custom.iss once temp.iss compiles successfully. The JSX program folder also contains isetup.txt, a plain text version of the Inno Setup help file, isetup.hlp, which details the capabilities and syntax of this software.

Hot Keys


All controls of the JSX Installer and Packager dialogs are directly usable with unique, mnemonic Alt+Letter combinations based on the initial letter of the label for the control. Thus, as you become familiar with the controls, you can operate them more quickly with hot keys rather than navigating to them with the tab key.

Change Log

Version 2.3 on January 14, 2011
Implemented a different technique for finding the user script directory, which should work regardless of whether JAWS is running as a Windows service or user process (typically determined by whether JAWS starts automatically at Windows startup or not). Stopped the installation of Internet Explorer scripts if HomerKit.zip is installed, since those scripts conflict with IEMax scripts that have superceded them, available separately at
http://EmpowermentZone.com/IEMax.exe
or .zip for a manual install.

Replaced JAWS 11 documentation with that for JAWS 12, i.e., jfw12doc.zip. Included the latest version of Inno Setup, version 5.4.0A.

Version 2.2 on March 8, 2010

Miscellaneous fixes. Added merge support for .jgf files. During a merge, if a file with the same name as a container file already exists, it is now backed up with a numeric suffix, e.g., to Default_01.jss. Made JSX compatible with 64-bit Windows. Added three optional script sets: JFW Technical by Michael Curran, JLS Utilities by Jim Snowbarger, and Script Template by Jamal Mazrui. Included latest version of Inno Setup. Included additional development tools for JAWS scripting: AppStamp, HomerJax, IniForm, and InPy.

Development Notes


For those technically interested, JAWS Script Exchange is developed with the WinBatch language (from WinBatch.com) and the source code is in jsx.wbt in the JSX folder. Ideas and feedbak from the discussion list, JAWSScripts@BlindProgramming.com, have aided the design and testing of JSX. The latest version is available at
http://www.EmpowermentZone.com/jsxsetup.exe

The code is covered by a modified version of the GNU General Public License (GPL), which is explained at
http://gnu.org/copyleft/gpl.html
Essentially, software that uses the code must be open source, except that I am willing to relax GPL conditions in a particular case if persuaded that a greater good would result.

I welcome feedback, which helps JSX improve over time. When reporting a problem, the more specifics the better, including steps to reproduce it, if possible.

Jamal Mazrui
Jamal@EmpowermentZone.com

End of Document