The Rexx Interface in Amiga Mosaic

Description of Rexx

Amiga Rexx fills three distinct roles:

ARexx as a macro language

As a macro language, ARexx allows users to capture a series of commands, so that the entire series can be easily invoked later.

Simple examples of the macro language role of ARexx are menu entries to:

ARexx as a script language

As a script language, ARexx provides many of the same features found in popular script languages on other platforms, such as Perl or TCL. A feature-for-feature comparison is not appropriate for this paper, but such can readily be generated by asking on the newsgroup devoted to any script language.

As with other script languages, the important features of ARexx are text manipulation features-parsing strings, looking for substrings, character translation, and so forth. ARexx includes programming language features useful in scripts, such as associative arrays and a mix of dynamic and lexical scoping as well as more usual programming language features.

Examples of scripts include:

ARexx as an IPC language

IPC languages are relatively rare. Other script languages may include libraries to access IPC facilities without having a native IPC facility, or possibly have access to the IPC facility provided by the underlying operating system. ARexx provides its own IPC facility, built on top of the AmigaDOS IPC facilities.

ARexx's IPC facility is based on an application that processes command strings from the script and sends back result strings. ARexx includes facilities for switching between applications and for finding the name for the current application. The application can do any required processing, including setting variables in the ARexx script.

Examples of IPC facilities include scripts that:

If an application supports ARexx, it may be used as a ``back end'' processor by other applications, without going through a script. An example is an audio presentation system for HTML that normally opens an input file, but fetches the HTML for the current document from Mosaic if not given a file name.

Features of the Amiga Mosaic ARexx interface

The Amiga Mosaic ARexx interface is still evolving. To find out the latest details, read the Amiga Mosaic ARexx manual on the World Wide Web.

Invocation

ARexx progams can be invoked from Amiga Mosaic by a string input gadget. or they can be tied to an entry in the Amiga Mosaic menus. Both methods of program invocation can use either the program name and its arguments or a quoted string to be evaluated as a ARexx expression.

Amiga Mosaic has 10 menu entries for which the user can provide a label and Rexx program. Because of the success of external processing, the menu entries for ``Add Current to Hotlist'', ``Hotlist'' and ``Print'' invoke ARexx programs instead of internal functionality.

Selected commands

The three commands of most interest in user extensibility are:

Fetch
fetches information about documents on the web. A URL can be given, or the current document can be used. Available information includes the HTML source, the title, and lists of images and links in the document.
Get
gets information about the running Mosaic. The URL of the home document, the text of the displayed document, or the text formatted by Mosaic, the history list, and information about user interface elements are all available.
Jump
jumps to a new location. A URL may be specified, the history list can be traversed, or a reload or a jump to the home document can be done.

In all cases where a URL can be specified, it is possible to add an index or a point in a map.

Other commands

Other commands allow manipulation of the Mosaic options, or the user interface, such as opening and closing dialog boxes, changing the geometry of windows, and similar things. These commands provide a great deal of functionality in preparing slide shows and the like, but are not discussed here.

Examples of Amiga Mosaic ARexx scripts

Example macros

Macros are typically a short collection of commands to be issued to the application from which they were invoked. Many of them are single commands that encompass a number of user actions. A typical example for Amiga Mosaic is jumping to a specific URL from a menu entry, with a command like

"'jump file://localhost/data:html/index.html'"

The first level of quotes (") indicates that this is a ARexx expression, not the name of a macro file. The second level (') is the string the expression evaluates to, which will be sent to Amiga Mosaic for execution.

Another simple example would include starting some other command from inside from the Mosaic menu. For instance, an external hotlist facility might be started by:

"address command 'run amhotlist'"

In this case, the ARexx address facility sends the command to a shell.

A more complex example encapsulates cutting and pasting the URL into emacs-w3. It includes a test to see if emacs is running, and starts emacs if it isn't. This can be used to access the emacs-w3 multiline text support.

/* Called from Mosaic to cause emacs-w3 to display the current document. */
/* Gnu emacs on the Amiga, like AMosaic, has extensive arexx support */ 
/* If there isn't an emacs we can talk to, create one */
if ~show('P', 'EMACS1') = 0 then do
    address command                          /* Send commands to the shell */
    call pragma 'stack', 200000              /* stack does not grow on the Amiga */
    'run <nil: >nil: gnuemacs:temacs'        /* Run emacs */
    'WaitForPort' portname                   /* Wait for it to be ready */
    address                                  /* Now send commands to Mosaic */
    end

options results                              /* Request a result string from mosaic */
'get url'                                    /* get the url into the variable result */
address EMACS1 '(w3-fetch "'result'")'       /* Now, tell emacs to use w3 to fetch that URL */

exit 0                                       /* Exit cleanly */

Example scripts

Since ARexx allows scripting, there are some simple applications that repeat actions waiting for some condition to change.

/* Update the currently displayed URL every argument minutes. */

arg minutes                     /* Get the number of minutes we need to wait */

do forever                      /* We don't ever want to stop */	
    call delay minutes * 50     /* Wait one minute */
    'jump reload'               /* Reload the document */
    end

If the argument isn't a number or is missing, this script will exit with an error from ARexx.

Another useful example is an auto-redial facility that attempts to fetch a document until the document changes. A user would invoke this after a fetch fails for whatever reason.

/* Keep getting the currently displayed URL until it changes. This is
   basically an "auto-redial" to use on a system that's overloaded. */

options results                 /* Get result strings from Mosaic */
'fetch source'                  /* Get the current source */
bad = result                    /* Save it as the "bad" source */
do until bad ~= result          /* Until the source isn't bad */
    call delay 3000             /* Wait one minute */
    'jump reload'               /* Reload the document */
    'fetch source'              /* And get the source to check */ 
    end

A recent request on comp.infosystems.www.users was for a script to use Mosaic to fetch a URL and format it as ASCII. With the ARexx interface, this is nearly trivial:
/* Style is one of the text formats supported by Amiga Mosaic */
parse arg style url

address amosaic.1               /* Use Amiga Mosaic for everything */
'jump' url                      /* Go fetch the document */
options results                 /* We need the results from this */

/* Get the appropriate string, or complain */
select
    when upper(style) = "TEXT" then 'get text'
    when upper(style) = "FORMATTED" then 'get formatted'
    when upper(style) = "POSTSCRIPT" then do
        call request 0, 0, "Postscript doesn't work yet!"
        exit
        end
    otherwise call request 0, 0, "Invalid argument" style	       
    end

/* Open the printer device, or complain if we can't */
if ~open(printer, "prt:", "Write") then do
    call request 0, 0, "Can't open printer!"
    exit
    end

call writech printer, result      /* Print the string */
exit                              /* And exit */

Unlike hotlist facilities in other browsers, an Amiga Mosaic hotlist program can run independently of Amiga Mosaic because it can query Amiga Mosaic for the title and URL of the current document. A common hostlist processor turns the hotlist into HTML to create an interesting links page. Here's a script that does this automatically if invoked from a menu entry:
/* Add a hotlist entry to an HTML "hot list" file after the first
   blank line. Create the file with an appropriate format if need be. */

/* Argument parsing - what there is of it */
parse arg infile outfile
if infile = "" then infile = "envarc:Mosaic/hotlist.html"
if outfile = "" then outfile = "env:Mosaic/hotlist.html"

/* Get the line to be added */
options results
'get url'
url = result
'fetch title'
new = '<li><a href="'url'">'result'</a>'

/* Get my two file handles */
nofile = ~open(infile, infile, 'Read')
if ~open(outfile, outfile, 'Write') then exit 10

/* Copy (or create) the header. Everything up to the first blank line
   in the input file is header, and left alone. */
if nofile then do
    call writeln outfile, "<HTML><HEAD><TITLE>Hotlist</TITLE></HEAD>" ,
        "<BODY><H1>Pages of interest</H1><MENU>"
    call writeln outfile, ""
    end
else
    do until line = ""
        line = readln(infile)
        call writeln outfile, line
        end

/* Add the new line */
call writeln outfile, new

/* Now copy the rest of infile to outfile if needed */
if nofile then
    call writeln outfile, "</MENU></BODY></HTML>"
else
    do until eof(infile)
        line = readln(infile)
        call writeln outfile, line
        end

/* Clean up, and copy outfile back to infile */
call close outfile
call close infile
address command 'copy' outfile infile
exit 0

Application interactions

One of the most useful features of an ARexx interface is that applications can use each other as processors for other computations. This is an area that is still being explored, and some planned features should make Mosaic a useful as a front end for other applications.

Current examples include the html audio presentation system already mentioned, and a hotlist processor that runs as an external task.