A script is text document that contains a list of commands for a computer system. By recording the commands in a text document they can be replayed over and over again without having to be re-entered by hand. This is particularly useful when command entry is slow or limited, such as on a handheld.
pedit has powerful scripting facilities, but like many of its more powerful facilities the learning curve is pretty steep. The pedit manual includes around 43 pages of documention which give all the pScripting details, but they are a little intimidating.
This tutorial assumes general experience of using pedit, but no previous scripting or programming experience should be necessary.
The scripts in this tutorial have been tested with peditPro 7.15 but the pedit family are updated frequently.
Since users can customize pedit to use different escape characters I’ve
followed the manual’s convention and used
ESC to indicate the escape
character. You will need to replace
ESC in the example code by the
escape character you have configured.
A pedit script, or pScript, consists of a script name followed by a list of pedit inputs. Invoking the script feeds the list of inputs to pedit as if they had been entered by the user.
pedit provides a single scriptPad; a separate edit area, similar to the magiPads. A menu option is provided for a scriptPad switcher, but at the moment only one scriptPad is supported. To go to the scriptPad do one of the following:
From a Memo:
scriptPad in|outfrom the
- Slide up from the [M] button
From the List View:
- Slide up from the [Recent] button
scriptPad is a special instance of magiPad and has the same menus and buttons. It can hold up to 32 Kbytes of pScripts.
Each pScript has the following structure:
The pScript is delimited by curly brackets.
pScriptName should be a unique name for the pScript. pedit can handle
scripts with identical names but it is simpler to keep each unique.
pScriptText - everything between the double colon and the closing
curly bracket - is the list of inputs to pedit that will be replayed
when the script is invoked. This can be up to 55 characters long. Any
white space, that is spaces, tabs or linefeeds (marking the ends of a
lines), are ignored and do not count towards that 55 characters.
For example, suppose that you keep a daily journal in peditPro and that each day’s entry begins with the date in the format:
But you find it tedious to enter the day name each day. Instead of
entering ‘Wednesday’ it would be so much quicker to run a ‘we’ script.
So you select
scriptPad in|out from the menu and enter the following:
and then click on the [OK] button.
To run the script position the cursor where ‘Wednesday’ needs to be entered and do one of the following:
Script Memo...from the
- Slide down from the [Q] button
pedit’s scriptName dialog
A ‘scriptName’ dialog will appear at the bottom of the screen. Enter
we and click on [:D] to run the script. ‘Wednesday’ will be inserted
at the cursor as a result of four stylus strokes instead of nine.
Any text in scriptPad outside of curly brackets is ignored, making it easy to add comments explaining what each script does. This may seem pointless for simple substitution scripts like ‘we’ but pScripting is addictive and you’ll be amazed by how soon you will be writing complex scripts that are not so easy to read and understand.
After using the ‘day name’ pScripts a few times you notice that you always have to enter a space after the year before calling the day name script. So why not update the script to put a space before the day name?
But, as mentioned above, white space is ignored so the space character has no effect. In cases where white space does need to be entered three special commands allow white space characters to be sent to pedit:
/xssends a space
/xtsends a tab
/xnsends a linefeed
So, updating your script to:
will have the desired effect, by explicitely feeding a space character to pedit before the day name.
Since white space is normally ignored it can be used to layout pScripts in a more readable manner, by placing each command on a different line. For example, it is easier to see what’s going on in our ‘we’ script when laid out as follows:
As well as text and white space, a script can contain pedit commands that are played back to drive the editor when the script is invoked. Let’s assume that after using the ‘day name’ scripts for a few more days you suddenly realise that you always insert the date before calling one of the scripts. Why not get the script to insert the day too?
ESC 6 command inserts the date and time, so we can update
the ‘we’ script as follows:
Remember to replace
ESC by whatever escape character you have
configured in the General tab of the
Preferences... dialog. On my
machine the escape character is ‘;’ and so the script reads:
Any pedit command accessible via the escape character can be issued in this way. For example the following script will hit [OK] to exit the current document, create a new one and insert the date for a new journal entry:
One problem with the new version of the ‘we’ script that inserts the date, is that it also inserts the time, destroying the classical elegance of the journal title. We need to update the script to go back and delete the time before inserting the day name.
Like everything in pedit, there is at least 17 ways this can be achieved. One way is send backspace characters to pedit, to cause it to delete the eight characters of the time. We can leave the space between the date and time, saving the script from having to explicitely output it.
Control characters, such as cursor moves and backspaces, cannot be entered directly into the script - they will just edit the script itself. Instead any character can be entered into the script for replay to pedit by specifying its hexadecimal (base 16) ASCII code. The ASCII encoding is a standard for allocating numerical codes to the characters that can be handled by a computer.
To find the ASCII code for a character supported by pedit do the following:
ASCII Table...from the
- pedit will display the 256 ASCII characters it supports
- Highlight a character and click on the [Q] button.
pedit values...dialog will be displayed. Click on [Next].
- The top line of the dialog will display the character details.
- Click [.Cancel]
For the character ‘A’ the
pedit values... dialog will display:
'A' = 0x0041 = 065
065 is A’s ASCII code in decimal.
Encoding details for ‘A’
Ox means that the following number is in base 16.
0041 is the base
16 value for ‘A’ in Unicode, but the last two digits are the same as the
code for ASCII. Note that base 16 needs 6 more digits than base ten, so
in this context A..F are digits not letters!
So from the above we can see that entering
/0x41 into a pScript will
send an ‘A’ character to pedit. Like in
/xs, the slash indicates that
the next character indicates a command rather than the character itself.
Certain ASCII characters are interpreted by pedit as cursor movement commands, for example:
/0x0Bmeans page up
/0x0Cmeans page down
/0x1Cmeans cursor left
/0x1Dmeans cursor right
/0x1Emeans cursor up
/0x1Fmeans cursor down
So issuing eight backspaces will remove the time from after the date:
In the first part of this tutorial it was mentioned that the pScriptText part of a pScript - that part that is replayed to pedit when the script is run - is limited to 55 characters.
This wasn’t entirely accurate. The Palm operating system maintains a 55 entry queue for text input to an application. When the user enters text via Graffiti or a keyboard the character codes are appended to the key-event queue at one end, and the application reads them from the other. The use of a queue means that characters are not lost if received from the user before the application is ready to read them. Up to 55 characters can be waiting in the queue for the application to handle them. This is why you can sometimes type ahead of pedit when it is updating the display, but the characters you enter are not lost.
pScripts make use of this key-event queue to feed commands and data into pedit. When the pScript is run it interprets the commands and writes the characters to the key-event queue. When the end of the script is reached, or the queue is full, control is passed to pedit which reads the key codes from the queue and processes them.
As you have probably realised multi-character commands in the pScript,
/xs may result in only one character being added to the
key-event queue. Let’s take a look at the last pScript we wrote and work
out what it places in the key-event queue:
So although the pScriptText is 51 characters long, it only appends 19 key codes to the key-event queue. The pedit manual lists the number of characters that each command or token adds to the queue.
Under some versions of the Palm operating system the size of the
key-event queue can be increased with the
However, this facility is no longer available under PalmOS 5+.
The last section mentioned a pFunction. pedit has numerous pFunctions that can be called from within pScripts to provide a wide variety of special services - everything from date handling to simulating Graffiti actions. Although we will cover numerous pFunctions in this tutorial series, we will only scratch the surface of the full range available. See the pedit manual for full detail.
pFunctions are all called with the following syntax:
pFuncName is the name of the function and
pFuncParams are a
list of parameters (that may be empty).
As you will see from the pedit manual many of the functions have two or
three versions. For example, the
/&pscript function that is used to
call another script has three versions:
/&pscript@- ‘immediate’ or ‘right now’ version
/&pscript- ‘runtime’ version
/&pscript$- ‘last action’ version
The versions only differ in at what point in the running of the script they are processed. In this section we will only consider the ‘immediate’ pFunctions.
When a script is being run pedit will process ‘immediate’ pFunctions at the point at which they appear in the script. Consider the following:
test1 is invoked pedit processes the first line, adding each
character of ‘This tests how ‘ to the key-event queue. It then
/&script@ pFunction. This tells pedit to temporarily
stop processing the current script and run the script named within the
square brackets. In pScripts
@@ is used as the delimiter for pStrings -
they indicate the start and end of a lump of text that is to be
considered as a single entity. In this case the pString is the name of
the pScript to be run.
pedit runs the
test2 pScript, which results in
added to the key-event queue. When the
test2 pScript finishes pedit
goes back to where it left off in the previous pScript. So it then adds
‘are invoked.’ to the key-event queue.
At this point, the
test1 pScript has finished and there are no other
scripts being processed, so pedit starts work on processing the
contents of the key-event queue. It reads each character that has been
queued and inserts it into the text being edited. The result is:
This tests how pFunctions are invoked.
So how do we use this exciting new ability to call one pScript from another in the real world? Going back to our ‘day name’ script example, we had seven individual scripts:
We have the same piece of code to output the day, month and year repeated for each day of the week. This is inefficient for three reasons:
- It is a waste of time entering the same code seven times. We want to enter it only once.
- It is a waste of space to store the same piece of code seven times.
- When we want to update the code (and we will) we want to change it just once in a single place.
The obvious solution is to move the code that outputs the day, month and year out into a separate pScript and call it from each of the day name pScripts. For example we can update the example to:
This is much neater and efficient, especially when, leafing through the
pedit manual, we discover that there are a series of
tokens that output different parts of the date. These include:
/dD- which outputs the day of the month.
/Lm- which outputs a three letter abbreviation of the month in the local language set on the Palm.
/dY- which outputs the year as four digits.
So we can make our date pScript more efficient by rewriting it (just once) as:
and the seven ‘day name’ pScripts do not need to be changed to take advantage of the new code.
Finally, you may have noticed while perusing the pedit manual section on
/d and related tokens, that
/LD adds the name of the current day to
the key-event queue. This means that all our individual day name
pScripts are redundant and that all we need is:
Note that we add a linefeed at the end so that user can start entering the diary text on the next line.