[Users] [Developers] []

Word Services Suite Specification for Be

Second Draft

Michael Crawford
Crawford Software Consulting

Introduction to Word Services
This specification is subject to change
References
Where to Discuss the Protocol
The Word Services SDK
Basic Structure of the Protocol
Formal Protocol Specification
Word Services Discussion Archives

Introduction to Word Services

Word Services allows any application that uses text to link to an external spellchecker, grammar checker or other text service as if it is a built-in menu item.

Word Services is not just for spellchecking - server applications can do any sort of operation on text. For example, I am writing a text encryptor. Someone else is writing a Text to Speech reader on the MacOS.

The protocol provides basic tools for

Word Services is not just for word processors. Any application that allows text editing should consider using Word Services. Potential client programs include (among others): Word Services provides many advantages to users and developers over traditional built-in spellers.

Users can select a single speller and dictionary to share among all their applications. This means that disk space is required for only one dictionary, and that the user only has to teach new words to the spellchecker once. Also, a single user interface is used for spelling among all the client apps. Since Word Services is an open protocol, the user can pick their favorite server apps from several competing vendors. Word Services allows multiple servers to be installed. A user might pick servers for each of several languages, or for different functions. This is much better than using a built-in OEM speller, which is fixed and cannot be changed at will. The user only needs to pay for a speller once; programs that use OEM spellers have a hidden license fee, which the user would have to pay repeatedly even if they're using the same OEM code in different programs.

Client developers can provide the capability for spellchecking without the cost of actually licensing an OEM speller. Some client vendors will bundle Word Services spellcheckers, but many will not, depending on the user to either get one or use the server they already have. The protocol and SDK are free - this is a particular advantage for shareware and in-house software authors. Developers can link to support multiple servers by writing to a single, simple protocol, using sample source that is provided in the Word Services Software Development Kit. They don't have to debug someone else's weird code. On a protected memory OS like Be, Word Services particularly provides greater reliability by placing a firewall between the client and server - if the server crashes, it won't take down the client.

Word Services is easy to implement and easy to use. The burden of driving the protocol is placed on the server developers, so client developers will find it particularly simple to put Word Services in their applications. To use Word Services, a client program need only:

Clients don't need to implement the logic of an extended protocol. That is the responsibility of the server. This means it is harder to write a server, but it is not too hard.

This specification is subject to change

This is a beta draft of the Word Services Suite for BeOS, now updated for the Preview Release. It is an opening point for discussion, not the final cast in stone protocol standard. I invite you to implement applications based on the protocol draft, but be aware that if you do you will probably need to revise them slightly when the protocol becomes final.

The DR8 Word Services was based on Jon Watte's proposed scripting standard. Be provides a scripting API in the Preview Release that provides the communication facilities needed by Word Services. With the PR scripting we can be much more sure of the protocol spec; there remains only some details to settle.

References

This draft assumes a basic familiarity of Word Services for MacOS. The Be version will be similar to MacOS Word Services, with some changes and improvements. The best place to start learning about Word Services is the MacHack '94 paper on Word Services. Full details are given in the Word Services Apple Event Suite specification. Also, you will want to read the scripting documentation in the Be Book.

Where to Discuss the Protocol

I'd like to make a mailing list for Word Services. I haven't been able to do that yet. I think my service provider will allow me to make a simple group mail alias, which will work but has some drawbacks. For the present, I think the best place to discuss the protocol is on the Usenet Newsgroup comp.sys.be.programmer. Alternatively, you can send comments to .

I'll try to make digests of the comments and place them on the Word Services web site.

The Word Services SDK

I have written the initial Word Services Software Development Kit for BeOS. This includes a demo release of Spellswell and the early source code to QuickLetter Letter Writer. (QL will be a commercial product; in a future release I will branch off the code and call it Writeswell Jr., whose source will remain free).

Be thoughtfully provides the source code to BeMail on its installation CD. I have implemented Word Services in BeMail and provide the source code as an example to client developers. I have also written a Word Services add-on for Adamation's Adam e-mail client. The SDK provides a demonstration version of Spellswell that is be suitable for Word Services testing (full versions of Spellswell are be real cheap, though - Spellswell Plus for MacOS is just $14.95. A complimentary test copy will be provided to developers who actually implement Word Services in their products - it is hoped that all the Word Services vendors will exchange free test copies with the other developers). I may also provide another simple kind of server.

For various reasons I can't supply source code to a Word Services server. This doesn't mean you can't write one - it just means you have to try harder, by studying the protocol specification and testing with the example Word Services client, and with whatever clients appear. It's this way on MacOS too, and it hasn't stopped anyone. I am happy to clarify technical points in the protocol spec for anyone.

Get the Spellswell Demo appropriate for your machine, and also get the Word Services client source code. The executables are built for both architectures in the client zip file.

You may download:

Developers who are in the BeOS Release 4 beta test program may download: These can also be had from Michael Crawford's mirror site at Scruznet:

If you have a Macintosh, you may wish to download the MacOS Word Services SDK. It comes with the Spellswell Demo, the complete source code to Writeswell Jr., and the protocol specification in a double-clickable Common Ground document.

Basic Structure of the Protocol

Word Services on Be is similar to the Word Services Apple Event Suite. Experience with Word Services on MacOS has shown that there are some ways the protocol could be improved. We will do that for MacOS eventually, and hopefully do it in an upwardly compatible way. On Be we will start fresh and use what we have learned on the MacOS.

The most obvious difference is that the protocol will use BMessages to transmit data and requests, rather than Apple Events. The format of the BMessages uses the Scripting API provided in the Preview Release. The particular BMessages we will use are a "Batch Process My Text" request that the client sends to the server, and B_GET_PROPERTY and B_SET_PROPERTY messages that the server sends to the client to fetch and change the text.

The text that is operated on is described by "specifiers". These are logical descriptions of where the text is contained, rather than direct pointers to the text. For example, a client might say "Batch process the first text block that is in the window named Foo". The server can add to the object specifiers to make subranges, such as "Set the 12th through the 15th characters of the first text block of the window named Foo to 'bar'".

The client application must provide BMessengers that target the text objects instead of specifiers. The server will send messages directly to the client text using the BMessenger. Note that any class derived from BHandler may receive messages, and that BViews are descendants of BHandler. Thus one can send messages directly to a view. It is also suggested that BHandler-derived objects be used to spellcheck a text selection - a subrange of text, that will know about its view without actually being a view.

The protocol is initiated when the user selects a service from a client application's menu. We need to get the service into the menu. This is one of the more difficult parts of Word Services for MacOS users - they have a hard time choosing a service to add. Initially, I provided sample source code to do this using the PPC Browser, but the browser doesn't supply any way to filter based on type of service provided - Apple Events don't have any concept of port numbers as TCP does. A better solution is to select the server from a standard file open dialog, but even that is hard for some people.

On Be, the service menu strings are stored as attributes of the server applications. Each time a server runs, it validates its attributes and rewrites them if necessary (in case the attributes got stripped by being packed in a tar archive).

Each time a client application runs, it rebuilds the whole services menu by scanning each file system for applications that have the "WordServicesServer" attribute greater than or equal to one. This means that the server must take care to see that this attribute is indexed and to create the index if it is not. (The index only knows about attributes written after the creation of the index, so the server must also rewrite its WordServicesServer attribute if it created the index.)

The server attributes will include the WordServicesServer attribute, the "Menu String Count" attribute, and one or more "Menu String N" attributes where N ranges from 0 to Menu String Count - 1.

Once you have installed some services in the filesystem by running a server, you can use the Browser's Find command to list the installed services. Select "by Formula" from the popup menu, and enter "WordServicesServer = 1" in the text entry, then click Search.

On MacOS, the service that is selected is determined by which server application is executed. Each server application is allowed only one menu string. This means, for all practical purposes, that a given server can only do one thing - a server could check spelling, or it could check grammar, but it cannot be told to do one or the other. This has proven to be a disadvantage. On Be, a server may have one or more menu strings. Each string has an index. When a client initiates a transaction, it provides the index to the server which then provides the corresponding service.

The following code shows how to query the filesystems and build the Services menu:

This will also be an advantage for text encryptors. We can have a separate menu item for encryption and decryption.

The client gets to specify exactly what text is to be processed. On the MacOS Word Services SDK, Writeswell Jr. specifies all of the text in the document. This isn't really the desired behaviour - the user might have already spellchecked the beginning of the text, or she might not want to check quoted text in an e-mail message. It is better if the selected text is processed; all of the text will be processed only if there is no selection. The Be Word Services SDK will have this behaviour (in the next build), as will the MacOS SDK in the next release.

In order to spellcheck just a selection, though, a temporary BHandler will need to be created that knows about the selected text in the BTextView (or paragraph, or whatever object you use to hold text). The text operated on by the server will be specified relative to the end of the selected text, not the whole text, and the length of the selection will be changed as words are replaced. Sample code for this will be provided.

The client gets to specify the text either as a single chunk, or as many chunks. The chunks are given as an array of object specifiers in the batch BMessage. The server extracts the chunks one by one and processes them, sending back a single specifier to the client each time it needs to get text.

I've found an obscure problem with this in writing an encryptor for the Mac. If each of the specifiers form part of a single text flow, such as paragraphs within a single story on a page layout, there is no problem - we can encrypt all of the text together and replace all of the objects with a single monolithic chunk. If the specifiers point to discrete objects, such as text fields in different records of a database, then they should be encrypted separately and replaced one at a time. There is presently no way to specify this on the MacOS. On the BeOS, a parameter to the Batch BMessage will specify a "contiguity" condition of either true or false. This parameter is optional; if it is absent, then it is assumed to be true.

Normally, a client can send a batch message and then forget all about Word Services - it just resumes its BLooper loop. The server drives the protocol, and the client passively responds to its requests, but it need not remember any state about Word Services. If the client needs to know when a transaction is complete, it can keep a flag noting that it is in Word Services, and reset this flag when a termination BMessage is received. The default behaviour for most clients will be to just ignore this message. A program that needed to do something special could pay attention to it. An example is that an e-mail program might want to have a "spellcheck before sending" option. It needs to know when checking is finished so that it can send the message.

Alternatively, the client may instantiate a "Word Services Session" object that keeps any necessary state, and delete it when the termination message is received. The destructor can fire of a BMessage the starts the process desired after checking.

Client developers that plan to use this need to be aware of a couple of things. The client does not know exactly what services are in the menu; the user can see them as text strings but the contents of the string are up to the server developer and provided only for the benefit of the user. The client program is expected to not interpret the strings. There could be more than one service in the menu; a user interface will be needed to select which service to perform before sending. It is conceivable that more than one service is desired by the user, in a particular order - for example, spellcheck and then encrypt. (Much better than spellchecking after encryption!) Finally, it is possible that the speller may crash or terminate abnormally without sending the termination message. The client needs to be prepared to deal with user input if it occurs before the termination message is received, and not lock the user out somehow.

When a speller finds an erroneous word, it is best if the word is highlighted in the original document. This would also be helpful for text to speech readers, which would highlight words as they progress. This is done by having the server set the "BackgroundHilite" property of a character range in the client document. This is optional for the client, but it is expected. If the client cannot do this, then the server should show a text box with the text. This has a great disadvantage, as the text is shown without formatting and without it's original context in the document. Please support background highlighting in client applications.

When the server changes some text in the client document, the document will change its length. This affects the offsets of the text, and makes it hard for a server to keep track of its position properly. For this reason, text positions are specified relative to the end of the enclosing text block using a B_REVERSE_INDEX_RANGE specifier. Instead of changing the 1st through 5th characters from the beginning of a paragraph, we would change the 100th through the 96th from the end.

There is a difference in the way text is replaced on the BeOS from the way it is done on the MacOS. On the Mac, one does a Set Data with the range specifier and the new text. Just one event is sent. On the BeOS, one must first send a B_SET_PROPERTY message with the range but no "data" item in the message. This deletes the text. Then one sends another B_SET_PROPERTY with the new text in the "data" item. This inserts the text.

Deleting and inserting the text can cause the font and style of the word to be lost. Before deleting the text, the server should use a B_GET_PROPERTY event to get the style of the first character of the word and set the new text to that style after insertion.

Formal Protocol Specification

Under Construction

The initial formal spec will be provided later today.

[Users] [Developers] []