A Python Console for PageStream

When PageStream implemented an ARexx port on the Amiga there was a console that allowed directly typing in commands and having them interpreted by ARexx and thus directly and immediately scripting PageStream. This sort of interactive interpreter makes script development substantially easier and quicker than it would otherwise be.

Python itself provides such an interactive interpreter which definitely facilitates rapid development. But as PageStream uses an embedded Python interpreter there was no way, until now, to directly and interactively script PageStream using Python.

This script provides a console that works like neither the ARexx console nor the Python standard interactive interpreter. But it does provide a somewhat similar, albeit much more limited, interface. There are three components of the interface: the history view, the command string and the buttons.


History

The history view dominates the dialog starting at 10 characters wide by 10 characters tall. It can be sized larger, though not smaller, and provides a scroller as necessary. All commands that are typed are echoed into this view, along with the results of stdout. Commands are prefixed by ">>> " while stdout is displayed as is. This basically copies the look of the Python interactive interpreter.


Command

The command string is where Python commands are entered. They are executed by hitting return or clicking the "Execute" button. A command's execution may be immediate or deferred. To have a command execute immediately it must not be preceded by any white space and must not end with either a colon or a semicolon.

Immediate Execution

The command is executed and, if anything resulted to stdout (such as with a print statement), both the command and output are copied to the history view. Each execution is independent so variables are not carried over from one command execution to the next. This is a primary motivator in having deferred execution. To write to a variable in a way that is durable between executions you must refer to it globally. This is done by globals()['myVar'] where "myVar" is the name of the variable. For example, globals()['count'] += 1.

Deferred Execution

When command execution is deferred each command line is still echoed to the history view, but it is not executed. When the command execution does occur the actual single commandline is echoed to the history view as a reference, and then is followed by any output to stdout. The motivation for deferring should be clear now. To facilitate writing single command lines that defer execution any command that ends in a semicolon will be deferred. To force execution of the current commandline enter an empty command. When a deferred execution occurs the commandline is cleared. To retain its context copy the deferred command as echoed into the history view and paste that into the command string, followed by a semicolon.


Buttons

There are four buttons: help, close, clear and execute

Help
Theoretically clicking this button opens this help file.
Close
Closes the window and quits the script.
Clear
Clears the console history. Any changes to the global context remain.
Execute
Equivalent to pressing return in the command string—execution may be immediate or delayed as discussed above

Examples

  >>> temp = 12
  >>> print temp  

Nothing happens here because the variable "temp" has no value in the scope of the second command.


  >>> temp = 12;
  >>> print temp
  >>> temp = 12;print temp
  12  

This time the expected output results thanks to deferred execution


  >>> globals()['temp'] = 12
  >>> print temp
  12  

This time the expected output results because the value was stored in the global name space.


  >>> import time
  >>> print time.clock()
  exceptions.NameError
  name 'time' is not defined  

The import succeeds, but only within the scope of that first command execution. Again, this can be resolved by deferring execution.


  >>> import time; print time.clock()
  206.37