How Mac OS 9 Apps Exposed Data to AppleScript

During the classic Mac OS 9 era, spreadsheet and database applications exposed their internal data to AppleScript by implementing the Open Scripting Architecture (OSA) and adhering to the Apple Event Object Model (AEOM). Rather than providing direct access to raw memory or file structures, applications functioned as specialized Apple Event servers that mapped tabular data, records, and calculations into a hierarchical object model. This architecture allowed scripters to query, manipulate, and extract structured data using standardized English-like syntax via the underlying Apple Event Manager.

The Apple Event Object Model and Terminology Resources

To make data readable and writable, developers included an aete (Apple Event Terminology Extension) resource in their application's resource fork. This binary resource defined the human-readable vocabulary—classes, properties, and commands—that the Script Editor compiled into raw four-character codes (OSTypes).

The core mechanism enabling data exposure was the Apple Event Object Model (AEOM). The AEOM structured an application’s internal data into a containment hierarchy:

  • Application contained documents or databases.
  • Databases contained layouts, tables, and records.
  • Records contained fields or cells.
  • Spreadsheets contained workbooks, sheets, rows, columns, and individual cells.

When an AppleScript targeted an application, the script compiled commands into low-level Apple Events containing "object specifiers." The receiving application unpacked these specifiers and mapped them directly to its internal C, Pascal, or C++ data structures.

Data Exposure in Database Applications

Classic Mac OS databases, such as FileMaker Pro and 4th Dimension (4D), exposed data using terminology native to relational and flat-file management.

FileMaker Pro, for example, exposed its schema through objects like database, layout, record, field, and cell. Applications maintained stateful contexts during script execution:

  1. Targeting Layouts: Because databases separated presentation from raw tables, AppleScript often interacted with a specific layout to determine which fields were visible and modifiable.
  2. Current Record Navigation: Databases exposed properties like current record or allowed direct index referencing (e.g., record 12).
  3. Data Retrieval: Reading a field returned native Apple Event descriptors (AEDesc). Text, numbers, dates, and container fields (such as embedded PICT images) were coerced into their corresponding AppleScript data types.

A typical database query relied on the application’s internal search engine rather than external filtering. When a script executed every record whose cell "Status" is "Paid", the database intercepted the whose test, ran the search natively through its indexing engine, and returned only the matching record references.

Data Exposure in Spreadsheet Applications

Spreadsheet applications, such as Microsoft Excel 98/2001 and ClarisWorks (later AppleWorks), represented data through a coordinate- and range-based model.

  1. Ranges and Coordinates: Cells were exposed either via absolute references (e.g., cell "A1" or range "A1:C10") or matrix indices (e.g., cell 1 of row 2).
  2. Values vs. Formulas: Spreadsheet engines exposed multiple attributes per cell. A scripter could query the formula property to see the underlying calculation string or the value property to read the computed result.
  3. Bulk Data Transfers: Querying single cells iteratively caused significant inter-process communication overhead. To optimize performance, spreadsheets exposed the value of a multi-cell range as a list of lists (a matrix). This allowed the application to package an entire table of values into a single Apple Event reply.

Query Resolution and Descriptor Coercion

At the system level, communication occurred through the Apple Event Manager using Apple Event Descriptors. When an AppleScript issued a get command:

  1. Token Resolution: The application resolved the hierarchical specifiers into internal pointers or memory tokens.
  2. Type Coercion: The application extracted the native value and passed it to the system's coercion handlers, packaging the data into standard descriptor types like typeChar, typeShortInteger, typeFloat, or typeAEList.
  3. Delivery: The Apple Event Manager transported the descriptor list back across process boundaries to the AppleScript component, where it was reconstituted into native script variables.