55-Char Limit
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, such as /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:
| Script | Key-event Queue | |
|---|---|---|
| {we:: | ||
| ; | 1: | ; |
| 6 | 2: | 6 |
| /0x08 | 3: | <Backspace> |
| /0x08 | 4: | <Backspace> |
| /0x08 | 5: | <Backspace> |
| /0x08 | 6: | <Backspace> |
| /0x08 | 7: | <Backspace> |
| /0x08 | 8: | <Backspace> |
| /0x08 | 9: | <Backspace> |
| /0x08 | 10: | <Backspace> |
| W | 11: | W |
| e | 12: | e |
| d | 13: | d |
| n | 14: | n |
| e | 15: | e |
| s | 16: | s |
| d | 17: | d |
| a | 18: | a |
| y | 19: | y |
| } | ||
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 /&setKeyQSize pFunction. However, this facility is no longer available under PalmOS 5+.
Immediate pFunctions
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 [pFuncParams]
where 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 and 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::
This /xs tests /xs how /xs
/&script@ [@@test2@@]
are /xs invoked.
}
{test2::
pfunctions /xs
}
When test1 is invoked pedit processes the first line, adding each
character of 'This tests how ' to the key-event
queue. It then processes the /&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
'pFunctions ' being 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:
{mo::
ESC 6
/0x08 /0x08 /0x08 /0x08
/0x08 /0x08 /0x08 /0x08
Monday
}
{tu::
ESC 6
/0x08 /0x08 /0x08 /0x08
/0x08 /0x08 /0x08 /0x08
Tuesday
}
...
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:
{date::
ESC 6
/0x08 /0x08 /0x08 /0x08
/0x08 /0x08 /0x08 /0x08
}
{mo::
/&script@ [@@date@@]
Monday
}
{tu::
/&script@ [@@date@@]
Tuesday
}
...
This is much neater and efficient, especially when, leafing through the pedit manual, we discover that there are a series of '/d', '/L' and '/E' 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:
{date::
/dD-/Lm-/dY /xs
}
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:
{ds::
/dD-/Lm-/dY /xs /LD /xn
}
Note that we add a linefeed at the end so that user can start entering the diary text on the next line.