Satimage Previous | Next
The AppleScript dictionary - the sdef file
Home Documentation Smile Computing Working with external codes The XCode projects The AppleScript dictionary - the sdef file  

You know how to have your code handle the AppleEvents that AppleScript will send. Now you must write the AppleScript dictionary of your application/Scripting Addition.

A program's AppleScript dictionary specifies the terminology that a script has to use to communicate with the program. You can view the dictionaries available with the File > Open a dictionary menu in Smile.

The .sdef file

To make the dictionary for your program, you rewrite the «ProjectName».sdef file in the project. This is an XML file.

Smile is an XML editor, where you can check your file. To open the file in Smile, drag its icon to the icon of Smile. The file opens in a new Unicode window. To check the XML syntax, press ^⌘R. To check the validity of the XML with respect to its DTD (as a sdef file), press ⌥⌘R. The error messages that you will get are very helpful to diagnose and solve any problem with the .sdef file.

Introducing XML

If you are not familiar with XML, all you have to know is that it is tagged text. A tag starts with < and ends with >. For instance <tag> is an opening tag. It has to be closed with a closing tag, which has to be </tag>. The tags define one element, and they enclose some text which in turn is XML - or raw text. <tag/> is a shortcut for <tag></tag>, an empty element. A tag may contain attributes, for instance in <tag name="fred"/> the tag element has a name attribute whose value is "fred". Elements may be nested but not interlaced.

In the .sdef file you have to write strings which may be lenghty - see for instance the description attribute. Since you are writing XML, some characters cannot be written as such. Use the following equivalents.

to have ...write ...

Structure of the .sdef file
The structure is described in man sdef.
Actually it is enough to use the examples provided. You duplicate existing classes or commands, and you change the attributes as required. The information is not the extensive documentation of sdef files, but it will enable you to make your own dictionary.
  • Suites
    A dictionary may contain several Suites (see for instance Smile's dictionary).
    The dictionary element may contain one or several suite elements. A suite requires two attributes: name and code (a string of 4 characters which specifies the Suite). It is usually good to provide also a description attribute.

    <suite name="Sample Additions" code="SAMP" description="This is a sample by Satimage to be used within Smile. Check for additional information.">

  • The classes
    A suite may contain one or several class elements. A class requires two attributes: name and code attribute (a string of 4 characters which identifies the class). It supports optional attributes.

        <class name="array of real" code="Lido" hidden="yes" plural="arrays of real">
        <class name="matrix" code="Matr" hidden="yes" plural="matrices">

  • The commands

    A suite may contain one or several command elements. A command requires two attributes: name and code. It supports optional attributes.
    The value of the code attribute should be 8 characters which identify the command: they make the two codes of 4 bytes which identify an AppleEvent. The first four characters should be the Suite's code. Those are the characters that you specify in EventDescription gEventDescriptionList[], in the file «ProjectName».cp.

    A command may contain a direct-parameter and a result, and parameter elements. These elements require a type attribute, and they should also be provided with a description attribute. The type attribute's value must be, either an AppleScript elementary type (integer, real, string, etc.) or a class already defined. In addition to the type attribute, the parameter elements require the two attributes name and code.
    The value for the code attribute must be a string of 4 characters which identify the parameter. This code is the AEKeyword that AEGetParamDesc expects when reading the input parameters (in the «ProjectName».cp file).

    Example :

                   <command name="mandelbrot" code="SAMPMAND" description="compute a fractal set associated to the iterations of the analytic function f(z)=z*z+c">
                        <direct-parameter type="integer" optional="yes" description="maximum number of iterations. Default: 2556."/>
                        <result type="matrix" description="a matrix containing for each value of c the number of iterations necessary to reach abs(f(z))&gt;2"/>
                        <parameter name="xdata" code="x$$$" type="array of real" description="real part of c"/>
                        <parameter name="ydata" code="y$$$" type="array of real" description="imaginary part of c"/>
                   <command name="julia" code="SAMPJULI" description="compute a julia fractal set">
                        <direct-parameter type="integer" optional="yes" description="maximum number of iterations. Default: 2556."/>
                        <result type="matrix" description=""/>
                        <parameter name="xdata" code="x$$$" type="array of real" description="real part of c"/>
                        <parameter name="ydata" code="y$$$" type="array of real" description="imaginary part of c"/>

    In this example, the variable gEventDescriptionList in the source code (in «ProjectName».cp) should be like below.

    EventDescription gEventDescriptionList[]={{'SAMP','MAND',0}, {'SAMP','JULI',1}};
    And an OsaxEventHandler function could be as follows.
    pascal OSErr OsaxEventHandler(const AppleEvent* message, AppleEvent* reply, long refCon){
              case 0: return MandelbrotFractalHandler( message, reply);
              case 1: return JuliaFractalHandler( message, reply);
              //insert here other cases as needed.
              default:return errAEEventNotHandled;

Important remarks
  • Naming a new command
    In your dictionary, you will define new verbs, new prepositions (the keyword to introduce a parameter for a verb), and new classes. If you choose a name already declared in another dictionary (in Smile's dictionary, or in a Scripting Addition's dictionary) you will experience terminology conflicts. It is important 1. to define as few new terms as possible - in order not to clog up the terminology space, 2. to define terms as specific as possible.

    The first rule is: do not use a term which would exist as such in the English language. For instance if you program a Scripting Addition which applies some minimization algorithm and you would like to name your function minimum, change your mind. (minimum is already a keyword in Satimage.osax.)

    Various strategies can avoid terminology conflicts. You can use compound names, for instance FindMinimum. A nice name for a new verb may be a name made of two words or more, such as find minimum value. AppleScript has no problem with names of several words, even when one of the individual words alone would conflict with an existing term.
    Another solution is to prefix all your new commands with a code of yours. For instance, all commands in the XMLLib.osax Scripting Addition begin with the three letters XML, making the naming pattern quite obvious (XMLOpen, XMLclose, etc). This ensures that neither you nor the users of your program will experience any terminology conflict.

  • Selecting a new 4-bytes code
    You will have to define new codes of four bytes - those codes make the connection between your dictionary and the C program. It is of primary importance that you use non-existing codes, or if you want to use terms that are already defined, that you use their respective codes. The list of the codes and terms defined by Apple can be found on this page. These codes may be any sequence of any four bytes.

    The first rule is: the codes that Apple defines use only lower-case alphabetical letters (for instance sdsk is the internal code for the term startup disk). Only define codes which include at least one upper-case letter or some non-alphabetical character.

    You can rapidly test whether a code of four bytes is already defined or not. Suppose you would want to test whether 'Par1' is already defined. In an AppleScript terminal in Smile, write «class Par1» in a new line. Run the line by pressing ⌘R. If the code was already defined, the expression with the chevrons will automatically be replaced with the corresponding term. (For instance, «class long» will compile into integer.)

    Checking whether an AppleEvent's identifier (made of two codes of 4 bytes) is already defined is similar. Suppose you are planning to use the SAMPMAND code. Run the following expression: «event SAMPMAND» in an AppleScript terminal. If the expression does not compile into an English-like term, then the code is free.

  • When changing a term
    When you change the AppleScript term for a command in your scriptable application without changing its 4-bytes code - for instance you rename your findMinimum command into reach minimum - the new terminology is available only after you quit and relaunch Smile.
Version française
Copyright ©2008 Paris, Satimage